elasticsearch 官方优化建议

news2024/9/8 23:10:10

.一般建议

  a.不要返回过大的结果集。这个建议对一般数据库都是适用的,如果要获取大量结果,可以使用search_after api,或者scroll (新版本中已经不推荐)。

 

  b.避免大的文档。

2. 如何提高索引速度

  a.使用批量请求。为了达到最好的效果,可以进行测试,递增地提高bulk的数量,比如从100,到200,再到400,达到一个吞吐量和响应时间的平衡。

  b.使用多线程发送数据。

  c.关闭或者减小refresh_interval。从内存缓存写入磁盘缓存(memorybuffer -> filesystem cache),这个过程叫做refresh。在这个过程之前内存缓存里面的文档是不可被搜索的,这也是为什么es被称为近实时索引的原因。

    在索引初始化(大量导入文档)的时候,可以关闭refresh_interval。当产品允许较大的不可搜索时间,可以将index.refresh_interval设置为30s,提高索引速度。

  d.初始化时关闭复制分片。索引时设置index.number_of_replicas为0,避免主分片复制数据,索引完毕后再调整到正常的复制分片数。

  e.关闭swapping。swap会极大地降低es的索引速度。

Swap分区(即交换区)在系统的物理内存不够用的时候,把硬盘空间中的一部分空间释放出来,以供当前运行的程序使用。
那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap分区中,等到那些程序要运行时,再从Swap分区中恢复保存的数据到内存中。

  f.给文件系统缓存分配足够多的内存。文件系统换行用来处理io操作,至少要将物理机一半的内存分配给文件系统缓存。比如物理机内存64g,那么至少分配32g给文件系统缓存,剩下的内存才考虑分配给es。

  g.使用自动生成的id。如果使用指定的id,es会检查这个id是否已经存在,而且随着文档数越多,这个判重操作越耗时。索引的时候,如果没有指定id,es会自动生成id。

{
    "_index": "sales",
    "_type": "_doc",
    "_id": "xb7IY4cB6Rdc8HbDycuE", // auto-generated id
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 10,
    "_primary_term": 1
}

  h.使用更好的硬件。比如SSD,或者Amazon的Elastic Block Storage。

  i.调整索引缓存大小。确保每个索引分片能获得512M的缓存,即 indices.memory.index_buffer_size = 512M,大于512M没有更多提升效果。

  j.使用cross-cluster replication 来实现读写分离,这样让索引集群压力更小。这和mysql中的读写分离很类似。

3.如何提到搜索速度

  a.给文件系统缓存分配足够多的内存。

  b.在linux环境中设置合适的readahead。但是es中的查询更多的是随机io,过大的readahead反而使文件系统的页缓存严重抖动,从而使查询性能下降。

Linux的文件预读readahead,指Linux系统内核将指定文件的某区域预读进页缓存起来,便于接下来对该区域进行读取时,不会因缺页(page fault)而阻塞。因为从内存读取比从磁盘读取要快很多。
预读可以有效的减少磁盘的寻道次数和应用程序的I/O等待时间,是改进磁盘读I/O性能的重要优化手段之一。使用命令lsblk查看readahead值。

  c.使用更好的硬件。

  d.好的文档模型。酌情使用nested query, parent query, 避免使用join query。

文档模型对比普通查询
nested query慢几倍
parent query慢几百倍
join query应当避免

  e.尽可能少的查询字段。在越多的字段上匹配,查询速度就越慢。在索引的时候可以将需要查询的多个字段聚合到一个字段中。使用copy_to 可以自动实现这一功能,以下示例将name和plot字段聚合到name_and_plot字段中。

PUT movies
{
  "mappings": {
    "properties": {
      "name_and_plot": {
        "type": "text"
      },
      "name": {
        "type": "text",
        "copy_to": "name_and_plot"
      },
      "plot": {
        "type": "text",
        "copy_to": "name_and_plot"
      }
    }
  }
}

  f.预先索引数据。比如如果想对price字段做range聚合,那么预先计算出单个文档的price范围,那么就能将range聚合转化成terms聚合。这样确实能提高效率,但是不太灵活。

