Elasticsearch索引調優和背後的原理

目標

靈雀雲私有云平臺的日誌系統從4年前就在使用 Elasticsearch 作爲日誌的接收平臺,從2.X 到 5.6 再到 6.7。根據客戶實際日誌量,需要確定何等的集羣規模大概支持多少日誌量。現在很多客戶在要求日誌系統支撐5w/s的日誌量不丟失,不延遲,且帶備份。根據官方的調優文檔指導,我們需要實踐出一套部署的規格和調參實踐。

ES集羣的部署

es集羣基於k8s部署,使用chart去管理 ,我們使用兩個deployment,第一個部署master節點,master 節點主要作爲管理metadata 的節點,不做存儲,聚合,io,因此配置可以稍微差些,但我們做測試,爲了最大化利用資源master 同時也做了data 節點,啓動master 後,繼續部署下一個deployment,需要確保兩個deployment部署的es 集羣名稱相同。且data 中指定master 的任一可達的IP。

我們繼續部署一個kibana 作爲監控。我們單個節點的配置是8C64G,1T SSD,es pod 的jvm爲31G,節點不再部署其他負載。master 3臺(也做data),data 節點9臺,共12個節點。

參數調整

  1. 使用Bulk requests,這個很顯然,一條日誌索引一次,顯然是不明智的,官方推薦,在一個節點上的單個shard,嘗試從100一個一個bulk開始,不斷double,等到了穩定延遲的時候則停止,但是不宜過多,根據日誌的size,要考慮批次內容太多的時候,會對內存造成壓力(index buffer)

  2. 使用 多 線程,增加併發寫入,這個也不難理解,需要觀察下返回值什麼時候出現,TOO_MANY_REQUESTS,出現則意味着ES處理到達了極限。

  3. 不去設置或者增加 refresh interval 這個參數。ES是一個日誌管理平臺,管理的核心就是Lucence,就像k8s 和docker 的關係,lucence 管理的是shard,每一個shard有一個提交點(本質是一個文件,描述了當前的segment和translog信息等),一個shard是由一個個的segment組成的,而segment並不是實時產生的。這裏需要展開講下,ES是一個準實時的系統爲什麼?爲什麼不是寫入就能查到?正是 refresh interval 這個參數,當前有很多索引請求到了以後,es不是直接寫盤。如圖:
    在這裏插入圖片描述
    這個時候,相當於我們寫代碼的時候,接收者收到了自己的接收buffer裏,這裏記住,默認是你JVM的10%,還是字節流。這個階段,我們是查不到的,因爲字段沒有實例化,如果調用了lucence 的接口,也就是refresh 。圖就變成了這樣:
    在這裏插入圖片描述
    這個階段就是可以查的了,這個階段就像寫代碼:

    fd = fopen(“/a/b/c.log”,'rw')
    fd.write(segment_obj)
    

    這個時候,你read 文件實際就可以獲取內容了,但是掉電以後就沒了,因爲你沒flush沒有寫到磁盤上。以上是refresh interval 參數的意義。

  4. 禁用swapping。這個很好理解,而且必須做的,不用說,docker 也不喜歡的。

  5. 足夠的操作系統緩存,官方推薦,至少機器的一半內存。用到它的地方很多,比如write,比如translog 的寫入,等等。不能含糊的,這個影響很多。

  6. 自動產生文件id,這個需要檢查下自己的代碼,有沒有使用了 BulkIndexRequest().Id(),有的話去掉了。

  7. 更快的硬件,SSD優先,分佈式存儲再見,NFS SMB別用了。

  8. 索引buffer 的size,這個在3裏提到了,默認10%

  9. translog 的配置,這個地方也可以展開說了,第三步裏我們如果只write的話,機器down的話,就會有數據丟失。那麼如何保持數據的持久化呢,3裏面我們提到,一次完整的提交,是需要把segment flush 到磁盤上的,但是現在你只是write了,可以查了,還不能保證掉電的數據安全,ES增加了一個translog,或者說transaction log, 它記錄了所有的es 的操作請求,是一個嚴格的二進制,數據密度高 ,所以當buffer 到了以後,同步的translog也有更新:
    在這裏插入圖片描述
    當你refresh 的時候,buffer 的數據,序列化到了segment裏(注意,還沒有落盤哦,只是write了下)如下圖:
    在這裏插入圖片描述
    其中translog忠實的記錄你的buffer內容,因爲是原封不動的寫入文件,所以比較快,當然translog它也是先到內存裏。
    在這裏插入圖片描述
    接着,在內存裏docs,開始寫入新的segment,清空buffer,修改提交點,fsync寫入磁盤,刪除translog。安全了。
    在這裏插入圖片描述

問題:

translog 安全麼?

在文件被 fsync 到磁盤前,被寫入的文件在重啓之後就會丟失。默認 translog 是每 5 秒被 fsync 刷新到硬盤, 或者在每次寫請求完成之後執行(e.g. index, delete, update, bulk)。這個過程在主分片和複製分片都會發生。最終, 基本上,這意味着在整個請求被 fsync 到主分片和複製分片的translog之前,你的客戶端不會得到一個 200 OK 響應。

這個行爲可以通過設置 durability 參數爲 async 來啓用:

PUT /my_index/_settings
{
    "index.translog.durability": "async",
    "index.translog.sync_interval": "5s"
}

如果你不確定這個行爲的後果,最好是使用默認的參數( "index.translog.durability": "request" )來避免數據丟失。

結論

,我們認爲12臺8C64G的主機ssd盤,是能夠支撐

引用

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