elasticsearch集群生产问题处理总结

对于elasticsearch这款中间件,笔者是很感兴趣的,在工作中处理的es生产问题大大小小有500+了,涉及es集群升级、扩容、数据迁移、双活、异地多活、灾备、冷热架构、角色分离等,逐渐形成一些问题处理经验,本篇文章会结合一些案例,提供下常见es生产问题处理思路供大家参考(不包含问题详情和报错日志等生产敏感信息,请大家理解)

问题一:

同网段集群9台节点,经常随机出现某台节点离开集群的现象,节点重启后恢复正常。

处理过程:

查看日志,发现该节点在夯住前经常有长时间gc停顿,刚开始可能几秒,十几秒,后面达到一百多秒,超过es节点健康检测时长(93秒),主节点将该节点踢出集群,

节点为什么会夯住那么长的时间?堆内存不够了?需要扩容吗?查看监控排除了这些可能性,后面对健康检测时长进行了调整(305秒),仍然有这种情况发生,并且看到发生节点脱离的情况时,gc停顿已经有上千秒了,所以延长健康检测时长并不是解决办法,必须要找到gc停顿如此之长的原因。经过hot_threads查询,发现9个节点中同一时刻总有一个节点上显示pinyin tokenizer的线程占用cpu很高,并且发现一个规律,这个pinyin tokenizer在哪个节点上,下一次发生节点脱离的情况时就必然是这个节点。那说明就跟这个pinyin分词器有关了,经了解,该pinyin分词器是业务侧从github下载的后,经过改造之后安装的。而改造的内容就是更改了拼音多音字的功能(pinyin分词器默认值匹配多音字中的一个音,业务侧改成了匹配多个音,会导致大量循环,耗费cpu),最后改成原版的pinyin分词器后,集群恢复正常。

 

问题二:

集群各节点配置相同、部署服务相同,但出现某台节点cpu消耗高的情况。

处理过程:

首先通过top等查询排除了该节点其他进程导致CPU占用高的情况,继续检查发现该节点write线程池有任务拒绝的情况,同配置下的集群各节点只有这台出现写数据异常,

那是不是该节点的磁盘写入有问题呢?通过iostat –x –d –k 1发现瓶颈不在磁盘上。使用top –Hp pid,用jstack打一下es的线程dump,发现也没什么问题。

接着查看es索引,发现集群中有一个索引数据量较大,在es集群中索引是均衡分配的,但每个分片的数据不会完全相等的,只是大致相同。用_cat/shards查看该索引的分片分配详情,然后计算索引分片在各个节点的总容量,此时发现一个特点,各节点cpu占用和这个总容量强相关,也就是总容量大一点的cpu占用也会相应高一些,而出问题的那个节点,该索引的分片总容量最高。手动分配该索引分片,将一部分分片迁移到容量最少的那个节点上,集群节点恢复正常,没有写任务异常了。

 

问题三:

Es客户端遇到java.io.IOException: Listener timeout afrter waiting for [30000] ms 超时报错

处理过程:

经过和上游沟通了解到,他们采用restClient方式连接es集群,设置的socketTimeout是30000ms,而这个restClient底层是封装了httpClient,基于http方式来连接es服务,查看es源码可以知道,http请求方式最终会被转为TransportService来处理,也就是tcp,由于tcp每次都要三次握手才能建立连接,比较耗时,所以这个httpClient采用连接池的方式来管理客户端请求,每次请求从连接池里取连接,否则进入队列等待。通过这些可以分析下,如果客户端频繁请求es服务,超过了这个httpCLient所维护的请求连接池,那请求就会变慢甚至超时。

所以继续和上游沟通他们的读写场景,发现他们有个定时任务每隔10s写入,并且采用单条写入的方式,这意味着每写一条数据都会占用一个连接,当写入并发量比较大时,httpClient连接池可能会被耗尽,自然就会有超时的问题了,为了验证这一点,检查了es服务端write连接池,发现果然有任务拒绝的情况(当并发写入量太大时,es处理不过来就会放入队列中,队列满了就会有任务拒绝的情况)。因此,让上游把他们的单条写入改成批量写入的方式,后面就没再出现过该问题。

 

问题四:

集群分片未分配。

处理过程:

这个问题其实比较宽泛,包含多种情况,也是在集群重启、升级、扩容、架构改造后等普遍遇到的问题,处理起来并不难。

首先_cluster/health检查集群状态,然后_cat/nodes看一下节点(如果说集群原本有10台节点,但只有9台节点在集群里,那第一步就是恢复故障节点,先把集群节点都恢复正常再说)平常我主要关注这三个指标:status、initialing_shards、unassigned_shards.

