四、初探[ElasticSearch]集群架构原理与搜索技术

一、浅析Elasticsearch架构原理

1.Elasticsearch的节点类型

在Elasticsearch主要分成两类节点,一类是Master,一类是DataNode。

1.1 Master节点

在Elasticsearch启动时,会选举出来一个Master节点。采用Zen Discovery1机制选出master节点并且找到集群中的其他节点,并建立连接。一个Elasticsearch集群中,只有一个Master节点。(这里的一个是在集群范围中的,而不是指定某台服务器一直就是主节点,主节点所在服务器宕机,其他的某一个节点有机会成为master节点)

Master节点主要功能::

  1. 管理索引和分片的创建、删除和重新分配。
  2. 监测节点的状态,并在需要时进行重分配。
  3. 协调节点之间的数据复制和同步工作。
  4. 处理集群级别操作,如创建或删除索引、添加或删除节点等。
  5. 维护集群的健康状态,并在集群出现问题时采取措施解决。
  6. 维护元数据2

1.2DataNode节点

与master节点不同,datanode节点可能会有多个。这个取决于你集群的节点数量,因为master在集群中只能有一个,其余为DataNode节点。
DataNode节点主要功能:

  1. 存储和索引数据:Data Node 节点会将索引分片存储在本地磁盘上,并对查询请求进行响应。
  2. 复制和同步数据:为了确保数据的可靠性和高可用性,ElasticSearch 会将每个原始分片的多个副本存储在不同的 Data Node 节点上,并定期将各节点上的数据进行同步。
  3. 参与搜索和聚合操作:当客户端提交搜索请求时,Data Node 节点会使用本地缓存和分片数据完成搜索和聚合操作。
  4. 执行数据维护操作:例如,清理过期数据和压缩分片等。

二、分片和副本机制

在第一篇文章中也有介绍过这俩个概念,这里在集群中再次进行解释
在这里插入图片描述

2.1分片

ElasticSearch是一个分布式的搜索引擎,索引索引可以分成一份或多份,多份分片分布在不同节点当中。ElasticSearch会自动管理分片,如果发现分片分布不均衡,就会自动迁移。

2.2副本

在ElasticSearch中每个分片都有一个主分片,可能会有若干个副本分片(默认一个分片,一个副本),这些副本也会分布在不同的节点上。

2.3指定分片、副本数量

PUT /test_index06
{
    
    
  "mappings": {
    
    
    "properties": {
    
    
      "name": {
    
    
        "type": "keyword",
        "index": true,
        "store": true
      },
      ................
    }
  },
  //设置分片数量1,副本数量2
  "settings": {
    
    
    "number_of_shards": 1,
    "number_of_replicas": 2
  }
}

2.4查看分片、主分片、副本分片

GET /_cat/indices?v

三、Elasticsearch工作流程

3.1Elasticsearch文档写入原理

在这里插入图片描述

如何知道我插入一条数据要保存到那个分片呢?

shard = hash(routing) % number_of_primary_shards
routing 是一个可变值,默认是文档的 _id。
number_of_primary_shards为分片数量
你也可以使用自己的自定义分片键,只需在索引时指定"_routing"字段即可。

3.2Elasticsearch检索原理

在这里插入图片描述
客户端发起查询请求,某个DataNode接收到请求,该DataNode就会成为协调节点。
协调节点(Coordinating Node)将查询请求广播到每一个数据节点,这些数据节点的分片会处理该查询请求, 每个分片进行数据查询,将符合条件的数据放在一个优先队列中,并将这些数据的文档ID、节点信息、分片信息返回给协调节点。
协调节点将所有的结果进行汇总,并进行全局排序, 协调节点向包含这些文档ID的分片发送get请求,对应的分片将文档数据返回给协调节点,最后协调节点将数据返回给客户端。

四、Elasticsearch准实时索引实现

在这里插入图片描述

4.1溢写到文件系统缓存

当数据写入到ES分片时,会首先写入到内存中,然后通过内存的buffer生成一个segment,并刷到文件系统缓存中,数据可以被检索(注意不是直接刷到磁盘)ES中默认1秒,refresh缓存一次。

4.2写translog保障容错

在写入到内存中的同时,也会记录translog日志,在refresh期间出现异常,会根据translog来进行数据恢复
等到文件系统缓存中的segment数据都刷到磁盘中,清空translog文件。

4.3flush到磁盘(刷盘)

ES默认每隔30分钟会将文件系统缓存的数据刷入到磁盘。

4.4segment合并

Segment太多时,ES定期会将多个segment合并成为大的segment,减少索引查询时IO开销,此阶段ES会真正的物理删除(之前执行过的delete的数据)。

五.手动控制搜索结果精准度

5.1operator与minimum_should_match简单使用

①查询document中的remark字段包含java或developer词组。

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": "java developer"
    }
  }
}

