es是开源的高扩展的分布式、RESTful风格、全文搜索和分析引擎。ELK技术栈的核心部分。
可以实现近乎实时的存储,检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别数据。
针对的数据类型是:

  • 大量非结构化文本数据
  • 文本记录量达到数十万百万甚至更多
  • 支持大量基于交互式文本的查询
  • 需求非常灵活的全文搜索查询
  • 高度相关的搜索结果
  • 对不同记录类型、非文本数据操作或安全事务处理的需求相对较少的情况

    ES

  1. 安装:略
  2. 端口:
    1. 9300内部组件通信端口
    2. 9200】浏览器访问http协议的restful端口
  3. 7.8版本需要jdk8以上

存储结构

es是面向文档型的数据库,一条数据就是一个文档。
es中的存储结构包括

  1. index:索引,相当于一个库
  2. type,在es7以后被删除了
  3. document:一条数据
  4. fields:字段,数据的属性

image.png

restful& json

restful

es的所有操作都是通过restful请求实现。
restful是资源定位、资源操作的一种规范,一种风格。REST式的web服务是一种ROA(面向资源的架构)。
规则要求使用http方法表明对资源的操作;使用URI确定资源。URI中不应包含与资源无关的其他描述(如,动词),仅仅能够指向对应资源。

  • 路径是资源的定位
  • 方法是资源的操作(请求方法)
    • 【GET,POST,PUT,DELETE,HEAD,PATCH,OPTIONS】

URI:统一资源标识符,通过URI能够确定某资源
URL:统一资源定位符,通过URL能够找到某资源,URL是URI的子集。

幂等性

同样的多次请求并不会产生不同的结果,每次请求都是相同的结果(对数据的影响是相同的)。如,get请求,并不是保证返回结果是相同的,而是对资源本身没有影响。

HTTP方法名称 描述 是否幂等 是否安全
OPTIONS 常用于获取服务器信息,不会对资源产生影响,也不会对资源进行修改
- OPTIONS方法最常见的场景是在浏览器的跨域请求中,如果浏览器发起的是一个跨域访问的API(不论是GET方法还是POST方法),在真正发送业务之前发送一个OPTIONS方法从服务端获取信息,从返回的信息中得获取到是否支持跨域访问,从而决定下一步是否能成功发送真正的业务请求。
Y Y
HEAD 用于请求资源的头部信息,不会对资源产生影响,也不会对资源进行修改。 Y Y
GET 用于获取资源信息,虽然可能每次返回的结果都不相同,但是GET方法本身不会对资源产生影响,在RESTFul语义里GET方法也不会修改资源 Y Y
PUT 在RESTFul语义里表示对资源进行全量更新,因此调用1次或N次的结果都是一致的。 Y N
DELETE 用于删除资源,调用1次或N次的结果都是相同的,因此是幂等的,但不是安全的。 Y N
POST 在RESTFul语义里表示新建资源,调用1次与调用N次的结果不同。 N N
PATCH 在RESTFul语义里表示对资源的局部更新,因此不能保证调用1次与调用N次的结果相同。 N N

Json

ES中数据的发送与响应是Json格式

Json:javascript object notation 表示特殊标记的JavaScript对象。极其适合序列化,在网络中传递。 对象中可以嵌套对象,整个对象作为属性。数组使用[]包裹 var obj = { “name”: “zhangsan”, “age”: 20, “info”: { “addr”: “xx” } } var objs = [obj,obj]

HTTP操作

post请求幂等非幂等均可以。请求后会返回一个id,不指定的情况下返回一个随机的字符串。可以自定义,自定义返回id的情况下,请求就是幂等性的,那么同样可以使用put请求。
DELETE方法也是幂等性的。

url请求参数

路径参数 作用
_cat 打印信息
_doc 文档数据操作
_create 文档数据的创建
_serach 全查询
_update 更新数据
_mapping 映射,类似mysql表结构
_cluster 集群操作,heath健康状态
_analyze 文档分析
_setting 设置
_all 应用于所有数据

请求参数说明

