【SolrCloud原理】Solr Overseer優化啓動性能

一、集羣信息
Solr版本:Solr 6.2,內核修改較多
集羣規模:30個節點,每個節點5個SolrServer實例;1000 coll * 10 shard * 3 replica = 30k core

二、優化前集羣啓動狀況

  1. 重啓成功還是失敗?失敗,索引無法對外服務。
  2. 重啓時長多長?重啓失敗後需維護人員手工干預,每個實例重啓約8分鐘。WTF~~
  3. 日誌信息彙總分析(Solr和ZK)從ZK看到stat /solr/overseer/queue達到9W多,可見消息積壓嚴重。 stat /solr/overseer/queue

三、優化後集羣啓動狀況

  1. 重啓成功還是失敗?成功!!!
  2. 重啓時長多長?約30分鐘左右,集羣所有索引狀態恢復正常。
  3. 日誌信息彙總分析(Solr和ZK)stat /solr/overseer/queue最多隻到達16000個子節點。注意Overseer中的STATE_UPDATE_MAX_QUEUE=20000可能導致隊列佔滿異常的情況,已經適度調大,並在ZkDistributedQueue對寫入ZK增加重試邏輯。

四、Performance Benchmark

  1. 3W Core無數據 —— 重啓耗時統計:重啓Solr集羣約30分鐘,所有shard狀態正常。
  2. 每個實例500M —— 重啓耗時統計:重啓Solr集羣約40分鐘,所有shard狀態正常。
  3. 每個實例1G —— 重啓耗時統計:重啓Solr集羣約40分鐘,所有shard狀態正常。
  4. 每個實例10G —— 重啓耗時統計:重啓Solr集羣約41分鐘,所有shard狀態正常。
  5. 每個實例100G —— 重啓耗時統計:重啓Solr集羣約68分鐘,所有shard狀態正常。
  6. 每個實例300G —— 重啓耗時統計:重啓Solr集羣約85分鐘,所有shard狀態正常。

五、社區Jira分析與總結
Overseer can become the bottleneck in very large clusters
這是個大單子,還沒有徹底解決,一共包含了4個子單,其中3張子單已經resolved。其中本次優化主要合入Solr 6.2的是以下四張單子:

  1. Improve stability and startup performance of SolrCloud with thousands of collections
    https://issues.apache.org/jira/browse/SOLR-7191
    主要優化點:
    a. 將coreZkRegister的實現類從newMDCAwareCachedThreadPool改成了newMDCAwareFixedThreadPool,因此需要將線程數作爲參數傳入;
    b. SolrCore,SolrCores,CoreDescriptor支持排序

  2. Better ZkStateWriter batching
    https://issues.apache.org/jira/browse/SOLR-10524
    主要優化點:
    a. 批量讀取ZK中Overseer queue的消息
    b. 對Msg排序,逐個處理移除

  3. Optimize using cache for DistributedQueue in case of single-consumer
    https://issues.apache.org/jira/browse/SOLR-10619
    主要優化點:
    a. 添加一個flag布爾參數singleConsumer,針對該場景做優化
    b. 優化fetch from zk的條件

  4. Remove the usage of workqueue for Overseer
    https://issues.apache.org/jira/browse/SOLR-11443
    主要優化點:
    a. Overseer中移除了workqueue的設計,採用batch操作大大縮減了對ZK的寫入壓力,但仍然是單線程循序處理Overseer queue的消息。
    b. ZkStateWriter中添加批量更新的設計,優化了flush機制:與上一次寫入ZK間隔2秒或者積壓10000個狀態更新請求時才往ZK寫入一次。這個設計減少了Overseer與ZK之間的網絡通信往返次數,大幅度提高ZK寫入性能。
    c. ZkDistributedQueue中添加批量刪除ZK node的remove方法,同樣減少了Overseer與ZK之間的網絡通信往返次數,提升了寫入效率。
    d. That is all?

References
https://issues.apache.org/jira/browse/SOLR-5872?jql=text ~ "overseer" (Overseer的JIRA單真不少!)
https://issues.apache.org/jira/browse/SOLR-5872 (你想消除Overseer?!那你就去做丫~)
https://issues.apache.org/jira/browse/SOLR-10265 (So great!!! Overseer是大集羣的性能瓶頸,分析得很清楚!)
https://issues.apache.org/jira/browse/SOLR-5475 (多線程想法,咋沒人實現尼?風險在哪裏?)
https://blog.csdn.net/iteye_423/article/details/82614070

還有兩張更久遠的單子:

  1. New optimized DistributedQueue implementation for overseer
    https://issues.apache.org/jira/browse/SOLR-6760

  2. Improve stability and startup performance of SolrCloud with thousands of collections
    https://issues.apache.org/jira/browse/SOLR-7191

啓動異常解析
1、Solr 6.2的PeerSync.java在高亮那行報了空指針異常:
【劃重點】開源Solr 7.4之後對PeerSync.java優化,增加了判空邏輯,社區相關JIRA單爲https://issues.apache.org/jira/browse/SOLR-10169

2019-01-23 18:32:17,169 | ERROR | recoveryExecutor-3-thread-112-processing-n:189.39.172.103:21104_solr x:coll_test497_shard1_replica1 s:shard1 c:coll_test497 r:core_node8 | Error while trying to recover. core=coll_test497_shard1_replica1:java.lang.NullPointerException
at org.apache.solr.update.PeerSync.alreadyInSync(PeerSync.java:339)
at org.apache.solr.update.PeerSync.sync(PeerSync.java:222)
at org.apache.solr.cloud.RecoveryStrategy.doRecovery(RecoveryStrategy.java:382)
at org.apache.solr.cloud.RecoveryStrategy.run(RecoveryStrategy.java:222)
at java.util.concurrent.ExecutorsRunnableAdapter.call(Executors.java:511)atjava.util.concurrent.FutureTask.run(FutureTask.java:266)atorg.apache.solr.common.util.ExecutorUtilRunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.solr.common.util.ExecutorUtilMDCAwareThreadPoolExecutor.lambda$execute0(ExecutorUtil.java:229)atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)atjava.util.concurrent.ThreadPoolExecutor0(ExecutorUtil.java:229) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutorWorker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
| org.apache.solr.common.SolrException.log(SolrException.java:159)
2019-01-23 18:32:17,169 | INFO | recoveryExecutor-3-thread-112-processing-n:189.39.172.103:21104_solr x:coll_test497_shard1_replica1 s:shard1 c:coll_test497 r:core_node8 | Replay not started, or was not successful… still buffering updates. | org.apache.solr.cloud.RecoveryStrategy.doRecovery(RecoveryStrategy.java:447)
2019-01-23 18:32:17,169 | INFO | recoveryExecutor-3-thread-112-processing-n:189.39.172.103:21104_solr x:coll_test497_shard1_replica1 s:shard1 c:coll_test497 r:core_node8 | RecoveryStrategy has been closed | org.apache.solr.cloud.RecoveryStrategy.doRecovery(RecoveryStrategy.java:480)
2019-01-23 18:32:17,169 | INFO | recoveryExecutor-3-thread-112-processing-n:189.39.172.103:21104_solr x:coll_test497_shard1_replica1 s:shard1 c:coll_test497 r:core_node8 | Finished recovery process, successful=[false] | org.apache.solr.cloud.RecoveryStrategy.doRecovery(RecoveryStrategy.java:530)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章