腾讯云 Elasticsearch Service(ES)是分布式多节点集群,每个节点均是由计算和存储两部分构成,如何根据业务需求来选择合适的配置,我们根据实际运营经验,在此提供一些 ES 常见使用场景下的配置选择建议。您可以根据业务需要进行参考,当然,最好的方法还是需要您在业务的实际使用过程中逐步去探索。依托腾讯云 ES 提供的弹性伸缩机制,在业务规模增大,性能遇到瓶颈的时候,您可以随时扩容,调整得到合适的集群规格。
一、计算/存储资源评估
考虑到传统场景如文本搜索、日志分析和向量搜索场景的配置估算差异,下面我们分两个场景来分别介绍:
场景一:文本搜索、日志分析场景
1. 存储容量评估
影响腾讯云 ES 服务存储容量的主要因素如下:
副本数量:副本有利于增加数据的可靠性,但同时会增加存储成本。默认和建议的副本数量为1,对于部分可以承受异常情况导致数据丢失的场景,可考虑设置副本数量为0。
数据膨胀:除原始数据外,ES 需要存储索引、列存数据等,在应用编码压缩等技术后,一般膨胀10%。
内部任务开销:ES 占用约20%的磁盘空间,用于 segment 合并、ES Translog、日志等。
操作系统预留:Linux 操作系统默认为 root 用户预留5%的磁盘空间,用于关键流程处理、系统恢复、防止磁盘碎片化问题等。
因此,数据在 ES 中占用的实际空间可通过下面公式估算:
实际空间 = 源数据 × (1 + 副本数量) × (1 + 数据膨胀) / (1 - 内部任务开销) / (1 - 操作系统预留)≈ 源数据 × (1 + 副本数量) × 1.45
为保证服务的稳定运行,建议至少预留15%的存储空间,因此建议申请的存储容量为:
存储容量 = 源数据 × (1 + 副本数量) × 1.45 × (1 + 预留空间)≈ 源数据 × (1 + 副本数量) × 1.67
2. 计算资源评估
ES 的计算资源主要消耗在写入和查询过程,而不同业务场景在写入和查询方面的复杂度不同、比重不同,导致计算资源相比存储资源较难评估。但一般情况下,存储资源会较早成为瓶颈,因此建议您优先评估存储资源量,然后参考 腾讯云 ES 节点类型 初步选择计算资源,在测试过程中确认计算资源是否足够。
下面针对几种常见使用场景,介绍计算资源评估过程中的一些经验:
日志场景:日志属于典型的写多读少类场景,计算资源主要消耗在写入过程中。我们在日志场景的经验是:2核8GB内存的资源最大可支持0.5万次写入/s的写入能力,但注意不同业务场景可能有偏差。由于实例性能基本随计算资源总量呈线性扩容,您可以按实例资源总量估算写入能力。例如8核32GB内存的资源可支持2万次写入/s的写入能力。
Metric 及 APM 等结构化数据场景:这也是写多读少类场景,但相比日志场景计算资源消耗较小,2核8GB内存的资源一般可支持1万次写入/s的写入能力,您可参照日志场景线性扩展的方式,评估不同规格实例的实际写入能力。
文本搜索场景:此类为读多写少类场景,计算资源主要消耗在查询过程,由于查询复杂度在不同使用场景差别非常大,计算资源也最难评估,建议您结合存储资源初步选择计算资源,然后在测试过程中验证、调整。
场景二:向量搜索场景
1. 计算资源评估
ES 向量场景支持向量和文本混合搜索(腾讯云 ES 我们建议采用 8.16以上版本), 考虑到向量场景需要将大量向量加载到内存中以保证搜索性能,因此向量场景评估的核心是内存。ES 主推 HNSW 图索引,这个算法查询速度快、搜索准确率高,应用非常广泛,下面介绍 HNSW 索引的内存评估方法:
第一步:评估向量内存(堆外内存)
向量内存 = (单向量大小 * 向量维度)* 向量数量 * (1 + 副本数)* 1.1
说明:
系数 1.1,是考虑预留 10% 作为图索引的临时空间。
如果您的向量搜索采用了量化技术(一般在向量数量过亿时,我们可以考虑量化),比如int8_hnsw, bbq_hnsw等,内存占用可以等比例减少,如下:
向量内存 = (单向量大小 * 量化压缩比例 * 向量维度 + 量化额外内存)* 向量数量 * (1 + 副本数)* 1.1
说明:
量化压缩比例:内存大小等比例缩小,即“单向量大小 x量化压缩比例”,比如向量为 float,则 int8 量化取 1/4,bbq 量化取 1/32。
量化额外内存:当向量为 float 或 bfloat16 时,对 bbq_hnsw 取值14,其他量化均可忽略。
第二步:评估总内存(堆外内存+堆内存)
总内存 = 向量内存 + 堆内存
说明:
堆内存,单节点内存 32GB及以下按 1 : 2 估算,32GB 以上可固定按 32GB。
举例(无量化):假设有 1 亿个 1024 维 float 向量(无量化),索引 1 主 1 副:
向量内存 = (4 字节 × 1024 维) × 100,000,000 个向量 × (1 + 1) * 1.1 = 880 GB
总内存 = 880GB + 32GB * 数据节点数 <= 128GB * 数据节点数
(说明:优先考虑大内存节点如 32 核 128 GB,则单节点堆内存为32GB)
推导出:数据节点数 >= 9.2 个
建议配置:32核128G * 10 个数据节点
举例(量化):对上述例子如果采用 int8 量化:
向量内存 = (4 字节 × 1/4 × 1024 维) × 100,000,000 个向量 × (1 + 1) * 1.1 = 220 GB
总内存 = 220GB + 32GB * 数据节点数 <= 128GB * 数据节点数
(说明:优先考虑大内存节点如 32 核 128 GB,则单节点堆内存为32GB)
推导出:数据节点数 >= 2.3 个
建议配置:32核128G * 3 个数据节点
对于向量和文本混合搜索:
如本文前面介绍,文本搜索一般是读多写少类场景,计算资源主要消耗在查询过程,由于查询复杂度在不同使用场景差别非常大,计算资源最难评估,我们可以简单按向量和文本 4 : 1 堆外内存比例粗略衡量(按向量未量化评估比例),实际建议根据业务场景实测数据来调整。
举例(无量化):对于上述例子,如果按向量搜索和文本搜索 4 : 1 的堆外内存比例,则:
向量内存 = (4 字节 × 1024 维) × 100,000,000 个向量 * (1 + 1) * 1.1 = 880 GB
文本内存 = 880 GB * 1/4 = 220GB
总内存 = 880GB + 220GB + 32GB * 数据节点数 <= 128GB * 数据节点数
推导出:数据节点数 >= 11.5 个
建议配置:32核128G * 12 个数据节点
举例(量化):对上述例子如果采用 int8 量化:
向量内存 = (4 字节 × 1/4 × 1024 维) × 100,000,000 个向量 * (1 + 1) * 1.1 = 220 GB
文本内存 = 880 GB * 1/4 = 220GB (按向量未量化的 880GB 的 4:1 来推算文本内存)
总内存 = 220GB + 220GB + 32GB * 数据节点数 <= 128GB * 数据节点数
推导出:数据节点数 >= 4.6 个
建议配置:32核128G * 5 个数据节点
2. 存储容量评估
向量存储可以沿用文本搜索的估算方式,预留 1.67 倍空间。
向量存储空间 = (单向量大小 * 向量维度)* 向量数量 * (1 + 副本数)* 1.67
如果您的向量搜索采用了量化技术,比如 int8_hnsw, bbq_hnsw 等,向量存储会增加“单向量大小 x 量化压缩比例”,因为量化虽然会减少内存使用,但实际会额外生成一份量化数据存储,因此要额外考虑这部分数据的存储空间,如下:
向量存储空间 = (单向量大小 * (1+量化压缩比例)* 向量维度)* 向量数量 * (1 + 副本数)* 1.67
对于向量和文本混合搜索:
总存储空间 = 向量存储空间 + 文本存储空间
说明:文本存储空间参考前面文本搜索场景的计算方法。
如果开启了行存裁剪将节省70%存储:
总存储空间 = (向量存储空间 + 文本存储空间)* (1 - 70%)
二、实例类型选择及测试
1. 数据节点
建议您至少选择3个节点,避免 ES 实例出现脑裂问题,保证 ES 实例具有较高的节点故障容错能力。
说明
脑裂:两个节点同时认为自己是唯一处于活动状态的服务器,从而出现争用资源的情况。
优先选择高规格的节点,避免大量低规格节点,这对大实例的性能、稳定性等有较大好处。例如,若您有40核160GB内存5TB存储容量需求,建议选择8核32GB内存1TB × 5节点的实例。同理,当您需要对实例扩容时,建议优先进行纵向扩容,把节点扩容到8核32GB或16核64GB的规格,然后再考虑横向扩容增加节点个数。
当完成实例类型的初步选择后,您可以使用真实数据进行测试,通过观察 CPU 使用率、写入指标(性能、拒绝率)、查询指标(QPS、拒绝率)等监控信息,进一步确认实例类型是否合适。另外,建议针对上述监控信息配置告警,方便在线上使用时,及时发现资源不足等问题。
2. 专用主节点
如果实例的数据节点大于一定数量,建议开启专用主节点,推荐配置如下:
超过 10 个数据节点:专用主节点建议采用 4C16G
超过 30 个数据节点:专用主节点建议采用 8C32G
超过 50 个数据节点:专用主节点建议采用 16C64G
说明:对于集群索引数、分片数较多或数据变更比较频繁的场景,需要适当提高专用主节点的规格配置。
3. 协调节点
对于写入或查询压力较大的场景,建议开启协调节点来分担数据节点压力,建议如下:
协调节点 2 个起步,建议 CPU:内存为 1:4 或 1:8
协调节点与数据节点数量建议 1:5 左右,协调节点规格建议等于或高于数据节点,或根据实际业务表现调整
举例:10个 8C32G 的数据节点,建议配置 2个 8C32G 的协调节点。
三、分片数量评估
每个 ES 索引被分为多个分片,数据按哈希算法打散到不同的分片中。由于索引分片的数量影响读写性能、故障恢复速度,且通常无法轻松更改,建议按照业务未来发展情况(如未来一两年的增长),提前规划索引的分片设置,这里给出常用建议:
单个分片大小建议在 20GB - 50GB,您可以据此初步确定索引的分片数量。分片不宜过大或过小:过大可能使 ES 的故障恢复速度变慢;过小可能导致非常多的分片,但因为每个分片使用一些数量的 CPU 和内存,从而导致读写性能、内存不足等问题。
分片数尽量等于数据节点数,若分片数较多,建议分片数为数据节点的整数倍,方便分片在数据节点均匀分布。
单节点所有索引的累计分片数不要超过 1000 个,集群总分片数控制在 3 万个以内。
在测试阶段,可以根据每个索引的实际大小、预期未来增长情况,适当调整分片数量。
对于日志、Metric 等场景中,建议使用 ES 自带的 Rollover Index 功能,持续滚动产生新索引,发现分片大小不合理时,通过该功能及时调整分片数量。
例如,假设实例有5个数据节点,索引当前大小为150GB,预期一年后增长50%。如果我们控制每个单分片为30GB,则大约需要150GB ×(1 + 50%)/ 30 ≈ 7个分片,考虑到有两个数据节点支撑2/7的数据压力,节点间压力相对不均匀,我们把分片数量调整到10个。