ES搜索引擎

ES定义

ES=elaticsearch简写, Elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

ES主要解决问题

1)检索相关数据;
2)返回统计结果;
3)速度要快。

ES的分布式架构原理

ElasticSearch设计的理念就是分布式搜索引擎,实质上实际上还是基于lucene。

es中存储数据的基本单位是索引,某些说你现在要在es中存储一些订单数据,你就应该在es中创建一个索引order_idx,所有的订单数据就都写到这个索引里面去,一个索引差不多就是相当于是mysql里的一张表。

一个index里可能就一个类型,但是确实如果说是一个index里有多个type的情况(注意,mapping types这个概念在ElasticSearch 7.X已被完全删除,详细说明可以参考官方文档),您可以认为index是一个类别的表,具体的每个类型代表mysql中的一个表。每个type有一个映射,如果您认为一个type是具体的一个表,index就代表多个type同属于的一个类型,而映射就是这个类型的表结构定义,你在mysql中创建一个表,肯定是要定义表结构的,里面有什么区别,每个分开是什么类型。实际上你往索引里的一个类型里面写的一条数据,叫做一条文档,一条文档就代表了mysql中某个表里的一行,每个文档有多个字段,每个字段就代表了这个文档中。
ES搜索引擎_第1张图片1)创建一个索引index,这个索引可以被分割成多个shard,每个shard存储部分数据。分割多个shard的好处在于,支持横向扩展,每个shard存储一部分数据,当数据增加的时候可以重新创建一个切割成多个的shard满足这个数据增加的情况。另外提高性能,数据分布在多个shard上,即多台服务器上,所有的操作都会在多台服务器上并行执行,提高防爆和性能。

2)这个shard的数据实际上是有多个备份,每个shard都有一个primary shard,负责写入数据,还有几个replica shard。primary shard写入数据之后,就会将数据同步到其他的replica shard上去。

3)ES中有多个节点,会自动选举一个例程为master节点,这个master例程实际上就是干一些管理的工作,从而维护元数据,也可以成为协调节点。

4)如果非master节点宕机后,那么会由master节点中断,如果宕机的那个节点是primary shard,master节点会自动将其他的replica节点转换为primary节点继续工作。

ES写数据过程

ES搜索引擎_第2张图片

1)客户端选择一个es节点将数据发送过去,这个节点的数据就是coordinating node(协调节点)

2)协调节点通过对数据进行Hash算法,并对文档数据进行路由,将请求转发给对应的节点(具有primary shard)。

3)实际的节点上有一个primary shard处理请求,然后将数据同步到replica节点上,协调节点发现primary node和replica node都搞定之后,就返回响应结果给客户端。

4)实际的节点上有一个primary shard处理请求时,会将数据写入到内存buffer中,在缓存中的数据是搜索不到的;在这里也可以将数据写入到translog中,也可不写入。每个一秒将数据refresh到os cache中,数据refresh中,这个数据就可以被搜索到了。(所以es是准实时的,因为写入的数据1秒之后才可以看到,也可以通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到。只要数据被输入os cache中,buffer就会被清空了,因为不需要保留buffer了,数据在translog里面已经持久化到磁盘去一份了,在此同时也可以将数据写入到translog中。translog日志文件的作用是什么?您执行提交操作之前,数据或是停留在buffer中,或者是停留在os cache中,无论是buffer还是os cache都是内存,一旦这台机器死了,内存中的数据就全丢了。所以需要将数据对应的操作写入一个专门的日志文件translog中,立即此时机器停机机,再次重启的时候,es会自动读取日志文件中的数据,恢复到内存缓冲区和os cache中去。)

5)translog其实也是先写os cache的,**至少每隔5秒刷一次到磁盘中去,所以每次情况下,可能有5秒的数据会仅停留在buffer或translog文件的os cache中,如果此时机器挂了,会丢失 5秒钟的数据。但是这样性能比较好,最多丢5秒的数据。**也可以将translog设置成每次写入操作必须是直接fsync到磁盘,但是性能会差很多。

ES读数据过程

1)可以通过doc id来查询,会根据doc id进行hash,判断出来当时把doc id分配到了其中shard上面去,从那个shard去查询。

2)客户端发送请求到coordinate node(协调节点),协调节点对doc id进行哈希路由,将请求转发到对应的节点,此时会使用round-robin 随机迭代算法,在orimary shard以及所有副本中随机选择一个。

3)接收请求的节点返回文档给coordinate code(协调节点),协调节点返回数据给客户端。

删除/更新数据灵活原理

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

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

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

倒排索引

在搜索引擎中,每个文档都有一个对应的文档ID,文档内容被表示为一系列关键字的集合。例如,文档1经过分词,提取了20个关键字,每个关键字都会记录它在文档中出现的次数和出现位置。

然后,倒排索引就是关键字到文档 ID的映射,每个关键字都对应着一段的文件,这些文件中都出现了关键字。

倒排索引的两个重要细节:

  • 倒排索引中的所有词项对应一个或多个文档;
  • 倒排索引中的词项根据字典顺序升序排列

ES在数据量很大的情况下(数十亿等级)如何提高查询效率ES搜索引擎_第3张图片

es的搜索引擎严重依赖于不断的filesystem cache,你如果给filesystem cache更多的内存,尽量让内存可以容纳所有的idx segment file索引数据文件,那么你搜索的时候就基本都是走内存的,性能会非常高。

归根结底,你要让es性能要好,最佳的情况下,就是你的机器的内存,至少可以容纳你的总数据量的一半。

es + hbase
hbase的特点是适用于海量数据的在线存储,就是对hbase可以写入海量数据,但是不要做复杂的搜索,做很简单的一些根据id或范围进行查询的这么一个操作就可以了。根据名称和age去搜索,拿到的结果可能就20个doc id,然后根据doc id到hbase里去查询每个对应doc id的完整的数据,给对应来,再返回给前端。

数据预热

举个例子,拿微博来说,你可以把一些大V,平时看的人很多的数据,你自己预先后台搞个系统,每隔一会儿,自己的后台系统去搜索一下热数据,刷到filesystem cache里去,后面用户实际上来看这个热数据的时候,他们就是直接从内存里搜索了,很快。

或者是电商,你可以将平时查看最多的一些商品,例如说iphone 8,热数据提前后台搞个程序,每隔1分钟自己主动访问一次,刷到filesystem cache里去。

对于那些你觉得比较热的,经常会有人访问的数据,最好做一个专门的缓存预热磁盘,就是**对热数据每隔交替,就提前访问一下,让数据进入filesystem cache里面去。**这样一次别人访问的时候,性能一定会好很多。

你可能感兴趣的:(es)