elasticsearch-注意点

原理剖析

1)写数据

  • 客户端选择一个 node 发送请求过去,这个 node 就是 coordinating node(协调节点)。
  • coordinating node 对 document 进行路由,将请求转发给对应的 node(有 primary shard)。
  • 实际的 node 上的 primary shard 处理请求,然后将数据同步到 replica node。
  • coordinating node 如果发现 primary node 和所有 replica node 都搞定之后,就返回响应结果给客户端。

2)读数据。

  • 客户端发送请求到任意一个 node,成为 coordinate node。
  • coordinate node 对 doc id 进行哈希路由,将请求转发到对应的 node,此时会使用 round-robin - - 随机轮询算法,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡。
  • 接收请求的 node 返回 document 给 coordinate node。
    coordinate node 返回 document 给客户端。

写数据,实际上都写到磁盘文件里去了,查询的时候,操作系统会将磁盘文件里的数据自动缓存到 filesystem cache 里面去。es 的搜索引擎严重依赖于底层的 filesystem cache,你如果给 filesystem cache 更多的内存,尽量让内存可以容纳所有的 idx segment file 索引数据文件,那么你搜索的时候就基本都是走内存的,性能会非常高。所以,最佳的情况下,就是你的机器的内存,至少可以容纳你的总数据量的一半。建议用 es + hbase 这么一个架构。

3)搜索数据。

  • 客户端发送请求到一个 coordinate node。
  • 协调节点将搜索请求转发到所有的 shard 对应的 primary shard 或 replica shard,都可以。
  • query phase:每个 shard 将自己的搜索结果(其实就是一些 doc id)返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
  • fetch phase:接着由协调节点根据 doc id 去各个节点上拉取实际的 document 数据,最终返回给客户端。

其实 es 第一是准实时的,数据写入 1 秒后可以搜索到;可能会丢失数据的。有 5 秒的数据,停留在 buffer、translog os cache、segment file os cache 中,而不在磁盘上,此时如果宕机,会导致 5 秒的数据丢失。数据写入 segment file 之后,同时就建立好了倒排索引。

4)删除/更新数据
如果是删除操作,commit 的时候会生成一个 .del 文件,里面将某个 doc 标识为 deleted 状态,那么搜索的时候根据 .del 文件就知道这个 doc 是否被删除了。

如果是更新操作,就是将原来的 doc 标识为 deleted 状态,然后新写入一条数据。

buffer 每次 refresh 一次,就会产生一个 segment file,所以默认情况下是 1 秒钟一个 segment file,这样下来 segment file 会越来越多,此时会定期执行 merge。每次 merge 的时候,会将多个 segment file 合并成一个,同时这里会将标识为 deleted 的 doc 给物理删除掉,然后将新的 segment file 写入磁盘,这里会写一个 commit point,标识所有新的 segment file,然后打开 segment file 供搜索使用,同时删除旧的 segment file。

常见错误以及解决方案

采用动态Mapping

1、1.5.x版本之后,需要分词的字段需要设定text类型和对应的analyzer ;仅需要精确匹配的可直接设置为keyword类型。
2、长文本高亮需要在text类型的基础上,设置fast-vector-highlighter高亮方式,高亮效率能提升20倍以上。

聚合设置不当导致OOM

聚合的默认Collection Mode称为深度优先,可在适当时候选择广度优先

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"aggs" : {
"play_aggs" : {
"terms" : {
"field" : "players",
"size" : 10,
"collect_mode" : "breadth_first" //广度优先
},
"aggs" : {
"other_aggs" : {
"terms" : {
"field" : "players",
"size" : 5 //默认深度优先
}
}
}
}
}
}

ES索引设置不当

1、ES启动的默认群集名称称为elasticsearch。 如果群集中有许多节点,最好保持命名标志尽可能一致。

2、节点的恢复设置也很重要。 假设群集中的某些节点由于故障而重新启动,并且某些节点在其他节点之后重启。 为了使所有这些节点之间的数据保持一致,我们必须运行一致性程序,以使所有集群保持一致状态。

1
2
3
4
5
#只要10个数据或主节点已加入群集,即可恢复
gateway.recover_after_nodes:10
#集群中期待启动节点达到20个以及时间超过7分钟后,集群重启或恢复
gateway.expected_nodes:20
gateway.recover_after_time:7m

3、 防脑裂配置。minimum_master_nodes对于群集稳定性非常重要。 它们有助于防止脑裂。
此设置的建议值为(N / 2)+ 1 , 其中N是候选主节点的节点数。

线程池设置不合理

1
threadpool.bulk.queue_size:2000
文章作者: gqsu
文章链接: http://www.ipdax.com/2019/02/18/elasticsearch-注意点/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 技术笔记分享
支付宝打赏
微信打赏