Status是yellow的话,那就好办了,至少数据没丢,只是有副本未分配而已,大不了重新分配一下副本。

然后如果initialing_shards大于0,那就什么都别操作,集群正在分配分片呢,等它恢复完毕再说。

如果initialing_shards等于0并且unassigned_shards大于0,此时就说明有问题了,

执行下_cluster/allocation/explain?pretty 看下未分配的原因,这个未分配的原因有很多,并且很多情况下你会

看到底下有一行/_cluster/reroute?retry_failed=true,如果看到有这行内容后,那就不用犹豫了,直接执行

curl –XPOST /_cluster/reroute?retry_failed=true,然后你会发现initialing_shards又大于0了,就等它继续恢复吧。

如果执行/_cluster/reroute?retry_failed=true后,initialing_shards仍然是0,并且集群状态也没恢复为green,这种情况还真有,不过我只遇到过一次,

当时异常索引有个主分片损坏了,幸好该索引有设置副本,只是暂时副本无法转换为主分片,针对异常索引的分片,执行reroute,重新路由下分片后,

该分片的副本就会继续分配,集群最后恢复正常。

总之这个分片未分配的问题是es集群中最常见的,问题原因也多种多样,要具体问题具体分析。

 

问题五:

集群快照数据导入无法完全恢复。

处理过程:

经过和上游沟通,了解到问题背景是旧集群的数据迁移到新集群,采用了快照方式,结果将旧集群的快照导入到新集群时(两个集群版本一致),发现快照导入后数据无法完全恢复,

至于处理过程,因为之前我在测试环境做快照迁移测试遇到过该问题,当时发现报的异常是跟分词器有关,就意识到新集群未安装老集群所用到的分词器,那快照导数据肯定无法

恢复完毕了。既然跟我的情况类似,就让上游检查新集群是否安装了旧集群用到的分词器,发现果然也没安装。。分词器装好后,数据顺利导入,集群恢复正常。

 

问题六:

同一个查询语句多次请求es(比如25次循环查询)总有几次耗时明显变慢。

处理过程:

首先是照例检查了集群状态、配置、各节点状态、索引、线程池等情况,发现无异常,那服务端应该是没什么问题的,问上游是怎么获取es客户端的,他们把代码

发过来,发现代码的逻辑是每次请求过来都会生成一个es客户端…正常情况下应该是复用一个客户端,让上游改造成单例模式后,查询恢复正常。

 

问题七:

应用端请求es报错:data too large

处理过程:

这种问题遇到过几次,直接原因就是应用端一次性请求的数据过多,es的堆内存扛不住了,那处理方式也不难,首先,既然是堆内存扛不住,那先检查堆内存配置是不是太小了,比如主机内存16g,es堆内存配置却只有2g,这肯定是不够的,改成8g即可(es堆内存应设置为主机内存的一半并且不超过32g,当然这只是理论值,实际情况下最大配置为26g较好,并且也和业务侧的查询特点有关,比如是否有大量聚合、排序等搜索,一般可以不用考虑如此详细,按照主机内存一半并且不超过32g进行配置即可),

如果说堆内存配置合理,那就要跟上游确认好他们一次查的数据有多大,业务侧是否必须依赖这样一次性查询大量数据的场景(在实际生产环境中,这种场景基本都可以用分批查询代替)。一般来说,到这一步时问题就可以解决了,不过有次遇到过业务侧反馈每次查询的量并不大(一次一万条),但依然遇到了这种报错。经过和他们详细了解,发现他们用的是from+size的方式进行查询,并且存在查询上万页数据的情况,那这样堆内存肯定又扛不住了,最后让他们评估改造成scroll方式进行查询后,问题得到解决

 

 

问题八:

应用端查询es报错,提示任务被拒绝(reject)

处理过程:

查询任务被拒绝,那首先看下search线程池情况,发现各节点都存在1万多个查询请求被拒绝掉了。主机配置是8c16g,那search线程池默认大小就是 (8 * 3) / 2 + 1 = 13,

集群共9台节点,13 * 9 = 117,也就是说es集群可以并发处理的查询请求是117个,并发量超过117,则后续任务进入队列(队列大小为1000),超过队列大小就会出现任务拒绝的情况,经了解,业务侧并没有这么大的并发查询场景,但他们是和多个业务系统共有一个es集群,排查监控,发现有大量搜索请求(单个ip有10w+)通过业务系统来访问es,

