2 万字详解,彻底讲透 Elasticsearch( 六 )

  • logs:日志文件目录 。
  • modules:模块库,例如 x-pack 的模块 。
  • plugins:插件目录 。
  • ②安装目录下运行 bin/elasticsearch来启动 ES 。
    ③默认在 9200 端口运行,请求 curl http://localhost:9200/ 或者浏览器输入 http://localhost:9200,得到一个 JSON 对象,其中包含当前节点、集群、版本等信息 。
    { "name" : "U7fp3O9","cluster_name" : "elasticsearch","cluster_uuid" : "-Rj8jGQvRIelGd9ckicUOA","version" : {"number" : "6.8.1","build_flavor" : "default","build_type" : "zip","build_hash" : "1fad4e1","build_date" : "2019-06-18T13:16:52.517138Z","build_snapshot" : false,"lucene_version" : "7.7.0","minimum_wire_compatibility_version" : "5.6.0","minimum_index_compatibility_version" : "5.0.0"},"tagline" : "You Know, for Search"} 
    集群健康状态要检查群集运行状况,我们可以在 Kibana 控制台中运行以下命令 GET /_cluster/health,得到如下信息:
    { "cluster_name" : "wujiajian","status" : "yellow","timed_out" : false,"number_of_nodes" : 1,"number_of_data_nodes" : 1,"active_primary_shards" : 9,"active_shards" : 9,"relocating_shards" : 0,"initializing_shards" : 0,"unassigned_shards" : 5,"delayed_unassigned_shards" : 0,"number_of_pending_tasks" : 0,"number_of_in_flight_fetch" : 0,"task_max_waiting_in_queue_millis" : 0,"active_shards_percent_as_number" : 64.28571428571429}集群状态通过 绿,黄,红 来标识:
    • 绿色:集群健康完好,一切功能齐全正常,所有分片和副本都可以正常工作 。
    • 黄色:预警状态,所有主分片功能正常,但至少有一个副本是不能正常工作的 。此时集群是可以正常工作的,但是高可用性在某种程度上会受影响 。
    • 红色:集群不可正常使用 。某个或某些分片及其副本异常不可用,这时集群的查询操作还能执行,但是返回的结果会不准确 。对于分配到这个分片的写入请求将会报错,最终会导致数据的丢失 。
    当集群状态为红色时,它将会继续从可用的分片提供搜索请求服务,但是你需要尽快修复那些未分配的分片 。
     
    ES 机制原理ES 的基本概念和基本操作介绍完了之后,我们可能还有很多疑惑:
    • 它们内部是如何运行的?
    • 主分片和副本分片是如何同步的?
    • 创建索引的流程是什么样的?
    • ES 如何将索引数据分配到不同的分片上的?以及这些索引数据是如何存储的?
    • 为什么说 ES 是近实时搜索引擎而文档的 CRUD (创建-读取-更新-删除) 操作是实时的?
    • 以及 Elasticsearch 是怎样保证更新被持久化在断电时也不丢失数据?
    • 还有为什么删除文档不会立刻释放空间?
    带着这些疑问我们进入接下来的内容 。
     
    写索引原理下图描述了 3 个节点的集群,共拥有 12 个分片,其中有 4 个主分片(S0、S1、S2、S3)和 8 个副本分片(R0、R1、R2、R3),每个主分片对应两个副本分片,节点 1 是主节点(Master 节点)负责整个集群的状态 。
    2 万字详解,彻底讲透 Elasticsearch

    文章插图
    写索引是只能写在主分片上,然后同步到副本分片 。这里有四个主分片,一条数据 ES 是根据什么规则写到特定分片上的呢?
    这条索引数据为什么被写到 S0 上而不写到 S1 或 S2 上?那条数据为什么又被写到 S3 上而不写到 S0 上了?
    首先这肯定不会是随机的,否则将来要获取文档的时候我们就不知道从何处寻找了 。
    实际上,这个过程是根据下面这个公式决定的:
    shard = hash(routing) % number_of_primary_shards Routing 是一个可变值,默认是文档的 _id,也可以设置成一个自定义的值 。
    Routing 通过 Hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards(主分片的数量)后得到余数 。
    这个在 0 到
    number_of_primary_shards-1之间的余数,就是我们所寻求的文档所在分片的位置 。
    这就解释了为什么我们要在创建索引的时候就确定好主分片的数量并且永远不会改变这个数量:因为如果数量变化了,那么所有之前路由的值都会无效,文档也再也找不到了 。


    推荐阅读