1. PB 级别数据量场景下的 Elasticsearch 调优

1.1. 硬件与操作系统层面

涉及大量 Pipeline Processor 或分词操作的情况建议选择更多核的 CPU 发挥并发优势

Elasticsearch 是重 I/O 和内存操作的程序,对磁盘和内存有较高的要求。建议使用 SSD 硬盘和本地存储,避免网络传输消耗

Elasticsearch 各项查询操作都非常依赖内存。一部分是 JVM 堆内存上的一些数据结构,另一部分是非堆内存。推荐使用 64G内存的机器,并将 JVM 堆内存的大小限制为 4GB~32GB;JVM 堆内存越小,GC 越快,Lucene 缓存的内存越多,查询性能也就越好。当堆内存小于 32GB 时,JVM 会使用内存对象指针压缩技术来优化性能。一旦内存超过 32GB,则不但会浪费内存而且会导致 CPU 和 GC 的性能降低。

内存交换对 Elasticsearch 来说是显著影响性能的行为,建议配置禁用内存交换,可在 elasticsearch.yaml 中将 bootstrap.memory_lock 参数配置为 true。

1.2. 集群配置层面

推荐配置 3个专有主节点仅执行集群层面的操作。

在一台物理机上建议只部署一个节点,也就是一个 Elasticsearch 进程。

当写入量较大时,集群经常会出现写入进程池满载且抛出异常的情况,可以适当增加集群写入进程池的大小,可配置的参数时 thread_pool.write.size 及 thread_pook.write.queue_size

1.3. 业务操作层面

数据写入应尽量采用 bulk 方式。建议将多条数据批量写入集群中,但也需要限定同一批数据的条数,推荐设置为1000~10000条,避免对网络或发送端产生影响。

业务查询应尽量避免返回文档的所有字段,存在大量返回结果会导致额外的性能损耗。如果需要进行分页查询,应尽量避免深度随机分页。

如果业务查询不关注数据与查询条件的匹配程度,可以使用 query-bool-filter 查询代替 query 查询。

对业务的聚合查询,应避免深度嵌套聚合查询,尤其是有大量 bucket 类型的聚合查询,例如 Terms 聚合或 Filter 聚合会产生大量 bucket ,影响聚合性能。

避免对高基数字段做 Terms 聚合。(如 ip、URL 等)

对于 Ters 查询,如果匹配的字段类型很少,可以通过修改 execution_hint 参数的值来修改 Terms 聚合的执行方式以提升性能。

1.4. 监控和预计指标

硬件和操作系统:CPU、内存、磁盘

集群层面:集群状态、集群的 CPU 利用率、集群的磁盘使用率、集群 JVM 个内存区的使用率、集群 GC 情况、集群索引数、集群分片数、集群未分配分片数、单节点承载的最大数据量

索引层面:索引单分片最大存储容量、索引是否只读

业务层面:读取和写入的平均延迟、读取和写入的拒绝率、每秒写入次数。

2. 预测 Elasticsearch 规模并控制成本

节点类型 节点类型 存储需求 内存需求 计算需求 网络需求 节点数量
主节点 管理集群状态 最少3个
数据节点 存储与检索数据 极高
Ingest 节点 转换输入的数据
机器学习节点 运行机器学习模型 极高 极高
协调节点 分发请求,合并结果

2.1. 数据节点配置预估

一般从3个维度评估,分别是存储容量、分片数、搜索吞吐量。

存储容量根据以下信息评估:

  • 每天将存储多少原始数据
  • 数据会保留多少天
  • 需要设置多少副本
  • 为每个数据节点计划分配多少内存
  • 内存与磁盘设定的比例
  • 数据膨胀系数:Elasticsearch 需要额外使用倒排索引、列式存储,一般会有10% 的数据膨胀
  • 内部任务开销比例:Elasticsearch 需要额外约20%的磁盘空间,用于 segment 合并、translog 存储和运行日志等
  • 操作系统预留比例:Linux 默认为 root 用户预留 5% 的磁盘空间
  • 预留磁盘警戒比例:一般设置为 15%
  • 保留一个数据节点用于容错

假设副本分片的数量为 r,数据膨胀系统为 g,内部任务开销比例为 t,操作系统预留比例为 0,警戒比例为 w,可以通过以下公式计算存储:

存储容量=原始数据量*(1+r)*(1+g)*(1-t)/(1-o)*(1+w)

根据经验值计算,存储容量约为原始数据量的 1.67 倍。根据存储容量,可以通过以下公式评估需要的数据节点数:

数据节点数=ceil(存储容量/单节点内存/内存与磁盘比例)+ 容错数据节点数

节点类型 存储目标 磁盘类型建议 内存与磁盘比例
热节点 搜索为主 SSD 大于 200Gbit/s 1:30
温节点 存储为主 HDD 约 100Gbit/s 1:100
冷节点 归档为主 小于 100Gbit/s 1:500

腾讯云对冷节点和热节点内存与磁盘比例的经验值分别为 1:480 和 1:96

分片数需要根据业务进行合理配置,可以参考以下信息评估:

  • 集群有多少个索引
  • 每个索引的主分片和副分片设置的数量
  • 索引是否有滚动策略?是按时间滚动还是按存储容量滚动?
  • 索引保留的时间

官方建议 1GB JVM 堆内存承载的分片数不超过 20个。

总的数据节点数=ceil(总分片数/(20*单节点内存))

除了存储容量和分片数,还需要考虑搜索吞吐量:

  • 期望的每秒峰值搜索次数
  • 期望的搜索平均响应时间
  • 在每个数据节点上期望有几核 CPU 以及对应的线程数