插入文档:

PUT index/_doc/1
{
  "designation": "spoon",
  "price": 13
}

range聚合查询:

GET index/_search
{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 10 },
          { "from": 10, "to": 100 },
          { "from": 100 }
        ]
      }
    }
  }
}

另一种做法,预先计算price_range:

PUT index
{
  "mappings": {
    "properties": {
      "price_range": {
        "type": "keyword"
      }
    }
  }
}

PUT index/_doc/1
{
  "designation": "spoon",
  "price": 13,
  "price_range": "10-100"
}

使用terms聚合:

GET index/_search
{
  "aggs": {
    "price_ranges": {
      "terms": {
        "field": "price_range"
      }
    }
  }
}

  g.尽可能将字段自定义为keyword。对于数字类型的字段,es对其range查询做了优化。在term层级的查询下,keyword字段比数字类型要好。

    在以下两种情况下可以考虑将数字类型定义为keyword:

      1.不需要对这些数据进行range查询

      2.有很高的查询速度要求。

    如果实在不清楚哪个好,可以用 multi-field为数字类型的字段同时定义数字类型和keyword类型。

  h.避免使用脚本。如果可能,避免使用脚本排序,使用脚本聚合,以及script_scorequery。

  i.使用四舍五入的日期。这样有助于es进行缓存,精确到秒级别的查询有时候并无必要。

实时查询(秒级):

PUT index/_doc/1
{
  "my_date": "2016-05-11T16:30:55.328Z"
}

GET index/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "my_date": {
            "gte": "now-1h",
            "lte": "now"
          }
        }
      }
    }
  }
}

分钟级查询:

GET index/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "my_date": {
            "gte": "now-1h/m",
            "lte": "now/m"
          }
        }
      }
    }
  }
}

  j.对只读索引进行force-merge。在时序索引中,过期的索引都是只读的,将其合并成一个段能加快查询速度。

  k.预热global ordinals。ordinals 是doc values的具体存储形式。一般情况下一个字段的global ordinals是懒加载的。如果某个字段在聚合上用到很多,我们可以先将其预热(加载到heap),当做field data cache.的一部分。

PUT index
{
  "mappings": {
    "properties": {
      "foo": {
        "type": "keyword",
        "eager_global_ordinals": true
      }
    }
  }
}

  l.预热文件系统缓存。设置index.store.preload参数即可。注意,必须确保文件系统缓存足够大,否则会让查询变得更慢。

  m.使用索引排序来加速连接查询。比如我们要进行过滤 a AND b AND …​,然后a是low-cardinality(低区分度)。那么我们可以先对a进行排序,那么一旦a的某个值不匹配这个表达式,那么有相同的值的文档都可以跳过。

  n.使用preference进行缓存使用优化。es中有非常多的缓存,比如文件系统缓存(最重要),请求缓存,查询缓存,但是这些缓存都是在节点层面。默认情况下es会使用round-robin算法分配查询到不同的分片上去,这样缓存就失效了。

    如果可以,使用preference参数将用户的请求和对应的分片或者节点绑定起来,这样缓存就不会失效。例如:

GET /_search?preference=_shards:2,3
{
    "query": {
        "match": {
            "title": "elasticsearch"
        }
    }
}

  o.更多的复制分片会提升吞吐量(但并不一定)。在系统资源充足的情况下,复制分片越多吞吐量会越高。但是过多的分片会让故障恢复变得更慢。

  p.使用profile api优化查询语句。和mysql中的explain类似,例如:

GET /my-index-000001/_search
{
  "profile": true,
  "query" : {
    "match" : { "message" : "GET /search" }
  }
}

