丟失資料的本質
在本文開始前,首先明白一個點,平時我們說的元件資料不丟失究竟是在指什麼,如果你往ES寫入資料,ES返回給你寫入錯誤,這個不算資料丟失。如果你往ES寫入資料,ES返回給你成功,但是後續因為ES節點重啟或當機導致寫入的資料不見了,這個才叫資料丟失。
簡而言之,丟失資料的本質是ES本身搞丟了返回結果是成功寫入的資料
。
資料寫入流程
1,寫入時,ES會首先往一塊記憶體快取中寫入資料,這快記憶體快取在ES中叫index buffer
,此時資料是不可見的,只有經過refresh
操作後,資料才能變得可見。
index buffer的大小設定可以透過 下面的請求去進行設定,如下,設定了index buffer的大小為總記憶體的30%
PUT /_cluster/settings
{
"persistent" : {
"indices.memory.index_buffer_size" : "30%"
}
}
2, 在寫入index buffer成功後,會寫translog
記錄寫入的資料。此時資料依然不可見。由於作業系統對檔案寫入,並不會立即落盤。所以ES提供了關於刷盤的配置,index.translog.durability
兩個選項值,如下,
request
會在每次建立segment寫入資料後就對translog進行刷盤操作。async
則會定時對translog進行刷盤操作。定時重新整理到磁碟的週期是透過index.translog.sync_interval
引數去進行控制,預設是5s。
3,refresh
操作可以主動觸發也可以定時觸發,預設是1s會進行一次, 該操作會建立一個lucece的segment段用於儲存新寫入到index buffer
中的資料,注意這裡即使寫入到了segment裡,資料還是在os Cache
系統檔案系統快取中,並沒有落入磁碟,只有 在lucece將資料 commit 到磁碟後,資料才能落盤。
4, 在檔案系統快取中的segment總歸還是要寫入磁碟,預設每30分鐘,或者當translog的日誌量達到某個量級時,segment會進行落盤,同時刪掉translog日誌。這個量級由index.translog.flush_threshold_size
去進行控制,預設是512mb。
在瞭解了ES的寫入資料的過程後,我們可以發現,如果將index.translog.durability
設定為request
,這樣便能讓每次請求返回客戶端成功時,保證一定會有translog日誌儲存到磁碟上,後續如果在系統快取中的segment因為系統當機而沒有落盤依然能夠透過translog去進行恢復。
而如果index.translog.durability
設定為 async
則有可能會丟失5s的資料。