4

Elasticsearch性能优化

 2 years ago
source link: https://jelly.jd.com/article/6164366566c14901a1f855c4
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Elasticsearch性能优化
上传日期:2021.11.03
Elasticsearch发布时带有的默认值,可为Elasticsearch的开箱即用带来很好的体验。全文搜索、高亮、聚合、索引文档 等功能,无需用户修改即可使用 当你更清楚的知道你想如何使用Elasticsearch后,你可以做很多的优化以提高你的用例的性能,下面的内容告诉你 你应该/不应该 修改哪些配置

一、索引速度调优

  1. 批量请求比单文档索引请求好
  2. 调大refresh interval

    默认的index.refresh_interval为1s,这迫使Elasticsearch每秒创建一个新的分段,增加这个值(比如:30s)将允许更大的部分flush并减少未来的合并压力

  3. 加载大量数据时禁用refresh和replicas

    如果需要一次加载大量数据,则应该将index.refresh_interval设置为-1,并将index.number_of_replicas设置为0来禁用刷新。

    这会暂时导致索引处于危险之中,因为任何分片的丢失都将导致数据丢失,但是同时索引将会更快,因为文档只被索引一次。

    初始加载完成后,可以将index.refresh_interval和index.number_of_replicas设置回其原始值

  4. 设置参数,禁止操作系统将es进程转换出去

    应该确保操作系统不会转换 java进程,通过禁止swap

    具体如 https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html

  5. 为文件系统缓存分配一半的物理内存

    文件系统缓存将用于缓冲I/O操作,应该确保将运行Elasticsearch的计算机内存至少减少到文件系统缓存的一半

  6. 使用自动生成的id(auto-generated ids)

    索引具有显式id的文档时,Elasticsearch需要检查具有相同id的文档是否已经存在于相同的分片中,这是昂贵的操作,并且随着索引增长而变得更加昂贵。

    通过使用自动生成的ID,Elasticsearch可以跳过这个检查,这使索引更快

  7. 配置更好的硬件

    一般是I/O密集型的,需要考虑以下几个因素:

    a. 为文件系统缓存分配更多的内存

    b. 使用SSD硬盘

    c. 使用本地存储(不要使用NFS、SMB等远程文件系统)

  8. 加大 indexing buffer size

    如果节点只做大量的索引,确保index.memory.index_buffer_size足够大,每个分区最多可以提供512MB的索引缓冲区,而且索引的性能通常不会提高。

    Elasticsearch采用该设置(java堆的一个百分比或绝对字节大小),并将其用作所有活动分片的共享缓冲区。非常活跃的碎片自然会使用这个缓冲区,而不是执行轻量级索引的碎片。

    默认值是10%,通常很多。例如,如果你给JVM 10GB的内存,它会给索引缓冲区1GB,这足以承载两个索引很重的分片。

  9. 禁用_field_names字段

    _field_names字段引入了一些索引时间开销,所以如果不需要运行存在查询,需要禁用它。

    具体如 https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-field-names-field.html

  10. 其余再去看看"磁盘使用调优"

    参见 https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-disk-usage.html