{
  "took": 25,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 5,
      "relation": "eq"
    },
    "max_score": 0.17402273,
    "hits": [...] 
  },
  "profile": {
    "shards": [
      {
        "id": "[2aE02wS1R8q_QFnYu6vDVQ][my-index-000001][0]",
        "searches": [
          {
            "query": [
              {
                "type": "BooleanQuery",
                "description": "message:get message:search",
                "time_in_nanos" : 11972972,
                "breakdown" : {
                  "set_min_competitive_score_count": 0,
                  "match_count": 5,
                  "shallow_advance_count": 0,
                  "set_min_competitive_score": 0,
                  "next_doc": 39022,
                  "match": 4456,
                  "next_doc_count": 5,
                  "score_count": 5,
                  "compute_max_score_count": 0,
                  "compute_max_score": 0,
                  "advance": 84525,
                  "advance_count": 1,
                  "score": 37779,
                  "build_scorer_count": 2,
                  "create_weight": 4694895,
                  "shallow_advance": 0,
                  "create_weight_count": 1,
                  "build_scorer": 7112295
                },...

  q.使用 index_phrases 加速phrase query。index_phrases,会将两个单词的组合单独索引,这样可以加速phrase query。

  r.使用 index_phrases 加速prefix query。同上。

  s.使用constant_keyword加速过滤。如果某个字段的大多数情况下的值是个常量,但是我们又经常要对其进行过滤,我们可以将其拆分成两个索引,一个使用constant_keyword,一个不使用。

mapping如下:

UT bicycles
{
  "mappings": {
    "properties": {
      "cycle_type": {
        "type": "constant_keyword",
        "value": "bicycle"
      },
      "name": {
        "type": "text"
      }
    }
  }
}

PUT other_cycles
{
  "mappings": {
    "properties": {
      "cycle_type": {
        "type": "keyword"
      },
      "name": {
        "type": "text"
      }
    }
  }
}

查询语句:

GET bicycles,other_cycles/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "description": "dutch"
        }
      },
      "filter": {
        "term": {
          "cycle_type": "bicycle"
        }
      }
    }
  }
}

在查询bicycles索引时,es会将查询语句自动转换为:

GET bicycles,other_cycles/_search
{
  "query": {
    "match": {
      "description": "dutch"
    }
  }
}

4.磁盘优化

  a.禁用不需要的特性。

    比如数字类型的字段如果不需要进行过滤,可以不对其进行索引。

PUT index
{
  "mappings": {
    "properties": {
      "foo": {
        "type": "integer",
        "index": false
      }
    }
  }
}

    es会对text类型的字段存储一些打分信息,如果不需要对这些字段进行打分,可以将其设置为match_only_text类型

  b.不要使用默认动态字符串映射。默认动态字符串映射会将字符串类型映射为text和keyword类型,这样很浪费空间。可以预先配置所有字符串映射类型为keyword。

PUT index
{
  "mappings": {
    "dynamic_templates": [
      {
        "strings": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

  c.监控分片大小。越大的分片能更有效地存储数据。但是分片越大,故障恢复也会越慢。

  d.禁用_source字段。_source会存储原始的json数据,如果不需要,就将其禁用。

  e.使用best_compression进行压缩。es默认使用 LZ4 进行压缩,使用best_compression可以提升压缩比率,但是会影响数据存取性能。

  f.force-merge.强制合并段能提升存储效率。注意,force-merge应当在没有文件写入后进行,  比如在过期的时序索引节点上。

  g.shrink 索引。即收缩索引,将当前索引重新索引成分片数更少的索引。分片越大,存储效率越高。

    shrink索引有如下条件。

    1.索引必须只读。

    2.节点必须包含索引的所有分片(主分片,或者复制分片都可以)

    3.索引状态必须是健康的。

  h.使用能满足需求的最小的数字类型。比如能用byte, 不用short。这个在其他db比如mysql中也适用。

  i.使用索引排序来提升文档的压缩性能。排序后相似的文档会放在一起,es能根据他们的特性有效地进行压缩。

    设定索引排序:

PUT my-index-000001
{
  "settings": {
    "index": {
      "sort.field": "date", 
      "sort.order": "desc"  
    }
  },
  "mappings": {
    "properties": {
      "date": {
        "type": "date"
      }
    }
  }
}

  j.索引文档时保证json字段顺序一致。es在存储的时候将多个文档压缩成一成block,如果json文档顺序一致,es能更好的对更长的相同的字符串进行压缩。

  k.roll-up历史数据。使用roll up api来归档历史数据,他们依然可以访问,但是有着更高的存储效率。

5.分片大小

  1.将索引分片大小保持在10G~50G之间

  2.平均下来每G堆内存下不要超过20个分片。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/816255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HCIP中期考试实验

考试需求 1、该拓扑为公司网络,其中包括公司总部、公司分部以及公司骨干网,不包含运营商公网部分。 2、设备名称均使用拓扑上名称改名,并且区分大小写。 3、整张拓扑均使用私网地址进行配置。 4、整张网络中,运行OSPF协议或者BGP…

Java -接口

接口 基本介绍 接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。 class 类名 implements 接口{自己属性;自己方法;必须实现的接口的抽象方法; // 只需要重写抽象方法即可 }接口中的方法…

【腾讯云 Cloud Studio 实战训练营】永不宕机的IDE,Coding Everywhere

【腾讯云 Cloud Studio 实战训练营】永不宕机的IDE,随时随地写代码! 写在最前视频讲解:Cloud Studio活动简介何为腾讯云 Cloud Studio?Cloud Studio简介免费试用,上手无忧Cloud Studio 特点及优势云端开发多种预制环境可选metawo…

C# 定时器改进版

一、概述 前不久写了一篇名为 “C# 定时器封装版” 的帖子,它是用的定时器 事件订阅 的方式完成的,虽然可以实现需求,但是它有个缺点,就是定时器的执行的间隔时间只能用固定的时间,假设你想每个事件有自己的单独间隔…

HEVC 速率控制(码控)介绍

视频编码速率控制 速率控制: 通过选择一系列编码参数,使得视频编码后的比特率满足所有需要的速率限制,并且使得编码失真尽量小。速率控制属于率失真优化的范畴,速率控制算法的重点是确定与速率相关的量化参数(Quantiz…

医学影像PACS系统源码:多功能服务器和阅片系统

PACS系统是以最新的IT技术为基础,遵循医疗卫生行业IHE/DICOM3.0和HL7标准,开发的多功能服务器和阅片系统。通过简单高性能的阅片功能,支持繁忙时的影像诊断业务,拥有保存影像的院内Web传输及离线影像等功能,同时具有备…

Python中的列表怎么排序

目录 Python中的列表是什么 python怎么给列表排序 给列表排序需要注意什么 总结 Python中的列表是什么 在Python中,列表(List)是一种有序且可变的数据类型。它允许存储多个元素,并且可以根据需要进行修改。 列表使用方括号&…

自定义类型讲解

💕痛苦难道是白忍受的吗?💕 作者:Mylvzi 文章主要内容:自定义类型讲解 一.结构体 定义: 数组:多组相同类型元素的集合 结构体:多组不同类型元素的集合-->管理多组不同类型数据…

大家做性能测试都用什么工具

在进行测试时,选择适合的测试工具至关重要,因为优秀的测试工具能够显著提高工作效率。对于性能测试和自动化测试而言,大多数人会选择传统的JMeter等工具,然而这些工具存在学习成本高、使用门槛高的问题。 因此,我在这…

微信小程序开发学习之--地图绘制行政区域图

不知道大家有没有感觉就是在做微信小程序地图功能时刚刚接触时候真的感觉好迷茫呀,文档看不懂,资料找不到,就很难受呀,比如我现在的功能就想想绘制出一个区域的轮廓图,主要是为了显眼,效果图如下&#xff1…

官方Office 技巧免费学习平台-WPS学堂

WPS学堂是WPS官方Office 技巧免费学习平台,目前网站累计上线 3000个免费教学视频图文,包含WPS表格(Excel)、WPS文字(Word)、WPS演示(PPT)的操作技巧及新手入门系列课视频,而且教学视频都可以直接在线学习,不…

14.2 【Linux】软件磁盘阵列(Software RAID)

14.2.1 什么是 RAID 磁盘阵列全名是“ Redundant Arrays of Inexpensive Disks, RAID ”,英翻中的意思是:容错式廉价磁盘阵列。 RAID 可以通过一个技术(软件或硬件),将多个较小的磁盘整合成为一个较大的磁盘设备&…

图数据库Neo4j学习四——Spring Data NEO

1配置 1.1Maven依赖 <!--neo4j --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency>1.2yml配置 spring:data:neo4j:uri: bolt://localhost:76…

【机器学习】Cost Function for Logistic Regression

Cost Function for Logistic Regression 1. 平方差能否用于逻辑回归&#xff1f;2. 逻辑损失函数loss3. 损失函数cost附录 导入所需的库 import numpy as np %matplotlib widget import matplotlib.pyplot as plt from plt_logistic_loss import plt_logistic_cost, plt_two_…

利用易查分制作分班查询系统,怎么导入数据?

暑假过半&#xff0c;新学期即将到来&#xff0c;这对学校来说是一个重要的时刻。新学期的开始意味着学校将面临新生入学和老生升入高年级的情况&#xff0c;这就需要进行分班工作的安排。分班工作是一项繁琐而关键的任务&#xff0c;它直接关系到学生们在新学期中的班级和同学…

【Linux进程篇】进程概念(1)

【Linux进程篇】进程概念&#xff08;1&#xff09; 目录 【Linux进程篇】进程概念&#xff08;1&#xff09;进程基本概念描述进程-PCBtask_struct-PCB的一种task_ struct内容分类 组织进程查看进程通过系统调用获取进程标示符通过系统调用创建进程——fork初识 作者&#xff…

SpringMVC源码分析 —— 拦截器是何时调用的

SpringMVC源码分析&#xff0c;拦截器是何时、以什么方式调用的&#xff1f;本文将进行详细说明 环境准备 springboot 2.3.7.RELEASE 笔者创建一个springboot的web项目&#xff0c;使用的springboot的版本是2.3.7.RELEASE 对应的spring-web版本是5.2.12.RELEASE 下面将对上面…

【NLP-新工具】语音转文本与OpenAI的用途

一、说明 OpenAI最近2022发布了一个名为Whisper的新语音识别模型。与DALLE-2和GPT-3不同&#xff0c;Whisper是一个免费的开源模型。它的主要功能就是将语音翻译成文本。本文将介绍如何使用这个重要应用库。 二、 Whisper概念 2.1 Whisper是啥&#xff1f; Whisper 是一种自动…

考完软考,有什么备考心得和学习经验可以分享吗?

恭&#xfffd;&#xfffd;您完成软考考试&#xff01;备考软考确实是一项艰苦的任务&#xff0c;但也是一次很有收获的学习和成长过程。下面分享一些备考心得和学习经验&#xff0c;以及针对系统集成项目管理工程师和信息系统项目管理师考试的备考建议&#xff1a; 备考心得…

PACS系统源码:支持三维重建功能、集成放射科管理RIS系统、图文报告编辑、打印、多级审核机制

PACS系统源码 PACS系统是以最新的IT技术为基础&#xff0c;遵循医疗卫生行业IHE/DICOM3.0和HL7标准&#xff0c;开发的多功能服务器和阅片系统。通过简单高性能的阅片功能&#xff0c;支持繁忙时的影像诊断业务&#xff0c;拥有保存影像的院内Web传输及离线影像等功能&#xf…