Elasticsearch最佳实践之分片使用优化

44次阅读

共计 1864 个字符,预计需要花费 5 分钟才能阅读完成。

本文由云 + 社区发表作者:老生姜

一、遇到的问题
与大多数分布式系统一样,Elasticsearch 按照一定的 Hash 规则把用户数据切分成多个分片,然后打散到不同机器进行存储,从而实现大规模数据的分布式存储。
cluster.png
然而在一些复杂的应用场景中使用 Elasticsearch,经常会遇到分片过多引发的一系列问题。起初我们在支撑内部某业务时,单集群内有约 1000 个子业务,大部分子业务保留 31 天的数据。如果每个子业务按天滚动建立 Index,每个 Index 5 个分片、一主两从共三副本的情况下,集群内部会有多达 45w~ 个分片。在集群内分片过多时,经常遇到下面这些问题:
1. 创建分片慢:Elasticsearch 创建分片的速度会随着集群内分片数的增加而变慢。以 ES 5.5.2 版本、3 节点集群为例,在默认配置下,当集群分片数超过 1w 时,创建 index 的耗时一般在几十秒甚至以上。2. 集群易崩溃:在凌晨触发 Elasticsearch 自动创建 Index 时,由于创建速度太慢,容易导致大量写入请求堆积在内存,从而压垮集群。3. 写入拒绝:分片过多的场景中,如果不能及时掌控业务变化,可能经常遇到单分片记录超限、写入拒绝等问题。
二、解决过程

拆分集群 对于存在明显分界线的业务,可以按照业务、地域使用不同集群,这种拆分集群的思路是非常靠谱的。Elasticsearch 官方建议使用小而美的集群,避免巨无霸式的集群,我们在实际使用过程中对这一点也深有体会。但对于我们的场景,已经按照地域拆分了集群,且同一地域的子业务间分界线不明显,拆分过多的集群维护成本较高。
调整滚动周期 根据保留时长调整 index 滚动周期是最简单有效的思路。例如保留 3 天的数据按天滚动,保留 31 天的数据按周滚动,保留一年的数据按月滚动。合理的滚动周期,可以在存储成本增加不大的情况下,大幅降低分片数量。对于我们的场景,大部分数据保留 31 天,在按周滚动的情况下,集群的总分片数可以下降到 6.5w~ 个。
合理设置分片数和副本数 集群内部除个别子业务压力较高外,大部分业务压力较小,合理设置单 Index 的分片数效果也不错。我们的经验是单个分片的大小在 10GB~30GB 之间比较合适,对于压力非常小的业务可以直接分配 1 个分片。其他用户可结合具体场景考虑,同时注意单分片的记录条数不要超过上限 2,147,483,519。在平衡我们的业务场景对数据可靠性的要求 及 不同副本数对存储成本的开销 两个因素之后,我们选择使用一主一从的副本策略。目前我们集群单 Index 的平均分配数为 3,集群的总分片数下降到 3w~ 个。
分片分配流程优化 默认情况下,ES 在分配分片时会考虑分片 relocation 对磁盘空间的影响。在分片数较少时,这个优化处理的副作用不明显。但随着单机分片数量的上升,这个优化处理涉及的多层循环嵌套过程耗时愈发明显。可通过 cluster.routing.allocation.disk.include_relocations: false 关闭此功能,这对磁盘均衡程度影响不明显。
预创建 Index 对于单集群 3w 分片的场景,集中在每周某天 0 点创建 Index,对集群的压力还是较大,且存储空间存在波动。考虑到集群的持续扩展能力和可靠性,我们采用预创建方式提前创建分片,并把按 Index 的创建时间均匀打散到每周的每一天。
持续调整分片数 对于集群分片的调整,通常不是一蹴而就的。随着业务的发展,不断新增的子业务 或 原有子业务规模发生突变,都需要持续调整分片数量。默认情况下,新增的子业务会有默认的分片数量,如果不足,会在测试阶段及上线初期及时发现。随着业务发展,系统会考虑 Index 近期的数据量、写入速度、集群规模等因素,动态调整分片数量。

三、后续
目前,Elasticsearch 的分片均衡策略尚有瑕疵,例如:1. 机器的空间利用不是非常均衡,对于此类场景,用户可暂时通过调整机器空间的高低水位线配置触发数据均衡;2. 当集群扩容新节点时,Elasticsearch 会把大量新建分片分配到新机器,导致新机器压力过高,目前用户可临时通过 index.routing.allocation.total_shards_per_node 配置进行限制。
这是我们后续在分片使用方面的优化工作,通过直接优化分片均衡策略,更优雅的解决上述问题。如果大家有分片使用方面的问题 或 经验,欢迎一起交流讨论!
此文已由腾讯云 + 社区在各渠道发布
获取更多新鲜技术干货,可以关注我们腾讯云技术社区 - 云加社区官方号及知乎机构号

正文完
 0