容器化RDS|計算儲存分離架構下的 IO 優化

沃趣科技發表於2018-01-12
沃趣科技  熊中哲

在基於 KubernetesDocker 構建的私有 RDS , 普遍採用了計算儲存分離架構. 該架構優勢明顯但對於資料庫類 Latency Sensitive 應用而言, IO 效能問題無法迴避, 下面分享一下我們針對 MySQL 做的優化以及優化後的收益.


計算儲存分離架構

架構示意圖如下:


儲存層由分散式檔案系統組成, Provisoner 的方式整合到 Kubernetes .

 

在我們看來, 計算儲存分離的最大優勢在於:

 

將有狀態的資料下沉到儲存層, 這使得 RDS 在排程時, 無需感知計算節點的儲存介質, 只需排程到滿足計算資源要求的 Node, 資料庫例項啟動時, 只需在分散式檔案系統掛mapping volume 即可. 可以顯著的提高資料庫例項的部署密度和計算資源利用率

其他的好處還有很多, 譬如架構更清晰, 擴充套件更方便, 問題定位更簡單等,這裡不贅述.

 


計算儲存分離架構的缺點

俗話說的好

 

上帝為你關上一扇窗的同時, 再關上一扇門.

 

如下圖所示

 

 

 

相較本地儲存, 網路開銷會成為 IO 開銷的一部分, 我們認為會帶來兩個很明顯的問題:

 

●     資料庫是 Latency Sensitive 型應用, 網路延時會極大影響資料庫能力(QPS,TPS)

 

●     在高密度部署的場景, 網路頻寬會成為瓶頸, 可能導致計算 & 儲存資源利用不充分.

 

 

其實還有一個極其重要的問題, 由於kubernetes 本身沒有提供 Voting 服務和 類似 Oracle Rac Fence 機制, 在計算儲存分離架構下, 當叢集發生腦裂, 並觸發 Node Controller Kubelet 的驅逐機制時, 可能會出現多個資料庫例項同時訪問一份資料檔案導致 Data Corruption 的情況, 資料的損失對使用者而言是不可估量也不可忍受的. 我們在 kubernetes 1.7.8 下使用 Oracle , MySQL 都可以100%復現這個場景, 通過在 Kubernetes 新增 Fence 機制, 我們已解決該問題. 如果大家有興趣, 會再做專門的分享.

 

 

下面, 就需要結合 MySQL 的特性來進行有針對性的優化.


      

 以下測試方案的設計, 測試資料的梳理來自於沃趣科技 MySQL 專家 @董大爺@波多野老師.

DoubleWrite

MySQL 中我們首先想到了 DoubleWrite. 首先看下官方解釋, 它是幹什麼的 :

 

The InnoDB doublewrite buffer was implemented to recover from half-written pages. This can happen when there's a power failure while InnoDB is writing a page to disk. On reading that page, InnoDB can discover the corruption from the mismatch of the page checksum. However, in order to recover, an intact copy of the page would be needed.

The double write buffer provides such a copy.

Whenever InnoDB flushes a page to disk, it is first written to the double write buffer. Only when the buffer is safely flushed to disk will InnoDB write the page to the final destination. When recovering, InnoDB scans the double write buffer and for each valid page in the buffer checks if the page in the data file is valid too.

Although data is written twice, the doublewrite buffer does not require twice as much I/O, as data is written to the buffer in a large sequential chunk with a single fsync() call. There is extra time consumed however, and the effect becomes visible with fast storage and a heavy write load.

 

簡單說 DoubleWrite 的實現是防止資料頁寫入時發生故障導致頁損壞(partial write),所以每次寫資料檔案時都要將一份資料寫到共享表空間中當啟動時發現資料頁 Checkum 校驗不正確時會使用共享表空間中副本進行恢復,從 DoubleWrite 實現來看這部分會產生一定量的 IO . 所以,

最好的優化 就是減少 IO, 在底層儲存介質或檔案系統支援 Atomic Write的前提下, 可以關閉MySQL DoubleWrite 以減少 IO


單機架構 : 關閉 DoubleWrite

MariaDB 已支援該功能(底層儲存介質需支援 Atomic Write ), 並在單機環境做了相關測試.資料如下 :

結論  : 單機環境下, 啟用Atomic Write(關閉 DoubleWrite )能立即帶來30%左右的寫效能改善

 

原文地址 : http://blog.mariadb.org/mariadb-introduces-atomic-writes/

計算儲存分離架構 : 關閉 DoubleWrite

所以, 重點是我們需要測試一下在計算儲存分離架構下(分散式儲存必須支援 Atomic Write ), 關閉 DoubleWrite Buffer 的收益.

測試場景

●     採用Sysbench 模擬 OLTP 敷在模型 (MariaDB 相同)

 

●     資料庫版本選擇了更流行的 MySQL 5.7.19 (測試時的最新版本)

 

●     由本地儲存改為分散式檔案系統

 

●     測試資料量, 資料檔案大寫

○     10GB

○     100GB

 
測試結果 : 10GB資料量

Sysbench 指標

 

指標型別

執行緒個數

表數量

資料量

測試時長(分鐘)

平均tps

平均qps

響應時間(95%)

oltp開雙寫

256

8

500W

10

5632

112643

73.13 ms

oltp關雙寫

256

8

500W

10

5647

112959

86.00 ms

 

分散式檔案系統指標

 

在計算儲存分離架構下, 啟用Atomic Write(關閉 DoubleWrite ), 10GB資料量, 因為大部分資料已經快取到資料庫 buffer cache , 所以在 IO 不是瓶頸的情況下:

○     Sysbench指標, 提升不明顯

■     tps ↑0.2656%qps ↑0.2797%rst ↑14.9651%

○     分散式檔案系統指標

■     Throughput 下降53%, 顯著優化了網路頻寬

測試結果 : 100GB資料量

Sysbench 指標

 

指標型別

執行緒個數

表數量

資料量

測試時長(分鐘)

平均tps

平均qps

響應時間(95%)

oltp開雙寫

256

8

500W

10

2260

45202

227.40 ms

oltp關雙寫

256

8

500W

10

2519

50394

277.21 ms

 

分散式檔案系統指標

在計算儲存分離架構下, 啟用Atomic Write(關閉 DoubleWrite ), 100GB資料量, 因為大部分資料無法快取到資料庫 buffer cache , 所以在 IO 是瓶頸的情況下:

○     Sysbench指標, 提升明顯

■     TPS ↑28.0892%QPS ↑28.0893%RST ↓169.2033%

○     分散式檔案系統指標

■     IOPS 提升22.3%

■     Latency 下降 39%

■     IOPS 提升22.3%的情況下, Throughput 僅多消耗 3.6%

總結

       想讓資料庫安全,高效的執行到 KubernetesDocker 的架構下並不容易, 本文分享的只是眾多問題之一, 任重而道遠..., 想在上面持續發力的同學, 自求多福吧.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2150076/,如需轉載,請註明出處,否則將追究法律責任。

相關文章