利用JuiceFS使MySQL?備份驗證性能提升?10?倍
前言:
JuiceFS 非常適合用來做 MySQL 物理備份,具體使用參考官方文檔。在測試時,備份驗證的數(shù)據(jù)準備(xtrabackup --prepare)過程非常慢。我們借助 JuiceFS 提供的性能分析工具做了分析,快速發(fā)現(xiàn)性能瓶頸,通過不斷調整 XtraBackup 的參數(shù)和 JuiceFS 的掛載參數(shù),在一個小時內將時間縮短到原先的 1/10。本文將我們性能分析和優(yōu)化的過程記錄分享下來,給大家分析和優(yōu)化 IO 性能提供參考。
數(shù)據(jù)準備
我們通過 SysBench 工具生成一個大小 11GiB 左右的單表數(shù)據(jù)庫,數(shù)據(jù)庫表的 partition 設置成 10。為了模擬一個正常的數(shù)據(jù)庫讀寫場景,通過 SysBench 以秒 50 個請求的壓力訪問數(shù)據(jù)庫,在該壓力下數(shù)據(jù)庫對數(shù)據(jù)盤造成的寫數(shù)據(jù)在 8~10MiB/s 范圍內。通過下列命令將數(shù)據(jù)庫備份到 JuiceFS 上。
# xtrabackup --backup --target-dir=/jfs/base/
為了保證每次數(shù)據(jù)準備操作的數(shù)據(jù)完全一樣,使用 JuiceFS 的快照(snapshot)功能基于 /jfs/base 目錄生成快照 /jfs/base_snapshot/。每一次操作前都會將前一次數(shù)據(jù)準備操作過的數(shù)據(jù)刪掉重新生成一個新的快照。
使用默認參數(shù)
# ./juicefs mount volume-demoz /jfs # ?time xtrabackup --prepare --apply-log-only --target-dir=/jfs/base_snapshot
執(zhí)行總耗時62秒。
JuiceFS支持導出操作日志 oplog,并能對 oplog 進行可視化展示。在執(zhí)行 xtrabackup --prepare操作之前我們新開一個終端連接到該服務器,在命令行輸入
# cat /jfs/.oplog > oplog.txt
開始搜集 oplog 日志,然后執(zhí)行 xtrabackup --prepare 操作,操作結束后將 oplog.txt 下載到本地,上傳到 JuiceFS 提供的 oplog 分析頁面:https://juicefs.com/oplog/。
我們將 oplog 進行可視化展示

這里先大致介紹下這個圖中各種元素含義。我們的一條 oplog 中包含了時間戳,線程 ID,文件系統(tǒng)操作函數(shù)(read, write, fsync, flush 等),操作持續(xù)的時間等。左側數(shù)字表示線程 ID,橫軸表示時間,不同類型操作用不同顏色標記。

我們把局部圖像放大,不同顏色代表不同類型的操作就一目了然。
排除掉與本次操作無關的幾個線程。在數(shù)據(jù)準備過程中有 4 個線程負責讀,5 個線程負責寫數(shù)據(jù),讀寫在時間上都是重疊的。
增大 XtraBackup 的內存緩沖區(qū)
參考 XtraBackup 官方文檔,數(shù)據(jù)準備是使用內嵌的 InnoDB 在備份數(shù)據(jù)集上執(zhí)行故障修復(crash recovery)的過程。
使用 --use-memory 選項增大內嵌 InnoDB 的內存緩沖區(qū)大小,默認 100MB,我們增大到 4GB。
# time xtrabackup --prepare --use-memory=4G --apply-log-only --target-dir=/jfs/base_snapshot
執(zhí)行時間降到了33秒。

可以看到讀寫不重疊了 ,將數(shù)據(jù)讀到內存處理完成后寫入文件系統(tǒng)。
增大 XtraBackup 讀線程數(shù)
通過增大緩沖區(qū)將時間縮短了一半,整個讀的過程耗時依然比較明顯。我們看到每個讀線程基本都是跑滿的狀態(tài),我們嘗試增加更多的讀線程。
# time xtrabackup --prepare --use-memory=4G --innodb-file-io-threads=16 --innodb-read-io-threads=16 --apply-log-only --target-dir=/jfs/base_snapshot
行時間降到了23秒。

讀線程已經(jīng)增加到了 16 個(默認 4 個),讀操作降到 7 秒左右。
JuiceFS 啟用異步寫
上一步我們極大的優(yōu)化了讀操作時間,現(xiàn)在寫過程消耗的時間就比較明顯了。通過分析 oplog,發(fā)現(xiàn)寫操作中 fsync 是不能并行的,因此增大寫線程數(shù)并不能提升寫的效率,在實際操作過程中我們也通過增大寫線程數(shù)驗證了這一點,這里就不贅述了。分析 oplog 對同一個文件(相同文件描述符)的寫操作的參數(shù)(偏移,寫數(shù)據(jù)大小),發(fā)現(xiàn)有大量的隨機寫操作,我們可以在掛載 JuiceFS 時啟用 --writeback 選項,寫數(shù)據(jù)時先寫本地盤,再異步寫到對象存儲。
# ./juicefs mount --writeback volume-demoz /jfs # time xtrabackup --prepare --use-memory=4G --innodb-file-io-threads=16 --innodb-read-io-threads=16 --apply-log-only --target-dir=/jfs/base_snapshot
時間降到了 11.8 秒。

寫過程已經(jīng)降到 1.5 秒左右。
我們看到讀線程讀操作依然比較密集,我們嘗試持續(xù)增加讀線程數(shù),InnoDB 讀線程數(shù)最大為 64,我們直接調成 64。
# time xtrabackup --prepare --use-memory=4G --innodb-file-io-threads=64 --innodb-read-io-threads=64 --apply-log-only --target-dir=/jfs/base_snapshot
執(zhí)行時間 11.2 秒,相比之前基本沒變化。

