柚子快報激活碼778899分享:分布式 Kafka 線上問題
柚子快報激活碼778899分享:分布式 Kafka 線上問題
訂單寬表數(shù)據(jù)不同步
事情的起因是用戶在 app 上查不到訂單了,而訂單數(shù)據(jù)是從 mysql 的 order_search 表查詢的,order_search 表的數(shù)據(jù)是從 oracle 的 order 表同步過來的,查不到說明同步有問題
首先重啟,同步數(shù)據(jù),問題解決,然后查找原因。首先看日志,有如下兩種情況
有的容器消費消息的日志正常打印有的容器很長時間沒有消費消息的日志(看著像是消息丟失,找運維確認后明確發(fā)送沒問題,只能是消費的問題)
接著看容器的狀況
查看了應用重啟前各個容器的 CPU 和內(nèi)存情況,發(fā)現(xiàn)并不均勻,有如下三種情況
CPU一直很高(內(nèi)存穩(wěn)定)CPU和內(nèi)存一直穩(wěn)定上升CPU一直很低(內(nèi)存穩(wěn)定)
看監(jiān)控發(fā)現(xiàn)消息在分區(qū)中分布的也不均衡
問題排查
接著就按照如下現(xiàn)象來進行排查問題
為什么消息發(fā)送不均衡為什么有的容器CPU一直很高,有的一直很低,有的持續(xù)升高(CPU飆高的機器,內(nèi)存也不斷上漲)
為什么會出現(xiàn)這些現(xiàn)象?
producer發(fā)送消息和consumer消費消息都有對應的負載均衡策略,既然消息發(fā)送不均衡,只需要看producer的負載均衡策略即可
producer的負載均衡實現(xiàn)類為 DefaultPartitioner,具體實現(xiàn)為
如果 key 為 null:消息將以輪詢的方式,在所有可用分區(qū)中分別寫入消息如果 key 不為 null:對 Key 值進行 Hash 計算,從所有分區(qū)中根據(jù) Key 的 Hash 值計算出一個分區(qū)號;擁有相同 Key 值的消息被寫入同一個分區(qū);
所以推測發(fā)送的消息指定了key,看消費日志確定了猜想,key的名字為表名
這樣就明確了,同一張表的數(shù)據(jù)只會被發(fā)送到同一個分區(qū),同一個分區(qū)的數(shù)據(jù)只能被一個 Consumer 消費
接著我們查到 CPU 一直比較高的容器,消費的是合同表的數(shù)據(jù),合同表的數(shù)據(jù)變更比較頻繁,所以CPU比較高
而 CPU 持續(xù)飆升的容器,消費的是訂單表的數(shù)據(jù)。
接著就是排查消費訂單表的容器為什么CPU和內(nèi)存持續(xù)飆升
首先用生成 dump 文件,用 Eclipse Memory Analyzer 分析一下看是否發(fā)生了內(nèi)存泄露
點擊 Leak Supects 查看內(nèi)存泄漏分析
總共使用了110MB內(nèi)存,Thread線程占用了29M,總共創(chuàng)建了2686個線程,看一下這些線程是哪些?
線程數(shù)量最多的線程名字為datasync-execuotr-1,到代碼中查看是否有類似線程
每消費一次訂單表的數(shù)據(jù),調(diào)用一次 asyncConfig.getAsyncExecutor()方法,就會新創(chuàng)建一個線程池,核心線程數(shù)為10,不斷創(chuàng)建線程導致內(nèi)存和 CPU 不斷飆升,消息不能正常消費,后續(xù)消費消息改成使用一個固定的線程池后,消息正常消費
柚子快報激活碼778899分享:分布式 Kafka 線上問題
好文閱讀
本文內(nèi)容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權,聯(lián)系刪除。