添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
想出国的苦瓜  ·  pgsql ...·  2 年前    · 
眉毛粗的豆浆  ·  mysql - Trying to ...·  3 年前    · 

目录 [ 隐藏 ]

基于版本: 2.x – 5.x

在 es 的默认设置,是综合考虑数据可靠性,搜索实时性,写入速度等因素的,当你离开默认设置,追求极致的写入速度时,很多是以牺牲可靠性和搜索实时性为代价的.有时候,业务上对两者要求并不高,反而对写入速度要求很高,例如在我的场景中,要求每秒200w 条的平均写入速度,每条500字节左右

接下来的优化基于集群正常运行的前提下,如果是集群首次灌入数据,可以将副本数设置为0,写入完毕再调整回去,这样副本分片只需要拷贝,节省了索引过程.

综合来说,提升写入速度从以下几方面入手:

  • 加大 translog flush ,目的是降低 iops,writeblock
  • 加大 index refresh间隔, 目的除了降低 io, 更重要的降低了 segment merge 频率
  • 调整 bulk 线程池和队列
  • 优化磁盘间的任务均匀情况,将 shard 尽量均匀分布到物理主机的各磁盘
  • 优化节点间的任务分布,将任务尽量均匀的发到各节点
  • 优化 lucene 层建立索引的过程,目的是降低 CPU 占用率及 IO

translog flush 间隔调整

从 es 2.x 开始, 默认设置下,translog 的持久化策略为:每个请求都flush.对应配置项为:

是一个比较理想的值,如果你只有一块硬盘并且非 SSD, 应该把他设置为1,因为在旋转存储介质上并发写,由于寻址的原因,不会提升,只会降低写入速度.

merge 策略有三种:

  • tiered
  • log_byete_size
  • log_doc

默认情况下:

默认无限制

在大量的索引操作时,indices.memory.index_buffer_size默认设置可能不够,这和可用堆内存,单节点上的 shard 数量相关,可以考虑适当增大.

bulk 线程池和队列大小

建立索引的过程偏计算密集型任务,应该使用固定大小的线程池配置,来不及处理的放入队列,线程数量配置为 CPU 核心数+1,避免过多的上下文切换.队列大小可以适当增加.

磁盘间的任务均衡

如果你的部署方案是为path.data 配置多个路径来使用多块磁盘, es 在分配 shard 时,落到各磁盘上的 shard 可能并不均匀,这种不均匀可能会导致某些磁盘繁忙,利用率达到100%,这种不均匀达到一定程度可能会对写入性能产生负面影响.

es 在处理多路径时,优先将 shard 分配到可用空间百分比最多的磁盘,因此短时间内创建的 shard 可能被集中分配到这个磁盘,即使可用空间是99%和98%的差别.后来 es 在2.x 版本中开始解决这个问题的方式是:预估一下这个 shard 会使用的空间,从磁盘可用空间中减去这部分,直到现在6.x beta 版也是这种处理方式.但是实现也存在一些问题:

从可用空间减去预估大小

这种机制只存在于一次索引创建的过程中,下一次的索引创建,磁盘可用空间并不是上次做完减法以后的结果,这也可以理解,毕竟预估是不准的,一直减下去很快就减没了.

但是最终的效果是,这种机制并没有从根本上解决问题,即使没有完美的解决方案,这种机制的效果也不够好.

如果单一的机制不能解决所有的场景,至少应该为不同场景准备多种选择.

为此,我们为 es 增加了两种策略
简单轮询:系统初始阶段,简单轮询的效果是最均匀的
基于可用空间的动态加权轮询:以可用空间作为权重,在磁盘之间加权轮询

节点间的任务均衡

为了在节点间任务尽量均衡,数据写入客户端应该把 bulk 请求轮询发送到各个节点.

当使用 java api ,或者 rest api 的 bulk 接口发送数据时,客户端将会轮询的发送的集群节点,节点列表取决于:
client.transport.sniff 为 true,(默认为 false),列表为所有数据节点
否则,列表为初始化客户端对象时添加进去的节点.

java api 的 TransportClient 和 rest api 的 RestClient 都是线程安全的,当写入程序自己创建线程池控制并发,应该使用同一个 Client 对象.在此建议使用 rest api,兼容性好,只有吞吐量非常大才值得考虑序列化的开销,显然搜索并不是高吞吐量的业务.

观察bulk 请求在不同节点上的处理情况,通过cat 接口观察 bulk 线程池和队列情况,是否存在不均:

自动生成 doc ID

分析 es 写入流程可以看到,写入 doc 时如果是外部指定了 id,es 会先尝试读取原来doc的版本号, 判断是否需要更新,使用自动生成 doc id 可以避免这个环节.

调整字段 Mappings

字段的 index 属性设置为: not_analyzed,或者 no

对字段不分词,或者不索引,可以节省很多运算,降低 CPU 占用.尤其是 binary 类型,默认情况下占用 CPU 非常高,而这种类型根本不需要进行分词做索引.

单个 doc 在建立索引时的运算复杂度,最大的因素 不在于 doc 的字节数或者说某个字段 value 的长度,而是字段的数量. 例如在满负载的写入压力测试中,mapping 相同的情况下,一个有10个字段,200字节的 doc, 通过增加某些字段 value 的长度到500字节,写入 es 时速度下降很少,而如果字段数增加到20,即使整个 doc 字节数没增加多少,写入速度也会降低一倍.

使用不同的分析器:analyzer

不同的分析器在索引过程中运算复杂度也有较大的差异

调整_source 字段

_source 字段用于存储 doc 原始数据,对于部分不需要存储的字段,可以通过 includes excludes 来过滤,或者将 _source 禁用,一般用于索引和数据分离

