一、理解ES数据层和倒排索引:
一个 Elasticsearch 集群可以包含多个索引,相应的每个索引可以包含多个类型。不同的类型存储着多个文档,每个文档又有多个属性。
ES数据层结构与关系型数据库对比如下:
索引 | 表空间
类型 | 表
文档 | 表行数据
属性 | 数据字段
理解ES的倒排索引(此索引是增加查询速度的索引,非上面的索引),话不多说后续还会细讲,先仔细观察下图并细心品味思考:
假设我们有如下一个这样的数据集,我们以name列建立索引:
id | name | age
1 | elasticsearch | 23
2 | search | 24
3 | elastic | 23
关系数据库索引建立方式(按照字符顺序去建立索引表):
name | id
elastic | 3
elasticsearch | 1
search | 2
ES库倒排索引建立方式(按照分词器规则分词后建立索引表,增加检索速度):
name | id
elastic | [1,3]
search | [1,2]
在我看来,关系型数据库索引更像ASCII码对照表,根据ASCII值去查找对应的控制字符;
而ES的索引才更像我们使用的字典(成语辞典),我们根据目录找到成语,然后得到所在页码(一页可能有多个成语),找到对应的成语解释。注:倒排索引(反向索引),分词器
二、ES分布式集群概念和理解
1. 集群健康意味着什么?
- 集群健康3种状态和代表意义:
- green:所有主要分片和复制分片都可用
- yellow:所有主要分片可用,但不是所有复制分片都可用
- red:不是所有的主要分片都可用
- 注:单机部署的ES不能保证高可用,状态为yellow。也就是不存在复制分片,同一个节点上保存相同的数据副本是没有必要的,如果这个节点故障了,那所有的数据副本也会丢失。(如本文图1.2)
2. 集群的分片概念与横向扩展
-
分片及集群的概念
ES集群:一个集群(cluster)由一个或多个节点组成,它们具有相同的cluster.name,它们协同工作,分享数据和负载。当加入新的节点或者删除一个节点时,集群就会感知到并平衡数据。
ES节点:一个节点(node)就是一个Elasticsearch实例,集群中一个节点会被选举为主节点(master),它将临时管理集群级别的一些变更,例如新建或删除索引、增加或移除节点等。主节点不参与文档级别的变更或搜索,这意味着在流量增长的时候,该主节点不会成为集群的瓶颈。任何节点都可以成为主节点。
分片:一个分片(shard)是一个最小级别“工作单元(worker unit)”,ES索引存储在一个或多个分片中,一个分片只是保存了索引中所有数据的一部分。分片就是一个Lucene实例,并且它本身就是一个完整的搜索引擎。
分片在集群中理解:分片是Elasticsearch在集群中分发数据的关键。把分片想象成数据的容器。文档存储在分片中,然后分片分配到你集群中的节点上。当你的集群扩容或缩小,Elasticsearch将会自动在你的节点间迁移分片,以使集群保持平衡。
- 主分片(primary shard):索引中的每个文档属于一个单独的主分片,主分片的数量决定了索引最多能存储多少数据。
理论上主分片能存储的数据大小是没有限制的,限制取决于你实际的使用情况。分片的最大容量完全取决于你的使用状况:硬件存储的大小、文档的大小和复杂度、如何索引和查询你的文档,以及你期望的响应时间。
- 复制分片(replica shard):复制分片只是主分片的一个副本,它可以防止硬件故障导致的数据丢失,同时可以提供读请求,比如搜索或者从别的shard取回文档。
索引创建完成的时候,主分片的数量就固定了,但是复制分片的数量可以随时调整。也就是说:主分片不应缺失,否则就会丢失数据,集群状态此时为red。而复制分片会随分片的数量和集群的节点数量而动态地变更,直到集群将分片并发的迁移到各个节点完成,同时这也有利于ES可以根据需求扩大或者缩小规模(即横向扩展)。
-
为什么采用横向扩展?
首先我们先观察几种集群节点部署下的分片变化和扩展:-
单一节点的集群(无索引和有索引)
1.1 无索引的单一节点集群
1.2 有索引的单一节点集群 -
多节点集群(状态为green的)
2.1 双节点中所有的主分片和复制分片都已分配
2.2 三节点中所有的主分片和复制分片都已分配
2.3 将复制分片调整为2倍的三节点分配方式(number_of_replicas参数配置)
注:这些节点上的分片位置,由es自动管理,你只需理解节点中的分片是如何横向扩展的。
- Elasticsearch用于构建高可用和可扩展的系统。扩展的方式可以是购买更好的服务器(纵向扩展(vertical scale or scaling up))或者购买更多的服务器(横向扩展(horizontal scale or scaling out))。
- Elasticsearch虽然能从更强大的硬件中获得更好的性能,但是纵向扩展有它的局限性。真正的扩展应该是横向的,它通过增加节点来均摊负载和增加可靠性。对于大多数数据库而言,横向扩展意味着你的程序将做非常大的改动才能利用这些新添加的设备,但Elasticsearch天生就是分布式的,它知道如何管理节点来提供高扩展和高可用。
- 主分片或者复制分片都可以处理读请求——搜索或文档检索,所以数据的冗余越多,我们能处理的搜索吞吐量就越大。
-
3. 集群的故障转移和高可用应对
-
当我们将Node1节点宕机或杀死后,集群状况如下图:
3.1 图2.3中node1节点宕机或被kill -
ES故障转移做了哪些工作?
- 我们杀掉的节点是一个主节点。一个集群必须要有一个主节点才能使其功能正常,所以集群做的第一件事就是各节点选举了一个新的主节点:Node2;
- Node1中P1和P2两个主节点宕机时丢失,如果此时检查集群健康,状态将会是red。幸运的是,丢失的两个主分片的完整拷贝存在于其他节点上,所以新主节点(Node2)做的第一件事是把这些在Node2和Node3上的复制分片升级为主分片,这时集群健康回到yellow状态;
- 此时状态为yellow是因为我们指定了每个主分片对应两个复制分片,但是我们目前只有一个复制分片被分配。不过不用太担心这个:当我们杀掉Node2,我们的程序依然可以在没有丢失数据的情况下继续运行;
- 如果我们重启Node1,集群将能够重新分配丢失的复制分片,集群状况与上面的图2.3类似。如果Node1依旧有旧分片的拷贝,它将会尝试再利用它们,然后它只会从主分片上复制在故障期间有数据变更的那一部分。