0%

大数据存储框架之Elastaticsearch(4) 提升性能(持续更新)

本篇博文主要内容:

  • 批量处理、多条获取和多条搜索API接口

  • 刷新、冲刷、合并和存储

  • 过滤器缓存和过滤器调优

  • 调优脚本

  • 查询预热器

  • 均衡JVM堆大小和操作系统缓存

前言

Elastaticsearch 在进行做进行索引,搜索和抽取统计数值的聚集操作时,通常被认为是很快的。“快”是个模糊的概念。我们不免要问“到底有多快?”,对任何实例,“有多快”取决于具体用例、硬件和配置。
本篇博文中,老夫也会配置Elastaticsearch的最佳实践,从而让系统在应用场景下表现良好。当然,每一次性能的提升,是需要有其他东西的牺牲的。

  • 应用复杂性——在第一节中,老夫将展示如何在一个Http访问中合并多个请求,如 index/update/delete/get/search . 应用程序对于这种合并需要保持谨慎(因为这会增加应用程序的复杂性)。但是它可以大幅度的提升系统的整体性能。基本可以这么想,由于更少的网络传输,索引能快20-30倍,是不是很激动;
  • 牺牲索引速度换区搜索速度还是反之——第二节中,我们需要理解Elastaticsearch是如何处理Lucene分段的:刷新、冲刷、合并策略,以及存储设置是如何运作的,又是如何影响索引和搜索的性能的。调优索引的性能常常会对搜索产生负面影响,反之亦然;
  • 内存——影响Elastaticsearch速度的一个因素就是缓存。我们需要深入过滤器缓存的细节,理解充分最好的利用过滤器。还会涉及到分片查询换存,以及为Elastaticsearch的堆充分预留空间的同时,如何为操作系统保留足够的空间让其缓存索引。如果在冷启动的缓存上运行搜索时慢的让人无法忍受,那么你可以使用索引预热器在后台运行查询,来为缓存热身。
  • 以上所有——根据具体的使用场景,在索引阶段你分析文本的方式,以及使用的查询类型可能越来越复杂,这将拖慢其他操作。或者消耗更多内存。

合并请求

为了获得更快的索引速度,所能做的优化是通过bulk批量API。一次发送多篇文档进行索引。这个操作将节省网络来回的开销,并产生更大的吞吐量。一个单独的批量可以接受任何的索引操作。例如,可以创建或者重写文档。也可以将update/delete操作加入批量,不限于索引操作。
如果应用需要一次发送多条get或search操作,也有对应的批量处理:多条获取和多条搜索API。

批量索引、更新和删除

使用批量的索引

1
2
3
4
5
6
request_file=/opt/datas/es/test_bulk
echo '{"index":{"_index":"get-togther","_type":"group","_id":"10"}}
{"name":"es buchtest"}
{"index":{"_index":"get-togther","_type":"group","_id":"11"}}
{"name":"es bigdata buchtest"}'>$request_file
curl -H "Content-Type: application/json" -XPOST hadoop101:9200/_bulk --data-binary @$request_file

这里牵扯到程序代码的问题了,就不多说了。

优化Lucene分段的处理

一旦Elastaticsearch接收到应用所发送的文档,它会将其索引到内存中称为分段(segments)的倒排索引。这些分段会不时的写入到磁盘,且是不可变的,只能被删除(这是为了操作系统更好的缓存他们)。另外,较大的分段会定期从较小的分段创建而来,用于优化倒排索引,使搜索更快。
有很多的调节方式来影响每一个环节中Elastaticsearch对于这些分段的处理,根据你的使用场景来配置这些,常常会带来意义重大的性能提升。一般可分为三类:

刷新(refresh)和冲刷(flush)频率
刷新,会让ES重新打开索引,让新建的文档可用于搜索。冲刷是将索引的数据从内存写入到磁盘。这两者都挺消耗资源的。
合并的策略
Lucene将数据存储在不可变的一组文件中,也就是所谓的分段中。随着索引的数量的增加,系统会创建更多的分段。由于在过多的分段中搜索是很慢的,因此在后台小的分段中会被合并成大的分段,保持分段的数量可控。不过,合并也是十分消耗性能的。
存储和存储限流
ES调节每秒写入的字节数,来限制合并对I/O系统的影响。根据硬件和应用,我们可以调整这个限制。

刷新和冲刷的阈值

我们先看一下这个 setting/ , 这是我其中一篇文档的setting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"flink-ci123" : {
"settings" : {
"index" : {
"refresh_interval" : "1s",
"number_of_shards" : "5",
"provided_name" : "flink-ci123",
"creation_date" : "1576485954822",
"number_of_replicas" : "1",
"uuid" : "3jQg9oB8TW-i06MwuWIMmQ",
"version" : {
"created" : "6060099"
}
}
}
}
}

何时刷新

默认的行为是每秒自动的刷新每份索引,可以修改时间间隔,这个可以是在运行时完成的。

1
2
3
4
PUT flink-ci123/_settings
{
"index.refresh_interval":"1024s"
}

小贴士: 为了确定修改生效了,可以运行如下命令来获取全部的索引设置:

1
GET flink-ci123/_settings?pretty

当增加’refresh_interval’值时,将获得更大的索引吞吐,因此花费在刷新上的系统资源就减少了
或者也可以将’refresh_interval’设置为 -1 , 彻底关闭自动刷新并依赖手动刷新。这对于索引只是定期批量变化的引用非常有效,如 产品和库存每晚更新的零售供应链。索引的吞吐量是非常重要的
因为想着总是快速更新,但是数据刷新并不是最重要的,因为无论如何都不可能获得完全的实时更新,所以每晚可以关闭自动刷新,进行批量bulk索引和更新,完成后在进行手动刷新。
为了实现手动刷新,访问带刷新索引的_refresh端点.

1
GET flink-ci123/_refresh

何时冲刷

重点: 不要认为:当刷新发生的时候,所有的数据(内存中)都已经完成了索引,因为最近一次的刷新也会将其写入磁盘。
重点: 对于ES,刷新的过程和内存分段写入磁盘的过程是独立的。
实际上,内存先索引到内存中,经过一次刷新后,ES也会搜索相应的内存分段(在内存中的搜索会快很多,因此,有的书中称这个过程为开心的)。将内存中的分段提交到磁盘上的Lucene索引过程,被称为冲刷(flush)、,无论分段是否能被搜到,冲刷都会发生。

为了确保某个节点宕机或分片移动位置的时候,内存数据不会丢失,ES将使用事务日志来跟踪尚未冲刷的索引操作。除了将内存分段提交到磁盘,冲刷还会清理事务日志,如图所示:
flush-1
冲刷操作将分段从内存中移动到磁盘上,并清除事务日志

如下所示,满足下列条件之一就会触发冲刷操作:

  • 内存缓冲区已满
  • 自上次冲刷后超过了一定的时间
  • 事务日志达到了一定的阈值

flush-transaction.png
为了控制冲刷发生的频率,不要调整这3个条件的设置。
内存缓冲区的大小在 elastaticsearch.yml 配置文件中定义,通过 indices.memory,index_buffer_size 来设置。这个设置控制了整个节点的缓冲区,其值可以是全部JVM堆内存的百分比,如10%,也可以是 100 MB 这样的固定值。

这是打赏的地方...

本文标题:大数据存储框架之Elastaticsearch(4) 提升性能(持续更新)

文章作者:Mr.Sun

发布时间:2019年12月16日 - 09:40:10

最后更新:2020年06月15日 - 10:05:35

原始链接:http://www.blog.sun-iot.xyz/posts/162fb96b

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

---------Thanks for your attention---------