我們看到,讀線程讀操作已經(jīng)比較稀疏了,應該是線程讀的數(shù)據(jù)之間有依賴關系,導致不能完全并行化,已經(jīng)不能通過提升線程數(shù)壓縮讀過程的時間了。
增大 JuiceFS 的磁盤緩存
在上一步中,我們通過提升讀線程數(shù)來提升讀過程的效率已經(jīng)到頂了,只能通過降低讀數(shù)據(jù)的延遲來減少讀過程時間。
JuiceFS 在讀操作處理上提供了預讀和緩存加速能力,我們接下來嘗試通過增大 JuiceFS 的本地緩存來降低讀操作的延遲。
將 JuiceFS 的本地緩存由高效云盤換成 SSD 云盤,并將緩存大小由 1G 改成 10G。
# ./juicefs mount --writeback volume-demoz --cache-size=10000 --cache-dir=/data/jfsCache /jfs # time xtrabackup --prepare --use-memory=4G --innodb-file-io-threads=64 --innodb-read-io-threads=64 --apply-log-only --target-dir=/jfs/base_snapshot
執(zhí)行時間降到了 6.9 秒。

通過提升緩存性能和增大緩存空間進一步減少了讀操作耗時。
到此我們總結一下,我們通過分析 oplog,不斷尋找可以優(yōu)化的點,將整個數(shù)據(jù)準備過程一步步從 62 秒降到 6.9 秒,效果通過下圖更直觀的展示。

增大數(shù)據(jù)庫數(shù)據(jù)量
以上的操作都是針對 11G 這樣一個比較小的數(shù)據(jù)集不斷調整參數(shù)進行優(yōu)化得到一個很好的結果。作為對比,我們以同樣的方式生成一個 115G 左右的 partition 為10的單表數(shù)據(jù)庫。在 SysBench 持續(xù)每秒 50 個請求情況下,執(zhí)行備份操作。
# time xtrabackup --prepare --use-memory=4G --innodb-file-io-threads=64 --innodb-read-io-threads=64 --apply-log-only --target-dir=/jfs/base_snapshot
這個過程耗時 74 秒。

我們看到,讀和寫還是分開的。
在數(shù)據(jù)量增大10倍左右,相應的準備時間也增大到10倍。這是因為備份(xtrabackup --backup)過程所需的時間擴大到 10 倍,在 SysBench 對數(shù)據(jù)庫壓力不變的情況下,備份過程中產生的 xtrabackup_logfile 也是原先的 10 倍。數(shù)據(jù)準備是要把 xtrabackup_logfile 中的所有數(shù)據(jù)更新合并到數(shù)據(jù)文件中,可見即使數(shù)據(jù)規(guī)模增大了 10 倍,但更新單條日志的時間基本不變。從上圖也可以驗證這一點,數(shù)據(jù)規(guī)模增大后,準備過程仍然是分成了讀數(shù)據(jù)和寫數(shù)據(jù)這兩個明顯的過程,說明設定的 4GB 的緩沖區(qū)大小仍然是夠用的,整個過程仍然可以在內存中完成然后更新到文件系統(tǒng)。
總結
我們使用 SysBench 這個相對簡單的工具構造初始數(shù)據(jù),持續(xù)給數(shù)據(jù)庫一定數(shù)據(jù)更新的壓力模擬數(shù)據(jù)備份時數(shù)據(jù)庫運行場景。使用 JuiceFS 的 oplog 來觀察 XtraBackup 在數(shù)據(jù)準備過程中訪問備份數(shù)據(jù)的讀寫特點,調整 XtraBackup 和 JuiceFS 的參數(shù)來不斷優(yōu)化數(shù)據(jù)準備過程的效率。
在實際生產場景中,情況比我們 SysBench 模擬要復雜得多,我們上面的線性關系不一定嚴格成立,但是我們通過分析 oplog 快速發(fā)現(xiàn)可以優(yōu)化的點,進而不斷調整 XtraBackup 和 JuiceFS 的緩存和并發(fā)的思路是通用的。
整個調參過程耗時 1 小時左右,oplog 分析工具在這個過程中發(fā)揮了很大的作用,幫助我們快速定位系統(tǒng)性能瓶頸,從而針對性地調整參數(shù)做優(yōu)化,也希望這個 oplog 分析功能也能幫助大家快速定位和分析遇到的性能問題。
到此這篇關于利用JuiceFS使MySQL 備份驗證性能提升 10 倍的文章就介紹到這了,更多相關 MySQL 性能提升 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
MySQL數(shù)據(jù)庫優(yōu)化之索引實現(xiàn)原理與用法分析
這篇文章主要介紹了MySQL數(shù)據(jù)庫優(yōu)化之索引實現(xiàn)原理與用法,結合實例形式分析了mysql數(shù)據(jù)庫優(yōu)化操作的索引原理、具體實現(xiàn)與相關操作注意事項,需要的朋友可以參考下2020-01-01
DBeaver連接本地MySQL并創(chuàng)建數(shù)據(jù)庫/表的基礎操作教程
DBeaver是一款功能強大的數(shù)據(jù)庫管理工具,支持創(chuàng)建多種數(shù)據(jù)庫,包括達夢數(shù)據(jù)庫,這篇文章主要給大家介紹了關于DBeaver連接本地MySQL并創(chuàng)建數(shù)據(jù)庫/表的基礎操作教程,需要的朋友可以參考下2024-02-02
MySQL 存儲過程中執(zhí)行動態(tài)SQL語句的方法
這篇文章主要介紹了MySQL 存儲過程中執(zhí)行動態(tài)SQL語句的方法,需要的朋友可以參考下2014-08-08

