Docker部署Elasticsearch磁盘占用远高于索引统计值,如何排查及降低占用
异常磁盘占用排查全流程
注意:
_cat/allocation返回的disk.used是节点所在挂载盘的总使用量,并非ES自身产生的索引存储量,和disk.indices(ES实际索引分片占用)的差值,本质就是磁盘上非索引部分的总占用。
定位容器内真实磁盘占比来源
- 先确认ES数据目录的实际文件大小,ES默认数据路径为
/usr/share/elasticsearch/data,执行命令逐目录统计占用:docker exec -it es du -sh /usr/share/elasticsearch/data/* - 对比各子目录大小和索引统计值的差异:
indices目录:存储正式索引的分片文件,正常大小应和_cat/indices返回的总store.size(约7.8GB)匹配- translog目录:分片事务日志存储位置,大流量写入场景下如果刷盘配置异常,容易累积几十GB未合并的日志文件
.tmp开头的临时目录:存储分片恢复、段合并过程中的临时文件,这类文件不计入索引存储统计值,异常中断操作后可能长期残留
- 排查完ES数据目录后,再统计容器内其他路径的占用:
docker exec -it es du -sh /* 2>/dev/null | sort -hr
重点关注ES的GC日志、慢查询日志路径,如果日志没有挂载到宿主机,长期运行可能累积大量无效日志文件
排查Docker存储层的冗余占用
- 当前使用overlay存储驱动,容器显示的磁盘占用包含Docker镜像只读层、容器可写层两部分,很多额外占用并不来自ES运行数据:
- 执行命令查看容器可写层的实际大小:
docker ps -s,对应es容器的SIZE列就是可写层的额外占用(不包含独立挂载的卷目录) - 常见冗余来源:容器内临时安装的调试工具、历史运行残留的临时文件、未做轮转的日志文件全部存在容器可写层,长期运行可能占用数十GB空间
- 注意:如果ES数据目录没有配置独立的宿主机卷挂载,所有数据都会存在容器可写层,容器删除后数据会全部丢失,属于部署的典型配置缺陷
- 执行命令查看容器可写层的实际大小:
排查未被统计的残留分片
- 当前节点存在2个UNASSIGNED的分片,这类分片如果在本地留有残留文件,不会被索引的统计口径计入:
- 执行命令查看节点全量分片列表:
curl 'localhost:9201/_cat/shards?v',确认是否有属于已删除索引的分片文件残留在本地磁盘 - 如果之前执行过索引删除、分片搬迁中断操作,可能出现索引元数据已经删除,但物理分片文件没有被清理的情况,这类残留会直接造成统计值和实际磁盘占用的巨大差异
- 执行命令查看节点全量分片列表:
降低ES磁盘消耗的实操手段
- 优化translog配置:
将默认的每次请求强制刷盘策略,调整为按时间间隔刷盘,设置translog最大大小阈值,避免异常写入导致translog无限累积:index.translog.sync_interval: 5s index.translog.flush_threshold_size: 1g - 清理无效残留文件:
确认无使用价值的临时目录、残留分片、过期日志文件可直接删除;执行分片清理API触发节点上无效文件的物理回收:curl -XPOST 'localhost:9201/_flush?force=true' - 修正部署的卷挂载逻辑:
将ES的数据目录、日志目录全部挂载为宿主机独立卷,不要存在容器可写层内,既避免Docker存储层的冗余统计,也防止容器重建时丢失数据 - 优化索引存储效率:
对长期存储的冷数据索引,开启最优压缩编码index.codec: best_compression,可降低30%-50%的索引存储空间;定期清理无查询需求的历史索引,减少无效存储占用
内容的提问来源于stack exchange,提问作者Yuri Glushenkov
相关产品推荐
相关产品推荐

