ElasticSearch 升級過程中給涉及到的術語-3 事務日誌-Translog

1、事務日誌介紹 

       只有在luncene commit以後,luncene的改變纔會被持久化,這是一個相對開銷很大的操作,因而不能在每個索引後或者刪除操作後執行;

在一次提交之後和另一次提交之前發生的更改將在進程退出或硬件故障的情況下由Lucene從索引中刪除。由於luncene commit 開銷太大而不能在每次操作後執行,因此每個分片的copy都有一個事物日誌,這個事物日誌成爲translog。所有的索引操作和刪除操作在被luncen的內部索引處理後,在被確認之前寫入事物日誌;在程序崩潰時,最近被確認的,但是還沒有包括在lucene commit  裏的事務,反而可以在分片恢復後通過事物日誌恢復;

       Elasticsearch 刷新就是lucene的commit的執行過程,且會啓動一個新的事物日誌;爲了防止事物日誌太大,刷新操作是在後臺自動執行的,這使得在恢復期間執行重播操作將花費大量的時間;雖然手動刷新很少用,但是通過API也可以手動執行刷新。

2 、事務日誌設置

     事務日誌中的數據只有在事務日誌爲fsync且commit以後纔會持久化到磁盤上;在硬件出現故障時,任何在上次事務日誌提交前寫入的數據都將丟失;默認情況下,如果index.translog.durability 被設置爲 async ,或者在每個 index, delete, update, or bulk請求後被設置爲request(默認就是request),Elasticsearch 每隔5秒鐘會 fsync(被同步) 和commit 事務日誌 。更精確的說,如果被設置爲request,事務日誌在主分片和被分配的副本上被成功的fsynced 和commit,則Elasticsearch 只會向客戶端報告index, delete, update, or bulk 請求的成功狀態;

以下動態更新每個索引的設置將控制事務日誌行爲:

index.translog.sync_interval

    多久事物日誌被fsync到磁盤 和提交-忽略寫的操作。 默認5s. 設置的值需要大於等於 100ms;

index.translog.durability

        是否在每個index, delete, update, or bulk請求後去執行fsync  和commit 事務日誌;具體參數設置如下:

    request

             (默認)每個請求後執行 fsync 和 commit操作。發生硬件故障時, 所有確認的寫操作都將寫入到磁盤;

    async

             每隔sync_interval間隔將會執行fsync and commit.。發生硬件故障時, 所有確認的寫操作在上次自動提交後都會被丟棄;

index.translog.flush_threshold_size

        事務日誌中存儲着所有的還沒有安全持久化到lucene的操作(即,還不是lucene 提交點的部分數據)。儘管這些操作對寫操作很有用,但是分片如果將要在過去shutdown 和在現在恢復,則需要被再次索引;這個設置控制着這些操作的最大的總大小,以此來阻止恢復數據取太多的數據;一旦獲取的大小到達了最大最大值,則啓動刷新操作,產生一個新的luncene 提交點;默認值爲512M;

index.translog.retention.size

        這個參數主要指保留的事物日誌的總大小;在恢復備份數據時,太多的事物日誌文件將增加基於sync 操作的機率;如果事務日誌不夠,則備份恢復將會回退到基於sync 的文件;默認值爲512mb;

index.translog.retention.age

        事務日誌保留的最長時間. 默認12h.

 

3 、事務日誌損壞

        在某些情況寫(驅動損壞或者人爲的錯誤),分片上拷貝的事物日誌可能損壞。當這種損壞由於checksum 不匹配被es 發現時,es獲取分片失敗,且拒絕使用分片上的數據;但是如果其他分片上有可用的數據,則es 將從其他節點上利用正常的分片分配和恢復機制恢復數據;特別情況下,如果發現被損壞的分片在主分片上,那麼備份分片將變爲主分片;

        如果沒有從已經成功恢復的es中獲取任何數據,用戶可能想要以丟失事務日誌中包含的數據爲代價來恢復分片中的部分數據,我們提供了一個命令行工具 elasticsearch-translog  7.0. 以後將完全移除,且用 elasticsearch-shard tool 替代);

     elasticsearch-translog 需要在關閉es後使用,如果你在es運行中執行這個命令,則將永久的丟失事物日誌中的所有文檔!!!!

