elasticsearch集群节点重启导致分片丢失的问题

记录一下es丢失分片的问题。

5.4.3版本的es。3个节点分布在三台主机上,分片设置为5分片1副本的配置。因为压力测试,需要升级节点java堆内存,从2G升级到6G。因为是测试集群,在改了jvm.options配置之后(要改es软件目录下的才生效,配置目录下的不生效),挨个重启节点,每个节点相差几秒钟的样子。好了,在我一顿操作猛如虎之后,集群起来了,皆大欢喜,继续测试。过了10来天,开发找过来,说一个refresh操作需要执行超过10s,问题必现。拿到出问题的索引后,通过GET /_cluster/state 发现0和3分片unassigned。再继续通过explain:
GET /_cluster/allocation/explain 
{
  "index": "dcvs_nonmotorvehicle", 
   "shard": 3, 
   "primary": true
}
结果如下:
{
  "index": "dcvs_nonmotorvehicle",
  "shard": 3,
  "primary": true,
  "current_state": "unassigned",
  "unassigned_info": {
    "reason": "CLUSTER_RECOVERED",
    "at": "2020-04-10T03:40:41.127Z",
    "last_allocation_status": "no_valid_shard_copy"
  },
  "can_allocate": "no_valid_shard_copy",
  "allocate_explanation": "cannot allocate because a previous copy of the primary shard existed but can no longer be found on the nodes in the cluster",
  "node_allocation_decisions": [
    {
      "node_id": "TklXzLKySf-czdu8zZ5hyQ",
      "node_name": "MYSQL2",
      "transport_address": "10.45.156.202:9300",
      "node_attributes": {
        "cname": "202",
        "rack_id": "rack_two"
      },
      "node_decision": "no",
      "store": {
        "found": false
      }
    },
    {
      "node_id": "WDaA85bmQhKZxvgq4ve0Kw",
      "node_name": "MHA-MASTER",
      "transport_address": "10.45.156.210:9300",
      "node_attributes": {
        "cname": "210",
        "rack_id": "rack_three"
      },
      "node_decision": "no",
      "store": {
        "found": false
      }
    },
    {
      "node_id": "dAXXDGDyQaGcex6VcZP0eg",
      "node_name": "MYSQL1",
      "transport_address": "10.45.156.201:9300",
      "node_attributes": {
        "cname": "201",
        "rack_id": "rack_one"
      },
      "node_decision": "no",
      "store": {
        "found": false
      }
    }
  ]
}

从这个结果来看,分片没有分配是因为在集群上没有找到对应分片的文件,但是这个有点扯,3个节点,一主一从的分片配置,怎么同时primary和replica都丢了。日志没有发现错误。cannot allocate because a previous copy of the primary shard existed but can no longer be found on the nodes in the cluster。

注意上面的store项,"found": false表示没有找到分片的任何segment文件。如果能找到分片较旧的segment,这里会显示对应陈旧的allocate id的内容。

"store": {
        "found": false
      }

说到较旧的分片,就不能不说in_sync_allocations。这其中包括了各个索引最新的primary分片以及副本的allocate id。不在此之内的,就是陈旧的了。关于allocate id的由来,可参考Allocate primary shard based on allocation IDs #14739 。这个特性是在5.0以后引入的,5.0以前的版本可能会因为index.number_of_replicas设置大于当前启动的节点数,而导致分片不能recover并处于unassigned状态,可参考Unassigned shards after complete cluster failure (All nodes down) #18393
GET  _cluster/state?filter_path=metadata.indices.dcvs_nonmotorvehicle.in_sync_allocations.*
response:
{
  "metadata": {
    "indices": {
      "dcvs_nonmotorvehicle": {
        "in_sync_allocations": {
          "0": [
            "jEUUKBeZR3qkoQRAGswKDw",
            "vjwq3vkBTlG1Yyv1r52Jvw"
          ],
          "1": [
            "9KaFWzldRvihoyW29tEEeA",
            "r3zovKQ-SdGx-22SaM0Akw"
          ],
          "2": [
            "C2gf_7P1QDylq9d8vSPvGg",
            "qEFI9y72TFKQAZagr1_GbA"
          ],
          "3": [
            "G5iiaRxMR_OMbf6piZDFmQ",
            "uxj0i2THQgSsU3WOaJjr5g"
          ],
          "4": [
            "Z-pnmvQ_QuGs3lUIXx2IdQ",
            "nSj91FNnTwuQbF76cqsyZw"
          ]
        }
      }
    }
  }
}

