mns是阿裡雲提供的開箱即用的 隊列服務,容易上手。當資料量很大,特别是做大批量資料同步時,很多人就會遇到性能瓶頸。
下面就給大家介紹下,提升單機mns client性能的幾種方法。
首先考慮的是網絡環境。
使用内網endpoint吧,不細說。
其次,利用多線程提升并發度。
嗯。。。100個線程,tps怎麼也得10+倍了吧。但是沒卵用,多線程似乎失效?
so翻了翻源碼,當看到mns底層使用的http reactor子產品,defaultconnectingioreactor、abstractmultiworkerioreactor時,問題逐漸變得明朗起來。
原來事情的真相是這樣:
mns client 是個singleton。官網的例子用這個singleton搞出了一大堆cloudqueue,想要發揮多線程的魔力。
其實看圖可知,不論搞出多少cloudqueue,下面共用的是io 線程池和連接配接池,而它們才是真正幹活的啊。
這種感覺就好比,一家飯店,找了大堆服務員在門口拉客,但後面就一個廚子。
是以,單純增加cloudqueue沒有用,相反,由于cloudqueue放任務到io池裡都是記憶體操作是很快的,并不要很多線程。
道理明白後,要做的事情就簡單了,多線程的正确姿勢是:增多worker。
再次,批量處理。像kafka、flume等都是加大batch提升吞吐量的。
mns client sdk也有類似的api,如
激動地給batch設了個100,run,服務端異常,50,異常,20異常。說好的batch呢,難道是個假api?
當試到16這個magic number時,終于成功了。翻看下官網文檔,也沒有對magic number說明。
簡單測試了下,4core8g,單條消息1k byte。
4線程: total send message 16000, cost 5681, tps 2816
8線程: total send message 16000, cost 4603, tps 3475
16線程:total send message 16000, cost 1973, tps 8109
敬告:對于那些一不小心就超過上面測試資料的同學,歡迎加入橙鷹資料(據說是杭州一個很牛x很低調的大資料公司)。
btw, 優化的意義。下面是阿裡雲另一款高性能mq産品,
控制台建立mns隊列時,pollingwaitseconds預設值是0。
這個值必須要設定
因為mns會按請求次數收費。依稀記得那個晚上,幾w塊就灰飛煙滅了。推薦設10~30。
使用過kafka,metaq的同學知道,消息消費掉後,會commit offset告訴broker。
不同的地方是,在使用mns時,為了不丢資料,通常是消費成功後,手動删除消息。
如果消息被消費後,超過了visibilitytimeout,再去删除這個消息,就會遇到喜聞樂見的not found錯誤。
常會有這種情景,給隊列發送了很多消息,想把消息全部删除後重新灌批資料,但是由于沒有一鍵清除的方法,使用者會删除該隊列,然後重建個同名的隊列。
這樣産生的問題是,原來的mns client找不到該隊列了,必須要重新開機。