请求参数 说明
from 起始位置
size 查询数量
_source 显示字段
sort 排序
must 同时成立,类似and
must_not 必须不是xxxx
should 不用同时成立,类似or,满足条件最好,得分会更高,不满足没有关系
term 和match一样可以匹配属性值,全文检索用match,非text字段使用term
match 分词匹配
match_phrase 完全匹配
multi_match 多字段分词匹配
filter 过滤条件
range 查询范围
highlight 高亮显示
aggs 聚合操作
avg 求平均值
terms 分组
type 索引结构定义中字段类型,keyword关键字类型不支持分词
index 索引结构定义中是否支持索引,false不支持根据该字段查询。

响应结果字段描述

键名称 描述
hits 查询匹配的根节点
total 表示匹配到的文档总数
hits[] hits数组包含了匹配到的前10条数据
_index 索引,相当于数据库
_type 文档类型,相当于数据库表
_id 每个文档的标识符
_version 版本号
_seq_no 并发控制字段,每次更新+1,乐观锁控制
_primary_term 同上,主分片重新分配时会改变
_source 文档存储的实际数据
_score 相关性得分(relevance score),它衡量了文档与查询的匹配程度。默认的,返回的结果中关联性最大的文档排在首位
took 整个搜索请求花费的毫秒数
_shards _shards节点告诉我们参与查询的分片数(total字段),有多少是成功的(successful字段),有多少的是失败的(failed字段)
timed_out 查询超时与否

_version和_seq_no: post更新会对比原来的数据,如果一样,_version不发生变化,seq_no也不变。 put和不带_update的post请求会直接更新_seq_no和_version。

http://localhost:9200/

  1. // 创建索引
  2. put http://localhost:9200/indexname
  3. // 获取索引信息
  4. get http://localhost:9200/indexname
  5. // 查看所有索引信息
  6. get http://localhost:9200/_cat/indeices?v
  7. // 删除索引
  8. deletehttp://localhost:9200/indexname
  9. // 创建文档(支持自定义id)
  10. posthttp://localhost:9200/_doc(/id)
  11. // 根据id查询文档
  12. gethttp://localhost:9200/_doc/id
  13. // 全查询,也可以使用json【{"query":{"match_all":{}}}
  14. gethttp://localhost:9200/_serach
  15. // 根据id修改数据(id已经存在)【全量修改】,会更新版本
  16. puthttp://localhost:9200/_doc/id
  17. // 修改数据,局部修改
  18. posthttp://localhost:9200/_update/id
  19. // 删除数据
  20. DELETEhttp://localhost:9200/_doc/id
  21. // 根据条件查询(category=小米),也可以使用json【{"query":{"match":{"category":"小米"}}}】
  22. gethttp://localhost:9200/_serach?q=category:小米
  23. // 分页查询,使用json【{"query":{"match_all":{},"from":0,"size":2,"_source":["category"]}}
  24. gethttp://localhost:9200/_serach
  25. // 查询请求json
  26. {
  27. "query": {
  28. "match_all": {}, // 查询所有数据
  29. "from": 0, //起始位置
  30. "size": 2, //查询数量
  31. "_source": ["category"], //显示字段
  32. "sort":{
  33. "price": {
  34. "order":"desc" //倒序排序
  35. }
  36. }
  37. },
  38. highlight:{ //高亮显示
  39. "fields":{ //高亮字段列表
  40. "category":{} //高亮显示
  41. }
  42. }
  43. }
  44. // 多条件查询
  45. {
  46. "query": { //查询操作
  47. "bool": { //查询条件集合
  48. "must": [ // 同时成立,等同于andshould等同于or
  49. {
  50. "match": { // 分词匹配条件
  51. "category": "小米" //条件1
  52. }
  53. },
  54. {
  55. "match": {
  56. "category": "华为" //条件2
  57. }
  58. }
  59. ],
  60. "filter": { //过滤条件
  61. "range": { //范围
  62. "price": { //条件
  63. "gt": 5000 //大于5000
  64. }
  65. }
  66. }
  67. }
  68. }
  69. }
  70. // 聚合查询
  71. {
  72. "aggs": { //聚合查询
  73. "price_group": { //查询名称,随意
  74. "terms": { // 分组 avg】平均值
  75. "filed": "price" // 分组字段
  76. }
  77. }
  78. },
  79. "size": 0 // 只显示聚合结果,不显示其他
  80. }
  81. // 索引结构json
  82. {
  83. "properties": {
  84. "name": {
  85. "type": "text",
  86. "index": true
  87. },
  88. "sex": {
  89. "type": "keyword",
  90. "index": true
  91. }
  92. }
  93. }
  94. //
  95. //