临时的处理是对unassigned的分片重新分配了空的内容,但是这会使分片上原有的内容丢失。即使后来再通过任何方法把分片找回来,es也会将后来找到的内容delete并overwrite。因为es会认为,后来分配的空分片的内容是较新的。

重新分配分片使用reroute API。reroute接受两种操作allocate_stale_primary和allocate_empty_primary。这两种都会造成数据丢失,es出于提醒用户的目的,因此专门需要指定"accept_data_loss": true 。另外就是指定索引名称、要分配的分片id、和要将分片分配到的节点名称,这里只primary分片,replicat分片会自动找节点存储。

allocate_stale_primary:以集群内存在的陈旧的分片内容,再次分配。

allocate_empty_primary:分配空内容的分片

例如:

POST /_cluster/reroute
{
    "commands" : [
        {
          "allocate_stale_primary" : {
                "index" : "dcvs_aps", "shard" : 3,
                "node" : "MYSQL2",
                "accept_data_loss": true
          }
        }
    ]
}

这里简单说下索引在磁盘上的存储结构:比如下面这个,

data/nodes/0/indices/dVPzxUgxRoubKRDEb4Qktg/0/index

data/nodes/0/indices都是一样的,dVPzxUgxRoubKRDEb4Qktg就是索引的唯一id,后面的0表示是分片id=0,再后面的index文件夹下面,就是segment文件了,如下是整个树形结构。中间省略了一大部分。

[elasticsearch@mysql2 indices]$ pwd
/bigdata/cluster5.4/data/nodes/0/indices
[elasticsearch@mysql2 indices]$ cd ..
[elasticsearch@mysql2 0]$ ls
indices  node.lock  _state
[elasticsearch@mysql2 0]$ tree -l -N
.
├── indices
│   ├── 00iymGs4R9iuuxVCbdWanQ
│   │   ├── 0
│   │   │   ├── index
│   │   │   │   ├── segments_e
│   │   │   │   └── write.lock
│   │   │   ├── _state
│   │   │   │   └── state-1.st
│   │   │   └── translog
│   │   │       ├── translog-1.tlog
│   │   │       └── translog.ckp
│   │   ├── 1
│   │   │   ├── index
│   │   │   │   ├── segments_f
│   │   │   │   └── write.lock
│   │   │   ├── _state
│   │   │   │   └── state-1.st
│   │   │   └── translog
│   │   │       ├── translog-1.tlog
│   │   │       └── translog.ckp
│   │   ├── 2
│   │   │   ├── index
│   │   │   │   ├── _0.cfe
│   │   │   │   ├── _0.cfs
│   │   │   │   ├── _0.si
│   │   │   │   ├── segments_f
│   │   │   │   └── write.lock
│   │   │   ├── _state
│   │   │   │   └── state-1.st
│   │   │   └── translog
│   │   │       ├── translog-1.tlog
│   │   │       └── translog.ckp
│   │   └── _state
│   │       └── state-98.st
...
├── node.lock
└── _state
    ├── global-8603.st
    └── node-11.st

1460 directories, 5702 file

临时的处理过后,继续寻找原因中。

每一次出现问题都是进步的机会,出现问题使我烦恼,解决问题使我快乐。

  • 1
    点赞
  • 10
    收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

技术菜逼

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值