Elasticsearch-性能相关
1.从合理分配节点角色角度分析
节点类型
- 不同角色的节点
- Master eligible / Data / Ingest / Coordinating / Machine Learning
- 在开发环境中,一个节点可承担多个角色
- 在生产环境中
- 根据数据量,输入和查询的吞吐量,选择合适的部署方式
- 建议设置单一角色的节点
单一角色(职责分离)的好处
- Master eligible nodes:负责集群状态的管理
- 使用低配置的CPU,RAM和磁盘
- 一般在生产环境中配置3台
- 一个集群只有一个活跃的主节点
- 负责分片管理, 索引创建, 集群管理等操作
- Data nodes:负责数据存储及处理客户端请求
- 使用高配置的CPU,RAM和磁盘
- Ingest nodes:负责数据处理
- 使用高配的CPU,中等配置的RAM,低配置的磁盘
- Coordinating nodes:负责接收个处理用户的请求
- 中/高配置CPU,中/高配置RAM,低配置的磁盘
- 生产环境中,建议为一些大的集群配置Coordinating only nodes
- 可以充当load blancers,降低Master和Data nodes的负载
- 有时候无法预知客户端会发送怎么样的请求
- 大量占用内存的深度聚合查询,可能会引发OOM
如果Master节点和Data节点或者Coordinating节点混合部署,可能会导致以下问题
- 数据节点相对有比较大的内存占用
- Coordinating节点有时候可能会有开销很高的查询,导致OOM
- 这些都有可能影响Master节点,导致集群的不稳定
水平扩展的场景
- 当磁盘容量无法满足需求时,可以增加数据节点,磁盘读写压力大时,增加数据节点
- 前提是paimary node设置得足够大
- 当系统中有大量的复杂查询及聚合的时候,增加Coordinating节点,增加查询的性能
2.使用Hot&Warm体系结构提高性能和降低成本
适用场景
- 数据通常不会有Update操作
- 基于时间序列且数据量比较大的索引
Hot节点只存放经常要被查询和分析的数据,提高了整体的查询性能
同时引入Warm节点,低配置大容量的机器存放老数据,以降低部署成本
两类数据节点,不同的硬件配置
- Hot节点:索引不断有新文档写入,通常使用SSD
- Warm节点:索引不存在新数据的写入,同时也不存在数据查询,通常使用HDD
3. 从分片的角度分析
单个分片
- 7.0 开始,新创建一个索引时,默认只有一个主分片
- 单个分片,查询算分,聚合不准的问题都可以得以避免
- 单个索引,单个分片的时候,集群无法实现水平扩展
- 即使新增加节点,也无法实现水平扩展
两个分片
- 集群增加一个节点后,Elasticsearch会自动进行分片的移动,也叫Shard Rebalancing
如何设计分片数?
- 当分片数>节点数时
- 一旦集群中右新数据节点的加入,分片就可以自动进行分配
- 分片在重新分配时,系统不会有downtime
多分片的好处:一个索引如果分布在不同的节点,多个节点并行执行
- 查询可以并行执行
- 数据写入可以分散到多个机器
分片过多带来的副作用
- Shard是Elasticsearch实现集群水平扩展的最小单位
- 过多设置分片数会带来一些潜在的问题
- 每个分片是一个lucene的实例,会占用机器的资源。过多的分片会导致额外的性能开销
- 系统文件描述符/RAM/CPU
- 每次搜索的请求,需要从每个分片上获取数据
- 分片的Meta信息由Master节点维护,过多会增加管理的负担
- 每个分片是一个lucene的实例,会占用机器的资源。过多的分片会导致额外的性能开销
如何确定主分片数
- 从存储的物理角度看
- 日志类应用,单个分片不要大于50GB
- 搜索类应用,单个分片不要超过20GB
- 为什么要控制分片存储大小?
- 提高Update性能
- Merge操作时,减少所需资源
- 丢失节点后,具备更快的恢复速度/便于分片在集群内Rebalancing
如何确定副本分片数
- 副本分片是主分片的拷贝
- 提高系统可用性,防止数据丢失
- 需要占用和主分片一样的资源
- 对性能的影响
- 副本会降低数据的索引速度:有几份副本就会有几倍的CPU资源消耗在索引上
- 会减缓对主分片的查询压力,但是会消耗同样的内存资源
- 如果机器资源充分,提高副本数,可以提高整体查询的QPS
多分片索引Terms聚合分析不准
原因:数据分散在多个分片上,Coordinating Node无法获取数据全貌
解决方法:
1. 当数据量不大的时候,设置Primary Shard为1,实现准确性
2. 在分布式数据上,设置shard_size参数,提高精准度(原理:每次从Shard上额外多获取数据,提高准确率)
4. 集群写性能优化
- 写性能优化的目标:增大写吞吐量,越高越好
- 客户端:多线程,批量写
- 服务端:单个性能问题,往往是多个因素造成的。需要先分解问题,在单个节点上进行调整并且结合测试,尽可能压榨硬件资源,以达到最高吞吐量
常用手段:
- 降低IO操作
- 使用ES自动生成的文档ID / 一些相关的ES配置,入Refresh Interval
- 降低CPU和存储开销
- 减少不必要分词 / 避免不需要的doc_values / 文档的字段尽量保证相同的顺序,可以提高文档的压缩率
- 尽可能做到写入和分片的负载均衡,实现水平扩展
- 调整Bulk线程池和队列
Finally,一切优化都要基于高质量的数据建模
- 只需要聚合不需要被搜索,Index设置成false
- 不需要算分,Norms设置成false
- 不要对字符串使用默认的Dynamic Mapping,字段数过多,会对性能产生比较大的影响
- Index_options控制在创建倒排索引大的时候,哪些内容会被添加到倒排索引中,优化这些配置,一定程度可以节约CPU
- 关闭_source,减少IO操作(除非特殊情况,否则不建议)
针对性能的取舍
如果需要追求极致的写入速度,可以牺牲数据可靠性及搜索实时性来换取性能
- 牺牲可靠性:将副本分片设置为0,写入完毕再调整回去
- 牺牲搜索实时性:增加Refresh Interval的时间
- 牺牲可靠性:修改Translog的配置
数据的写入过程
- Refresh
- 将文档先保存在Index Buffer中,以refresh_interval为间隔时间,定期清空buffer,生成segment,借助文件系统缓存的特性,先将segment放在文件系统缓存中,并开放查询,实现搜索的实时性
- Translog
- segment没有写入磁盘,即便发生了当机,重启后,数据也能恢复,默认配置是每次请求都会落盘
- Flush
- 删除旧的translog文件
- 生成的segment并写入磁盘/更新commit point并写入磁盘。ES自动完成,可优化点不多
Refresh Interval
- 降低Refresh的频率
- 增加refresh_interval的数值。默认为1s,如果设置成-1,会禁止自动refresh
- 避免过于频繁的refresh,而生成过多的segment文件
- 但是会降低搜索的实时性
- 增加refresh_interval的数值。默认为1s,如果设置成-1,会禁止自动refresh
Translog
降低写入磁盘的频率,但是会降低容灾能力
- Index.translog.durability:默认是 request,每个请求都落盘。设置成 async,异步写入
- Index.translog.sync_interval 设置为 60s,每分钟执行一次
- Index.translog.flush_threshod_size: 默认 512 mb,可以适当调大。 当 translog 超过该值,会触发 flush
5. 集群读性能优化
尽可能'反规范化'数据,从而获取最佳性能
- 使用 Nested 类型的数据。查询速度会慢几倍
- 使用 Parent / Child 关系。查询速度会慢几百倍
尽量使用Filter Context,利用缓存机制,减少不必要算分
结合profile,explain API分析慢查询的问题,持续优化数据模型
- 严禁使用*开头通配符Terms查询
优化查询语句

浙公网安备 33010602011771号