1、震盪問題
搜索同一 query,結果ES返回的順序卻不盡相同,可能會有兩個原因導致此問題發生:
- 這就是請求輪詢到不同分片,而未設置排序條件,相同相關性評分情況下,是按照所在 segment 中 lucene id 來排序的,相同數據的不同備份之間該 id 是不能保證一致的,故造成結果震盪問題。
- 主節點 和 副本 數據沒能及時同步,導致使用相同排序情況下排序結果會有略微的震盪
一般解決方案就是在搜索策略中設置一些搜索參數來解決此類問題,一般會有以下 9 中情況可參考:
- `_primary`:發送到集群的相關操作請求只會在主分片上執行。
- `_primary_first`:指查詢會先在主分片中查詢,如果主分片找不到(掛了),就會在副本中查詢。
- `_replica`:發送到集群的相關操作請求只會在副本上執行。
- `_replica_first`:指查詢會先在副本中查詢,如果副本找不到(掛了),就會在主分片中查詢。
- `_local`:指查詢操作會優先在本地節點有的分片中查詢,沒有的話再在其它節點查詢。
- `_prefer_nodes:abc, xyz`:在提供的節點上優先執行(在這種情況下為'abc'或'xyz')
- `_shards: 2,3`:限制操作到指定的分片(2 和 3)。這個偏好可以與其他偏好組合,但必須首先出現:_shards:2, 3 | _primary`
- `_only_nodes: node1,node2`:指在指定 id 的節點里面進行查詢,如果該節點只有要查詢索引的部分分片,就只在這部分分片中查找,不同節點之間用 “,” 分隔。
- custom(自定義):注意自定義的 preference 參數不能以下划線 "_" 開頭。
當 preference 為自定義時,即該參數不為空,且開頭不以 “下划線” 開頭時,特別注意:如果以用戶query作為自定義preference時,一定要處理以下划線開頭的情況,這種情況下如果不屬於以上8種情況,則會拋出異常。
我們在實際情況中解決此類問題一般會采用兩種方案:
- 使用 preference = '_primary_first' 參數來進行搜索,這樣優先使用主節點進行搜索,當主節點掛掉后會打到副本進行搜索。
- 缺點:會給 主節點 造成很大的壓力,因為 index 也會先索引主節點后通過批量打包的方式快速同步,而 search 又都集中在主節點,會造成主節點 cpu 升高,內存增加。
- 使用 preference = custom 參數來進行搜索,這樣在 preference 后拼接一個用戶 uid 或 openudid,這樣就能保證每個人使用相同的搜索詞重復搜索最終展現的結果是一致的。
2、排查命令
1、熱點線程,即最耗 cpu 或 內存 對應的線程,且起對應執行的線程棧
GET /_nodes/hot_threads
2、指定某節點的熱點線程
GET _nodes/MFW10.133.1.30-9202/hot_threads
3、查看當前 es 集群所有節點線程池狀況
GET /_cat/thread_pool?pretty
4、查看當前 es 集群所有節點指定類型線程池狀況以及格式化詳情,例如:search 類型
GET /_cat/thread_pool/search?v&h=ip,port,type,name,active,rejected,completed,size,queue,queue_size
5、查看當前 es 集群所有節點指定類型線程池狀況以及格式化詳情,例如:index 類型
GET /_cat/thread_pool/index?v&h=ip,port,type,name,active,rejected,completed,size,queue,queue_size