这样可以降低 io 的压力,不过实际场景大多数情况不会禁用 _source ,而即使过滤掉某些字段,对于写入速度的提示效果也不大,满负荷写入情况下,基本是CPU 先跑满了,瓶颈在于 CPU.

禁用 _all 字段

_all 字段默认是开启的,其中包含所有字段分词后的关键词,作用是可以在搜索的时候不指定特定字段,从所有字段中检索.如果你不需要这个特性,可以禁用 _all,可以小幅的降低CPU 压力,对速度影响并不明显.

对于 Analyzed 的字段禁用 Norms

Norms 用于在搜索时计算 doc 的评分,如果不需要评分,可以禁用他:

index_options 设置

index_options 用于控制在建立倒排索引过程中,哪些内容会被添加到倒排,例如 doc数量,词频,positions,offsets等信息,优化这些设置可以一定程度降低索引过程中运算任务,节省 CPU 占用率

不过实际场景中,通常很难确定业务将来会不会用到这些信息,除非一开始方案就明确这样设计的

方法比结论重要

当面对一个系统性问题的时候,往往是多种因素造成的,在处理集群的写入性能问题上,先将问题分解,在单台上分析调整最高能力到某种系统资源达到极限,其中观察利用率,io block,线程切换,堆栈状态等,解决局部问题,在此基础上解决整体问题会容易很多

jvm 参数除了 Xmx,Xms 其他尽量使用默认,一些看起来比较合理的参数实际效果可能适得其反。

共享下我的配置:

template-base
elasticsearch

https://doc.yonyoucloud.com/doc/mastering-elasticsearch/chapter-3/36_README.html
https://qbox.io/blog/maximize-guide-elasticsearch-indexing-performance-part-1
https://qbox.io/blog/maximize-guide-elasticsearch-indexing-performance-part-2
https://qbox.io/blog/maximize-guide-elasticsearch-indexing-performance-part-3

相关文章:

  1. elasticsearch 一次长时间 FGC 问题分析
  2. elasticsearch 写流程
  3. elasticsearch 机制和架构
假设我们的应用场景要求是,每秒 300 万的 写入 速度 ,每条 500 字节左右。 针对这种对于搜索性能要求不高,但是对 写入 要求较高的场景,我们需要尽可能的选择恰当写 优化 策略。 综合来说,可以考虑以下几个方面来提升写索引...
1、refresh时间间隔 优化 点: 减少刷新频率,降低潜在的写磁盘性能损耗, 默认的刷新时间间隔是1s,对于 写入 量很大的场景,这样的配置会导致 写入 吞吐量很低,适当提高刷新间隔,可以提升 写入 量,代价就是让新 写入 的数据在60s之后可以被搜索,新数据可见的及时性有所下降。 在bulk大量数据到ES集群的时候可以关闭刷新频率,把其值设置为-1就是关闭了刷新频率,在导入完之后设置成合理的值即可,例
导语:在腾讯金融科技数据应用部的全民BI项目里,我们每天面对超过10亿级的数据 写入 ,提高es 写入 性能迫在眉睫,在最近的一次 优化 中,有幸参与到了 elasticsearch 开源社区中。 为了更便捷地分析数据,腾讯金融科技数据应用部去年推出了全民BI的系统。这个系统通过 elasticsearch 进行基础的统计,超过10亿级的数据量需要尽可能快速地导入到es系统中。即使经过多次的参数 优化 ,我们依然需...
sed -i ‘1i\时报错: sed: -i may not be used with stdin mac中应该写为:【mac自带的sed命令,是基于bsd的,所以与Linux-like下常用的gnu不一样】 sed -i "" '1i\ insert value here
1、用bulk批量 写入 你如果要往es里面灌入数据的话,那么根据你的业务场景来,如果你的业务场景可以支持让你将一批数据聚合起来,一次性 写入 es,那么就尽量采用bulk的方式,每次批量写个几百条这样子。 bulk批量 写入 的性能比你一条一条 写入 大量的document的性能要好很多。但是如果要知道一个bulk请求最佳的大小,需要对单个es node的单个shard做压测。先bulk 写入 100个doc...
Kafka是高吞吐低延迟的高并发、高性能的消息中间件,在大数据领域有极为广泛的运用。配置良好的Kafka集群甚至可以做到每秒几十万、上百万的超高并发 写入 。 那么Kafka到底是如何做到这么高的吞吐量和性能的呢? 一、页缓存技术 + 磁盘顺序写 首先Kafka每次接收到数据都会往磁盘上去写,为了保证数据 写入 性能,Kafka是基于操作系统的页缓存来实现文件 写入 的。 操作系统本身有一层缓存,叫做page...
"number_of_shards": 5, "number_of_repl
这个问题说白了,就是看你有没有实际用过 ES,因为啥?其实 ES 性能并没有你想象中那么好的。 很多时候数据量大了,特别是有几亿条数据的时候,可能你会懵逼的发现,跑个搜索怎么一下 5~10s,坑爹了。 第一次搜索的时候,是 5~10s,后面反而就快了,可能就几百毫秒。 你就很懵,每个用户第一次访问都会比较慢,比较卡么?所以你要是没玩儿过 ES,或者就是自己玩玩儿 Demo,...
qq_15282423: 不要误导别人了,什么kibana就是这样处理的?kibana没这么笨 GET /index1,index2,index3/_search?ignore_unavailable=true 加?ignore_unavailable=true就可以 Elasticsearch集群冷热分离-实际操作 dzdyx: curator 有官方文档吗?不知道怎么用啊