API操作

  1. 导入依赖
  2. 创建mvn工程

todo 完善

集群环境搭建

win环境解压后目录

  • 【data】存放数据
  • 【log】存放日志
  • 【bin】存放启动命令
  • 【jdk】自带jdk环境
  • 【config】配置文件
  • 【modules】模块
  • 【plugins】存放插件

配置文件修改内容

  1. 【cluster.name】集群名称
  2. 【node.name】节点名称,不能重复
  3. 【node.master】是否为master
  4. 【node.data】是否为数据节点
  5. 【network.host】hostip
  6. 【http.port】http端口
  7. 【tcpsport.tcp.port】tcp监听端口
  8. 【http.cors.enabled: true/false】跨域配置
  9. 【http.cors.allow-origin:’*’】跨域配置
  10. 【discovery.seed_hosts:[“host1:port”]】加入的主节点ip和端口(内部端口)
  11. 【discovery.zen.fd.ping_timeout】连接超时时间
  12. 【discovery.zen.fd.ping_retries】重连次数

linux单机环境

es不允许root用户直接运行,所以要创建新用户。

  1. # 新增用户
  2. useradd es
  3. # 设置密码
  4. passwd es
  5. #设置权限,设置文件夹所有者
  6. chown -R es:es /path

配置文件修改内容

  • elasticsearch.yml文件
    1. 【cluster.name】集群名称
    2. 【node.name】节点名称,不能重复
    3. 【network.host】hostip
    4. 【http.port】http端口
    5. 【cluster.initial_master_nodes:[“node-1”]】设置master节点
  • limits.conf
    1. 【es soft nofile 65536】每个进程可以打开文件数量限制
    2. 【es hard nofile 65536】每个进程可以打开文件数量限制
  • 20-nproc.conf
    1. 【es soft nofile 65536】每个进程可以打开文件数量限制
    2. 【es hard nofile 65536】每个进程可以打开文件数量限制
  • sysctl.conf
    1. 【vm.max_map_count=655360】进程可以拥有的虚拟内存区域
    2. sysctl -p

linux集群环境

配置文件修改

  • elasticsearch.yml文件
    1. 【cluster.name】集群名称
    2. 【node.name】节点名称,不能重复
    3. 【node.master】是否为master
    4. 【node.data】是否为数据节点
    5. 【network.host】hostip
    6. 【http.port】http端口
    7. 【http.cors.enabled: true/false】跨域配置
    8. 【http.cors.allow-origin:’*’】跨域配置
    9. 【http.max_content_length】http请求体最大长度
    10. 【cluster.initial_master_nodes:[“node-1”]】设置master节点
    11. 【discovery.seed_hosts:[“host1:port”]】加入的主节点ip和端口(内部端口)
    12. 【gatway.recover_after_nodes:2】
    13. 数据备份时一致性参数

