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节点维护,过多会增加管理的负担

如何确定主分片数

  • 从存储的物理角度看
    • 日志类应用,单个分片不要大于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文件
      • 但是会降低搜索的实时性

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查询

优化查询语句

  

 

 

posted @ 2020-11-29 23:16  下山打老虎i  阅读(190)  评论(0)    收藏  举报