ElasticSearch如何增删改查/CURD数据? #W10

总结一下在ES中,CURD分别是什么情况。

假设,有这样的一个集群(图片来源):


三个节点,一个索引A, A有两个主分片, 每个主分片有两个副本分片(灰色),A包含一个type B。基于这个集群,我们来从宏观脉络上梳理一下,数据的增删改查。在ES中数据其实是不可被修改的,只能进行替换,或者标记(删除),也就是说,用户进行的CURD其实就只有“读“和”写”这两个操作,下面来分别梳理。

如何进行读?

ES中数据时分布式存储的,数据分散到不同的分片和节点上,然而ES的每个节点都可以响应集群中的任意读取操作,它是怎么做到的呢?

假设记得读取操作为:  GET  /A/B/001 ,数据存放到分片0上,你把请求发送到NODE3 。 

ES中默认通过对_id进行哈希映射来决定数据是存放到哪一个分片上, 每个节点都知道这个映射规则,所以当请求到达NODE3的时候,NODE3知道数据是存放在分片0上的,所以它可以直接在自己的的R0上获取数据,然后直接返回,也可以将请求转发到拥有分片0数据的节点NODE2上(NODE1也行),然后将NODE2返回的数据再返回给用户。 可能是直接返回,也可能途中经历过请求转发,转发在很多时候是为了负载均衡。

如何新增数据?

新增数据是“写”操作,必须先在主分片上进行,然后再将更改同步到副本分片上。

PUT /A/B/123?op_type=create
{ ... }

  1. 假设上面的请求被发送到NODE1上。
  2. NODE1通过对”123“进行哈希映射操作,知道要将数据存放到分片0上,于是将请求转发到拥有主分片0的节点NODE3上
  3. NODE3 进行新增操作,如果成功了,会将请求并行转发到其他副本分片上,当都返回成功后,会告诉客户端插入成功

如果文档已经存在,则会返回插入失败。ES通过   索引/type/_id   来唯一标识文档。

如何更新?

ES中无法进行真正的更新操作,我们所看到的更新操作实际上是,ES根据最新的数据,重新进行插入,新增加了一个数据版本,旧数据以一个老版本的形式存在。 没有类似MySQL中的update操作。

PUT /A/B/123
{ ... }
  1. 客户端查询出 123的数据,然后将数据包更新,准备带上新数据进行更新请求
  2. 更新请求被发送到NODE1上
  3. 通过哈希映射,将请求转发到NODE3上(和上面一样),更新成功后会将数据异步转发到其他副本分片上

有两个点值得继续探讨,一是上面第三步的“异步转发”,二是ES如何保证更新时的并发安全。

当主分片把更改转发到副本分片时, 它不会转发更新请求。 相反,它转发完整文档的新版本。
请记住,这些更改将会异步转发到副本分片,并且不能保证它们以发送它们相同的顺序到达。
如果Elasticsearch仅转发更改请求,则可能以错误的顺序应用更改,导致得到损坏的文档。

ES中文文档中有这么一段注解。说的是主分片更新成功后,是将“数据整体“异步转发到副本分片,而不是像插入请求时将“插入请求”转发到副本分片。 转发的是数据体本身,而不是更新请求。这样做的目的是保证更新后的数据包能按照更新顺序依次同步到副本分片,如果转发请求,有可能会由于网络拥塞导致 ”先发起的更新请求比后发起的后到“,理论上是先发先到,这样会导致,新的数据被旧请求中的脏数据覆盖,导致新数据丢失。

要防止这种情况发生的要点是,保证数据按照更新时间顺序到达副本分片。而ES的异步机制可以保证这点(初步猜测是通过类似队列机制实现),而转发更新请求则不能保证。 这个点也就顺利地引出了ES是如何保证更新时的并发安全的。

并发更新都需要锁的参与,ES通过乐观锁来实现更新安全,相关资料可以看我的这篇文章

简单地说,ES每个文档都有一个数据版本字段,用来表示文档当前的版本,每一次更新操作,都会将版本号做+1 的操作。每次更新其实都是从 “一个版本号增加到更大的版本号”, 更新操作本身会带上一个版本号,ES每次会检查这个版本号是否是最新的,如果是最新的才进行更新操作。

如何删除?

数据不会被真正删除,ES只是标记数据已经被删除,实际上数据还是存在于ES中。ES会在以后的索引操作中对被标记删除的数据进行清理操作。 不过,ES是如何标记数据已经被删除的呢?  不可能是增加一个del字段,来标识其删除状态的吧?

ES会在索引中维护一个 .del的文件,会将标记删除数据的写入这个文件。在进行读取等操作时,这个.del文件也会参与过滤,如果被搜索出数据出现在了文件中,则会将其过滤掉。 

这样便实现了”删除“,真正的删除都是ES在后台进行的,索引本身是不能被更新的,只能被重建,重建之后就不会包含被删除的数据了,这是一个复杂的话题,后面我会继续梳理这方面的知识。


猜你喜欢

转载自blog.csdn.net/u012671917/article/details/80296997