爲了運行 elasticsearch-translog 日誌工,需要指定 truncate 子命令 以及損壞的事務日誌目錄,用 -d 來指定;

如:

$ bin/elasticsearch-translog truncate -d /var/lib/elasticsearchdata/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/

Checking existing translog files

如果沒有關閉es 則會如下所示

$ bin/elasticsearch-translog truncate -d /var/lib/elasticsearchdata/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/

Checking existing translog files

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!   WARNING: Elasticsearch MUST be stopped before running this tool   !

!                                                                     !

!   WARNING:    Documents inside of translog files will be lost       !

!                                                                     !

!   WARNING:          The following files will be DELETED!            !

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

--> data/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/translog-41.ckp

--> data/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/translog-6.ckp

--> data/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/translog-37.ckp

--> data/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/translog-24.ckp

--> data/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/translog-11.ckp



Continue and DELETE files? [y/N] y

Reading translog UUID information from Lucene commit from shard at [data/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/index]

Translog Generation: 3

Translog UUID      : AxqC4rocTC6e0fwsljAh-Q

Removing existing translog files

Creating new empty checkpoint at [data/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/translog.ckp]

Creating new empty translog at [data/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/translog-3.tlog]

Done.

4、elasticsearch-shard

在某些情況,lucene的索引和分片的事務日誌可能會損壞, elasticsearch-shard命令將移除損壞部分分片的數據。如果確實沒有任何方法恢復數據,則這將是最後的手段去處理損壞的數據,並保存與之相關的不受影響的數據;

執行 elasticsearch-shard  之前停止 elasticsearch!! (運行之前備份好數據,因爲這是個破壞性的從分片刪除數據的操作!!)

爲了刪除損壞的數據需要用子命令: remove-corrupted-data

有兩種方式來指定路徑:

  • 指定index name 和shard name 用 --index 和--shard-id 選項;

  • 用 --dir  選項指訂損壞索引或者事務日誌的全路徑;

移除損壞數據

elasticsearch-shard 分析分片的拷貝及損壞的概覽

$ bin/elasticsearch-shard remove-corrupted-data --index twitter --shard-id 0

    WARNING: Elasticsearch MUST be stopped before running this tool.

  Please make a complete backup of your index before using this tool.

Opening Lucene index at /var/lib/elasticsearchdata/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/index/

>> Lucene index is corrupted at /var/lib/elasticsearchdata/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/index/

Opening translog at /var/lib/elasticsearchdata/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/

>> Translog is clean at /var/lib/elasticsearchdata/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/translog/

 Corrupted Lucene index segments found - 32 documents will be lost.

         WARNING:              YOU WILL LOSE DATA.

Continue and remove docs from the index ? Y

WARNING: 1 broken segments (containing 32 documents) detected

Took 0.056 sec total.

Writing...

OK

Wrote new segments file "segments_c"

Marking index with the new history uuid : 0pIBd9VTSOeMfzYT6p0AsA

Changing allocation id V8QXk-QXSZinZMT-NvEq4w to tjm9Ve6uTBewVFAlfUMWjA

You should run the following command to allocate this shard:

POST /_cluster/reroute

{

  "commands" : [

    {

      "allocate_stale_primary" : {

        "index" : "index42",

        "shard" : 0,

        "node" : "II47uXW2QvqzHBnMcl2o_Q",

        "accept_data_loss" : false

      }

    }

  ]

}

You must accept the possibility of data loss by changing parameter `accept_data_loss` to `true`.

Deleted corrupt marker corrupted_FzTSBSuxT7i3Tls_TgwEag from /var/lib/elasticsearchdata/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0/index/

當用 elasticsearch-shard丟棄損壞數據時, 分片的allocation id 會變;重啓節點後,必須用cluster reroute API   告訴 Elasticsearch 使用新的ID. 可用 -h 查看elasticsearch-shard 支持的而所有參數;

 

5、集羣reroute

1)、介紹

reroute 命令允許手動的改變每個分片的在集羣中的分配;如,一個分片可以從一個節點移動到另一個節點,可以取消分配,可以給未分配的分片指定存儲的節點;

簡單reroute API 調用:

