一况毅、現(xiàn)象
每天夜里12點(diǎn)準(zhǔn)時(shí)出現(xiàn)延遲告警恤批,查看canal的監(jiān)控指標(biāo)异吻,delay指標(biāo)延遲在5-10分鐘,blocking指標(biāo)中的sink喜庞、dump趨于100%诀浪,同時(shí)canal服務(wù)的cpu及memeory很穩(wěn)定40%左右。
二延都、分析
被告警吵的實(shí)在受不了了雷猪,于是下定決心解決這個(gè)問題。首先花了點(diǎn)時(shí)間研究了一下canal源碼晰房,整個(gè)canal的解析流程大致分成4步春宣。
binlog dump -- parse -- sink -- kafka(rocketmq)
目前從指標(biāo)分析酵颁,dump及sink都阻塞了,所以判斷出是發(fā)送kafka能力沒跟上月帝,(出問題的canal是kafka模式啟動(dòng)的)。
三幽污、調(diào)優(yōu)的過程
找到可能的原因之后嚷辅,就開始仔細(xì)地看了一下canal的kafka發(fā)送邏輯。在這個(gè)過程中距误,看到了kafka的幾個(gè)參數(shù)簸搞,canal的默認(rèn)值如下
1、kafka.acks = all,這里的ack有3個(gè)選項(xiàng)准潭,0趁俊、1、all 刑然。all是要等topic的某個(gè)分區(qū)的所有副本都同步完數(shù)據(jù)后才會(huì)給客戶端響應(yīng)寺擂,1只要topic的leader分區(qū)接收到數(shù)據(jù)就會(huì)給客戶端響應(yīng),0是只要數(shù)據(jù)發(fā)出去了會(huì)立即返回泼掠,不會(huì)等待分區(qū)是否接收到數(shù)據(jù)怔软。因此,首先我把這個(gè)值改成了1择镇,為什么選擇改成1挡逼,是因?yàn)?在kafka集群穩(wěn)定的情況下是能夠保證binlog的順序性的。
結(jié)果:改完之后腻豌,發(fā)現(xiàn)效果不明顯家坎,依然有延遲(卒)
2、kafka.batch.size, 這個(gè)值是控制kafka批量消息的大小的吝梅,默認(rèn)是16384 (16K)虱疏,這里要更具實(shí)際的binlog event對象的值合理修改,這個(gè)值的修改我也是觀察了好久數(shù)據(jù)才定位到問題的憔涉。我們的event對象大小是45K订框,所以默認(rèn)的16K壓根就沒起到批量發(fā)送的作用,沒解析一個(gè)event對象就會(huì)發(fā)送兜叨,導(dǎo)致吞吐量上不去穿扳,于是我改成了 921600 (900K),注意這個(gè)值不能超過broker端的最大發(fā)送字節(jié)(message.max.bytes)
結(jié)果:改完之后,發(fā)現(xiàn)效果不明顯国旷,依然有延遲(卒)
3矛物、kafka.linger.ms,批量發(fā)送消息的最大等待時(shí)長跪但,這里我改成了100履羞,需要自己判斷
結(jié)果:改完之后,效果依然不明顯,延遲依舊(卒)
到這里就有點(diǎn)抓狂了忆首,因?yàn)橹荒茉谝估矧?yàn)證爱榔,一等就是一天,修改這些值已經(jīng)搞了快一周了糙及,老板一直催要結(jié)果详幽。害,只能接著觀察數(shù)據(jù)浸锨,接著干唇聘。
4、canal.mq.canalBatchSize柱搜,最后終于找到了這個(gè)參數(shù)迟郎,這個(gè)參數(shù)不是kafka相關(guān)的,這個(gè)是從環(huán)形隊(duì)列中批量處理的event數(shù)量聪蘸,本來我以為這個(gè)是指的event數(shù)量宪肖,結(jié)果看完源碼才發(fā)現(xiàn),canal的內(nèi)存隊(duì)列是通過內(nèi)存大小限制的宇姚,默認(rèn)這個(gè)值是50匈庭,其實(shí)不是拿50個(gè)event對象,而是拿50K的數(shù)量浑劳,如果event很大阱持,每次就只取很少的量,我的event 45K魔熏,所以每次都只取一個(gè)對象衷咽,更本沒法提高吞吐量。根據(jù)高峰期的寫入峰值蒜绽,峰值大概3M/s镶骗,于是我把這個(gè)canal.mq.canalBatchSize設(shè)置成了4500,也就是(4500K)躲雅。
當(dāng)晚就懷著一顆激動(dòng)地心鼎姊,眼睛一眨不眨地盯著canal監(jiān)控。下面是監(jiān)控截圖相赁。3307是優(yōu)化了的相寇,其他幾個(gè)沒有優(yōu)化。
3307的blocking明顯降低
3307的delay明顯降低
完美钮科,竣工唤衫,睡覺!