峰值线程数=ceil(每秒峰值搜索次数*平均响应时间/1000)

线程池大小=ceil((每个节点的物理 CPU 核数*单核的线程数*3/2)+1)

数据节点数=ceil(峰值线程数/线程池大小)

通常可以从以下方面思考如何降低 Elasticsearch 集群的成本

  • 业务是否真正需要保留很长时间的数据:Elasticsearch 一般用于存储日志、监控等有时效性的数据,在成本有限的情况下,控制存储容量是降低成本最主要的方法
  • 利用 Elasticsearch 索引生命周期管理实现热温冷架构:将历史数据迁移到成本更低的硬件中
  • 合理配置压缩算法:例如使用腾讯云 Elasticsearch 优化后的 Zstandard 压缩算法,相对 Lucene 默认的压缩算法 LZ4 可提升 35% 的行式存储压缩性,并且性能相当。
  • 合理配置副本分片的数量:如果对数据可用性要求不高,那么可以减少副本分片的数量或将副本分片的数量配置为0
  • 根据业务场景合理配置字段的行式存储与列式存储
  • 业务是否可以将数据汇总以减少存储容量:数据汇总是将原始数据归档或删除,可保留重要的数据或将数据合并,从而减少存储容量。

3. 数据采样

3.1. 常见的采样策略

常见的采样策略包含以下5种:

百分数采样:根据设置的百分数采样,根据随机算法抽取数据

限流采样:根据限制的数据采样,若超过限制的数量则不采样

状态采样:根据调用链的状态采样,只对指定状态的调用链进行采样,如错误的调用链

延迟采样:根据调用链的耗时采样,只对超过耗时的调用链进行采样,例如慢调用

染色采样:根据调用链设置的 tag 采样,只对包含指定 tag 和其对应值的调用链进行采用,如灰度发布时的调用链

在不同的场景下,对系统有不同的采样需求,例如以下的几种场景:

  • 降低系统损耗
  • 对错误调用链路的全量采集
  • 对慢调用的全量采集
  • 对特殊请求的全量采集

基于 QPS 的自适应采样结合错误调用全量采样、慢调用全量采样、特殊请求全量采用来设计,需要预先设置以下的采样参数:

采样最小阈值:在 QPS 小于 QPS 设定的最小阈值的情况下,采样率为 100%,对低吞吐量的应用链路进行全量采样。例如,将最小 QPS 设置为100,每秒收到的请求数小于 100 的应用产生的链路信息会被全部采样。

采样最大阈值:在 QPS 大于阈值的情况下,当超过最大阈值时,采样率为0。即在高并发场景下,超过一定数量的请求直接不采样,消除链路组件对应用性能的影响,确保业务稳定运行。例如,将最大 QPS 设置为 10000,则每秒请求数大于10000的应用在超过 10000 之后的调用信息将全部丢弃

采样百分数:在 QPS 大于最小阈值且小于最大阈值的情况下,采样率为设置的百分数。例如,将采样百分数设置为10%,采样 QPS 最小阈值为100,采样 QPS 最大阈值为 10000,该应用最大采样率为 10000*10%,最小采样数为 10。

慢调用阈值:在配置了慢调用阈值的情况下,无论采样的 QPS 阈值和采样百分数设置为多少,都会对超过慢调用阈值的链路信息进行采集。如果慢调用阈值为 10秒,那么超过10秒的调用链都会被采样。

错误回溯采样:在启用错误回溯采样的情况下,无论采样的 QPS 阈值和采样百分数设置为多少,都会对错误的调用链路进行采样。错误回溯采样并不完全是单元采样,而是可以在产生错误的服务的上游同时感知到该错误,并对上游的链路也进行采样。

染色采样 tag:在配置了染色采样 tag 的情况下,无论采样的 QPS 阈值和采样百分数设置为多少,都对带有该 Tag 的链路进行采样。

3.2. 链路采集方案对比

项目 OpenTelemetry SkyWalking Spring Cloud Sleuth
数据协议 OTLP,支持 ZipKin、Jaeger 协议 遵循 OpenTracing 规范,Segment 包含 span 底层为 Zipkin ,遵循 OpenTracing
语言支持

Java\Go\Python\JavaScript\C++\.NET

\Erlang\PHP\Ruby\Rust\Swift

Java\Python\LUA\Kong\JavaScript\Rust\PHP Java
组件和框架支持 MySQL\Redis\Kafka\Spring\Dubbo\Netty MySQL\Redis\Kafka\Spring\Dubbo\Netty Spring Cloud 框架
MySQL\Redis\Kafka\Netty
采集方式 SDK\Agent SDK\Agent SDK
采集的颗粒度 接口级埋点 接口级埋点 不支持接口级埋点
数据上报方式 HTTP\Zipkin\Jaeger gRPC\Zipkin HTTP

3.3. 链路采集性能对比

指标 OpenTelemetry SkyWalking Spring Cloud Sleuth
采样率 100% 100% 100%
线程数/个 10 10 10
请求总数/个 100000 100000 100000
每秒请求数/秒 6267.06 5883.37 6392.10
平均请求时间/秒 0.159 0.170 0.156
最大请求时间/个 17 85 21
P50/秒 1 2 1
P75/秒 2 2 2
P95/秒 2 2 2
P99/秒 4 7 4

  • 无标签

0 评论

你还没有登录。你所做的任何更改会将作者标记为匿名用户。 如果你已经拥有帐户,请登录