【consistency】一致性默认为大多数保存完即可;其他数值:1,只需要主分片执行完成;all,所有分片全部没问题。
【timeout】如选择all时,存在节点宕机,分片不会完成all的复制,设置timeout超时,超过规定时间可以终止。

  1. todo: P32

    核心概念

    索引:es中万物皆索引,一切都是为了提高搜索性能。
    文档:一个可以被索引的基础信息单元,也就是一条数据。
    字段:一条信息分有多个属性,属性也是字段。
    映射:类似于表结构,如字段的类型,分片数量,备份数量等。
    分片:一个索引可以分为多个分片,每个分片存储一定量的数据。创建索引时可以指定分片的数量。每一个分片也是一个功能完善独立的索引。可以提高容量和吞吐量。
    副本:数据备份,副本分布在不同机器上达到高可用的目的
    词条:索引中最小的存储和查询单元。
    词典:字典,词条的集合。B+树,hashmap
    倒排表:多个倒排项的合集。词条和文档Id列表的对应表
  1. // 索引创建分配和副本配置
  2. {
  3. "setting" : {
  4. "number_of_shards":3,
  5. "number_of_replicas":1
  6. }
  7. }

写数据流程

  1. 客户端请求任意节点,称之为协调节点
  2. 协调节点经过hash计算,得出存放的分片,然后转发写入请求到主分片
  3. 目标分片接收到写入请求,写入到本地
  4. 备份数据发送给备份分片
  5. 等待所有(根据配置不同)备份节点都保存完后返回协调节点
  6. 协调节点返回给客户端。

image.png
image.png
其中第3步写入本地磁盘的过程:

  1. 首先将数据写入内存中,此时新数据不可用,数据落盘后才能提供查询
  2. 将修改信息写入translog
  3. 写入内存后每隔1秒refresh到缓冲区中(为解决只能落盘后才能查询效率低的问题,中间加入系统文件缓冲区)
  4. 清空内存中的segment,返回结果给客户端【数据写入到系统缓冲区之后可以提供查询,refresh的间隔是1s】
  5. translog每隔5s写入磁盘一次
  6. 每隔30min或者超出translog文件大小将触发commit操作。

    commit操作会将内存中的数据refresh到系统缓存文件。然后创建一个commit point标记这段时间内产生的segement,生成新的translog文件。然后对标记了的segment进行合并,对标记删除的数据进行删除操作。

段合并:
为了避免过多segment,影响性能,会对段(segment)进行段合并,段合并的过程会造成大量的IO和性能消耗,会降低搜索性能。可以手动进行段合并(optimize)。

optimize命令建议不在运行环境中执行,导致无法搜索。

数据备份时一致性参数
【consistency】一致性默认为大多数保存完即可;其他数值:1,只需要主分片执行完成;all,所有分片全部没问题。
【timeout】如选择all时,存在节点宕机,分片不会完成all的复制,设置timeout超时,超过规定时间可以终止。

读取数据流程

  • docId搜索

    1. 请求发送给协调节点
    2. 协调节点通过hash算法根据docId找到对应的分片列表,此时使用随机轮询算法,在主分片和其余副本中随机选择转发查询请求,使得读取能够负载均衡。
    3. 目标节点收到请求,索引找到对应文档(数据),返回给协调节点。
    4. 协调节点返回给客户端。
  • 全文搜索

    1. 请求发送给协调节点
    2. 协调节点先将搜索请求分发给所有的分片(主副都可)
    3. 协调节点根据每个分片返回的数据【docId】进行合并,排序,分页等操作后,确定最后返回结果的docId,然后根据docId去对应的分片去拉取对应的文档【变为docId搜索】
    4. 目标节点收到请求,索引找到对应文档(数据),返回给协调节点。
    5. 协调节点返回给客户端。

修改数据流程

  1. 请求发送给协调节点
  2. 协调节点通过hash算法找到对应的主分片所在节点,转发修改请求
  3. 目标节点收到请求,索引找到对应文档(数据),尝试修改数据,如果存在另外线程修改中,那么会进行自旋,直到修完成或者超过重复次数【retry_on_conflict】。
  4. 主分片修改完成后,将新版本数据转发到副本分片重新建立索引。
  5. 所有副本都返回成功,向协调节点返回,向客户端返回。

    发送给副本分片的是新版本的文档数据,而不是更新请求。因为发送请求可能会以错误的顺序应用更改造成数据不一致。

多文档操作流程在单节点操作上加入了前期分解和最后返回的整合

倒排索引

