一、前言
日常在处理ES集群时,比如在进行节点扩缩容时,经常会导致索引分片在不同节点分配不均匀,导致负载高,在日常进行ES缩容扩缩容时,总结了如下脚本。
并在生产环境中使用,非常好用。
后续还会逐步补充一些命令和脚本。
1.1 创建空索引
该问题主要解决某个节点索引和其他节点索引分片相差很多,往节点中填充空索引,保持索引节点平衡,环节大的索引索引分片分配到其他节点时导致负载增长。
后续可逐步删除空索引,让索引分片缓慢均衡到各节点。
前段时间我们就是在进行ES节点扩容时,扩容后,发现凌晨大量索引写入,导致负载升高,原因就是索引分片要均衡到各个节点。
#!/bin/bash
# Elasticsearch节点的IP地址和端口
ES_HOST="xxx.xxx.xxx.xxx:9200"
# Elasticsearch超级用户的身份验证凭据
USERNAME="elastic"
PASSWORD="esuser123"
# 索引名称的前缀和数量
INDEX_PREFIX="fsp_log"
INDEX_COUNT=10
# 索引的设置
INDEX_SETTINGS='{"settings": {"number_of_shards": 1, "number_of_replicas": 0}}'
# 循环创建索引
for ((i=0; i<100; i++)); do
INDEX_NAME="${INDEX_PREFIX}-${i}"
echo "Creating index: $INDEX_NAME"
curl -XPUT -u "$USERNAME:$PASSWORD" "http://$ES_HOST/$INDEX_NAME" -H 'Content-Type: application/json' -d "$INDEX_SETTINGS"
done
然后通过crontab来部署该脚本,选择每天一个合适时段提前创建好第二天的相应索引。
1.2 根据日期提前创建索引
这个问题也是在我们近期处理ES问题时,由于应用程序自动在凌晨创建索引,导致产生大量开销,而且这些索引有部分索引还很大,索引后缀使用日期格式,比如xxx_2023-08-17.
为解决此问题,我们想到了通过crontab定时任务在应用程序自动创建索引前提前先创建好空索引,这样避免了自动创建索引产生的大量开销。
#!/bin/bash
# Elasticsearch节点的IP地址和端口
ES_HOST="xxx.xxx.xxx:9200"
# Elasticsearch超级用户的身份验证凭据
USERNAME="elastic"
PASSWORD="esuser123"
# 索引名称的前缀列表
INDEX_PREFIXES=(
"crov_kaxxx_",
"rdc_xxxx"
)
# 获取当前系统时间之后的第二天日期
NEXT_DAY=$(date -d '+1 days' +"%Y-%m-%d")
# 循环创建索引
for prefix in "${INDEX_PREFIXES[@]}"
do
INDEX_NAME="${prefix}${NEXT_DAY}"
echo "Creating index: $INDEX_NAME"
curl -XPUT -u "$USERNAME:$PASSWORD" "http://$ES_HOST/$INDEX_NAME" -H 'Content-Type: application/json'
done
echo "Index creation complete."
1.3 查询未分配分片
此问题主要解决哪些索引没有分片导致ES告警。
curl -s -u elastic -XGET "http://192.168.xxx.xxx:9200/_cat/shards" | grep UNASSIGNED
1.4 精确定位unassigned shard的位置
curl -s -u elastic -XGET http://192.168.xxx.xxx:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason| grep UNASSIGNED
# 每行列出索引的名称,分片编号,是主分片p还是副本分片r,以及其未分配的原因
1.5 查询索引恢复信息
curl -s -u elastic:xxxx -XGET "http://192.168.xxx.xxx:9200/_cat/recovery?v&active_only&h=i,s,shost,thost,fp,bp,tr,trp,trt"
-XGET: 指定 HTTP 请求方法为 GET。
"http://192.168.xxx.xxx:9200/_cat/recovery?v&active_only&h=i,s,shost,thost,fp,bp,tr,trp,trt": 请求的 URL,其中:
http://192.168.xxx.xxx:9200 是 Elasticsearch 节点的 IP 地址和端口。
_cat/recovery 是 Elasticsearch 的内置 API,用于获取索引恢复相关信息。
v 参数表示显示详细信息,包括列标题。
active_only 参数表示仅显示正在进行恢复的索引。
h 参数指定要显示的列,具体含义如下:
i: 索引名称。
s: 恢复阶段(stage)。
shost: 源节点的主机名。
thost: 目标节点的主机名。
fp: 复制片段的完成百分比。
bp: 复制片段的当前大小(以字节为单位)。
tr: 复制片段的总数。
trp: 复制片段的已恢复数。
trt: 复制片段的总时间。
使用该命令,您可以查看正在进行索引恢复的详细信息,包括源节点、目标节点、复制片段的进度等。
1.6 查询所有副本分片并排序
curl -s -u elastic -XGET "http://192.168.xxx.xxx:9200/_cat/shards?v" | grep ' r ' | sort -k5,5 -rn
# 输出结果分别是:
# 第一列:索引名称
# 第二列:索引分片ID
# 第三列:r 代表该分片是副本分片
# 第四列:该索引分片当前处于的活动状态
# 第五列:表示该分片中文档的数量
# 第六列:表示分片所在节点的IP地址
# 第七列:表示分片所在的节点的名称
1.7 查询索引名称及大小并排序
--- 查询索引名称和大小,并排除系统自动生成的含有 .xxx 这种索引并排序
curl -s -u elastic:xxxxx -XGET "http://xxx.xxx.xxx.xxx:9200/_cat/indices?format=json" | jq -r '.[] | select(.index | startswith(".") | not) | [.index, .["store.size"]] | @tsv' | sort > /home/esuser/esuser_indexttx
-- 以下命令查询的信息相对较多
curl -X GET "localhost:9200/_cat/indices?v&pretty"
这个命令会返回每个索引的以下信息:
- `health` 状态
- `status` 状态
- `index` 索引名
- `uuid` 索引的UUID
- `pri` 主分片数量
- `rep` 副本分片数量
- `docs.count` 文档数量
- `docs.deleted` 删除的文档数量
- `store.size` 存储大小
- `pri.store.size` 主分片的存储大小