ES 定时清理索引
ES会将索引存放在内存中,以加速查询性能,但如果长期将使用不频繁的数据放入内存,将会浪费我们的一些资源,下面先举例子一个由于无用数据过多导致的问题
自动清理脚本
#!/bin/bash
###################################
#删除早于十天的ES集群的索引
###################################
function delete_indices() {
comp_date=`date -d "10 day ago" +"%Y-%m-%d"`
date1="$1 00:00:00"
date2="$comp_date 00:00:00"
t1=`date -d "$date1" +%s`
t2=`date -d "$date2" +%s`
if [ $t1 -le $t2 ]; then
echo "$1时间早于$comp_date,进行索引删除"
#转换一下格式,将类似2017-10-01格式转化为2017.10.01
format_date=`echo $1| sed 's/-/\./g'`
curl -XDELETE http://127.0.0.1:9200/*$format_date
fi
}
curl -XGET http://127.0.0.1:9200/_cat/indices | awk -F" " '{print $3}' | awk -F"-" '{print $NF}' | egrep "[0-9]*\.[0-9]*\.[0-9]*" | sort | uniq | sed 's/\./-/g' | while read LINE
do
#调用索引删除函数
echo "delete indexes..."
delete_indices $LINE
echo "deleted success"
done
不清理的危害
我有一个自己的服务器,部署了一些常见的中间件docker容器,通过 fluentd
将他们的日志输出到 ES
中,在 kibana
中进行展示。
有天手机收到邮件告警,说ES占用CPU异常(自己整的docker监控,对自己部署的容器进行了监控与告警)。
于是到 Grafana 中查看,发现ES的CPU占用开始尖刺形而后长期过高,猜测是GC导致的。
登录服务器查看ES的GC日志,如下:频繁触发GC,可回收垃圾较少,且占用时间过高(5s)。
而正常应该是这种,偶尔一次young GC,年轻代每次回收约90%的垃圾
因为我服务器配置较低,只能给ES很少的资源,限制了其内存,当因为索引过多,内存达到上限后不断触发GC(可以看到基本每两个安全点都要触发一次GC),由于JVM
认为他们是不能回收的,故每次基本不会回收东西,导致频繁触发,我这里使用的是ES
默认CMS
垃圾回收器,CMS垃圾回收器在识别垃圾时,会扫描JVM堆空间中的对象,这部分会占用较多CPU。
既然找到了根本原因(频繁触发GC),那就要对症下药,把无用垃圾的干掉,将CPU占用降下去。
进入ESHD
,发现索引数量确实有点多,内存占用达到限定值。
进入 kibana
,将无用的索引先手动清理如
DELETE /fluentd.*.202007*
删掉过旧的日志索引,清理后再到grafana
查看。
为了更好的避免该问题,需要定时清理ES中无用的索引。这里为了省事,写了一个脚本,在文章首部。
总结
因为没有特别重要的服务,故没及时清理与优化,旧的日志太多,2个月前都有,导致ES中无用索引较多,导致频繁GC,导致CPU占用过高。
这里还有其他几个点可以探索,为什么是早上8点开始有"着火"的趋势?
- 每新过一天,fluentd 都会为每个采集的容器生成新的日志索引,可以看到其实每天的早上8点都有上升的趋势。
- 差8小时?时区原因(+8时区)