Elasticsearch核心概念

  1. 索引Index:一个索引就是一个拥有几分相似特征的文档的集合,一切设计都是为了提高搜索的性能(sql-数据库)
  2. 类型Type: 不经常使用了(sql-表)
  3. 映射Mapping:是处理数据的方式和规则方面做一些限制,如:某个字段的数据类型、默认值、分析器、是否被索引等等。这些都是映射里面可以设置的(sql-类似设置字段限制)
  4. 文档Document: 一个文档是一个可被索引的基础信息单元,也就是一条数据。,文档的格式为Json(sql-行)
  5. 分片Shards :一个索引可以存储超出单个节点硬件限制的大量数据,每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。
    第一,允许你水平分割 / 扩展你的内容容量。
    第二允许你在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量
  6. 副本Replicas:创建分片的一份或多份拷贝,这些拷贝叫做复制分片(副本),第一,提供了高可用性,第二增加吞吐量,一切操作可以在副本上进行。

Elasticsearch框架

SSB索引范围_数据

一个运行中的 Elasticsearch 实例称为一个节点,而集群是由一个或者多个拥有相同cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。

当一个节点被选举成为主节点时, 它将负责管理集群范围内的所有变更,例如增加、
删除索引,或者增加、删除节点等。
而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。 任何节点都可以成为主节点。

无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的。

如图所示Node1为一个主节点,负责管理其他节点的分配,P0,P1,P2(蓝色为分片),P0,P1,P2(白色为分片副本)

Elasticsearch分配问题

故障转移:

只有一个节点在运行时,意味着会有一个单点故障问题——没有冗余(此时为黄色状态,说明可以进行操作但是副本没有分配安全性没有保障),此时再启动一个节点就好啦,再启动一个节点,分片和分片副本都能分配成功(此时集群为绿色健康状态)。

节点上分片的分配原则:

尽量均匀分布
分片和副本不能在同一节点上,如果此刻一个节点GG了要保证有分片副本在另外的节点上。

扩容问题:

把索引分成几片是在索引创建的时候就决定的,如果现在索引被分成了三个分片,有一个副本,则两个节点均匀分配,如果此刻节点增加到7个,如何均匀分配?答:应该增加节点数量,这样还能提高系统的性能,一共3个主分片,6个副本分片。

故障问题:

此时主节点突然GG了怎么办?因为其他节点上还有副本,系统会新选出来一个新的主节点代替。

Elasticsearch数据写入,读取过程

数据如何写入:

SSB索引范围_elasticsearch_02


如图所示,先到任意节点进行请求写入,然后进行路由计算(我看看到底要写入哪个分片,计算公式:shard = hash(routing) % number_of_primary_shards)在计算出来的主分片内P0写入数据,P0的副本R0也写入数据,两个都写好后客户端得到反馈。

一定要副本全部反馈后才能客户确认吗?
不一定的,为了节省时间,提高效率consistency即一致性,保障大多数就行
one :只要主分片状态 ok 就允许执行写操作。
all:必须要主分片和所有副本分片的状态没问题才允许执行写操作。
quorum:默认值为quorum , 即大多数的分片副本状态没问题就允许执行写操作。

如果没有足够的副本分片会发生什么?
Elasticsearch 会等待,希望更多的分片出现。你可以使用timeout参数使它更早终止。

数据如何读取:

SSB索引范围_倒排索引_03


如图所示,先到任意节点进行请求读取,ES计算有是哪个主分片和分片副本是我要查找的,给出主分片和分片副本们后,为了负载均衡进行轮询查询,把结果给具体节点返回。

数据如何更新:

SSB索引范围_Elastic_04


如图所示,客户端向Node 1发送更新请求,它将请求转发到主分片所在的Node 3 。

Node 3从主分片检索文档,修改_source字段中的JSON,并且尝试重新索引主分片的文档。如果文档已经被另一个进程修改,它会重试步骤3 ,超过retry_on_conflict次后放弃。3成功地更新文档,它将新版本的文档并行转发到Node 1和 Node 2上的副本分片,重新建立索引。一旦所有副本分片都返回成功,Node 3向协调节点也返回成功,协调节点向客户端返回成功。

倒排索引

Elasticsearch是建立在全文搜索引擎 Apache Lucene™ 基础上的搜索引擎。它的搜索原理是和Lucene相同的倒排索引。适用于快速的全文搜索。
1001 my name is sunmeng
正常的索引情况是 1001-》模糊查找,倒排索引为
my 1001
name 1001
is 1001
sun 1001
sunmeng 1001
在搜索过程中分词处理是很重要的一步
词条:索引里面最小的存储和查询单元
词典:词条的集合,字典,用B+树和 hash实现
倒排查找的过程:先在词典中查看是否有此词条,如果有,进入倒排表查出该词条的文档指针。

文档搜索

全文检索会为整个文档集合建立一个很大的倒排索引并将其写入到磁盘。 一旦新的索引就绪,旧的就会被其替换,这样最近的变化便可以被检索到。
倒排索引在磁盘中不发生改变,优点:
第一,不需要锁
第二,生命周期变长,缓存长时间有效
第三,可以被压缩
第四,性能提升。

如果更新了怎么办?
用更多的索引。通过增加新的补充索引来反映新近的修改,而不是直接重写整个倒排索引。每一个倒排索引都会被轮流查询到,从最早的开始查询完后再对结果进行合并。使用段的概念,
第一步,建立一个内存索引缓存,第二步,不时地, 缓存被提交。内存缓存中写入更新的索引,新的索引,排队等待磁盘读入,第三步,内存缓存被清空,等待接收新的文档

文档的删除,不是真正的删除只是被标记删除,当缓存新的补充索引足够大的时候,将补充索引合并为一个新的索引,此刻将标记删除真正删除

文档的近实时搜索

SSB索引范围_elasticsearch_05

如果所示,当有一个新的索引的时候,根据按段搜索提交写入segment中,当写成功的时候写入日志Translog中来保障安全性(防止突然中断丧失数据),增加一个OS cache缓冲区,这个缓冲区1s更新一次,当半个小时向磁盘进行写入并更新日志。

文档冲突

当两个人同时对索引进行更新怎么办呐?
两种方式:悲观锁(锁资源),乐观锁(使用版本号)
这里用乐观并发的控制