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;

发布了32 篇原创文章 · 获赞 8 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/jeffiny/article/details/84586664
今日推荐