ElasticSearch相关概念

最近整理一些es面试的相关内容。大部分来自于网上信息整理。

基础概念

ElasticSearch相关概念_第1张图片

节点(Node)
    物理概念,一个运行的Elasticearch实例,一般是一台机器上的一个进程。

索引(Index):
    逻辑概念,包括配置信息mapping和倒排正排数据文件,一个索引的数据文件可能会分布于一台机器,也有可能分布于多台机器。索引的另外一层意思是倒排索引文件。

分片(Shard)
    为了支持更大量的数据,索引一般会按某个维度分成多个部分,每个部分就是一个分片,分片被节点(Node)管理。一个节点(Node)一般会管理多个分片,这些分片可能是属于同一份索引,也有可能属于不同索引,但是为了可靠性和可用性,同一个索引的分片尽量会分布在不同节点(Node)上。分片有两种,主分片和副本分片。

副本(Replica)
    同一个分片(Shard)的备份数据,一个分片可能会有0个或多个副本,这些副本中的数据保证强一致或最终一致。


架构容错

ElasticSearch相关概念_第2张图片

    建索引(Index)的时候,一个Doc先是经过路由规则定位到主Shard,发送这个doc到主Shard上建索引,成功后再发送这个Doc到这个Shard的副本上建索引,等副本上建索引成功后才返回成功。
    在这种架构中,索引数据全部位于Shard中,主Shard和副本Shard各存储一份。当某个副本Shard或者主Shard丢失(比如机器宕机,网络中断等)时,需要将丢失的Shard在其他Node中恢复回来,这时候就需要从其他副本(Replica)全量拷贝这个Shard的所有数据到新Node上构造新Shard。这个拷贝过程需要一段时间,这段时间内只能由剩余主副本来承载流量,在恢复完成之前,整个系统会处于一个比较危险的状态,直到failover结束。
    这里就体现了副本(Replica)存在的一个理由,避免数据丢失,提高数据可靠性。副本(Replica)存在的另一个理由是读请求量很大的时候,一个Node无法承载所有流量,这个时候就需要一个副本来分流查询压力,目的就是扩展查询能力。


主流的分布式架构

  • 基于本地文件系统的分布式系统

ElasticSearch相关概念_第3张图片
    Index一共有3个Shard,每个Shard除了Primary Shard外,还有一个Replica Shard。当Node 3机器宕机或磁盘损坏的时候,首先确认P3已经不可用,重新选举R3位Primary Shard,此Shard发生主备切换。然后重新找一台机器Node 7,在Node7 上重新启动P3的新Replica。由于数据都会存在本地磁盘,此时需要将Shard 3的数据从Node 6上拷贝到Node7上。
    为了保证可靠性,就需要冗余Shard,会导致更多的物理资源消耗。这种思想的另外一种表现形式是使用双集群,集群级别做备份。
    这种架构中为了保证可用性和可靠性,需要双集群或者Replica才能用于生产环境,Elasticsearch使用的就是这种架构方式。



  • 基于分布式文件系统的分布式系统
    ElasticSearch相关概念_第4张图片
        另一种思路是:存储和计算分离
        第一种思路的问题根源是数据量大,拷贝数据耗时多,那么有没有办法可以不拷贝数据?为了实现这个目的,一种思路是底层存储层使用共享存储,每个Shard只需要连接到一个分布式文件系统中的一个目录/文件即可,Shard中不含有数据,只含有计算部分。相当于每个Node中只负责计算部分,存储部分放在底层的另一个分布式文件系统中,比如HDFS。
        上图中,Node 1 连接到第一个文件;Node 2连接到第二个文件;Node3连接到第三个文件。当Node 3机器宕机后,只需要在Node 4机器上新建一个空的Shard,然后构造一个新连接,连接到底层分布式文件系统的第三个文件即可,创建连接的速度是很快的,总耗时会非常短。
        这种架构同时也有一个不足:访问分布式文件系统的性能可能不及访问本地文件系统。在上一代分布式文件系统中,这是一个比较明显的问题,但是目前使用了各种用户态协议栈后,这个差距已经越来越小了。HBase使用的就是这种架构方式。Solr也支持这种形式的架构。

ES索引优化技术

  • 传统索引方法(mysql)

ElasticSearch相关概念_第5张图片
ElasticSearch相关概念_第6张图片
B+树,root节点能存更多数据,且支持between查询。

  • ES索引优化(倒排索引)

在这里插入图片描述
ElasticSearch相关概念_第7张图片
    Mysql只有term dictionary这一层,是以b-tree 排序的方式存储在磁盘上的。检索一个term需要若干次的random access的磁盘操作。而Lucene在term dictionary 的基础上添加了term index来加速检索,term index以树的形式缓存在内存中。从term index查到对应的term dictionary的block 位置之后,再去磁盘上找 term,大大减少了磁盘的random access次数。
    Term index在内存中是以FST(finite state transducers)的形式保存的,其特点是非常节省内存。Term dictionary在磁盘上是以分 block 的方式保存的,一个 block内部利用公共前缀压缩,比如都是Ab开头的单词就可以把 Ab 省去。这样term dictionary可以比b-tree更节约磁盘空间。


并查询优化

  • 利用skip-list合并
    ElasticSearch相关概念_第8张图片
    ElasticSearch相关概念_第9张图片
        以上是三个 posting list。我们现在需要把它们用 AND 的关系合并,得出 posting list 的交集。如果使用跳表,对最短的posting list中的每个id,逐个在另外两个posting list中查找看是否存在,最后得到交集的结果。

  • 利用bitset合并
       Bitset 是一种很直观的数据结构,对应 posting list 如:[1,3,4,7,10],对应的 bitset 就是:[1,0,1,1,0,0,1,0,0,1]。

总结

    Elasticsearch支持以上两种的联合索引方式,如果查询的 filter 缓存到了内存中(以 bitset 的形式),那么合并就是两个bitset的AND。如果查询的 filter 没有缓存,那么就用skip list的方式去遍历两个on disk的posting list。

你可能感兴趣的:(ElasticSearch)