curl -X POST "localhost:9200/_cluster/reroute" -H 'Content-Type: application/json' -d'

{

    "commands" : [

        {

            "move" : {

                "index" : "test", "shard" : 0,

                "from_node" : "node1", "to_node" : "node2"

            }

        },

        {

          "allocate_replica" : {

                "index" : "test", "shard" : 1,

                "node" : "node3"

          }

        }

    ]

}

'

在執行reroute命令後,es會再資源均衡(設計到的設置爲 cluster.routing.rebalance.enable) 。例如, 如果一個分配請求需要將一個分片從一個node1 移動到node2,這可能導致分片從node2再移回node1來使資源均衡;  

集羣可以通過 cluster.routing.allocation.enable 來禁止分配. 如果分配被禁止,則只有一中情況會分配-就是用了 reroute 命令,伴隨而來的分配是由於再平衡;如果運行reroute 以 ?dry_run URI 請求參數方式,或者通過在請求體中傳遞 "dry_run": true,可以運行在"dry run"模式運行;  集羣會計算運行此命令後集羣的狀態,且返回在reroute命令(和再平衡)執行後的狀態,但是實際上不會執行請求的改變;

如果請求時有 ?explain URI 請求參數,則會 返回信息中包括詳細的命令可以執行和不可以執行的解釋;  

命令具體如下:

move

從一個節點移動到另一節點; 接受的參數 index 和shard 指索引的名稱和分片的編號; from_node分片移出的節點, to_node 要移動到的節點;

cancel

取消分片的分配或者恢復;接受的參數  index 和shard  指索引的名稱和分片的編號, node 指:不會分配的節點;通過取消主要分片和允許它們通過正常的數據恢復機制再初始化,可以強制已存在主分片的備份分片再同步;默認情況下,只有備份分片可以取消;如果確實需要取消主分片的分配,則需要在請求中添加allow_primary  標誌;

allocate_replica

允許未分配的分片被分配到一個節點;接受的參數 index 和shard 指索引的名稱和分片的編號;  node 指:分配的節點;可以考慮allocation deciders ;

2)、失敗後再分配

在放棄分配和不給分片分配前,集羣會連續嘗試index.allocation.max_retries  (默認爲5)設定的最大次數;可能會因爲結構性的問題(如,解析器指向一個整個節點都不存在的禁用詞文件),導致多次嘗試;

一旦問題解決了,分配可以通過調用 reroute API 帶着 ?retry_failed URI請求參數  手動的再分配(每次在這些分片上嘗試一次);

3)、不可恢復的錯誤上的強制分配

有兩種以上的方式可以使主分片分配到一個節點;這些命令用時候需要極其小心,因爲主分片通常由Elasticsearch 完全自動的分配;主分片不能被不能被完全自動的分配主要有以下原因:

  • 新索引創建了,但是沒有合適的節點滿足分配的決策;

  • 集羣中當前數據節點中沒有發現 up-to-date 的分片拷貝, 系統不會自動把一箇舊的分片拷貝移動到主分片中;

以下命令很危險,和可能導致數據丟失;這就意味着在源數據不可能恢復且集羣的管理員能接受數據丟失的情況下采才用;如果有可以即解決的零時的問題時,參考retry_failed;強調:如果這些命令執行時,有個新的節點加入集羣中,且保留着壞的分片數據,那麼新加入的節點上的數據會被刪除或者覆蓋!!

allocate_stale_primary

分配主分片到一個保留着舊的數據的節點;

接受的參數index 和 shard指索引的名稱和分片的編號,  node 分片分配的節點。用這個命令可能導致提供的id的分片數據丟失;如果一個節點有好的數據再次加入集羣中,那麼這些好的數據會被刪除或者被舊的數據覆蓋;爲了確保這些含義都被理解;這個命令需要 accept_data_loss  被設置爲true;

allocate_empty_primary

分配一個空的主分片到一個節點;

接受的參數index 和 shard指索引的名稱和分片的編號,  node 分片分配的節點.。用這個命令的話導致這個分片的所有的索引數據丟失,如果有節點後來加入這個集羣,那麼數據將會別刪除;爲了確保這些含義都被理解;這個命令需要 accept_data_loss 被設置爲true;

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