深度分析 | MyCat與DBLE的對比性能調優

問題原由:mysql


用benchmarksql_for_mysql對原生MyCat-1.6.1和DBLE-2.17.07版作性能測試對比,發現DBLE性能只到原生版MyCat的70%左右。git

 

問題分析過程:github


分析過程主要有如下內容:包括現象,收集數據,分析猜想緣由,驗證猜想的方式來進行。算法


開源分佈式中間件DBLE:sql

  • 社區官網,獲取DBLE快速入門指南及最新資訊:
    https://opensource.actionsky.com 
    後端

  • GitHub主頁,查看官方文檔:session

    https://github.com/actiontech/dble併發

  • 社區技術交流羣,迅速獲取官方支持app

    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(N*logK*2) 。

 

 

  • 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上的配置添加<property name="txIsolation">2</property>(默認是3)與默認作對比:


性能比是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,再將配置改成<property name="txIsolation">2</property>,避開上述的bug。


8. 收穫

 

1.測試環境的搭建不管是配置參數仍是各個節點的狀態都要同步,保證公平。

2.性能分析工具的使用。

3.性能測試可能一次的結果具備偶然性,須要屢次驗證。

4.當有矛盾的結論時候,可能就快接近問題的真相了,須要持續關注。

相關文章
相關標籤/搜索