二、搜索速度调优

  1. 文件系统缓存越大越好

    为了使得搜索速度更快,Elasticsearch严重依赖文件系统缓存

    一般来说,需要至少一半的可用内存作为文件系统缓存,这样Elasticsearch可以再物理内存中保有索引的热点区域

  2. 文档模型文档需要使用合适的类型,从而使得搜索时间操作消耗更少的资源

    避免join操作。具体是指a.nested会使得查询慢好几倍,b.parent-child关系 更是使得查询慢几百倍

    如果无需join能解决问题,则查询速度会快很多。

  3. 预索引数据

    根据“搜索数据最常用的方式”来优化索引数据的方式。

    举例:所有文档都有price字段,大部分query在fixed ranges上运行range aggregation,那可以把给定范围的数据预先索引下。然后使用terms aggregation。

  4. Mappings(能用keyword最好)数字类型的数据,并不意味着一定非要使用numeric类型的字段

    一般来说,存储标识符的字段(书号、或者来自数据库标识一条记录的数字),使用keyword更好

  5. 避免运行脚本

    一般来说,脚本应该避免。如果是绝对需要的话,应该使用painless和expressions引擎

  6. 强制merge只读的索引

    只读的索引可以从“merge成一个单独的大segment”中受益

  7. 预热全局序数

    全局序数用于在keyword字段上运行terms aggregation。Elasticsearch不知道哪些字段将用于/不用于term aggregation

    因此全局序数在需要时才加载进内存,但可以在mapping type上,定义eager_global_ordinals==true。这样,refresh时就会加载全局序数

  8. 预热文件系统缓存

    机器重启时,文件系统缓存就被清空

    操作系统将索引的热点区域加载进文件系统缓存是需要花费一段时间的。设置index.store.preload可以告知操作系统这些文件是需要提早加载进入内存

  9. 使用索引排序来加速连接

    索引排序对于以较慢的索引为代价来加快连接速度非常有用。在索引分类文档中阅读更多关于它的信息。

  10. 使用preference来优化高速缓存利用率

    有多个缓存可以帮助提高搜索性能,例如文件系统缓存,请求缓存或查询缓存。

    然而,所有这些缓存都维护在节点级别,这意味着如果连续运行两次相同的请求,则有一个或多个副本,并使用循环(默认路由算法),那么这两个请求将转到不同的分片副本,阻止节点级别的缓存帮助。

    由于搜索应用程序的用户一个接一个地运行类似的请求是常见的,例如为了分析索引的较窄的子集,使用标识当前用户或会话的优选值可以帮助优化高速缓存的使用。

  11. 副本可能有助于吞吐量,但不会一直存在

    除了提高弹性外,副本可以帮助提高吞吐量。例如,如果您有单个分片索引和三个节点,则需要将副本数设置为2,以便共有3个分片副本,以便使用所有节点。

    现在假设你有一个2-shards索引和两个节点。

    在一种情况下,副本的数量是0,这意味着每个节点拥有一个分片。在第二种情况下,副本的数量是1,这意味着每个节点都有两个碎片。

    哪个设置在搜索性能方面表现最好?通常情况下,每个节点的碎片数少的设置将会更好。

    原因在于它将可用文件系统缓存的份额提高到了每个碎片,而文件系统缓存可能是Elasticsearch的1号性能因子。

    同时,要注意,没有副本的设置在发生单个节点故障的情况下会出现故障,因此在吞吐量和可用性之间进行权衡。

    那么复制品的数量是多少?如果您有一个具有num_nodes节点的群集,那么num_primaries总共是主分片,如果您希望能够一次处理max_failures节点故障,那么正确的副本数是max(max_failures,ceil(num_nodes / num_primaries) - 1)。

  12. 打开自适应副本选择

    当存在多个数据副本时,Elasticsearch可以使用一组称为自适应副本选择的标准,根据包含分片的每个副本的节点的响应时间,服务时间和队列大小来选择数据的最佳副本。这可以提高查询吞吐量并减少搜索量大的应用程序的延迟。

三、通用建议

  1. 不要 返回大的结果集

    Elasticsearch设计来作为搜索引擎,它非常擅长返回匹配query的top n文档。

    但如“返回满足某个query的 所有文档”等数据库领域的工作,并不是es最擅长的领域。如果确实需要返回所有文档,可以使用Scroll API

  2. 避免大的文档,即单个文档小了会更好

    考虑到http.max_context_length默认==100MB,Elasticsearch拒绝索引操作100MB的文档。

    当然可以提高这个限制,但Lucene本身也有限制的,其为2GB 即使不考虑上面的限制,大的文档会给 网络/内存/硬盘带来更大的压力;

    a. 任何搜索请求,都需要获取 _id 字段,由于文件系统缓存工作方式。即使它不请求 _source字段,获取大文档 _id 字段消耗更大

    b. 索引大文档时消耗内存会是文档本身大小的好几倍

    c. 大文档的 proximity search, highlighting 也更加昂贵。它们的消耗直接取决于文档本身的大小


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK