本文由雲+社區發表

作者:老生薑

一、遇到的問題

  與大多數分散式系統一樣,Elasticsearch按照一定的Hash規則把用戶數據切分成多個分片,然後打散到不同機器進行存儲,從而實現大規模數據的分散式存儲。

cluster.png

  然而在一些複雜的應用場景中使用Elasticsearch,經常會遇到分片過多引發的一系列問題。起初我們在支撐內部某業務時,單集群內有約1000個子業務,大部分子業務保留31天的數據。如果每個子業務按天滾動建立Index,每個Index 5個分片、一主兩從共三副本的情況下,集群內部會有多達45w~個分片。在集群內分片過多時,經常遇到下面這些問題:

  1. 創建分片慢:Elasticsearch創建分片的速度會隨著集群內分片數的增加而變慢。以ES 5.5.2版本、3節點集群為例,在默認配置下,當集群分片數超過1w時,創建index的耗時一般在幾十秒甚至以上。   2. 集群易崩潰:在凌晨觸發Elasticsearch自動創建Index時,由於創建速度太慢,容易導致大量寫入請求堆積在內存,從而壓垮集群。   3. 寫入拒絕:分片過多的場景中,如果不能及時掌控業務變化,可能經常遇到單分片記錄超限、寫入拒絕等問題。

二、解決過程

  1. 拆分集群 對於存在明顯分界線的業務,可以按照業務、地域使用不同集群,這種拆分集群的思路是非常靠譜的。Elasticsearch官方建議使用小而美的集群,避免巨無霸式的集群,我們在實際使用過程中對這一點也深有體會。但對於我們的場景,已經按照地域拆分了集群,且同一地域的子業務間分界線不明顯,拆分過多的集群維護成本較高。
  2. 調整滾動周期 根據保留時長調整index滾動周期是最簡單有效的思路。例如保留3天的數據按天滾動,保留31天的數據按周滾動,保留一年的數據按月滾動。合理的滾動周期,可以在存儲成本增加不大的情況下,大幅降低分片數量。 對於我們的場景,大部分數據保留31天,在按周滾動的情況下,集群的總分片數可以下降到6.5w~個。
  3. 合理設置分片數和副本數 集群內部除個別子業務壓力較高外,大部分業務壓力較小,合理設置單Index的分片數效果也不錯。我們的經驗是單個分片的大小在10GB~30GB之間比較合適,對於壓力非常小的業務可以直接分配1個分片。其他用戶可結合具體場景考慮,同時注意單分片的記錄條數不要超過上限2,147,483,519。 在平衡我們的業務場景對數據可靠性的要求 及 不同副本數對存儲成本的開銷 兩個因素之後,我們選擇使用一主一從的副本策略。 目前我們集群單Index的平均分配數為3,集群的總分片數下降到3w~個。
  4. 分片分配流程優化 默認情況下,ES在分配分片時會考慮分片relocation對磁碟空間的影響。在分片數較少時,這個優化處理的副作用不明顯。但隨著單機分片數量的上升,這個優化處理涉及的多層循環嵌套過程耗時愈發明顯。可通過cluster.routing.allocation.disk.include_relocations: false關閉此功能,這對磁碟均衡程度影響不明顯。
  5. 預創建Index 對於單集群3w分片的場景,集中在每周某天0點創建Index,對集群的壓力還是較大,且存儲空間存在波動。考慮到集群的持續擴展能力和可靠性,我們採用預創建方式提前創建分片,並把按Index的創建時間均勻打散到每周的每一天。
  6. 持續調整分片數 對於集群分片的調整,通常不是一蹴而就的。隨著業務的發展,不斷新增的子業務 或 原有子業務規模發生突變,都需要持續調整分片數量。 默認情況下,新增的子業務會有默認的分片數量,如果不足,會在測試階段及上線初期及時發現。隨著業務發展,系統會考慮Index近期的數據量、寫入速度、集群規模等因素,動態調整分片數量。

三、後續

  目前,Elasticsearch的分片均衡策略尚有瑕疵,例如:1. 機器的空間利用不是非常均衡,對於此類場景,用戶可暫時通過調整機器空間的高低水位線配置觸發數據均衡;2. 當集群擴容新節點時,Elasticsearch會把大量新建分片分配到新機器,導致新機器壓力過高,目前用戶可臨時通過index.routing.allocation.total_shards_per_node配置進行限制。

  這是我們後續在分片使用方面的優化工作,通過直接優化分片均衡策略,更優雅的解決上述問題。如果大家有分片使用方面的問題 或 經驗,歡迎一起交流討論!

此文已由騰訊雲+社區在各渠道發布

獲取更多新鮮技術乾貨,可以關注我們騰訊雲技術社區-雲加社區官方號及知乎機構號

推薦閱讀:

相关文章