近期有和别人聊到es的极限读写能力的问题:问题如下

关于elasticsearch的极限写入优化问题_压测

下边是我的答案

针对您问的问题,我先合并回答。

从集群规划来说

  您问题的核心是es集群的极限读写能力。这个问题,应该先从es的集群规划开始回答。好的能力是建立在一个健康的集群之上的。而集群规划则包括集群的节点数,索引的分片数,同时还包括您提到的我们需要让es集群的节点分工明确(不同的节点承担不同的角色的好处,不同角色节点的职责不一样,消耗的资源不一样。data节点做分片数据的处理。协调节点做结果合并,master节点做集群元数据的管理。如果把节点混在一起,大量任务进来以后,可能会导致master节点发生脑裂。在角色合理分配以后我们可以给针对不同的角色节点分配不同的资源,达到资源利用率最大化)。另外集群规划,还包括了每个节点应该分配多大的资源。
   针对es索引的mapping结构也要注意到,应该对索引的功能进行完整的评估,明确每个字段的意义,来决定是否分词,是或否要存储。
  追求es的极限读写能力,我们不能忽略的一个点就是:硬件资源,最具代表的是CPU核心数,磁盘的读写能力(有条件的话升级SSD,不过不要组磁盘矩阵。如果单台服务器上有多个节点,我们可以给数据节点挂载不同的磁盘目录)网络传输能力也要考虑到特别是当索引的分片数比较多的时候,所有分片获取到的结果都要传输到协调节点做汇总。还是需要根据实际的硬件资源,实际的索引需求来进行压测,达到CPU和IO的临界最大值,至少不能让其中某个类型的资源制约另外的资源的发挥。
  es的堆应该合理的来调配,也就是和JVM相关的。假如我们的节点配制的堆内存比较大,比如31G,我们可以使用G1垃圾回收器(这里需要我们真的深入研究JVM中的垃圾回收器,才能知道为什么这么来调配)。在写入压测的时候,在关注上述硬件资源的同时,也应该关注我们的堆,以及垃圾回收的情况。

------------------------------------------------------------------------------------------------------------------------------

  先保证我们的es集群在极佳状态
  再分别说读写

------------------------------------------------------------------------------------------------------------------------------

关于 bulk的极限写入

  我曾负责压测过阿里云数据中心提供的es私有云。我说一下自己做过的点。
  首先看了es的压测报告,他们说特定资源下可以每秒写5W,而我们实际上的压测结果是4W左右。实际上es的写入能力,并不能用条数来衡量。应该是文档累计的大小。之所以我们的写入能力差是因为此时,es集群的极限写能力在磁盘,大概每秒9M多点。我们测算了阿里的测试数据,根据文档大小来算。 它们的文档比较小,我们的文档内容比较大,最终的结果是:阿里测试数据文档大小 * 5W  ~= 我们自己的数据* 4W ~= 10M。
  在过程中,做了以下几点优化:

  • 1. 合理的算出桶提交的文档数,大约在 10M最佳。
  • 2. 在允许的条件下,将集群的副本数设置为0。
  • 3. 增大refresh的时间间隔。
  • 4. 增大批量写入的线程数。我们大概提升到了8个批量写入的线程。发现已经没有明显的提高了,并且集群的负载已经非常高了。
  • 5. 如果可以的话,使用自动生成的id(这个根据业务来定,特定场景下就是需要自定义ip,比如网络空间测绘中对资源的描述,应该是有一个key值作为id)。
  • 6.合理根据公式调大index buffer。
  • 7.如果可控制的话,通过设置routting,将一个批次的数据最好打到同一个分片去执行。

 关于es的查询

  时间有限,这里就不说查询技巧之类的了。
  说一下您问的关于如何做到在查询的时候预热数据。
  曾和阿里云数据中心的人聊过es,结论是并不是什么数据都要放在es中。 对我们网络空间测绘的场景,我们对资产的刻画通常都有几十到上百的维度描述字段。为了平台的各方面检索能力,我们还不得不存这些字段。像他们所说的es的极资源分配,最好是存储的数据都缓存在内存中。对于网络空间测绘的场景,数据在10T以上,甚至更多,根本不可能做到都缓存。 但是基于es特性的检索能力。
  我在做单个索引基于10T数据检索的时候,发现并不是所有的查询都很耗时。我有去抓取es中耗时且大量的查询操作,并把这些操作通过定期轮训的方式去预热加载到内存中来。这实际上是去短板的做法。
  您说的预热更多的是想要提升查询性能,减少召回花费的时间。除了一些查询技巧以外,做了一些测试以后,发现,通过减少搜索结果集,也就是拆分索引的方式。可以很有效的提升检索的性能(不过这要在业务写一个路由所有的路由器,并且需要在入库的时候双写,甚至多写)。

关于这个问题的补充

 后边也有再去看一些文章,看大厂的一些优化方法。我在上边都有列出来了。

滴滴ElasticSearch千万级TPS写入性能翻倍技术剖析