作者簡介
藍寅,開源分布式中間件DBLE項目負責人;持續專注于數據庫方面的技術, 始終在一線從事開發;對數據復制,讀寫分離,分庫分表的有深入的理解與實踐。
問題起因:
用benchmarksql_for_mysql對原生MyCat-1.6.1和DBLE-2.17.07版做性能測試對比,發現DBLE性能只到原生版MyCat的70%左右。
問題分析過程:
分析過程主要有以下內容:包括現象,收集數據,分析猜測原因,驗證猜測的方式來進行。
開源分布式中間件DBLE:
社區官網,獲取DBLE快速入門指南及最新資訊:
https://opensource.actionsky.com
GitHub主頁,查看官方文檔:
https://github.com/actiontech...
社區技術交流群,迅速獲取官方支持:
QQ群:669663113
**1.分析瓶頸
1.1 先對兩者進行一個CPU占用的堆棧分析**
通過對CPU火焰圖的比較,發現DBLE用在純排序上的CPU占用在15%以上,而MyCat在排序上沒有看到明顯的CPU占用。( 復盤時的思考:這里有明顯的可疑之處,應當及早觀察兩者是否公平)
1.2 首先猜測可能的原因
a.由于MyCat對以下這條用例實現有bug:具體方式是直接原句下發SQL到節點,收到各個節點的結果后直接做加法;而DBLE則是改寫為select distinct s_i_id 收集全部結果集,然后在中間件做去重和統計的工作。所以兩者在這個case上的對比是不公平的。
b.排序本身算法選擇的問題
1.3 對猜測原因的驗證
a.去除有bug的case,并未看到性能有提升,而且考慮這條用例在所有用例出現的概率只有4%,涉及到的數據也不多,所以應該不是性能問題的主因。
b.去除有排序的case,看到兩者性能接近,確定是排序的問題。
2.猜測原因
2.1 猜測一:源碼實現原因
2.1.1 猜測描述
梳理DBLE源碼排序邏輯的實現細節,是多路歸并的排序,理論上是最優選擇。
實際上具體的實現上有可優化的空間,如下圖, N個數的K路排序的初始化值理論最優復雜度是O(N),而這里變成了O(NlogK2) 。
2.1.2 驗證猜測
為了快速將排序的因素排除,將cmp函數直接返回1再次做測試。結果提升了10%的性能,所以雖然cmp是有性能問題,但導致性能如此大還有其他原因。(復盤:新版本已優化此處10%的性能差異)
2.2 猜測二:回到排序SQL
查看B-SQL源碼,有3個排序SQL,其中有2個排序SQL的排序列不在select 項中,這本來應該引發MyCat的bug的,但我們在返回集和抓包中都沒有發現。再仔細閱讀源碼,原來B-SQL通過hard code的方式使得壓力永遠跑不到這兩個代碼路徑上,這樣我們又排除了2個干擾因素,問題集中到剩下的那個排序上了。
將排序除去,64數據量,64并發,DBLE的性能是MyCat的96%。
證明確實和排序有關。
3.分析多并發壓力排序性能的原因
3.1 猜測排序算法在特殊場景下的適用性
3.1.1 猜測描述
由于MyCat排序采用的是timsort, 時間復雜度的可能最優是O(n)。
而DBLE的多路歸并排序在B-SQL這個場景下時間復雜度最差情況是O(n*(k-1)).
猜測timSort排序在B-SQL多并發場景下可能會優于多路歸并。
3.1.2 驗證猜測
用B-SQL壓測并統計函數調用次數。
結論:
在B-SQL場景下:
兩者平均每個排序調用的cmp函數的次數并沒有發生明顯的異化
每個排序cmp次數雖然沒有大的差異,但總的調用次數卻相差很大,DBLE大約是MyCat的5倍
4. 分析DBLE排序時cmp函數次數調用多的原因
問題集中在了為什么DBLE會有更多次的比較函數調用。
4.1 驗證壓力下發的SQL是否與cmp函數調用相符是否下發的SQL就不公平
4.1.1收集數據
用抓包的方式分別抓取B-SQL發給MyCat和DBLE的包,結果發現 DBLE的所有SQL中排序這條SQL的發生次數是MyCat的10倍左右。
再次用yourkit查看調用次數和CPU分布驗證,發現調用次數確實符合抓包的結論,CPU分布也是DBLE分了大量的時間用于排序,而MyCat對排序的分配幾乎可以忽略。這也與最一開始的火焰圖結論一樣。
用wireshark分析DBLE抓包結果,發現某些連接執行一段時間之后大量的重復出現排序+delete的query請求直到壓力結束,舉例如下圖。
4.1.2 分析原因
分析B-SQL源碼這里發現只有delete的數據為0才會引發死循環。
4.1.3 驗證測試
在引發死循環的原因找到之前,先修改代碼驗證測試。無論result是否是0都設置newOrderRemoved=true使得B-SQL跳出死循環。
驗證測試,DBLE性能終于符合預期,變為MyCat的105%。
至此,B-SQL有排序引發DBLE性能下降的原因找到了,某種場景下B-SQL對DBLE執行delete,影響行數為0,導致此時會有死循環,發送了大量排序請求,嚴重降低了DBLE性能,并且并發壓力越大越容易出現,但也有一定幾率不會觸發。
5.分析哪種場景下delete行數為0
5.1隔離級別測試
因為對隔離級別并不熟悉,花了很長時間才想到原因,在MySQL上做了一個實驗:
也就是說,在并發情況下確實有可能有死循環出現。
5.2 分析為什么只有在DBLE上有這個問題而在MyCat上沒有這個問題
原因是DBLE和MyCat的默認隔離級別都是REPEATED_READ,但MyCat的實現有bug,除非客戶端顯式使用set語句,MyCat后端連接使用的隔離級別都是下屬結點上的默認隔離級別;而DBLE會在獲取后端連接后同步上下文,使得session級別的隔離級別和DBLE配置相同。而后端的四個結點中除了1臺是REPEATED_READ,其他三個結點都是READ_COMMITTED。這樣同樣的并發條件,DBLE100%會觸發,而MyCat只有25%的概率觸發。
5.3 驗證測試
將DBLE上的配置添加
性能比是1:0.75.符合期望,性能原因全部找到。
6. 吐槽
最后吐槽一下B-SQL,找了官方的B-SQL4.1版和5.0版,4.1版并未對此情況做任何改進,仍有可能陷入死循環影響測試。
而5.0的對應代碼處有這么一段注釋,不知道PGSQL是否這里真的會觸發異常,但MySQL并不會觸發異常,仍有可能陷入死循環。
7.性能原因回顧
1.cmp函數時候初始化值的問題,影響部分性能,非主要性能瓶頸,新版本已改進。
2.同時觸發了MyCat和B-SQL的兩個bug,導致測試的性能數據負負得正;
Mycat bug:配置的隔離級別不生效問題
B-SQL bug:RR隔離級別下,delete死循環問題
需要將MySQL結點都改為READ_COMMITED,再將配置改為
8.收獲
1.測試環境的搭建無論是配置參數還是各個節點的狀態都要同步,保證公平。
2.性能分析工具的使用。
3.性能測試可能一次的結果具有偶然性,需要多次驗證。
4.當有矛盾的結論時候,可能就快接近問題的真相了,需要持續關注。
開源分布式中間件DBLE
社區官網: https://opensource.actionsky....
GitHub主頁: https://github.com/actiontech...
技術交流群:669663113
開源數據傳輸中間件DTLE
社區官網: https://opensource.actionsky....
GitHub主頁: https://github.com/actiontech...
技術交流群:852990221
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/17951.html
摘要:往期精選社區投稿和跨分片查詢結果不一致案例分析自定義拆分算法配置解析使用指南開源分布式中間件快速入門指南配置解析社區活動如何獲取全國場主題大會免費入場券 DBLE是基于開源項目MyCat發展的企業級開源分布式中間件,適用于高并發及TB級海量數據處理場景;江湖人送外號 MyCat Plus;其簡單穩定,持續維護,良好的社區環境和廣大的群眾基礎使DBLE得到了社區的大力支持。 DBLE項目...
閱讀 2443·2021-11-19 09:59
閱讀 1970·2019-08-30 15:55
閱讀 929·2019-08-29 13:30
閱讀 1330·2019-08-26 10:18
閱讀 3081·2019-08-23 18:36
閱讀 2382·2019-08-23 18:25
閱讀 1155·2019-08-23 18:07
閱讀 430·2019-08-23 17:15