这是悟空的第 104 篇原创文章
html
做者 | 悟空聊架构前端
来源 | 悟空聊架构(ID:PassJava666)java
ES 搜索引擎系列文章汇总:node
1、别只会搜日志了,求你懂点原理吧mysql
本文主要内容以下:sql

搜索引擎如今是用得愈来愈多了,好比咱们日志系统中用到的 ELK 就用到了搜索引擎 Elasticsearch(简称 ES)。数据库
那对于搜索这种技术来讲,最看重的是搜索的结果的准确性
和搜索的响应时间
。ES 的准确性能够经过 倒排索引算法来保证,那响应时间就须要磁盘或缓存来支持了,那么磁盘和缓存会带来哪些坑呢?( 其实不管是分布式的,仍是单机模式下的搜索引擎都会遇到这个问题。)小程序
1、ES 慢查询之坑
Elasticsearch 是现现在用的最普遍的搜索引擎。它是一个分布式的开源搜索和分析引擎,适用于全部类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。
1.1 工做原理:
ES 的工做原理:往 ES 里写数据时,实际是写到磁盘文件,查询时,操做系统会将磁盘文件里的数据自动缓存 filesystem cache
里面。若是给 filesystem cache
更多的内存,尽可能让内存能够容纳全部的 idx segment file
索引数据文件,则搜索的时候走内存,性能较好。

坑:
首先若是访问磁盘那必定很慢,而走缓存会快不少。但若是不少没用的字段数据都丢到缓存里面,则会浪费缓存的空间,因此不少数据仍是存在磁盘里面的,那么大部分查询走的数据库,则会带来性能问题。
1.2 案例
ES 节点 3 台机器,每台机器 32 G 内存,总内存 96 G,给 ES JVM 堆内存是 16 G,那么剩下来给 cache 的是 16 G,总共 ES 集群的的 cache 占用内存 48 G ,若是全部的数据占据磁盘空间 600 G,那么每台机器的数据量是 200 G,而查询时,有 150 G 左右的的数据是走磁盘查询的,那么走 cache 的几率是 48 G/ 600 G = 8%,也就是说大量查询是走磁盘的。
1.3 避坑指南:
1.3.1 存储关键信息

-
将数据中索引字段存到 cache,好比 一行数据有 name、gender、age、city、job 字段,而检索这条数据只须要 name 和 gender 就能够查询出数据,那么 cache 就只须要存 id、name 和 gender 字段。别把全部字段都丢到 cache 里面,纯属浪费空间,资源是有限的。
-
那剩下的字段怎么检索出来?能够把其余字段存到 mysql/hbase 里面。
-
hbase 特色:适用于海量数据的在线存储。缺点是不能进行复杂的搜索。根据 name 和 gender 字段从 ES 中拿到 100 条数据 ( 包含 doc id ) ,而后根据 doc id 再去 hbase 中查询每一个 doc id 对应的完整数据,将结果组装后返回给前端 ( 须要考虑分页的状况 ) 。
1.3.2 数据预热
-
将访问量高的数据或者即将访问量高的数据放到 filesystem cache 里面。 -
每隔一段时间就从数据库访问下数据,而后同步到 filesystem cache 里面。
1.3.3 冷热分离
-
不常访问的数据和常常访问的数据进行隔离。好比 3 台机器存放冷数据的索引,另外 3 台存放热数据的索引。
1.3.4 避免使用关联查询
-
ES 中的关联查询是比较慢的,性能不佳,尽可能避免使用。
2、ES 架构之坑
一般状况下,咱们会使用 ES 的集群模式,在集群规模不大的状况下,性能还算能够,但若是集群规模变得很大,则会遇到集群瓶颈,也就是说集群扩大,性能提高甚微,甚至不增反降。
ES 的集群也是采用中心化的分布式架构,整个集群只有一个是 Master 节点。而它的职责很是重要:负责整个集群的元数据管理,元数据包含全局的配置信息、索引信息、节点信息,若是元数据发生改变,则须要 master 节点将变动信息发布到集群的其余节点。
另外由于 master 节点的任务处理是单线程的,因此每次处理任务时,须要等待所有节点接收到变动信息,并处理完变动的任务后,才算完成了变动任务。

那么这样的架构会带来什么问题:
-
响应时间问题。若是元数据发生了改变,但某节点 假死
,好比 JVM 的内存爆了,可是进程还活着,那么响应 master 节点的时间会很是长,进而影响单个同步信息任务的完成时间。 -
任务恢复问题。有大量恢复任务的时候,任务须要排队,恢复时间变长。 -
任务回调问题。任务执行完成后,须要回调大量 listener 处理元数据变动。若是分片的数据很大,则处理时间会到 10 秒级,严重影响了集群的恢复能力。
解决方案:采用 ES 的 tribe node 特性实现 ES 多集群。文中后面会介绍下 tribe node 的原理。
3、业务场景的坑
ES 的被普遍应用到多个场景,好比查询日志、查询商品资料、数据聚合等。而这些场景的需求又有很是大的差别,这也是一个坑。
-
场景一:前端首页搜索功能。好比搜索商品,数据实时写入的频率不高,可是读的频率很高。

-
场景二:日志检索的功能。日志系统中,咱们通常都是 ELK 这种架构模式,对实时写入要求很高,而查询的次数其实很少,毕竟查询日志多工做仍是开发和运维人员来作。

-
场景三:监控、分析的功能。ES 也会被运用到须要监控数据和分析数据的场景中,而这种场景又是对 ES 的内存要求比较高,由于这些分析功能是在内存中完成的,若内存出现太大的压力,则会形成系统的垃圾回收,可能出现短暂的服务抖动。
解决方案:按业务场景划分 ES 集群,一样采用 ES tribe node 功能。
4、ES Tribe Node 方案
ES tribe node 功能原理图以下所示:

-
有两个 ES 集群,每一个集群都有多个 ES 节点。 -
Logstash 负责日志搜集。 -
Kibana 负责客户端查询,将查询命令传送到 ES Tribe Node。 -
ES Tribe Node 还承担了集群管理的职责。
参考资料:
https://www.infoq.cn/article/SbfS6uOcF_gW6FEpQlLK https://www.elastic.co/guide/en/elasticsearch/reference/2.0/modules-tribe.html advance-java
ES 搜索引擎系列文章汇总:
- END -
本文分享自微信公众号 - 悟空聊架构(PassJava666)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。