ElasticSearch写入性能优化

ES提高写入性能的目标

增大写吞吐量,越高越好

基本原则

  • 客户端:多线程,批量写
  1. 可以通过性能测试,确定最佳文档数量
  2. 多线程:需要观察是否由HTTP429返回,实现Retry以及线程数量的自动调节
  • 服务器端:先分解问题,在单个节点上测试调整以达到最高吞吐量
  1. 使用更好的硬件(通过观察CPU/IO Block)
  2. 线程切换/堆栈状况

服务器端优化写入性能的一些手段

  • 降低IO操作
  1. 使用ES自动生成的文档ID(可以避免get操作)
  2. 一些相关的ES配置,如Refresh Interval
  • 降低CPU和存储开销

  1. 减少不必要的分词
  2. 避免不需要的doc_values
  3. 文档的字段尽量保证相同的顺序,可以提高文档的压缩率
  • 尽可能做到写入和分片的负载均衡,实现水平扩展
  1. Shard Filering
  2. Write Load Balancer
  • 调整Bulk线程池和队列

索引建模实践(关闭无关的功能)

  • 如果只需要聚合不需要搜索,Index设置成false
  • 如果不需要算分,Norms设置成false
  • 不要对字符串使用默认的dynamic mapping。字段数量过多,会对性能产生较大的影响
  • Index_options控制在创建倒排索引时,哪些内容会被添加到倒排索引中。优化这些设置,一定程度节约CPU
  • 关闭_source,减少IO操作(适合指标型数据,关闭会影响update等操作);
PUT index
{
    "mappings": {
        "properties": {
            "foo": {
                "type": "integer",
                "index": false
             }
        }
    }
}
-------------------------------
PUT index
{
    "mappings": {
        "properties": {
            "foo": {
                "type": "text",
                "norms": false
             }
        }
    }
}

针对性能的取舍

  • 如果需要追求极致的写入速度,可以牺牲数据可靠性及搜索及时性以换取性能
  1. 牺牲可靠性:将副本分片设置为0,写入完毕再调回去
  2. 牺牲搜索及时性:增加Refresh Inteval的时间
  3. 牺牲可靠性:修改Translog的配置

数据写入过程分析

Refresh:将文档先保存在Index Buffer中,以refresh_interval为间隔时间,定期清空buffer, 生成segment, 借助文件系统缓存的特性,先将segment放在文件系统缓存中,并开放查询,以提升搜索的实时性

Translog:segment没有写入磁盘,即便发生了宕机,重启后数据也能恢复,默认配置是每次请求都会落盘

Flush:删除旧的translog文件,生成segment并写入磁盘,更新commit point并写入磁盘,这里一般由ES自动完成,优化空间不大

写入配置优化

Refresh Interval

  • 通过调大数值来降低Refresh的频率,(默认1s ,如果设置为-1 ,会禁止自动refresh),避免生成过多的segment文件,但是会降低搜索的实时性
  • 增大静态配置参数indices.memory.index_buffer_size, 默认10%,会导致自动触发refresh

Translog

降低写磁盘的频率,但是会降低容灾能力

  • Index.translog.durability: 默认为request, 每个请求都落盘。设置成async,异步写入
  • Index.translog.sync_interval设置为60s ,每分钟执行一次
  • index.translog.flush_threshod_size:默认512mb,可以适当调大。当translog超过这个数值会触发flush

分片设定

  • 副本在写入时设为0,完成后再增加
  • 合理设置主分片数,确保均匀分配在所有数据节点上
  • Index.routing.allocation.total_share_per_node:限定每个索引在每个节点上可分配的主分片数量

Bulk,线程池和队列大小

客户端

  • 单个builk请求体的数据量不要太大,官方建议大约5-15mb
  • 写入端的bulk请求超时需要足够长,建议60s以上
  • 写入端尽量将数据轮询到不同节点

服务端

  • 索引创建属于计算密集型任务,应该使用固定大小的线程池来配置,来不及处理的放入队列,线程数应该配置为CPU核数+1,避免过多的上下文切换
  • 队列大小可以适当增加,不要过大,否则占用的内存会导致GC

优化配置DEMO

DELETE myindex
PUT myindex
{
  "settings": {
    "index": {
      "refresh_interval": "30s",//设置30S一次refresh,默认1S
      "number_of_shards": "2"
    },
    "routing": {
      "allocation": {
        "total_shards_per_node": "3" //控制分片,避免数据热点
      }
    },
    "translog": {
      "sync_interval": "30s",   //降低translog落盘
      "durability": "async"
    },
    "number_of_replicas": 0     //避免副本影响(允许丢数据)
  },
  "mappings": {
    "dynamic": false,    //避免不必要的字段索引,必要时可以通过update by query索引必要的字段
    "properties": {}
  }
}

 

更多内容推荐

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值