一、什么是文档存储(distributed document store)

Elasticsearch在跑起来以后,其实起到的第一个最核心的功能,就是一个分布式的文档数据存储系统。ES是分布式的。文档数据存储系统。文档数据,存储系统。

文档数据:es可以存储和操作json文档类型的数据,而且这也是es的核心数据结构。

存储系统:es可以对json文档类型的数据进行存储,查询,创建,更新,删除,等等操作。其实已经起到了一个什么样的效果呢?其实ES满足了这些功能,就可以说已经是一个NoSQL的存储系统了。

围绕着document在操作,其实就是把es当成了一个NoSQL存储引擎,一个可以存储文档类型数据的存储系统,在操作里面的document。

es可以作为一个分布式的文档存储系统,所以说,我们的应用系统,是不是就可以基于这个概念,去进行相关的应用程序的开发了。

什么类型的应用程序呢?

(1)数据量较大,es的分布式本质,可以帮助你快速进行扩容,承载大量数据

(2)数据结构灵活多变,随时可能会变化,而且数据结构之间的关系,非常复杂,如果我们用传统数据库,那是不是很坑,因为要面临大量的表

(3)对数据的相关操作,较为简单,比如就是一些简单的增删改查,用我们之前讲解的那些document操作就可以搞定

(4)NoSQL数据库,适用的也是类似于上面的这种场景

举个例子,比如说像一些网站系统,或者是普通的电商系统,博客系统,面向对象概念比较复杂,但是作为终端网站来说,没什么太复杂的功能,就是一些简单的CRUD操作,而且数据量可能还比较大。这个时候选用ES这种NoSQL型的数据存储,比传统的复杂的功能务必强大的支持SQL的关系型数据库,更加合适一些。无论是性能,还是吞吐量,可能都会更好。

二、document数据路由原理

1、document路由到shard上是什么意思?

我们知道,一个index的数据会被分为多片,每片都在一个shard中。 所以说,一个document ,只能存在于一个shard中。

当客户端创建document的时候, es此时就需要决定,这个document放在这个index的哪个shard上。这个过程,就称之为数据路由(document routing)。

es数据存储位置 es数据存储和原理_java

2、路由算法

公式:shard = hash(routing) % number_of_primary_shards

举个例子,一个index有3个primary shard,P0,P1,P2。每次增删改查一个document的时候,都会带过来一个routing number,默认就是这个document的_id(可能是手动指定,也可能是自动生成)默认routing = _id;假设_id=1;会将这个routing值,传入一个hash函数中,产出一个routing值的hash值,hash(routing) = 21(假设),然后将hash函数产出的值对这个index的primary shard的数量求余数,21 % 3 = 0,就决定了,这个document就放在P0上。

决定一个document在哪个shard上,最重要的一个值就是routing值,默认是_id,也可以手动指定,相同的routing值,每次过来,从hash函数中,产出的hash值一定是相同的。

无论hash值是几,无论是什么数字,对number_of_primary_shards求余数,结果一定是在0~number_of_primary_shards-1之间这个范围内的。

3、_id or custom routing value

默认的routing就是_id。也可以在发送请求的时候,手动指定一个routing value,比如说put /index/_doc/id?routing=user_id

手动指定routing value是很有用的,可以保证说,某一类document一定被路由到一个shard上去,那么在后续进行应用级别的负载均衡,以及提升批量读取的性能的时候,是很有帮助的

4、primary shard数量为啥是不可变的?

primary shard 数量之所有不能变化的原因是由于es的路由算法决定的。假如primary shard 可以变的话,当新增了一个节点后通过路由算法最后得出来的值会发生变化,导致找不到数据,造成数据假丢失的情况(增加节点之后得出来的值和之前的值不一样)。

es数据存储位置 es数据存储和原理_算法_02

三、增删改查内部原理

elasticsearch 内部增删改执行步骤如下所示

(1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)

(2)coordinating node,对document进行路由,将请求转发给对应的node(有primary shard)

(3)实际的node上的primary shard处理请求,然后将数据同步到replica node

(4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端

es数据存储位置 es数据存储和原理_算法_03

四、es查询操作内部原理

elasticsearch 内部查询执行步骤如下所示

1、客户端发送请求到任意一个node,成为coordinate node

2、coordinate node对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其所有replica中随机选择一个,让读请求负载均衡

3、接收请求的node返回document给coordinate node

4、coordinate node返回document给客户端

特殊情况:document如果还在建立索引过程中,可能只有primary shard有,任何一个replica shard都没有,此时可能会导致无法读取到document,但是document完成索引建立之后,primary shard和replica shard就都有了

es数据存储位置 es数据存储和原理_算法_04