我们知道数据是存储在 shard 中的,而 index 会映射一个或者多个 shard 。
那这时候我要存储一条数据到某个索引下,这条数据是在哪个 index 下的呢?

一切按照官方教程使用 三条命令,在本机启动三个节点组装成伪集群。

  1. ~ % > ./elasticsearch
  2. ~ % > ./elasticsearch -Epath.data=data2 -Epath.logs=log2
  3. ~ % > ./elasticsearch -Epath.data=data3 -Epath.logs=log3

创建索引

  1. PUT /items?pretty
  2. {
  3. "settings": {
  4. "number_of_replicas": 2,
  5. "number_of_shards": 3
  6. }
  7. }
  8. #--------------------------------------------
  9. {
  10. "acknowledged" : true,
  11. "shards_acknowledged" : true,
  12. "index" : "items"
  13. }
  14. #--------------------------------------------

当前版本 7.8
文档地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html
ES 默认 number_of_shards 为 1, 默认 number_of_replicas 为 1,即一个分片只有一个副本
下面命令可以查看索引信息

  1. GET _cat/indices/items
  2. yellow open items 9N1LLfTaQc2W5i4bDK9N0Q 3 2 0 0 624b 624b

存放数据

  1. POST /items/_doc
  2. {
  3. "name" : "科技美容深度补水",
  4. "price" : 23
  5. }
  6. {
  7. "_index" : "items",
  8. "_type" : "_doc",
  9. "_id" : "Z0uWE3YBcIKM7P9r8uHR",
  10. "_version" : 1,
  11. "result" : "created",
  12. "_shards" : {
  13. "total" : 3,
  14. "successful" : 1,
  15. "failed" : 0
  16. },
  17. "_seq_no" : 0,
  18. "_primary_term" : 1
  19. }

查询数据

  1. GET /items/_doc/Z0uWE3YBcIKM7P9r8uHR
  2. {
  3. "_index" : "items",
  4. "_type" : "_doc",
  5. "_id" : "Z0uWE3YBcIKM7P9r8uHR",
  6. "_version" : 1,
  7. "_seq_no" : 0,
  8. "_primary_term" : 1,
  9. "found" : true,
  10. "_source" : {
  11. "name" : "科技美容深度补水",
  12. "price" : 23
  13. }
  14. }

一条数据该存放在哪个 shard

通过命令可以看出:在存放数据时并没有指定到哪个 shard,那数据是存在哪里的呢?当一条数据进来,会默认会根据 id 做路由

shard = hash(routing) % number_of_primary_shards

从而确定存放在哪个 shard。 routing 默认是 _id, 也可以设置其他。这个 id 可以自己指定也可以系统给生成,如果不指定则会系统自动生成。

PUT 一条数据的过程是什么样的?

image.png
写入过程主要如下:
1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)
2)协调节点对document进行路由,将请求转发给对应的node(有primary shard)
3)实际的node上的primary shard处理请求,然后将数据同步到replica node
4)协调节点如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端

在写操作时,默认情况下,只需要 primary shard 处于活跃状态即可进行操作。
在索引设置时可以设置这个属性 index.write.wait_for_active_shards 默认是 1,即 primary shard 写入成功即可返回。
如果设置为 all 则相当于 number_of_replicas+1 就是 primary shard 数量 + replica shard 数量。 就是需要等待 primary shard 和 replica shard 都写入成功才算成功。
可以通过索引设置动态覆盖此默认设置。

总结

如何查看数据在哪个 shard 上呢?

  1. GET /items/_search_shards?routing=Z0uWE3YBcIKM7P9r8uHR&pretty
  2. {
  3. "nodes" : {
  4. "CAO7En0eQn2in76aHo1lRQ" : {
  5. "name" : "192.168.124.12",
  6. "ephemeral_id" : "l15ZXnXXS1CkU8_H3829ug",
  7. "transport_address" : "127.0.0.1:9300",
  8. "attributes" : { }
  9. }
  10. },
  11. "indices" : {
  12. "items" : { }
  13. },
  14. "shards" : [
  15. [
  16. {
  17. "state" : "STARTED",
  18. "primary" : true,
  19. "node" : "CAO7En0eQn2in76aHo1lRQ",
  20. "relocating_node" : null,
  21. "shard" : 0,
  22. "index" : "items",
  23. "allocation_id" : {
  24. "id" : "yaFLUxJESamHj9G3L0uWYg"
  25. }
  26. }
  27. ]
  28. ]
  29. }

通过上面命令可以查到数据 Z0uWE3YBcIKM7P9r8uHR 的所在 shard。