现在原因找到了,就是大量的查询请求访问es集群,集群处理不过来,就产生了任务拒绝的报错,那处理方式就有两种思路了:

  1. 业务侧排查如此大量搜索请求过来是否正常,存在恶意请求,则进行过滤
  2. es集群进行索引优化(执行段合并,优化索引查询速度),同时扩容es节点,提高es集群并发处理能力,另外,查看监控发现es节点cpu空闲较多,可以适当调高search线程池。

 

问题九:

es集群进行冷热架构改造后,索引分片数据未实现冷热分离效果

处理过程:

经了解,这套es集群只设置了一个warm节点,并且只有索引a也设置成了warm索引,而索引a是1主1副本配置,由于es不允许副本和主分片分配在同一节点上(因为这样做意义不大,徒增节点负担),所以该索引就会有分片分配在其他节点上,要解决这个问题也很简单,再加一个warm节点即可,让索引a的主分片和副本都能分配在warm节点上,就可以达到冷热分离的效果了

 

问题十:

es集群进行角色分离后,重启后集群状态出现异常

处理过程:

经过检查集群节点发现,这套es集群有台节点A(node.master: true  node.data: true)被改成了选主节点(node.mater: true  node.data: false),由于有的索引没设置副本,

那这些索引的主分片分配在节点A上的数据,在经过角色分离改造后,就无法自动分配到其他节点了,对于es集群来说,这部分数据相当于丢失了,集群状态自然就会异常。

处理方式是先把节点A的角色改回来(数据文件还保存在磁盘中,数据可以被恢复过来),然后给索引添加副本(当然也可以手动迁移分片,只是这样比较麻烦,不如利用副本自动分配机制,也可以提高es集群的高可用性),等待副本恢复完毕后,再进行原先的角色分离操作即可。


 

 

总结:

中医讲究个望闻问切,笔者在处理es集群生产问题过程中,也逐渐形成了这样一套“望闻问切“的方法论(用“望闻问切”不一定很贴切,只是举下例子,方便理解),

遇到生产问题,首先“望”一下集群整体概况,查看集群状态、各节点状态、索引情况等,

这些都是最直观的指标,如果有异常,针对性处理即可,

那如果“望”不出来什么异常,那就要主动检查并分析下集群各种配置是否合理了,也就是“闻”,

比如查看es堆内存配置、各节点角色分配、线程池、hot_threads、索引分片设置等,

经过“闻”这一阶段的检查分析,问题基本上都已经被“嗅”出来了。

当然还有很少一部分问题经过这一步后,依然找不到原因,那此时排查的重点就先不要集中在es集群上了,要结合业务侧情况综合分析,也就是开始“问”这一阶段了,

主要了解业务侧的读写情况、节点配置、获取es客户端的方式等等。比如上文中提到的多次查询偶尔几次查询变慢的问题,这种情况就属于业务侧获取es客户端连接方式不合理,

那你在es集群这一侧是查不出来什么问题的,必须要结合业务侧的情况。至此,我们就可以针对es集群问题对症下药了。

总的来说,本文的内容属于概括性质的,对具体问题的分析流程描述并不详细,主要分享一些经验思路供大家参考,如果大家有什么问题,欢迎评论区分享交流

 

 

 

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elasticsearch是一种开源的分布式搜索和分析引擎,它可以用于快速搜索、分析和存储大量的数据。Elasticsearch集群是由多个节点组成的,每个节点都可以存储和处理数据。以下是关于Elasticsearch集群的一些介绍和演示: 1. 集群原理: Elasticsearch内置了一个名为ZenDiscovery的模块,用于节点发现和选主等功能。这意味着在启动Elasticsearch节点时,它们会自动加入集群,并通过选举机制选择一个主节点来协调集群操作。这使得构建和管理Elasticsearch集群变得非常简单,不需要额外的配置和第三方组件。 2. 单节点演示: 单节点是最简单的Elasticsearch集群配置,它只包含一个节点。以下是一个示例演示如何启动一个单节点的Elasticsearch集群: ```shell # 启动Elasticsearch节点 ./bin/elasticsearch ``` 在启动节点后,您可以使用Elasticsearch的REST API进行索引、搜索和其他操作。 3. 多节点演示: 多节点是更常见的Elasticsearch集群配置,它包含多个节点,可以提供更高的可用性和性能。以下是一个示例演示如何启动一个多节点的Elasticsearch集群: ```shell # 启动第一个节点 ./bin/elasticsearch # 启动其他节点,并指定第一个节点的地址 ./bin/elasticsearch -Ecluster.initial_master_nodes=node1 ``` 在启动所有节点后,它们会自动加入集群,并通过选举机制选择一个主节点来协调集群操作。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值