正向(排)索引 关系型数据库中,存储一条数据时,通过主键索引能够找到整条数据。是正向索引。 倒排索引 与正向索引相对,非关系型数据中存储一条数据时,将文本进行切割存储,文本内容当作索引,通过文本内容索引出对应的文档的docId。

倒排索引在写入到磁盘之后不能被修改。
不能被修改优点:

  1. 无需加锁,所有线程都只是查询,不能做修改操作
  2. 一旦读入到缓存中会长时间保存,因为其不会被修改,无需更新到磁盘中,直接请求缓存
  3. 生命周期始终有效,不需要在每次数据改变时被重建。
  4. 大的倒排索引允许被压缩

无法被修改的缺点:当需要更新的时候,只能删除之后再重建。

动态更新索引:解决删除之后再重建的问题
引入更多的索引,每次更新内容建立新的索引,查询时将所有的结果做合并后返回。每次更新的索引称为段,查询时将所有的段结果聚合后返回,遇到需要删除的情况,会存在一个.del文件列出被删除的段的信息。被标记删除的段(为被物理删除前)仍会被查询到,在聚合后进行过滤。最终在合适的时间进行真正删除。

近实时搜索

主要原因:内存与系统缓存间fresh时间是1s

搜索时会查询系统缓存,但是部分数据仍然存在内存中,没有经过fresh,fresh的时间间隔是1s,所以1s内产生的数据,有可能查询不到,并非实时的搜索有这1s的误差,所以是近实时搜索。

文档分析

  1. 将文档切分成适合于倒排索引的词条
  2. 将词条进行标准格式化,利于搜索。

分析器

分析器的作用就是在创建索引的时候对文档进行拆解创建倒排索引;在查询的时候使用同样的分析器分析要搜索的内容,拆分成对应的词条。

  1. 字符过滤器:整理字符串。去除html,将符号转化成文字等。
  2. 分词器:整理好的字符串按照分词规则分为单个的词条
  3. token过滤器根据过滤规则改变词条,如大小写,去除无用词增加词条等。

内置分析器:

  • 简单分析器:在任何不是字母的地方分割文本,将词条小写。
  • 空格分析器:在空格的地方划分文本
  • 语言分析器:特定语言的分析器,如英语无用词组的删除。

分词器

keyword:关键字不可以被分词
text:文本可以分词

【ik_max_word】:最细粒度拆分
【ik_smart】:最粗粒度的拆分

  • IK分词器:默认分词器,会对中文每个字进行分词。
  • IK中文分词器:按照中文的词组进行分词。使用方法【解压放到plugins目录下,重启es】,支持自定义词组
    • 在ik文件夹下config目录下创建custom.dic文件,加入自定义词组
    • 修改IKAnalyzer.cfg.xml将新建文件配置其中
    • 重启es

文档冲突

如何保障文档一致性?

为解决文档访问冲突的问题,采用乐观锁的方式,使用版本号进行控制,保证读取和修改的数据都是最新数据,
对于旧版本的数据无法更新。

todo:_seq_no,_primary_term
使用version_type=external进行外部版本控制

管理工具

kibana,es-head

优化策略

硬件选择

所有文档数据存储在磁盘中。

  • 使用SSD固态硬盘
  • 使用RAID0,可以连续的存储空间分配到多个磁盘中,高效的利用每块磁盘,不需要备份,es已经提供了备份功能
  • 使用多块硬盘,配合RAID0
  • 不使用远程挂载的存储

分片策略

分片和副本是为了能够分布式扩容和故障转移,提高可用性。
分片数量不能动态修改,副本数量可以修改。
每个分片的底层都是lucene的索引,会消耗一定的文件句柄,内存以及CPU,如果多个分片处于同一个机器上就会竞争资源。用于计算相关度的词项统计是基于分片的,分片过多会造成每个分片分配的数据很少导致较低的相关度。

  • 分片数不超过节点数的3倍。
  • 节点数<=主分片数*(副本数+1)