或者这样查询

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": {
    
    
        "query": "java developer",
        "operator": "or"
      }
    }
  }
}

结果

 "hits" : [
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.77041256,
        "_source" : {
    
    
          "name" : "宝塔镇河妖",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java developer"
        }
      },
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.21110919,
        "_source" : {
    
    
          "name" : "天王盖地虎",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java"
        }
      }
    ]

②查询document中的remark字段,同时包含java和developer词组

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": {
    
    
        "query": "java developer",
        "operator": "and"
      }
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.77041256,
        "_source" : {
    
    
          "name" : "宝塔镇河妖",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java developer"
        }
      }
    ]

③minimum_should_match可以使用百分比或固定数字。百分比代表query搜索条件中词条百分比,如果无法整除,向下匹配(如,query条件有3个单词,如果使用百分比提供精准度计算,那么是无法除尽的,如果需要至少匹配两个单词,则需要用67%来进行描述。如果使用66%描述,ES则认为匹配一个单词即可)。固定数字代表query搜索条件中的词条,至少需要匹配多少个。
③-1百分比
查询内容包括java 或developer或assistant中匹配度达到66%即文档内容中,至少包括一个单词出现。

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": {
    
    
        "query": "java developer assistant",
        "minimum_should_match": "66%"
      }
    }
  }
}
"hits" : [
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.21110919,
        "_source" : {
    
    
          "name" : "天王盖地虎",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java"
        }
      },
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.160443,
        "_source" : {
    
    
          "name" : "宝塔镇河妖",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java developer"
        }
      }
    ]

查询内容包括java 或architect 或assistant中匹配度达到67%即文档内容中,至少包括两个个单词出现。

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": {
    
    
        "query": "java developer assistant",
        "minimum_should_match": "67%"
      }
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.77041256,
        "_source" : {
    
    
          "name" : "宝塔镇河妖",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java developer"
        }
      }
    ]

③-2固定数字
查询的内容中至少出现下面三个条件中的两个,即java、developer、assistant这三个单词,至少有两个同时出现才符合条件。

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "should": [
        {
    
    
          "match": {
    
    
            "remark": "java"
          }
        },
        {
    
    
          "match": {
    
    
            "remark": "developer"
          }
        },
        {
    
    
          "match": {
    
    
            "remark": "assistant"
          }
        }
      ],
      "minimum_should_match": 2
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.77041256,
        "_source" : {
    
    
          "name" : "宝塔镇河妖",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java developer"
        }
      }
    ]

5.2、match 的底层转换

我们输入的查询语句

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": "java developer"
    }
  }
}

转换后的查询语句

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "should": [
        {
    
    
          "term": {
    
    
            "remark": "java"
          }
        },
        {
    
    
          "term": {
    
    
            "remark": {
    
    
              "value": "developer"
            }
          }
        }
      ]
    }
  }
}

查询语句

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": {
    
    
        "query": "java developer",
        "operator": "and"
      }
    }
  }
}

转换后

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    
          "term": {
    
    
            "remark": "java"
          }
        },
        {
    
    
          "term": {
    
    
            "remark": {
    
    
              "value": "developer"
            }
          }
        }
      ]
    }
  }
}

查询条件

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": {
    
    
        "query": "java developer assistant",
        "minimum_should_match": "68%"
      }
    }
  }
}

转换后

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "should": [
        {
    
    
          "term": {
    
    
            "remark": "java"
          }
        },
        {
    
    
          "term": {
    
    
            "remark": "developer"
          }
        },
        {
    
    
          "term": {
    
    
            "remark": "assistant"
          }
        }
      ],
      "minimum_should_match": 2
    }
  }
}

使用转换后的语法执行搜索,效率更高。

5.3、boost权重控制

搜索document中remark字段中包含java的数据,如果remark中包含developer或assistant,则包含assistant的document优先显示。(就是将assistant数据匹配时的相关度分数增加)。
一般用于搜索时相关度排序使用。如:电商中的综合排序。将一个商品的销量,广告投放,评价值,库存,单价比较综合排序。在上述的排序元素中,广告投放权重最高,库存权重最低。还有就是百度搜索内容时前几一般都是广告。

例如
索引test_index05下全部数据为

"hits" : [
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
    
    
          "name" : "天王盖地虎",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java"
        }
      },
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
    
    
          "name" : "宝塔镇河妖",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java developer"
        }
      },
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
    
    
          "name" : "铁锅炖大鹅",
          "sex" : 1,
          "age" : 19,
          "address" : "天津",
          "remark" : "java assistant"
        }
      }
    ]

查询(boost越高,表示权重越高,越优先展示)

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    
          "match": {
    
    
            "remark": "java"
          }
        }
      ],
      "should": [
        {
    
    
          "match": {
    
    
            "remark": {
    
    
              "query": "developer",
              "boost": 1
            }
          }
        },
        {
    
    
          "match": {
    
    
            "remark": {
    
    
              "query": "assistant",
              "boost": 3
            }
          }
        }
      ]
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 2.3016074,
        "_source" : {
    
    
          "name" : "铁锅炖大鹅",
          "sex" : 1,
          "age" : 19,
          "address" : "天津",
          "remark" : "java assistant"
        }
      },
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.474477,
        "_source" : {
    
    
          "name" : "宝塔镇河妖",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java developer"
        }
      },
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.43250346,
        "_source" : {
    
    
          "name" : "天王盖地虎",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java"
        }
      }
    ]

查询

GET /test_index05/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    
          "match": {
    
    
            "remark": "java"
          }
        }
      ],
      "should": [
        {
    
    
          "match": {
    
    
            "remark": {
    
    
              "query": "developer",
              "boost": 2
            }
          }
        },
        {
    
    
          "match": {
    
    
            "remark": {
    
    
              "query": "assistant",
              "boost": 1
            }
          }
        }
      ]
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 2.611973,
        "_source" : {
    
    
          "name" : "宝塔镇河妖",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java developer"
        }
      },
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.9918565,
        "_source" : {
    
    
          "name" : "铁锅炖大鹅",
          "sex" : 1,
          "age" : 19,
          "address" : "天津",
          "remark" : "java assistant"
        }
      },
      {
    
    
        "_index" : "test_index05",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.43250346,
        "_source" : {
    
    
          "name" : "天王盖地虎",
          "sex" : 1,
          "age" : 25,
          "address" : "上海",
          "remark" : "java"
        }
      }
    ]

5.4、基于dis_max实现best fields策略进行多字段搜索

best_fields策略: 搜索的document中的某一个field,尽可能多的匹配搜索条件。
most_fields策略:与best fields相反的是,尽可能多的字段匹配到搜索条件。

dis_max语法: 直接获取搜索的多条件中的,单条件query相关度分数最高的数据,以这个数据做相关度排序。

best fields策略实现举例(是找name字段中’秀儿’匹配相关度分数或remark字段中’java developer’匹配相关度分数,哪个高,就使用哪一个相关度分数进行结果排序。)

GET /test_index06/_search
{
    
    
  "query": {
    
    
    "dis_max": {
    
    
      "queries": [
        {
    
    
          "match": {
    
    
            "remark": "java developer"
          }
        },
        {
    
    
          "match": {
    
    
            "name": "秀儿"
          }
        }
      ]
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vkjNUIcB14FuHovqnIz1",
        "_score" : 2.3842063,
        "_source" : {
    
    
          "name" : "秀儿",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vEjNUIcB14FuHovqKIyb",
        "_score" : 1.781607,
        "_source" : {
    
    
          "name" : "rod",
          "sex" : 1,
          "age" : 25,
          "book" : "Spring",
          "remark" : "java developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vUjNUIcB14FuHovqaYzA",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "rods",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "python developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "v0jOUIcB14FuHovqTYw0",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "Tom",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "wEjOUIcB14FuHovqYYw0",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "Amy",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      }
    ]

5.5、基于tie_breaker参数优化dis_max搜索效果

我不想根据打分最高的那个字段进行排序展示,我想让其他的字段也参与进来咋办?

dis_max是将多个搜索query条件中相关度分数最高的用于结果排序,忽略其他query分数,在某些情况下,可能还需要其他query条件中的相关度介入最终的结果排序,这个时候可以使用tie_breaker参数来优化dis_max搜索。tie_breaker参数代表的含义是:将其他query搜索条件的相关度分数乘以参数值,再参与到结果排序中。如果不定义此参数,相当于参数值为0。所以其他query条件的相关度分数被忽略。

tie_breaker指定的值最大为1,除最高分字段,设置其他字段打分的策略,即其他字段得分乘指定的系数,如果不加这个tie_breaker则默认为0

GET /test_index06/_search
{
    
    
  "query": {
    
    
    "dis_max": {
    
    
      "queries": [
        {
    
    
          "match": {
    
    
            "remark": "java developer"
          }
        },
        {
    
    
          "match": {
    
    
            "name": "秀儿"
          }
        }
      ],
      "tie_breaker": 0.5
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vkjNUIcB14FuHovqnIz1",
        "_score" : 2.5047874,
        "_source" : {
    
    
          "name" : "秀儿",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vEjNUIcB14FuHovqKIyb",
        "_score" : 1.781607,
        "_source" : {
    
    
          "name" : "rod",
          "sex" : 1,
          "age" : 25,
          "book" : "Spring",
          "remark" : "java developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vUjNUIcB14FuHovqaYzA",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "rods",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "python developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "v0jOUIcB14FuHovqTYw0",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "Tom",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "wEjOUIcB14FuHovqYYw0",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "Amy",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      }
    ]

5.6、使用multi_match简化dis_max+tie_breaker(不常用)

ES中相同结果的搜索也可以使用不同的语法语句来实现。

查询方式1

GET /test_index06/_search
{
    
    
  "query": {
    
    
    "dis_max": {
    
    
      "queries": [
        {
    
    
          "match": {
    
    
            "name": "Tom"
          }
        },
        {
    
    
          "match": {
    
    
            "remark": {
    
    
              "query": "java developer",
              "boost": 2,
              "minimum_should_match": 2
            }
          }
        }
      ],
      "tie_breaker": 0.5
    }
  }
}

结果

"hits" : {
    
    
    "total" : {
    
    
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 3.563214,
    "hits" : [
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vEjNUIcB14FuHovqKIyb",
        "_score" : 3.563214,
        "_source" : {
    
    
          "name" : "rod",
          "sex" : 1,
          "age" : 25,
          "book" : "Spring",
          "remark" : "java developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "v0jOUIcB14FuHovqTYw0",
        "_score" : 1.6360589,
        "_source" : {
    
    
          "name" : "Tom",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      }
    ]

查询方式2(其中type常用的有best_fields和most_fields。^n代表权重,相当于"boost":n。)

GET /test_index06/_search
{
    
    
  "query": {
    
    
    "multi_match": {
    
    
      "query": "Tom java developer",
      "fields": [
        "name",
        "remark^2"
      ],
      "type": "best_fields",
      "tie_breaker": 0.5,
      "minimum_should_match": "50%"
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vEjNUIcB14FuHovqKIyb",
        "_score" : 3.563214,
        "_source" : {
    
    
          "name" : "rod",
          "sex" : 1,
          "age" : 25,
          "book" : "Spring",
          "remark" : "java developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "v0jOUIcB14FuHovqTYw0",
        "_score" : 1.877221,
        "_source" : {
    
    
          "name" : "Tom",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vUjNUIcB14FuHovqaYzA",
        "_score" : 0.48232412,
        "_source" : {
    
    
          "name" : "rods",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "python developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vkjNUIcB14FuHovqnIz1",
        "_score" : 0.48232412,
        "_source" : {
    
    
          "name" : "秀儿",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "wEjOUIcB14FuHovqYYw0",
        "_score" : 0.48232412,
        "_source" : {
    
    
          "name" : "Amy",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      }
    ]

5.7、cross_fields搜索

cross fields : 一个唯一的标识,分部在多个fields中,使用这种唯一标识搜索数据就称为cross fields搜索。如:人名可以分为姓和名,地址可以分为省、市、区县、街道等。那么使用人名或地址来搜索document,就称为cross fields搜索。实现这种搜索,一般都是使用most fields搜索策略。因为这就不是一个field的问题。Cross fields搜索策略,是从多个字段中搜索条件数据。默认情况下,和most fields搜索的逻辑是一致的,计算相关度分数是和best fields策略一致的。一般来说,如果使用cross fields搜索策略,那么都会携带一个额外的参数operator。用来标记搜索条件如何在多个字段中匹配。在ES中也有cross fields搜索策略

例如(搜索条件中的java必须在name或remark字段中匹配,developer也必须在name或remark字段中匹配。)

GET /test_index06/_search
{
    
    
  "query": {
    
    
    "multi_match": {
    
    
      "query": "java developer",
      "fields": [
        "name",
        "remark"
      ],
      "type": "cross_fields",
      "operator": "and"
    }
  }
}

结果

"hits" : {
    
    
    "total" : {
    
    
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.781607,
    "hits" : [
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vEjNUIcB14FuHovqKIyb",
        "_score" : 1.781607,
        "_source" : {
    
    
          "name" : "rod",
          "sex" : 1,
          "age" : 25,
          "book" : "Spring",
          "remark" : "java developer"
        }
      }
    ]

most field策略问题:most fields策略是尽可能匹配更多的字段,所以会导致精确搜索结果排序问题。又因为cross fields搜索,不能使用minimum_should_match来去除长尾数据。所以在使用most fields和cross fields策略搜索数据的时候,都有不同的缺陷。所以商业项目开发中,都推荐使用best fields策略实现搜索。

5.8、copy_to组合fields

场景:在电商网站,如果在搜索框中输入“手机”,点击搜索,那么是在商品的类型名称、商品的名称、商品的卖点、商品的描述等字段中,哪一个字段内进行数据的匹配?如果使用某一个字段做搜索不合适,那么使用_all做搜索是否合适?也不合适,因为_all字段中可能包含图片,价格等字段。

假设,有一个字段,其中的内容包括(但不限于):商品类型名称、商品名称、商品卖点等字段的数据内容。是否可以在这个特殊的字段上进行数据搜索匹配?(我理解的就是融合多个字段为一个,理解为该商品的摘要信息。)

以keyword字段举例,它包括了category_name、product_name、sell_point三个字段的内容。

{
    
    
  "category_name" : "手机",
  "product_name" : "一加6T手机",
  "price" : 568800,
  "sell_point" : "国产Android手机",
  "tags": ["8G+128G", "256G可扩展"],
  "color" : "红色",
  "keyword" : "手机 一加6T手机 国产Android手机"
}

copy_to : 就是将多个字段,复制到一个字段中,实现一个多字段组合。copy_to可以解决cross fields搜索问题,在商业项目中,也用于解决搜索条件默认字段问题。 如果需要使用copy_to语法,则需要在定义index的时候,手工指定mapping映射策略。

例如

PUT /test_index07/_mapping
{
    
    
  "properties": {
    
    
    "provice": {
    
    
      "type": "text",
      "analyzer": "standard",
      "copy_to": "address"
    },
    "city": {
    
    
      "type": "text",
      "analyzer": "standard",
      "copy_to": "address"
    },
    "street": {
    
    
      "type": "text",
      "analyzer": "standard",
      "copy_to": "address"
    },
    "address": {
    
    
      "type": "text",
      "analyzer": "standard"
    }
  }
}

上述的mapping定义中,是新增了4个字段,分别是provice、city、street、address,其中provice、city、street三个字段的值,会自动复制到address字段中,实现一个字段的组合。那么在搜索地址的时候,就可以在address字段中做条件匹配,从而避免most fields策略导致的问题。在维护数据的时候,不需对address字段特殊的维护。因为address字段是一个组合字段,是由ES自动维护的。类似java代码中的推导属性。在存储的时候,未必存在,但是在逻辑上是一定存在的,因为address是由3个物理存在的属性province、city、street组成的。

5.9、近似匹配

给定一个短语,或者单词,匹配包含全部或者部分的内容。

举例(test_index06中remark字段没有go相关内容)

GET /test_index06/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": "developer go"
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vEjNUIcB14FuHovqKIyb",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "rod",
          "sex" : 1,
          "age" : 25,
          "book" : "Spring",
          "remark" : "java developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vUjNUIcB14FuHovqaYzA",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "rods",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "python developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vkjNUIcB14FuHovqnIz1",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "秀儿",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "v0jOUIcB14FuHovqTYw0",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "Tom",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      },
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "wEjOUIcB14FuHovqYYw0",
        "_score" : 0.24116206,
        "_source" : {
    
    
          "name" : "Amy",
          "sex" : 1,
          "age" : 26,
          "book" : "Spring",
          "remark" : "C developer"
        }
      }
    ]

举例

GET /test_index06/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "remark": "developerAA"
    }
  }
}

结果

"hits" : [ ]

如果需要的结果是有特殊要求,如:java developer 必须是一个完整的短语,不可分割;或document中的field内,包含的java 和developer 单词,且两个单词之间离的越近,相关度分数越高。那么这种特殊要求的搜索就是近似搜索。 搜索包括javb内容,搜索条件在java developer数据中搜索,或包括 j 搜索提示等数据近似搜索的一部分。如何上述特殊要求的搜索,使用match搜索语法就无法实现了。

5.10、match_phrase

短语搜索。就是搜索条件不分词。代表搜索条件不可分割。

举例(只会匹配出,java developer同时出现,并且连续的内容,即java developer为一个整体出现)

GET /test_index06/_search
{
    
    
  "query": {
    
    
    "match_phrase": {
    
    
      "remark": "java developer"
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index06",
        "_type" : "_doc",
        "_id" : "vEjNUIcB14FuHovqKIyb",
        "_score" : 1.7816072,
        "_source" : {
    
    
          "name" : "rod",
          "sex" : 1,
          "age" : 25,
          "book" : "Spring",
          "remark" : "java developer"
        }
      }
    ]

5.10.1match phrase原理 —— term position

ES是如何实现match phrase短语搜索的?其实在ES中,使用match phrase做搜索的时候,也是和match类似,首先对搜索条件进行分词-analyze。将搜索条件拆分成hello和world。既然是分词后再搜索,ES是如何实现短语搜索的?
这里涉及到了倒排索引的建立过程。在倒排索引建立的时候,ES会先对document数据进行分词,如:

查询如下句子是如何分词的

GET _analyze
{
    
    
  "text": "hello world, java spark",
  "analyzer": "standard"
}

结果

{
    
    
  "tokens" : [
    {
    
    
      "token" : "hello",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
    
    
      "token" : "world",
      "start_offset" : 6,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
    
    
      "token" : "java",
      "start_offset" : 13,
      "end_offset" : 17,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
    
    
      "token" : "spark",
      "start_offset" : 18,
      "end_offset" : 23,
      "type" : "<ALPHANUM>",
      "position" : 3
    }
  ]
}

从上述结果中,可以看到。ES在做分词的时候,除了将数据切分外,还会保留一个position。position代表的是这个词在整个数据中的下标。当ES执行match phrase搜索的时候,首先将搜索条件hello world分词为hello和world。然后在倒排索引中检索数据,如果hello和world都在某个document的某个field出现时,那么检查这两个匹配到的单词的position是否是连续的,如果是连续的,代表匹配成功,如果是不连续的,则匹配失败。

5.10.2match phrase搜索参数 – slop

场景举例:在做搜索操作的是,如果搜索参数是hello spark。而ES中存储的数据是hello world, java spark。那么使用match phrase则无法搜索到。在这个时候,可以使用match来解决这个问题。但是,当我们需要在搜索的结果中,做一个特殊的要求:hello和spark两个单词距离越近,document在结果集合中排序越靠前,这个时候再使用match则未必能得到想要的结果。

ES的搜索中,对match phrase提供了参数slop。slop代表match phrase短语搜索的时候,单词最多移动多少次,可以实现数据匹配。在所有匹配结果中,多个单词距离越近,相关度评分越高,排序越靠前。这种使用slop参数的match phrase搜索,就称为近似匹配(proximity search)

在Elasticsearch中,slop是指在查询语句中,词项之间可以允许的最大距离。它是一种模糊匹配(fuzzy matching)方式,用于解决用户输入错误或者数据存储时不准确的情况。
当我们进行一个带有slop参数的查询时,Elasticsearch将按照文档中出现的顺序检查查询语句中的每个词,并尝试找到它们之间最接近的匹配。如果两个词之间的距离小于或等于slop的值,则它们被认为是匹配的。
例子:
假设我们有以下三个文档:

{
    
    
  "id": 1,
  "title": "quick brown fox"
}
{
    
    
  "id": 2,
  "title": "quick red fox"
}
{
    
    
  "id": 3,
  "title": "slow brown dog"
}

我们希望查找包含“quick”和“fox”的文档,并且它们之间的最大距离为1。我们可以使用以下查询:

{
    
    
  "query": {
    
    
    "match_phrase": {
    
    
      "title": {
    
    
        "query": "quick fox",
        "slop": 1
      }
    }
  }
}

该查询将返回文档1和2,但不会返回文档3,因为“slow”和“brown”之间的距离大于1。(关于距离你可以去看下对应的position字段,即match phrase原理 —— term position下讲解的内容)

需要注意的是,slop值越大,匹配的结果会越多,但是精度也会降低。因此,在使用slop时,需要根据实际情况进行权衡。

5.11使用match和proximity search实现召回率和精准度平衡。

召回率:召回率就是搜索结果比率,如:索引A中有100个document,搜索时返回多少个document,就是召回率(recall)。
精准度:就是搜索结果的准确率,如:搜索条件为hello java,在搜索结果中尽可能让短语匹配和hello java离的近的结果排序靠前,就是精准度(precision)。
如果在搜索的时候,只使用match phrase语法,会导致召回率低下,因为搜索结果中必须包含短语(包括proximity search)。
如果在搜索的时候,只使用match语法,会导致精准度底下,因为搜索结果排序是根据相关度分数算法计算得到。
那么如果需要在结果中兼顾召回率和精准度的时候,就需要将match和proximity search混合使用,来得到搜索结果。

索引test_index08下所有内容

"hits" : {
    
    
    "total" : {
    
    
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "hello, java is very good, spark is also very good"
        }
      },
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "java and spark, development language "
        }
      },
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "Java Spark is a fast and general-purpose cluster computing system. It provides high-level APIs in Java, Scala, Python and R, and an optimized engine that supports general execution graphs."
        }
      },
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "6",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "java spark and, development language "
        }
      }
    ]

查询1

GET /test_index08/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "f": "java spark"
    }
  }
}

结果

"hits" : {
    
    
    "total" : {
    
    
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 0.28046143,
    "hits" : [
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 0.28046143,
        "_source" : {
    
    
          "f" : "java and spark, development language "
        }
      },
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "6",
        "_score" : 0.28046143,
        "_source" : {
    
    
          "f" : "java spark and, development language "
        }
      },
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.23111339,
        "_source" : {
    
    
          "f" : "hello, java is very good, spark is also very good"
        }
      },
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 0.16973917,
        "_source" : {
    
    
          "f" : "Java Spark is a fast and general-purpose cluster computing system. It provides high-level APIs in Java, Scala, Python and R, and an optimized engine that supports general execution graphs."
        }
      }
    ]

查询2

GET /test_index08/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    
          "match": {
    
    
            "f": "java spark"
          }
        }
      ],
      "should": [
        {
    
    
          "match_phrase": {
    
    
            "f": {
    
    
              "query": "java spark",
              "slop": 50
            }
          }
        }
      ]
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "6",
        "_score" : 0.56092286,
        "_source" : {
    
    
          "f" : "java spark and, development language "
        }
      },
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 0.4815065,
        "_source" : {
    
    
          "f" : "java and spark, development language "
        }
      },
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.32339638,
        "_source" : {
    
    
          "f" : "hello, java is very good, spark is also very good"
        }
      },
      {
    
    
        "_index" : "test_index08",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 0.30782324,
        "_source" : {
    
    
          "f" : "Java Spark is a fast and general-purpose cluster computing system. It provides high-level APIs in Java, Scala, Python and R, and an optimized engine that supports general execution graphs."
        }
      }
    ]

5.12前缀搜索 prefix search

使用前缀匹配实现搜索能力。通常针对keyword类型字段,也就是不分词的字段。

GET /test_a/_mapping
{
    
    
  "test_a" : {
    
    
    "mappings" : {
    
    
      "properties" : {
    
    
        "f" : {
    
    
          "type" : "text",
          "fields" : {
    
    
            "keyword" : {
    
    
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

所有数据如下

"hits" : [
      {
    
    
        "_index" : "test_a",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "hello, java is very good, spark is also very good"
        }
      },
      {
    
    
        "_index" : "test_a",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "java and spark, development language "
        }
      }
    ]

查询

GET /test_a/_search
{
    
    
  "query": {
    
    
    "prefix": {
    
    
      "f.keyword": {
    
    
        "value": "j"
      }
    }
  }
}

结果

    "hits" : [
      {
    
    
        "_index" : "test_a",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "java and spark, development language "
        }
      }
    ]

查询

GET /test_a/_search
{
    
    
  "query": {
    
    
    "prefix": {
    
    
      "f.keyword": {
    
    
        "value": "J"
      }
    }
  }
}

结果

"hits" : [ ]

针对前缀搜索,是对keyword类型字段而言。而keyword类型字段数据大小写敏感。前缀搜索效率比较低。前缀搜索不会计算相关度分数。前缀越短,效率越低。如果使用前缀搜索,建议使用长前缀。因为前缀搜索需要扫描完整的索引内容,所以前缀越长,相对效率越高。

5.13通配符搜索

通配符可以在倒排索引中使用,也可以在keyword类型字段中使用。
(性能很低,也是需要扫描完整的索引)
? :表示一个任意字符
*·:表示0~n个任意字符
查询

GET /test_a/_search
{
    
    
  "query": {
    
    
    "wildcard": {
    
    
      "f.keyword": {
    
    
        "value": "?e*o*"
      }
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_a",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "hello, java is very good, spark is also very good"
        }
      }
    ]

5.14正则搜索

在Elasticsearch中,regexp查询是一种使用正则表达式进行搜索的查询方式。它可以在指定字段上匹配满足正则表达式的文本。

ES支持正则表达式,可以在倒排索引或keyword类型字段中使用。
例如,假设我们有一个包含文档标题和内容的索引,并想要查找所有标题或内容中包含“Elastic”和“search”的文档。这时候,就可以使用regexp查询来实现:

{
    
    
    "query": {
    
    
        "regexp": {
    
    
            "_all": ".*Elastic.*search.*"
        }
    }
}

在上述例子中,“_all” 表示对所有字段进行搜索,".*"表示任意字符出现0次或多次。

需要注意的是,正则表达式的查询效率较低,因为它需要对每个文档的每个字段都进行逐一匹配。如果对性能要求较高,应该尽量避免使用正则表达式查询。

另外,Elasticsearch还支持设置正则表达式的参数,如ignore_case(是否忽略大小写),max_determinized_states(最大化自动机状态数),boost(权重系数),以及flags(正则表达式标志)。这些参数可以提高查询的准确性和灵活性。

再举例

GET /test_a/_search
{
    
    
  "query": {
    
    
    "regexp": {
    
    
      "f.keyword": "[A-z].+"
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_a",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "hello, java is very good, spark is also very good"
        }
      },
      {
    
    
        "_index" : "test_a",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
    
    
          "f" : "java and spark, development language "
        }
      }
    ]

性能很低,需要扫描完整索引,应该尽量避免在大型索引中使用

5.15搜索推荐

在Elasticsearch中,match_phrase_prefix查询是一种结合了match和prefix两种查询的组合查询。它可以用于匹配以指定前缀开头的短语。

具体来说,match_phrase_prefix查询会先将查询字符串拆分成一个个词项(term),然后使用前缀匹配算法进行匹配。通常情况下,match_phrase_prefix查询适用于需要匹配长短语但又希望支持前缀匹配的场景。
搜索推荐: search as your type, 搜索提示。如:索引中有若干数据以“hello”开头,那么在输入hello的时候,推荐相关信息。(类似百度输入框)

查询

GET /test_a/_search
{
    
    
  "query": {
    
    
    "match_phrase_prefix": {
    
    
      "f": {
    
    
        "query": "java s",
        "slop": 10,
        "max_expansions": 10
      }
    }
  }
}

结果

"hits" : [
      {
    
    
        "_index" : "test_a",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 0.28650534,
        "_source" : {
    
    
          "f" : "java and spark, development language "
        }
      },
      {
    
    
        "_index" : "test_a",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.11460209,
        "_source" : {
    
    
          "f" : "hello, java is very good, spark is also very good"
        }
      }
    ]

其原理和match phrase类似,是先使用match匹配term数据(java),然后在指定的slop移动次数范围内,前缀匹配(s),max_expansions是用于指定prefix最多匹配多少个term(单词),超过这个数量就不再匹配了。
这种语法的限制是,只有最后一个term会执行前缀搜索。
执行性能很差,最后一个term是需要扫描所有符合slop要求的倒排索引的term。
因为效率较低,如果必须使用,则一定要使用参数max_expansions。

5.16fuzzy模糊搜索技术

Elasticsearch中的fuzzy模糊搜索技术是一种基于编辑距离(Levenshtein Distance)算法的全文检索技术。它允许在查询时匹配相似但不完全相同的单词。具体来说,当我们进行一个fuzzy query时,Elasticsearch将会在索引中查找与查询字符串最接近的项。如果查询字符串中有一个拼写错误或者一个字符丢失,fuzzy search可以帮助我们找到那些被错误拼写的项。另外,fuzzy search也能够在搜索时匹配多个单词之间的相似性。在Elasticsearch中,我们可以使用fuzziness参数来设置模糊度,该参数表示最大编辑距离,即允许的最大差异数量。默认值为2,这意味着如果两个单词的编辑距离超过2,则它们将不会被匹配。我们可以通过增加或减少该参数来调整模糊度,以便更好地满足我们的需求。

搜索的时候,可能搜索条件文本输入错误,如:hello world -> hello word。这种拼写错误还是很常见的。fuzzy技术就是用于解决错误拼写的(在英文中很有效,在中文中几乎无效。)。其中fuzziness代表value的值word可以修改多少个字母来进行拼写错误的纠正(修改字母的数量包含字母变更,增加或减少字母。)。f代表要搜索的字段名称。
查询

GET /test_a/_search
{
    
    
  "query": {
    
    
    "fuzzy": {
    
    
      "f": {
    
    
        "value": "word",
        "fuzziness": 2
      }
    }
  }
}

结果

 "hits" : [
      {
    
    
        "_index" : "test_a",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.43569255,
        "_source" : {
    
    
          "f" : "hello, java is very good, spark is also very good"
        }
      }
    ]

  1. Zen Discovery 是 Elasticsearch 中的一种自动发现机制,它用于在分布式环境下管理节点的发现和连接。Zen Discovery 能够自动感知节点的加入和离开,并在必要时重新分配数据和重新平衡群集。
    Zen Discovery 机制包括以下几个方面:
    1.Ping 操作:每个节点会定期向其他节点发送 ping 请求,以确定其他节点是否还在运行。如果一个节点在一定时间内没有响应,那么它就被认为已经离开了群集。
    2.Unicast 发现:节点之间可以通过互相发送地址列表来进行发现。在这种方式下,节点需要知道其他节点的 IP 地址和端口号,才能够加入群集。当节点启动时,它会向配置的节点列表发送加入请求,如果请求成功,则会将该节点加入群集。
    3.Multicast 发现:在使用 Multicast 发现机制时,节点可以通过多播地址来进行发现。每个节点将自己的 IP 地址和端口号发布到特定的多播地址上,其他节点可以从该地址上接收到所有节点的信息,从而发现新的节点。这种方式下,节点可以更加灵活地管理群集,可以随时加入和离开群集。
    4.Master 选举:Zen Discovery 还包括了 Master 节点的选举机制,选举出的 Master 节点会负责协调群集中的各个节点。
    (当然,在某些情况下,可能需要手动指定主节点或禁用主节点竞选过程。可以通过在 elasticsearch.yml 配置文件中设置 node.master 参数来实现。如果将该参数设置为 false,则表示禁用该节点的主节点竞选功能;如果将该参数设置为 true,则表示该节点可以参与主节点竞选。默认情况下,所有节点都会参与主节点竞选,因此无需手动配置。) ↩︎

  2. 在 ElasticSearch 集群中,Master 节点维护的元数据包括以下信息:
    1.集群状态:保存了当前集群的状态,如运行状态、健康状态等。
    2.索引元数据:保存了所有索引的信息,例如字段映射、分片数量、副本数量、索引别名等。
    3.节点元数据:保存了所有节点的信息,例如 IP 地址、节点名称、可用空间、JVM 信息等。
    4.分片分配信息:保存了每个分片所属的节点信息、是否是主分片等。
    5.节点故障检测信息:保存了节点最近一次的心跳信息和下线时间,用于检测节点是否失效。
    这些元数据都存储在 Master 节点的内存中,并与其他节点进行同步,以确保集群中所有节点都拥有相同的元数据视图。通过 Master 节点维护这些元数据,可以实现集群管理和协调,确保数据的高可用性、一致性和完整性。 ↩︎

猜你喜欢

转载自blog.csdn.net/xiaobai_july/article/details/131047356
今日推荐