如何提高ElasticSearch 索引速度
我Google了下,大致给出的答案如下:
- 使用bulk API
- 初次索引的时候,把 replica 设置为 0
- 增大 threadpool.index.queue_size
- 增大 indices.memory.index_buffer_size
- 增大 index.translog.flush_threshold_ops
- 增大 index.translog.sync_interval
- 增大 index.engine.robin.refresh_interval
其中 5,6 属于 TransLog 相关。
4 则和Lucene相关
3 则因为ES里大量采用线程池,构建索引的时候,是有单独的线程池做处理的
7 的话个人认为影响不大
2 的话,能够使用上的场景有限。个人认为Replica这块可以使用Kafka的ISR机制。所有数据还是都从Primary写和读。Replica尽量只作为备份数据。
不过我希望大家知其然,并且根据原理,可以根据实际业务场景,做出相应的改动,而不仅仅是会配置上面几个参数。
Translog
为什么要有Translog? 因为Translog顺序写日志比构建索引更高效。我们不可能每加一条记录就Commit一次,这样会有大量的文件和磁盘IO产生。但是我们又想避免程序挂掉或者硬件故障而出现数据丢失,所以有了Translog,通常这种日志我们叫做Write Ahead Log。
为了保证数据的完整性,ES默认是每次request结束后都会进行一次sync操作。具体可以查看如下方法:
org.elasticsearch.action.bulk.TransportShardBulkAction.processAfter
该方法会调用IndexShard.sync 方法进行文件落地。
你也可以通过设置index.translog.durability=async
来完成异步落地。这里的异步其实可能会有一点点误导。前面是每次request结束后都会进行sync,这里的sync仅仅是将Translog落地。而无论你是否设置了async,都会执行如下操作:
根据条件,主要是每隔sync_interval(5s) ,如果flush_threshold_ops(Integer.MAX_VALUE),flush_threshold_size(512m),flush_threshold_period(30m) 满足对应的条件,则进行flush操作,这里除了对Translog进行Commit以外,也对索引进行了Commit。
所以如果你是海量的日志,可以容忍发生故障时丢失一定的数据,那么完全可以设置,index.translog.durability=async
,并且将前面提到的flush*相关的参数调大。
而极端情况,你还可以有两个选择:
设置
index.translog.durability=async
,接着设置index.translog.disable_flush=true
进行禁用定时flush。然后你可以通过应用程序自己手动来控制flush。通过改写ES 去掉Translog日志相关的功能
Version
Version可以让ES实现并发修改,但是带来的性能影响也是极大的,这里主要有两块:
- 需要访问索引里的版本号,触发磁盘读写
- 锁机制
目前而言,似乎没有办法直接关闭Version机制。你可以使用自增长ID并且在构建索引时,index 类型设置为create。这样可以跳过版本检查。
这个场景主要应用于不可变日志导入,随着ES被越来越多的用来做日志分析,日志没有主键ID,所以使用自增ID是合适的,并且不会进行更新,使用一个固定的版本号也是合适的。而不可变日志往往是追求吞吐量。
当然,如果有必要,我们也可以通过改写ES相关代码,禁用版本管理。
分发代理
ES是对索引进行了分片(Shard),然后数据被分发到不同的Shard。这样 查询和构建索引其实都存在一个问题:
如果是构建索引,则需要对数据分拣,然后根据Shard分布分发到不同的Node节点上。
如果是查询,则对外提供的Node需要收集各个Shard的数据做Merge
这都会对对外提供的节点造成较大的压力,从而影响整个bulk/query 的速度。
一个可行的方案是,直接面向客户提供构建索引和查询API的Node节点都采用client模式,不存储数据,可以达到一定的优化效果。
另外一个较为麻烦但似乎会更优的解决方案是,如果你使用类似Spark Streaming这种流式处理程序,在最后往ES输出的时候,可以做如下几件事情:
- 获取所有primary shard的信息,并且给所有shard带上一个顺序的数字序号,得到partition(顺序序号) -> shardId的映射关系
- 对数据进行repartition,分区后每个partition对应一个shard的数据
- 遍历这些partions,写入ES。方法为直接通过RPC 方式,类似
transportService.sendRequest
将数据批量发送到对应包含有对应ShardId的Node节点上。
这样有三点好处:
- 所有的数据都被直接分到各个Node上直接处理。避免所有的数据先集中到一台服务器
- 避免二次分发,减少一次网络IO
- 防止最先处理数据的Node压力太大而导致木桶短板效应
场景
因为我正好要做日志分析类的应用,追求高吞吐量,这样上面的三个优化其实都可以做了。一个典型只增不更新的日志入库操作,可以采用如下方案:
- 对接Spark Streaming,在Spark里对数据做好分片,直接推送到ES的各个节点
- 禁止自动flush操作,每个batch 结束后手动flush。
- 避免使用Version
我们可以预期ES会产生多少个新的Segment文件,通过控制batch的周期和大小,预判出ES Segment索引文件的生成大小和Merge情况。最大可能减少ES的一些额外消耗
总结
大体是下面这三个点让es比原生的lucene吞吐量下降了不少:
- 为了数据完整性 ES额外添加了WAL(tanslog)
- 为了能够并发修改 添加了版本机制
- 对外提供服务的node节点存在瓶颈
ES的线性扩展问题主要受限于第三点,
具体描述就是:
如果是构建索引,接受到请求的Node节点需要对数据分拣,然后根据Shard分布分发到不同的Node节点上。
如果是查询,则对外提供的Node需要收集各个Shard的数据做Merge
另外,索引的读写并不需要向Master汇报。
如何提高ElasticSearch 索引速度相关推荐
- SQL Server 提高创建索引速度的 2 个方法
方法 1. 使用tempdb来提速 create index index_name on table_name (column_list) with(sort_in_tempdb = on); 方法 ...
- 影响Lucene索引速度原因以及提高索引速度技巧
在网上看了一篇外文文章,里面介绍了提高Lucene索引速度的技巧,分享给大家. 先来看下影响索引的主要因素: MaxMergeDocs 该参数决定写入内存索引文档个数,到达该数目后就把该内存索引写入硬 ...
- lucene索引MySQL原因_影响Lucene索引速度原因以及提高索引速度技巧
在网上看了一篇外文文章,里面介绍了提高Lucene索引速度的技巧,分享给大家. 先来看下影响索引的主要因素: MaxMergeDocs 该参数决定写入内存索引文档个数,到达该数目后就把该内存索引写入硬 ...
- delphi报列表索引越界怎么处理_图解Elasticsearch索引机制,此篇带你领悟新世界...
前言 随着Elastic的上市,ELK不仅在互联网大公司得到长足的发展,而且在各个中小公司都得到非常广泛的应用,甚至连"婚庆网站"都开始使用Elasticsearch了.随之而来的 ...
- mysql索引 和 es索引_MySQL索引 VS ElasticSearch索引
今天MySQL数据库栏目介绍MySQL索引与ElasticSearch索引的对比. 前言 这段时间在维护产品的搜索功能,每次在管理台看到 elasticsearch 这么高效的查询效率我都很好奇他是如 ...
- 干货 | Elasticsearch 索引设计实战指南
题记 随着 Elastic 的上市,ELK Stack 不仅在 BAT 的大公司得到长足的发展,而且在各个中小公司都得到非常广泛的应用,甚至连"婚庆网站"都开始使用 Elastic ...
- 看完这篇文章,再也不怕 Elasticsearch 索引设计
题记 随着 Elastic 的上市,ELK Stack 不仅在 BAT 的大公司得到长足的发展,而且在各个中小公司都得到非常广泛的应用,甚至连"婚庆网站"都开始使用 Elastic ...
- Elasticsearch索引和查询性能调优的21条建议【下】
Elasticsearch是一款流行的分布式开源搜索和数据分析引擎,具备高性能.易扩展.容错性强等特点.它强化了Apache Lucene的搜索能力,把掌控海量数据索引和查询的方式提升到一个新的层次. ...
- Elasticsearch索引原理
最近在参与一个基于Elasticsearch作为底层数据框架提供大数据量(亿级)的实时统计查询的方案设计工作,花了些时间学习Elasticsearch的基础理论知识,整理了一下,希望能对Elastic ...
最新文章
- docker 常用命令集合
- CodeForces 459C(构造题)
- 2017-5-4 进程
- 系统烧写方法(MfgTool烧写工具)
- 哪些NPM仓库更易遭供应链攻击?研究员给出了预测指标
- 技术揭秘 | 如何设计 RQData 通讯协议
- dll导出类比较好的方式
- 绿联串口线linux驱动下载,绿联usb转串口驱动
- laravel 数据库迁移后增加字段
- BZOJ 3669 luogu 2387 魔法森林
- bugzilla dbd-mysql_Redhat 搭建bugzilla平台
- python基础知识大一总结与反思_反思总结及规划 其一
- WPS工具栏都是灰色不能编辑解决方法分享
- sundayplayer第一版本开放源代码
- Taro3.2 适配 React Native 之运行时架构详解
- AD9361配置(1)
- 解决mysql load data加载本地null数据,表里出现0的情况
- 用批处理删除指定字符之前或之后的所有内容(FOR /F 中的Delims和Tokens总结)
- 2019年中国研究生数学建模竞赛-华为杯(九)
- 分布式专题(2)- 分布式 Java通信