分片瞬时宕机,集群会等待一分钟观察是否会重新加入,在此期间重新加入了,则不变,如果没有重新加入,会触发新的分片分配。自平衡分片分配会带来资源开销,修改【delayed_timeout】可以控制等待时间,防止短暂断开连接造成的分片重新分配。

路由查询

数据存放分片计算公式:

  1. shard=hash(routing)%number_of_primary_shards
  2. routing默认是文档id,也可以自定义。

不带路由查询:

  1. 分发:请求达到协调节点后,将查询请求分发到每个分片上
  2. 聚合:协调节点搜集每个分片上的查询结果,进行汇总返回

带路由查询:
直接根据路由信息转发到某个分片查询,不需要要查询所有分片。

写入速度优化

  • 加大translog flush间隔,降低磁盘每秒的输入输出,和写锁的操作
  • 增大index refresh间隔,减少segment merge的次数
  • 调整bulk线程池和队列
  • 优化节点间的任务分布
  • 优化lucene层索引建立,降低cpu和IO

内存设置

ES默认的内存大小是1GB。
通过解压后的jvm.option文件来修改

  • 确保Xms和Xmx大小相同
  • 不要超过物理内存的50%,内存过大影响系统缓存的大小,造成频繁的flush到磁盘
  • 不要超过32G,跟操作系统的指针有关系,通常设置为31G

    重要配置项

  1. 【cluster.name】集群名称
  2. 【node.name】节点名称,不能重复
  3. 【node.master】是否为master
  4. 【node.data】是否为数据节点
  5. 【index.number_of_shards】分片数目,默认1
  6. 【index.number_of_replicas】副本数目,默认1
  7. 【transport.tcp.compress】节点间数据传输是否压缩,默认不压缩
  8. 【discovery.zen.minimum_master_nodes】选举master节点时需要的最少选举节点数。默认为1,网络不稳定时会出现脑裂(两个主节点),合理的数值为【候选节点数/2+1】
  9. 【dicovery.zen.ping.timeout】发现其他节点ping超时的时间。

常见面试题

为什么使用es?

主要解决关系型数据库全文索引的问题。关系型数据库使用like模糊查询,模糊查询会使得查询引擎放弃索引,使用全表扫描,在大数据量的情况下,效率低下。使用es全文索引能够解决模糊查询效率低的问题,提高查询速度。

master的选举流程?

  • ZenDiscovery模块负责选举,主要包含ping和unicast两部分
  • master节点的职责包括集群,节点,索引的管理,不负责文档级别的管理,data节点可以关闭http功能。
  • 【选举出自己认为的master节点】所有可以成为master的节点按照nodeId排序,每次选举时,每个节点都把自己能够通过ping知道存在的节点进行排序,选出第一个节点,暂定为master,进行投票。可以选举自己。
  • 【汇总选举结果】存在某个节点的投票数超过可以选举节点数量的一半【候选节点数/2+1;至少为2】,那么这个节点就是master。否则重新选举,直到满足选票条件。

    集群启动时,第一个节点(A)启动,选取自己作为master节点,但是数量不够【候选节点数/2+1;至少为2】 第二个启动(B)后,首先寻找是否存在master节点, 发现没有后,通过ping进行寻找备选节点,找到第一个节点(A) 进行排序选择了第一个启动的节点,选举A为master A节点选举自己为master,如果集群只有三个节点的话此时选择master节点是A

