生產環境HBase集羣內存常常處於高位(90%),並且GC以後也是內存依然處於高位,經分析內存所有由集羣的regionserver進程所持有,,常常重啓以後,大概3-4天就會保持在高位。由上述症狀,能夠判斷集羣內存有泄露的嫌疑。segmentfault
HBase系統中有兩塊大的內存管理模塊,一塊是MemStore ,一塊是BlockCache,前置是用於集羣寫入所屬內存,然後者用於緩存熱數據,提供查詢速度。這二者都可以經過配置文件進行配置。當前集羣均配置了0.4和0.4的比例。而考慮到HBase集羣是多寫少讀的情景,爲此而引入了MSLAB機制來優化HBase的MemStore 負擔。內存的使用率會呈現很優美的鋸齒圖形。緩存
起初認爲是讀寫業務量已經超過了集羣負載能力,但集羣業務也不大,寫和讀的TPS,帶寬吞吐量均未達到集羣限定的能力,並且CPU利用率大多半都被GC佔用,但內存就是持高不下,即便業務了停了一天,內存仍是不怎麼降低,很明顯和業務量無關。ide
那麼和compaction有關?經觀察的確能夠看compact時特別消耗時間。此時感受看到了但願,調整各個參數,把compact操做提高了10+倍以後,內存仍是持高不下 。剩下最根治的辦法就是分析內存,看一下內存數據都是什麼?有無內存泄露問題。函數
節點dump下regionserver的內存,分析發現內存中有50個RpcServer.FifoRWQ.default.read.handler線程,每一個線程持有了1.2%左右的總內存,那麼全部的線程持有的內存佔有量大於爲50*1.2%=60%。隨着查詢次數增多,線程持續的內存還會持續增長,以下圖。源碼分析
分析每個線程持有的內存數據,所有都是業務信息。優化
那麼繼續分析,此業務信息所屬對象:org.locationtech.geomesa.filter.factory.FastFilterFactory。而對比同規模的集羣,的確是此異常集羣開啓了GeoMesa特性。找到問題所在,那就看源碼分析是惟一出路。spa
經分析GeoMesa源碼,緩存數據爲GeoMesa的filterCache,所有都是查詢的條件及其優化後查詢條件。以下代碼:線程
override def getOrElseUpdate(key: K, op: => V): V = { val cached = caches.get.getIfPresent(key) if (cached != null) { cached } else { val value = op
//value=optimize(sft, ECQL.toFilter(ecql))
caches.get.put(key, value) value } }
致使集羣隨着查詢次數增多,內存一直持續不下。code
可否去掉此處緩存策略呢?爲何緩存此查詢信息呢,目的就是爲了減小一樣的查詢再次被優化的步驟。那麼咱們查詢添條件key有沒有重複使用,此處有個嚴格規定,就是key中不只保證使用相同的GeoMesa函數還有使用相同的參數,基於這個原則,業務上查詢條件是沒有重複的。server
咱們配置了可選參數useFilterCache,默認是開啓的,不必緩存此查詢條件,應予以刪除。
在配置文件中添加了useFilterCache參數,默認是開啓的,根據業務須要選擇開始和關閉filterCache特效。
經分析咱們業務場景不必緩存此查詢條件,,應予以關閉。優化後的集羣內存使用率狀況就恢復了正常狀態。