ELK集群升级记录

ES1.6升级至6.5.1版本记录

Posted by Mr.Zhou on January 11, 2019

背景

我司最早开始使用elk差不多在14年年末,也算是在国内es圈子里用的比较早的一批了,当时es版本还是1.2。版本虽早,但凭借着强大的搜索能力,完全碾压了其他同类开源日志分析工具,底层Lucene对日志索引、查询能力丝毫不比现在新版的功能逊色,最后我们选取了es1.6该稳定版,作为线上es服务,一直沿用至今。

但是,用的久了,问题也随之出现,由于业务发展,日志量开始变大,es data node频繁出现gc,并发索引能力下降,集群开始频繁出现索引延迟,当时我们并未选择立即升级es版本,而选择了偷懒的办法:横向扩展,也就是堆机器,以此满足日益增长的日志量,同时又基本保证了ES服务的SLA,满足用户每天的查询需求。最终,在5年后,19年的今天,我们用12台大致24~32核、64~128G、1~5T混合配置的服务器,扛下了4万的每秒并发,实在不是一个什么光彩的数据。

相对我们机房其他的es集群(es版本为5.2.2),es 1.6的索引能力实在太低,同时占用着这么多的服务器资源,服务器、机房机柜成本都是巨大的,于是我们下定决心,这次一定要把版本升上去,以缓解各方面的压力。

前置任务

日志采集端(生产者)

最早用的logstash,后因jvm太吃内存,并且多多少少存在一些bug(内存溢出、与kafka的长连接无法断开等),逐步改用filebeat,并利用salt批量执行安装、配置state.sls,以自动完成客户端日志采集,避免了人为手工修改配置的问题。这边能够批量推送filebeat配置文件得益于开发同学制订的统一日志规范,包括了日志格式、存放路径,保证自动化脚本能够识别日志,并且logstash indexer能够统一进行字段分割,没有这些规范,采集端的去logstash几乎是不可能的。

broker

最早用的redis,但因为redis内存管理较为复杂,后改用了kafka。kafka确实很优秀,除了需要对日志轮训时间、大小提前规划,平时运维管理起来几乎不用怎么费心。不过对于开发同学来说,kafka老版本对于消费程序来说有时可能会有功能问题,同样最好升级到新版。

logstash indexer(消费者)

这块一直没变过,始终是logstash,而且这部分较为重要,kafka partition的数量、logstash的work数量,jvm堆内存大小,都会直接影响es索引都并发能力。

es

有其他es集群做对比,新版es对文档索引能力有较大幅度提升,建议能升的话尽快进行升级。部署过程没有什么太困难的地方,正常部署即可。

升级过程

  • 部署新版kafka;
  • salt批量推送filebeat安装、配置文件,保证日志文件“双写”,即能通过原先的logstash ship到老版kafka,又能通过filebeat ship到新版的kafka;
  • 选取3台高配的es服务器,从老版es集群剥离出来,部署新版es程序,启动es服务,组成新es集群;
  • 部署新版logstash程序,作为indexer,从新版kafka中消费数据,并输出到es;

遇到的坑

  • 最初是先选了2台es服务器作为集群节点,索引效率还不错,两台也能达到2万多,但加入第三台后,索引效率反而变低了,最后将这台有问题的es节点剔除,重新再从老集群中抽一台高配服务器过来,才达到稳定索引状态,这说明了单台es服务器索引性能会影响整个集群索引效率;
  • 在两台es服务器作为集群的状态下,分片策略是:2个分片,1份副本,预想是1个节点负责1个主分片及1个副本,但在加入第三个数据节点后,集群2个主分片居然都locate到了新加入集群的那个节点上去了,原来的2个节点各取一份副本,导致晚高峰索引出现并发问题,增加indexer partition也无济于事,瓶颈应该是在es这边,1个数据节点扛不住将近3万的并发,最终导致索引延迟;
  • 在三台es服务器作为集群的状态下,分片策略是:3个分片,1份副本,预想同样也是1个节点负责1个主分片及1个副本,今天在早上8点自动创建新索引的时候,所有索引基本达到了预期状态,除了其中一个索引,2主分片在其中一个数据节点,但这次问题不大,因为发现的早,在及时reroute手工干预后,分片状态达到了预期的状态,在我写这篇文章的时候,还没到晚高峰,现在在2万4,尚未发现异常;

后续

老es集群还有些业务日志没导过来,预估最终5台es服务器,基本能够扛住原来12台服务器的量,最终部署情况届时再做更新。