干货 | Elasticsearch 集群健康值红色终极解决方案
题记
Elasticsearch当清理缓存( echo 3 > /proc/sys/vm/drop_caches )的时候,出现 如下集群健康值:red,红色预警状态,同时部分分片都成为灰色。
查看Elasticsearch启动日志会发现如下: 集群服务超时连接的情况。
bserver: timeout notification from cluster service. timeout setting [1m], time since start [1m]
该问题排查耗时很长,问题已经解决。 特将问题排查及解决方案详尽的整理出来。
1、集群状态解读
head插件会以不同的颜色显示。
1)、绿色——最健康的状态,代表所有的主分片和副本分片都可用; 2)、黄色——所有的主分片可用,但是部分副本分片不可用; 3)、红色——部分主分片不可用。(此时执行查询部分数据仍然可以查到,遇到这种情况,还是赶快解决比较好。)
参考官网:http://t.cn/RltLEpN(部分中文集群健康状态博文资料翻译的不够精确,以官网为准)
如果集群状态为红色, Head插件显示:集群健康值red 。则说明:至少一个主分片分配失败。
这将导致一些数据以及索引的某些部分不再可用。
尽管如此, ElasticSearch还是允许我们执行查询,至于是通知用户查询结果可能不完整还是挂起查询,则由应用构建者来决定。
2、什么是unassigned 分片?
一句话解释:未分配的分片。 启动ES的时候,通过Head插件不停刷新,你会发现集群分片会呈现紫色、灰色、最终绿色的状态。
3、为什么会出现 unassigned 分片?
如果不能分配分片,例如,您已经为集群中的节点数过分分配了副本分片的数量,则分片将保持UNASSIGNED状态。 其错误码为:ALLOCATION_FAILED。
你可以通过如下指令,查看集群中不同节点、不同索引的状态。
GET _cat/shards?h=index,shard,prirep,state,unassigned.reason
4、出现unassigned 分片后的症状?
head插件查看会:Elasticsearch启动N长时候后,某一个或几个分片仍持续为灰色。
5、unassigned 分片问题可能的原因?
1)INDEX_CREATED:由于创建索引的API导致未分配。 2)CLUSTER_RECOVERED :由于完全集群恢复导致未分配。 3)INDEX_REOPENED :由于打开open或关闭close一个索引导致未分配。 4)DANGLING_INDEX_IMPORTED :由于导入dangling索引的结果导致未分配。 5)NEW_INDEX_RESTORED :由于恢复到新索引导致未分配。 6)EXISTING_INDEX_RESTORED :由于恢复到已关闭的索引导致未分配。 7)REPLICA_ADDED:由于显式添加副本分片导致未分配。 8)ALLOCATION_FAILED :由于分片分配失败导致未分配。 9)NODE_LEFT :由于承载该分片的节点离开集群导致未分配。 10)REINITIALIZED :由于当分片从开始移动到初始化时导致未分配(例如,使用影子shadow副本分片)。 11)REROUTE_CANCELLED :作为显式取消重新路由命令的结果取消分配。 12)REALLOCATED_REPLICA :确定更好的副本位置被标定使用,导致现有的副本分配被取消,出现未分配。
6、集群状态红色如何排查?
症状:集群健康值红色; 日志:集群服务连接超时; 可能原因:集群中部分节点的主分片未分配。 接下来的解决方案主要围绕:使主分片unsigned 分片完成再分配展开。
7、如何Fixed unassigned 分片问题?
方案一:极端情况——这个分片数据已经不可用,直接删除该分片。 ES中没有直接删除分片的接口,除非整个节点数据已不再使用,删除节点。
curl -XDELETE ‘localhost:9200/index_name/’
方案二:集群中节点数量>=集群中所有索引的最大副本数量 +1。 N> = R + 1 其中: N——集群中节点的数目; R——集群中所有索引的最大副本数目。 知识点:
当节点加入和离开集群时,主节点会自动重新分配分片,以确保分片的多个副本不会分配给同一个节点。 换句话说,主节点不会将主分片分配给与其副本相同的节点,也不会将同一分片的两个副本分配给同一个节点。 如果没有足够的节点相应地分配分片,则分片可能会处于未分配状态。 由于我的集群就一个节点,即N=1;所以R=0,才能满足公式。
问题就转嫁为: 1)添加节点处理,即N增大; 2)删除副本分片,即R置为0。 R置为0的方式,可以通过如下命令行实现:
curl -XPUT "http://localhost:9200/_settings" -d'
{ "number_of_replicas" : 0 } '
方案三:allocate重新分配分片。 如果方案二仍然未解决,可以考虑重新分配分片。
可能的原因:
1)节点在重新启动时可能遇到问题。正常情况下,当一个节点恢复与群集的连接时,它会将有关其分片的信息转发给主节点,然后主节点将这分片从“未分配”转换为“已分配/已启动”。
2)当由于某种原因(例如节点的存储已被损坏)导致该进程失败时,分片可能保持未分配状态。
在这种情况下,您必须决定如何继续:尝试让原始节点恢复并重新加入集群(并且不要强制分配主分片);
或者强制使用Reroute API分配分片并重新索引缺少的数据原始数据源或备份。 如果您决定分配未分配的主分片,请确保将“allow_primary”:“true”标志添加到请求中。
ES5.X使用脚本如下:
NODE="YOUR NODE NAME"IFS=$'n'for line in
$(curl -s 'localhost:9200/_cat/shards' |
fgrep UNASSIGNED);
do
INDEX=$(echo $line | (awk '{print $1}'))
SHARD=$(echo $line | (awk '{print $2}'))
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
"commands": [
{
" allocate_replica ": {
"index": "'$INDEX'",
"shard": '$SHARD',
"node": "'$NODE'",
"allow_primary": true
}
}
]
}'done
ES2.X及早期版本,将 allocate_replica改为 allocate,其他不变。
脚本解读: 步骤1:定位 UNASSIGNED 的节点和分片。
curl -s 'localhost:9200/_cat/shards' |
fgrep UNASSIGNED
步骤2:通过 allocate_replica 将 UNASSIGNED的分片重新分配。
8、核心知识点
1)路由 原理很简单,把每个用户的数据都索引到一个独立分片中,在查询时只查询那个用户的分片。这时就需要使用路由。 使用路由优势:路由是优化集群的一个很强大的机制。 它能让我们根据应用程序的逻辑来部署文档, 从而可以用更少的资源构建更快速的查询。
2)在索引过程中使用路由 我们可以通过路由来控制 ElasticSearch 将文档发送到哪个分片。 路由参数值无关紧要,可以取任何值。重要的是在将不同文档放到同一个分片上时, 需要使用相同的值。
3)指定路由查询 路由允许用户构建更有效率的查询,当我们只需要从索引的一个特定子集中获取数据时, 为什么非要把查询发送到所有的节点呢?
指定路由查询举例:
curl -XGET 'localhost:9200/documents/_search?pretty&q=*:*&routing=A'
4)集群再路由reroute reroute命令允许显式地执行包含特定命令的集群重新路由分配。
例如,分片可以从一个节点移动到另一个节点,可以取消分配,或者可以在特定节点上显式分配未分配的分片。
5)allocate分配原理 分配unassigned的分片到一个节点。
将未分配的分片分配给节点。接受索引和分片的索引名称和分片号,以及将分片分配给它的节点。。 它还接受allow_primary标志来明确指定允许显式分配主分片(可能导致数据丢失)。
9、小结
1)该问题的排查累计超过6个小时,最终找到解决方案。之前几近没有思路,想放弃,但咬牙最终解决。
2) 切记,第一手资料很重要! Elasticsearch出现问题,最高效的解决方案是第一手资料ES英文官网文档,其次是ES英文论坛、ES github issues,再次是stackoverflow等英文论坛、博客。最后才是:Elasticsearch中文社区、其他相关中文技术博客等。
因为:所有的论坛、博客文字都是基于ES英文官方文档再整理,难免有缺失或错误。
3)自己的Elasticsearch基础原理、Lucene基础知识的不牢固,别无它法,继续深入研究,继续死磕中…….
参考
1、官网文档地址:http://t.cn/RlttuVY 2、Elasticsearch unassigned shards 应急处理方案 :http://t.cn/Rlwub5s 3、解决Unassigned Shards大探讨:http://t.cn/RlwuVFn 4、快照&重新存储数据方案:http://t.cn/RlwuXmm
- 【QQ/微信个人号变身机器人】炸群+远程监控个人PC的尝试
- HUST 1583 长度单位
- FZU 2167 大王叫我来巡山呐
- HDU 1021 Fibonacci Again
- Hadoop数据分析平台实战——180Oozie工作流使用介绍离线数据分析平台实战——180Oozie工作流使用介绍
- 博弈论及算法实现
- Hadoop数据分析平台实战——160Sqoop介绍离线数据分析平台实战——160Sqoop介绍
- HDU 2186 悼念512汶川大地震遇难同胞——一定要记住我爱你
- Hadoop数据分析平台实战——150Flume介绍离线数据分析平台实战——150Flume介绍
- Codeforces 714A Meeting of Old Friends
- Code forces 719A Vitya in the Countryside
- Hadoop数据分析平台实战——190Highcharts介绍离线数据分析平台实战——190Highcharts介绍
- HUST 1555 A Math Homework
- HUST 1541 Student’s question
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux下安装boost库的完整步骤记录
- Linux下使用killall命令终止进程的8大用法实例详解
- 关于AIX挂载NFS写入效率低效的解决方法
- Linux查看进程的所有信息的方法示例
- 新版VPS主机管理面板WDCP安装及使用体验-国产简单易用型VPS面板
- linux中普通用户的定时任务详解
- 详解在Linux中清空或删除大文件内容的5种方法
- 教你一招实现Linux中的文本比对
- 怎么禁用 Ubuntu 服务器中终端欢迎消息中的广告
- Linux系统下部署项目的设置方法
- Linux中设置路由以及虚拟机联网图文详解
- 在Linux中如何一次重命名多个文件详解
- Vim自定义高亮分组以及一些实用技巧小结
- Linux redis-Sentinel配置详解
- 使用 Apache Web 服务器配置两个或多个站点的方法