脑裂问题?

  • 脑裂【多个master】问题的成因
    • 网络问题:网络延迟造成节点访问不到master,从而进行了选举产生了新的master
    • 节点负载:主节点即为master又为data,访问量较大时造成es停止响应,其他节点收不到master的响应
    • 内存回收:data节点上的es进程占用内存较大,引发大规模GC,造成es进程失去响应。
  • 脑裂解决方案:
    • 减少误判:增加响应超时时间【discovery.zen.ping_timeout】,默认3s
    • 选举触发:设置选举触发节点数量【zdiscovery_zen.minimum_master_nodes】,当备选主节点中有这些个节点认为主节点挂掉了,才进行选举,官方建议一半以上。
    • 角色分离:master与data节点分离。master节点不负责存储数据,只负责管理。【node.data:false】

      索引文档的流程?

      见【写数据流程】

      更新和删除文档流程?

      见【修改数据流程】和【倒排索引】

      搜索流程?

  1. 搜索分为两个阶段,称之为query then fetch
  2. 【query】初始查询节点,协调节点广播到索引中的主分片或副本分片,在每个分片执行搜索并构建一个优先队列,大小为from+size。【近实时搜索】
  3. 【query】每个分片返回各自的优先队列中所有文档的id和排序值给协调节点,协调节点进行合并,产生一个全局排序后的结果列表
  4. 【fetch】协调节点会判断哪些数据需要被取回,并向相关节点提交多个get请求
  5. 【fetch】所有节点全部返回,协调节点汇总后返回给客户端

优化方法?

  • 机器64G内存最适合
  • 多内核优于cpu
  • 使用ssd固态硬盘
  • 避免远程访问,外部挂载,避免跨越多个数据中心
  • 保障jvm和服务器配置相同
  • 通过【gateway.recover_after_nodes、gateway.expected_nodes、gateway.recover_after_time】配置,避免重启时过多的分片交换
  • 使用单播发现,避免节点无意中加入集群
  • 避免修改垃圾回收器和线程池大小
  • 内存分一半给lucene,通过【ES_HEAP_SIZE】配置
  • 增大文件描述符的数量【es hard nofile 65536】

索引性能提升方法:

  1. 调整批量请求的大小
  2. 使用ssd
  3. 增加【index.translog.flush_threshold_size】默认512,设置为1G,可以在一次清空触发的时候在translog中累积更大的段,减少IO频率
  4. 对实时性不敏感可以修改【index.refresh_interval】改成30s,也能够减少磁盘IO频率
  5. 大批量导入时,可以关闭副本。

    es的GC

  • 倒排索引常驻内存,无法GC,需要监控内存增长趋势
  • 合理分配各类缓存的空间,【field cache,filter cache,indexing cache,bulk cache】
  • 避免大量返回结果搜索与聚合,如需要,采用scan&scroll api实现。
  • 超大规模集群可以拆成多个集群通过tribe node连接
  • 对集群的heap持续监控

    es如何实现大数据量的聚合?

    HLL算法,HyperLoglog,一种基数统计算法,用来进行去重操作,类似redis中的hyperloglog,使用位数组和hash算法实现的去重。

    并发情况下,如何保证读写一致?

  • 乐观锁,版本号控制。

  • 对于写操作,一致性级别【大多数、主、所有】设置成所有副本都同步完成后才支持访问,可以保证一致性
  • 对于读操作,设置replication为sync,使操作在主分片和副本分片都完成后才返回;设置为async,通过请求参数_preference(偏好设置)为primary来查询,确保版本最新。

当write consistency不是all的时候,需要指定从primary shard读
当write consistency为all的时候,而且replication是sync模式(默认),无需额外指定,如果replication是async模式,则需要从primary shard读取。

_preference:偏好设置,偏好设置可以设置只查询主分片、副本分片、指定分片、优先主或副等,通常用于存在部分分片不可用时。

如何监控集群状态

es-head插件
kibana

字典树

字典树又叫单词查找树,trie树。哈希树的变种,用于统计、排序和保存大量的字符串(不仅限于字符串)。经常用于词频统计。
优点:利用字符串的公共前缀减少查询时间,最大限度的减少无谓的字符串比较,查询效率比哈希树高。

核心思想:用空间换时间

  • 根节点不包含字符,除根节点外,其他节点均包含一个字符
  • 从根节点到某一结点,路径上的所有字符连起来,为该节点对应的字符串
  • 每个节点的所有子节点包含的字符都不相同

中文字典树,每个节点的子节点用一个哈希表存储,减少空间浪费,速度能够保证哈希的O(1)。

es中集群、节点、索引、文档、类型是什么?

【见核心概念】

倒排索引是什么?

【见倒排索引】

todo
scan&scroll api:提高分页查询效率的方法
tribe node
replication async