前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ElasticSearch大版本升级踩坑记

ElasticSearch大版本升级踩坑记

作者头像
有福
发布2018-08-28 14:38:18
1.2K0
发布2018-08-28 14:38:18
举报
文章被收录于专栏:极客生活极客生活

大版本升级,从ES 2.1到ES5.5,两年的数据,每天15GB,5个节点,前后历时一个月左右。

限制条件:

  1. 升级过程有新的数据不断进来,不能停止整个集群,否则会丢失数据。
  2. 没有额外的机器搭建一个全新的ES5集群,只有一个机器供缓冲使用。
  3. 一个临时的ES5节点cpu 8核,内存32GB,10T 磁盘,升级完成后需要释放掉这台机器。
  4. 很多线上的服务依赖于目前的ES2提供服务,线上服务不能中断。

记录一下整个流程。

首先是做决定到底是采用全集群方式升级还是平滑方式升级。

升级方案选择

全集群升级

1.关闭shard分配,防止关闭一个节点后ES集群误认为node故障,在剩余节点上执行 shard 恢复,如果数据过多,可能会由于产生大量IO造成ES集群挂起。

代码语言:javascript
复制
PUT _cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.enable": "none"
  }
}

2.执行同步刷新, 这样集群重新启动后shard恢复更快。

代码语言:javascript
复制
POST _flush/synced

3.关闭集群中所有的ES进程。

4.安装ES5,并且修改配置文件,配置好data路径。不要直接指向2.x的路径,否则一旦升级失败,老数据无法恢复。

5.配置好路径后将2.x的data目录copy到新的路径下。

6.启动ES5 集群,等待集群状态变为green即可

优点

简单,速度快,一步到位

缺点
  • 由于ES2.x到ES5.x内部结构变化较大,升级过程不可控,中间可能会有大坑或者升级失败
  • 目前ES存储的数据结构有需要改进的部分(比如某些字段类型,analyzed等),这样升级后还是原来的结构,后续可能还需要对数据进行reindex。
Reindex 平滑升级

这种升级方式其实就是对所有的数据做一次重新处理然后自己通过http接口重新写入到新的 ES5缓冲节点,然后再将原来的ES2的节点逐台加入的新的集群,之前的数据和配置都清空。

程序大致流程

ES2 -> scanner -> redis -> reindex -> ES5

引入Redis作为中间缓冲的考虑:

  1. 数据量巨大,索引过程很难保证一次成功,基于scroll方式取数据无法保证顺序,所以一旦中途失败无法判断offset,为了不丢不重复,只能从头再来
  2. 需要对每一个doc进行特有字段的部分处理, Redis中缓存的是处理后的doc
  3. ES的查询速度和索引速度不一致,从ES2读取数据经过处理后写入ES5整个流水线耗时太长,容易网络超时失败

升级方案踩坑记

经过内部讨论决定采用平滑升级的方式。

  • 使用python将每天的数据从ES2->ES5,每天大概2000万条数据,使用官方的elasticsearch python库每次到几百万数据的时候就会出现连接超时,由于没有offset机制,所以只能删除从头再来。后来基于requests库自己封装scroll API来进行reindex,有时发现1000多万的时候scroll API就返回没有谁了,后来经过调试发现不能只是简单的根据hits的条数是否为0来判断数据是否全都读取完毕。这里官方文档中并没有提及,最终添加了好几个判断条件和错误处理,终于可以完整的读完所有数据,一条不差。
  • 中间引入了redis作为缓存,防止reindex程序中间挂了,从头再来。es2->redis->es5,由于读的速度远远大于写的速度,而且只有一台es5节点,所以需要开多个进程往es5中写。突然有一天发现es5挂掉了,查找原因,发现redis的内存已经占满了所有机器的内存,操作系统自动杀掉了es5节点。于是加入流控机制,一旦redis中的数据超过限制,那么读取程序需要挂起。
  • 数据全都写入到ES5的临时节点后,开始一台一台的升级ES2。之前在ES2的升级过程中通过yum安装ES时发现ES已经从5.5.1升级到了5.5.2,ES对于版本的控制非常严格,虽然可以同时正常的查询工作,但是之前的数据都是5.5.1版本,无法在5.5.2版本的node上写入数据,没办法,只能先升级原先的es5tmp节点到5.5.2版本,由于是小版本升级,直接yum update然后重新启动节点即可。
  • 数据的存储之前并没有采用LVM管理,所以添加一块磁盘,需要修改ES的配置文件,然后重新启动机器,这次升级顺便将所有的ES的数据盘配置为LVM方式。由于之前已经有一部分数据写入到了新加入的非LVM节点上,所以需要将其中的shards再写回到es5tmp临时节点,查看文档,发现使用cluster.routing.allocation.exclude._ip设置可以达到要求,设置完成后分片会自动写回到临时节点上。LVM磁盘配置好后,重新加入集群,使用cluster.routing.allocation.include._ip设置后发现并没有作用,经过尝试发现,必须cluster.routing.allocation.exclude._ip设置为空字符串,同时cluster.routing.allocation.include._ip也必须设置为空。等待所有的ES2的节点都加入集群后,将临时节点的ip设置到exclude中,这样所有的shards和副本都会自动转移到新的节点上。
  • 由于内存和资源限制,整个升级过程是每次打开一个月的index,所有的主分片都从临时节点转移后,再设置replica个数为1,等所有副本都完成后,close这个月的所有index,然后开始下一个月。这样整个过程只保留了当前最新的一个月的数据(供在线服务使用)和正在进行中的那个月的数据,整个集群压力较小。
  • 升级完成后安装Kibana,发现ES已经升级到5.6了,不想折腾ES的各个节点升级到5.6,所以通过yum安装5.5.2的Kibana。
  • 升级完成后http query的接口已经完全变了,所有之前依赖es2的查询接口都需要重写。
  • 所以的kibana和ES节点都监听内网地址,不安装x-pack,通过部署一个nginx的代理和简单的用户名密码认证来做简单的安全验证。使用cerebro(之前的kopf)来对集群的状态进行简单的监控和更新配置。
  • 中间还包括了logstash配置更新,kibana配置更新,ES->Hadoop的代码更新不再一一细说。

知识点总结

整个过程涉及到的知识点如下:

  1. python requests库使用。
  2. es scroll API使用。
  3. yum 安装特定版本软件包以及配置清华源。
  4. 阿里云系统盘镜像创建以及替换部署。
  5. lvm管理多个磁盘。
  6. systemctl 使用以及service配置文件。
  7. es index template 配置。
  8. nginx basic auth反向代理配置。
  9. es hadoop map reduce API使用。
  10. python redis 使用。
  11. Logstash,ES,Kibana 安装部署以及配置。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.09.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 升级方案选择
    • 全集群升级
      • 优点
        • 缺点
          • Reindex 平滑升级
            • 程序大致流程
            • 升级方案踩坑记
            • 知识点总结
            相关产品与服务
            云数据库 Redis
            腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档