
于是就有了這篇文章。
2、hot_threads 幹什麼的?能吃嗎?
實戰業務場景中,當我們遇到叢集響應比平常慢且 CPU 使用率高時,我們需要做問題排查,找到根因叢集才能恢複“如絲般流暢"。
Elasticsearch提供了監視熱線程的能力, 以便能夠了解問題所在。
在 Java 中,熱點線程(hot threads)是占用大量 CPU 且執行時間很長的線程。
排查如上問題最常用的 API 就是:hot_threads API。
GET /_nodes/hot_threads
GET /_nodes/<node_id>/hot_threads
Hot Threads API 從CPU 端傳回有關 ElasticSearch 代碼的哪些部分是熱點或傳回目前叢集因某些原因而被卡在何處的資訊。
3、hot_threads 支援的參數清單
ignore_idle_threads
(可選,布爾值)
如果為true,則會過濾掉已知的空閑線程(例如,在套接字選擇中等待,或從空隊列中擷取任務)。
預設為true。
interval
(可選,時間機關)執行熱點線程的采樣間隔。
預設為500毫秒。
snapshots
(可選,整數)它是要擷取的堆棧跟蹤(在特定時間點嵌套的方法調用序列)數量。
預設為10。
threads
(可選,整數)檢視由type參數确定的資訊,ElasticSearch将采用指定數量的最“熱門”線程。
最“熱門”的線程,往往就是我們的問題所在。
預設為3。也就是傳回TOP 3 熱點線程。
master_timeout
(可選,時間機關)指定等待連接配接到主節點的時間段。
如果在逾時到期之前未收到任何響應,則請求将失敗并傳回錯誤。
預設為30秒。
timeout
(可選,時間機關)指定等待響應的時間段。
type
(可選,字元串)要采樣的類型。
可用的選項是:
1)block ——線程阻塞狀态的時間。
2)cpu ——線程占據CPU時間。
3)wait ——線程等待狀态的時間。
如果您想進一步了解線程狀态,請參見:
https://docs.oracle.com/javase/6/docs/api/java/lang/Thread.State.html預設為:cpu。
4、hot_threads 實戰舉例
結合剛才的參數,實戰一把。以下指令将告訴ElasticSearch以一秒鐘的間隔檢查處于 WAITING 狀态的線程。
GET /_nodes/hot_threads?type=wait&interval=1s
5、hot_threads API 原理
與其他傳回 JSON 結果的 API 不同,Hot Threads API傳回格式化的文本,你可以在其中區分幾個部分。這也是文章開頭說的“傳回一堆堆棧看不懂”的原因。
在看傳回堆棧結果資訊之前,先看一些有關Hot Threads API背後的邏輯原理知識。
ElasticSearch 接收所有正在運作的線程,并收集有關每個線程所花費的 CPU 時間,特定線程被阻塞或處于等待狀态的次數,被阻塞或處于等待狀态的時間等各種資訊。
然後等待特定的時間間隔 interval(由時間間隔參數指定)後,ElasticSearch 再次收集相同的資訊,并根據運作的時間(降序)對熱點線程進行排序。
注意,上述時間是針對 type 參數指定的給定操作類型統計的。
之後,由 ElasticSearch 分析前 N 個線程(其中 N 是由線程參數 threads 指定的線程數)。
ElasticSearch 所做的是每隔幾毫秒就會捕獲線程堆棧跟蹤的快照(快照數量由快照參數 snapshot 指定)。
最終:對堆棧跟蹤進行分組以可視化展示線程狀态的變化,就是我們看到的執行API 傳回的結果資訊。
以上的内容,把 hot_threads API 的相關參數串聯起來,相信讀到這裡你會對 hot_threads 有大緻的了解。
還是不了解傳回結果怎麼辦?别着急,下面就解讀了。
6、hot_threads API 傳回結果
現在,終于到了 hot_threads APi 傳回結果部分。
建議放大圖檔檢視。
6.1 響應的第一部分
包含節點的基本資訊。
如下所示:
{Data-(110.188)-1}{67A1DwgCR_eM5eFS-6MR1Q}{qTPWEpF-Q4GTZIlWr3qUqA}{10.6.110.188}{10.6.110.188:9301}{dil}
通過如上資訊,我們可以知道 Elasticsearch 的熱點線程所在節點資訊,當熱線程API調用涉及多個節點時,這很友善。
6.2 響應的第二部分
接下來的幾行可以分為幾個子部分。
6.2.1 開頭部分拆解
78.4% (391.7ms out of 500ms) cpu usage by thread 'elasticsearch[Data-(110.188)-1][search][T#38]'
[search] ——代表 search線程操作。
78.4% —— 代表名為 search 的線程在完成統計時占據了所有CPU時間的78.4%。
cpu usage ——訓示我們正在使用 cpu 的類型,目前是線程 CPU的使用率。
block usage —— 處于阻塞狀态的線程的阻塞使用率。
wait usage —— 處于等待狀态的線程的等待使用率。
注意:線程名稱在這裡非常重要,這是因為它,我們可以猜測 ElasticSearch 的哪些功能會導緻問題。
上面的示例,我們可以初步得出是 search 線程占據了大量的CPU。
實戰中,除了 search 還有其他的線程,列舉如下:
recovery_stream —— 用于恢複子產品事件
cache —— 用于緩存事件
merge —— 用于段合并線程
index ——用于資料索引(寫入)線程 等等。
6.2.2 第二子部分拆解
Hot Threads API響應的下一部分是從以下資訊開始的部分:
5/10 snapshots sharing following 35 elements
如上展示了:先前的線程資訊将伴随堆棧跟蹤資訊。
在我們的示例中,
5/10 —— 表示拍攝的 5 個快照具有相同的堆棧跟蹤資訊。
這在大多數情況下意味着對于目前線程,檢查時間有一半都花在 ElasticSearch 代碼的同一部分中。
7、小結
Elasticsearch CPU 使用率高的排查一般都會借助:hot_thread API 或者 top jstack 定位線程堆棧。
本文就 hot_thread API 應用場景、使用、傳回結果進行了詳細解讀,希望對你有幫助。
歡迎留言說一下你對熱點線程的了解或者你的實踐經驗。
如果,你有開頭類似的問題,查官方文檔也梳理不清楚,也歡迎你留言,根據留言點贊量,我們會寫文章專門梳理。
和你一起,死磕 Elasticsearch!
參考:
《Mastering Elasticsearch》
《Elasticsearch 7.0 bookbook》
https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-hot-threads.html