簡體   English   中英

JVM垃圾收集和內存Java數據庫

[英]JVM Garbage collection and In Memory Java Databases

我們正在評估一些基於Java的內存數據庫,如Hazelcast和VoltDB。 如果我們跨多個服務器復制數據,那么兩個節點的GC可能會同時命中服務器嗎?

例如,我們有兩個節點具有500 GB的內存,我們知道GC一旦開始就會大大影響我們的性能。那么兩個節點中的GC可能會出現什么樣的可能性呢?

換句話說 - 是否有可能阻止GC通過某些配置同時命中兩個節點? 我們期望每秒大約15k個請求的吞吐量,因此通過分布在4個或更多節點上,我們可以同時針對一個節點點擊25%的性能命中和相應的大小。

如果您確實想要阻止GC問題,請不要使用堆。 這就是為什么我們要為Hazelcast添加一個offheap商業產品。

在一般情況下:如果您將對象保留太長時間,或者創建頻率太高的對象而將它們復制到任期空間,則會出現GC問題。 因此,許多高速應用程序首先嘗試防止創建對象垃圾。

我目前正在開發Hazelcast的POC實現,其中完全刪除了對象創建。

您無法通過任何配置同時阻止GC在不同JVM中啟動。 話雖如此,您應該查看您的應用程序並可以微調GC。

正如Ben所指出的,VoltDB將所有數據存儲在堆中。 堆僅用於事務路由和存儲過程執行期間的臨時空間,因此每個事務的數據僅存活幾毫秒,並且大多數數據永遠不會在GC期間被提升或生存。 實際的SQL執行也是在堆之外執行的,因此臨時表不會生成垃圾。

VoltDB中的GC應占執行時間的1%。 您可以通過適當調整年輕一代的大小來選擇百分比。 在該吞吐量下的真實世界部署每隔幾秒就會執行一次年輕的GC,並且GC應該僅阻止一位數毫秒。 舊的發電機組應該很少,大約幾天,並且應該只阻斷10毫秒。 如果您想確保它們在非高峰時段發生,您可以手動調用它們。

我不明白為什么跨節點的並發GC很重要。 最糟糕的情況是,如果作為事務依賴關系的每個節點都背靠背地執行GC,那么延遲就是所涉及節點數量的總和。 我建議您測量並查看它是否實際影響了對您來說重要的一段時間的吞吐量。

我們在最新版本中為延遲付出了很多努力,我可以共享其中一個KPI。

這是一個3節點基准,50/50讀/寫32字節鍵和1024字節值。 有一個擁有50個線程的客戶端。 基准測試期間存在節點故障,基准測試運行30分鍾。 這不是吞吐量基准,因此只有一個客戶端實例具有少量線程。

Average throughput:               94,114 txns/sec
Average latency:                    0.46 ms
10th percentile latency:            0.26 ms
25th percentile latency:            0.32 ms
50th percentile latency:            0.45 ms
75th percentile latency:            0.54 ms
90th percentile latency:            0.61 ms
95th percentile latency:            0.67 ms
99th percentile latency:            0.83 ms
99.5th percentile latency:          1.44 ms
99.9th percentile latency:          3.65 ms
99.999th percentile latency:       16.00 ms

如果您進一步分析數字並與其他事件和指標相關聯,您會發現即使在高百分位數時GC也不是一個因素。 Hotspot的ParNew收集器非常好,如果你可以保持你的工作設置小,避免升級,即使在延遲方面很糟糕,它在吞吐量方面也很好。

在堆上存儲數據的數據庫必須更關心GC暫停。 在VoltDB,我們只關心它們,因為我們經常通過最大暫停時間來評估,而不是平均暫停時間或某個百分位數的暫停時間。

假設您在具有大量內存和內核的大型(ger)服務器上運行Hazelcast / VoltDB,新版Java中的Garbage First(G1)垃圾收集器可以在很大程度上改善您的擔憂。

http://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html

VoltDB將表數據存儲在堆中。 內存由SQL執行引擎進程分配,這些進程是用C ++編寫的。

VoltDB中的Java堆用於相對靜態的部署和與模式相關的數據,以及用於處理請求和響應的短期數據。 使用直接字節緩沖區和其他結構(甚至可以在此處閱讀更多內容),其中大部分內容都保持在堆外。

對於像Geode一樣保持一致性的內存數據庫(即在發布客戶端線程之前對其他節點進行同步復制),您的網絡將比熱點編譯器更受關注。 不過,這里有兩點輸入可以讓你達到語言不相關的程度:

1)如果要對讀取進行大量創建/更新:使用服務器上的堆外內存。 這最大限度地減少了GC。

2)使用Geode在C / C ++和Java對象之間的序列化映射來避免JNI。 具體來說,使用DataSerializer http://gemfire.docs.pivotal.io/geode/developing/data_serialization/gemfire_data_serialization.html如果您計划廣泛使用查詢而不是獲取/ puts,請使用PDXSerializer: http ://gemfire.docs .pivotal.io /晶洞/開發/ data_serialization / use_pdx_serializer.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM