ElasticSearch的REST APIs - 搜索API

ES 7.7 官方文檔

除了 Explain Api,大多數的搜索api都支持多索引(multi-index)

主要內容:

  • 路由 (Routing)
  • 自適應副本選擇策略 (Adaptive Replica Selection)
  • 統計分組 (Stats Groups)
  • 全局搜索超時時間 (Global Search Timeout)
  • 搜索取消策略 (Search Cancellation)
  • 搜索的併發和並行 (Search concurrency and parallelism)

路由 (Routing)

在執行搜索時,ES將根據自適應副本選擇(adaptive replica selection, 下面會講到 )公式選擇數據的“最佳”副本。 也可以通過參數"路由(routing)"來控制將在哪個分片上搜索。 例如,在索引twitter中插入/更新文檔時,路由的值可以是用戶名:

# 先刪除之前的測試的數據
DELETE /twitter

# 新增doc_id=1的文檔, 指定路由的值:
POST /twitter/_doc/1?routing=kimchy
{
  "user": "kimchy",
  "post_date": "2009-11-15T14:12:12",
  "message": "trying out Elasticsearch"
}
# 新增doc_id=2, 不指定路由
POST /twitter/_doc/2
{
  "user": "kimchy",
  "post_date": "2009-11-15T14:12:12",
  "message": "trying out Elasticsearch2"
}

獲取數據看一下:

GET /twitter/_doc/1

返回結果是:

{
  "_index" : "twitter",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "_routing" : "kimchy",  # 這裏多了一個 _routing 的值
  "found" : true,
  "_source" : {
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
  }
}

在這種情況下,如果我們只想在索引twitter上搜索一個特定的用戶,我們可以指定路由,結果是隻命中(檢索)相關的分片:

POST /twitter/_search?routing=kimchy
{
  "query": {
    "term": {
      "user": "kimchy"
    }
  }
}

官方文檔的查詢條件用了bool模式, 又用了query_string, 不適合入門閱讀

路由參數(_routing)可以使用逗號分割的字符串列表,這將命中與路由值相匹配的多個分片。

注意: someone says 只要在索引時候加入路由字段,那麼在以後的get,delete,update操作中都必須使用路由字段,否則會出現問題。

在執行上面的查詢時, 已經指定了路由, 但是仍然匹配了之前插入的2個文檔,但是第二個文檔明明沒有指定路由啊? 這可能與我的主分片數量是1有關。所有的數據都在一個分片上, 所以查詢的時候該分片上的數據都會被檢索到,默認的分片定位公式:shard_num = hash(\_routing) % num_primary_shards

自適應副本選擇 (Adaptive Replica Selection)

默認情況下,ES將使用所謂的自適應副本選擇策略。 這允許協調節點(coordinating node)根據以下標準將請求發送至被視爲“最佳”的副本:

  • 協調節點和包含副本的節點在之前的請求中的響應時間 (Response time of past requests between the coordinating node and the node containing the copy of the data)

  • 之前在包含數據的節點上執行搜索請求所花費的時間 (Time past search requests took to execute on the node containing the data)

  • 包含數據的節點上的搜索線程池的隊列大小 (The queue size of the search threadpool on the node containing the data)

簡單點說就是, 它會以服務器的響應時間和請求隊列作爲參考指標,智能的選擇副本進行查詢,儘可能的縮短請求響應時間。

不過,可以通過動態修改集羣的設置cluster.routing.use_adaptive_replica_selectionfalse來關閉,默認值是true

# 查詢集羣的所有設置
GET /_cluster/settings?include_defaults=true
# 查詢routing的設置
GET /_cluster/settings?&filter_path=transient.cluster.routing.*

# 關閉自適應副本選擇
PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.use_adaptive_replica_selection": false
  }
}

# 還原設置
PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.use_adaptive_replica_selection": null
  }
}

如果關閉了自適應副本選擇, 將在數據的所有副本(主分片和副本分片)之間以輪詢方式發送搜索請求到索引/索引分片。

統計分組 (Stats Groups)

搜索可以與統計分組關聯,後者維護每個組的統計聚合。 稍後可以使用索引的stats API進行檢索。 例如,下面是一個搜索請求,它將請求與兩個不同的組關聯起來:

POST /_search
{
  "query": {
    "match_all": {}
  },
  "stats": [ "group1", "group2" ]
}

全局搜索超時時間 (Global Search Timeout)

作爲搜索請求的body的一部分,單個搜索可以設置一個超時時間。 由於搜索請求可以來自多個資源,ES爲全局搜索的超時時間提供了一個動態的集羣級別(cluster-level)的設置,該設置適用於所有沒有在請求body中設置超時時間的搜索請求。 這些請求將在指定時間後使用下面的搜索取消(Search Cancellation)中描述的機制而被取消。因此,同樣適用於超時響應的警告。

搜索取消 (Search Cancellation)

可以使用標準的任務取消(task cancellation)機制來取消搜索,也可以在客戶端關閉用於執行請求的http連接時自動取消搜索。當請求超時或中止時,發送請求的http客戶端必須關閉連接。

搜索的併發和並行 (Search concurrency and parallelism)

默認情況下,ES不會根據請求命中的碎片數量拒絕任何搜索請求。 雖然ES將優化協調節點(coordinating node)上的搜索命令的執行,但大量的分片可能會對CPU和內存產生重大影響。 以更少、更大的分片的方式組織數據通常是一個更好的主意。 如果您想配置軟限制(soft limit),可以修改集羣設置action.search.shard_count以拒絕命中過多碎片的搜索請求。

last updated at 2021/11/9 23:06

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章