利用JuiceFS使MySQL?備份驗(yàn)證性能提升?10?倍
前言:
JuiceFS 非常適合用來做 MySQL 物理備份,具體使用參考官方文檔。在測試時(shí),備份驗(yàn)證的數(shù)據(jù)準(zhǔn)備(xtrabackup --prepare)過程非常慢。我們借助 JuiceFS 提供的性能分析工具做了分析,快速發(fā)現(xiàn)性能瓶頸,通過不斷調(diào)整 XtraBackup 的參數(shù)和 JuiceFS 的掛載參數(shù),在一個(gè)小時(shí)內(nèi)將時(shí)間縮短到原先的 1/10。本文將我們性能分析和優(yōu)化的過程記錄分享下來,給大家分析和優(yōu)化 IO 性能提供參考。
數(shù)據(jù)準(zhǔn)備
我們通過 SysBench 工具生成一個(gè)大小 11GiB 左右的單表數(shù)據(jù)庫,數(shù)據(jù)庫表的 partition 設(shè)置成 10。為了模擬一個(gè)正常的數(shù)據(jù)庫讀寫場景,通過 SysBench 以秒 50 個(gè)請求的壓力訪問數(shù)據(jù)庫,在該壓力下數(shù)據(jù)庫對數(shù)據(jù)盤造成的寫數(shù)據(jù)在 8~10MiB/s 范圍內(nèi)。通過下列命令將數(shù)據(jù)庫備份到 JuiceFS 上。
# xtrabackup --backup --target-dir=/jfs/base/
為了保證每次數(shù)據(jù)準(zhǔn)備操作的數(shù)據(jù)完全一樣,使用 JuiceFS
的快照(snapshot)功能基于 /jfs/base 目錄生成快照 /jfs/base_snapshot/。每一次操作前都會(huì)將前一次數(shù)據(jù)準(zhǔn)備操作過的數(shù)據(jù)刪掉重新生成一個(gè)新的快照。
使用默認(rèn)參數(shù)
# ./juicefs mount volume-demoz /jfs # ?time xtrabackup --prepare --apply-log-only --target-dir=/jfs/base_snapshot
執(zhí)行總耗時(shí)62秒。
JuiceFS支持導(dǎo)出操作日志 oplog,并能對 oplog 進(jìn)行可視化展示。在執(zhí)行 xtrabackup --prepare操作之前我們新開一個(gè)終端連接到該服務(wù)器,在命令行輸入
# cat /jfs/.oplog > oplog.txt
開始搜集 oplog 日志,然后執(zhí)行 xtrabackup --prepare 操作,操作結(jié)束后將 oplog.txt 下載到本地,上傳到 JuiceFS 提供的 oplog 分析頁面:https://juicefs.com/oplog/。
我們將 oplog 進(jìn)行可視化展示
這里先大致介紹下這個(gè)圖中各種元素含義。我們的一條 oplog 中包含了時(shí)間戳,線程 ID,文件系統(tǒng)操作函數(shù)(read, write, fsync, flush 等),操作持續(xù)的時(shí)間等。左側(cè)數(shù)字表示線程 ID,橫軸表示時(shí)間,不同類型操作用不同顏色標(biāo)記。
我們把局部圖像放大,不同顏色代表不同類型的操作就一目了然。
排除掉與本次操作無關(guān)的幾個(gè)線程。在數(shù)據(jù)準(zhǔn)備過程中有 4 個(gè)線程負(fù)責(zé)讀,5 個(gè)線程負(fù)責(zé)寫數(shù)據(jù),讀寫在時(shí)間上都是重疊的。
增大 XtraBackup 的內(nèi)存緩沖區(qū)
參考 XtraBackup 官方文檔,數(shù)據(jù)準(zhǔn)備是使用內(nèi)嵌的 InnoDB 在備份數(shù)據(jù)集上執(zhí)行故障修復(fù)(crash recovery)的過程。
使用 --use-memory
選項(xiàng)增大內(nèi)嵌 InnoDB 的內(nèi)存緩沖區(qū)大小,默認(rèn) 100MB,我們增大到 4GB。
# time xtrabackup --prepare --use-memory=4G --apply-log-only --target-dir=/jfs/base_snapshot
執(zhí)行時(shí)間降到了33秒。
可以看到讀寫不重疊了 ,將數(shù)據(jù)讀到內(nèi)存處理完成后寫入文件系統(tǒng)。
增大 XtraBackup 讀線程數(shù)
通過增大緩沖區(qū)將時(shí)間縮短了一半,整個(gè)讀的過程耗時(shí)依然比較明顯。我們看到每個(gè)讀線程基本都是跑滿的狀態(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
行時(shí)間降到了23秒。
讀線程已經(jīng)增加到了 16 個(gè)(默認(rèn) 4 個(gè)),讀操作降到 7 秒左右。
JuiceFS 啟用異步寫
上一步我們極大的優(yōu)化了讀操作時(shí)間,現(xiàn)在寫過程消耗的時(shí)間就比較明顯了。通過分析 oplog,發(fā)現(xiàn)寫操作中 fsync 是不能并行的,因此增大寫線程數(shù)并不能提升寫的效率,在實(shí)際操作過程中我們也通過增大寫線程數(shù)驗(yàn)證了這一點(diǎn),這里就不贅述了。分析 oplog 對同一個(gè)文件(相同文件描述符)的寫操作的參數(shù)(偏移,寫數(shù)據(jù)大?。l(fā)現(xiàn)有大量的隨機(jī)寫操作,我們可以在掛載 JuiceFS 時(shí)啟用 --writeback 選項(xiàng),寫數(shù)據(jù)時(shí)先寫本地盤,再異步寫到對象存儲(chǔ)。
# ./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
時(shí)間降到了 11.8 秒。
寫過程已經(jīng)降到 1.5 秒左右。
我們看到讀線程讀操作依然比較密集,我們嘗試持續(xù)增加讀線程數(shù),InnoDB 讀線程數(shù)最大為 64,我們直接調(diào)成 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í)行時(shí)間 11.2 秒,相比之前基本沒變化。
我們看到,讀線程讀操作已經(jīng)比較稀疏了,應(yīng)該是線程讀的數(shù)據(jù)之間有依賴關(guān)系,導(dǎo)致不能完全并行化,已經(jīng)不能通過提升線程數(shù)壓縮讀過程的時(shí)間了。
增大 JuiceFS 的磁盤緩存
在上一步中,我們通過提升讀線程數(shù)來提升讀過程的效率已經(jīng)到頂了,只能通過降低讀數(shù)據(jù)的延遲來減少讀過程時(shí)間。
JuiceFS 在讀操作處理上提供了預(yù)讀和緩存加速能力,我們接下來嘗試通過增大 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í)行時(shí)間降到了 6.9 秒。
通過提升緩存性能和增大緩存空間進(jìn)一步減少了讀操作耗時(shí)。
到此我們總結(jié)一下,我們通過分析 oplog,不斷尋找可以優(yōu)化的點(diǎn),將整個(gè)數(shù)據(jù)準(zhǔn)備過程一步步從 62 秒降到 6.9 秒,效果通過下圖更直觀的展示。
增大數(shù)據(jù)庫數(shù)據(jù)量
以上的操作都是針對 11G 這樣一個(gè)比較小的數(shù)據(jù)集不斷調(diào)整參數(shù)進(jìn)行優(yōu)化得到一個(gè)很好的結(jié)果。作為對比,我們以同樣的方式生成一個(gè) 115G 左右的 partition 為10的單表數(shù)據(jù)庫。在 SysBench 持續(xù)每秒 50 個(gè)請求情況下,執(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
這個(gè)過程耗時(shí) 74 秒。
我們看到,讀和寫還是分開的。
在數(shù)據(jù)量增大10倍左右,相應(yīng)的準(zhǔn)備時(shí)間也增大到10倍。這是因?yàn)閭浞荩?code>xtrabackup --backup)過程所需的時(shí)間擴(kuò)大到 10 倍,在 SysBench 對數(shù)據(jù)庫壓力不變的情況下,備份過程中產(chǎn)生的 xtrabackup_logfile
也是原先的 10 倍。數(shù)據(jù)準(zhǔn)備是要把 xtrabackup_logfile
中的所有數(shù)據(jù)更新合并到數(shù)據(jù)文件中,可見即使數(shù)據(jù)規(guī)模增大了 10 倍,但更新單條日志的時(shí)間基本不變。從上圖也可以驗(yàn)證這一點(diǎn),數(shù)據(jù)規(guī)模增大后,準(zhǔn)備過程仍然是分成了讀數(shù)據(jù)和寫數(shù)據(jù)這兩個(gè)明顯的過程,說明設(shè)定的 4GB 的緩沖區(qū)大小仍然是夠用的,整個(gè)過程仍然可以在內(nèi)存中完成然后更新到文件系統(tǒng)。
總結(jié)
我們使用 SysBench
這個(gè)相對簡單的工具構(gòu)造初始數(shù)據(jù),持續(xù)給數(shù)據(jù)庫一定數(shù)據(jù)更新的壓力模擬數(shù)據(jù)備份時(shí)數(shù)據(jù)庫運(yùn)行場景。使用 JuiceFS
的 oplog 來觀察 XtraBackup 在數(shù)據(jù)準(zhǔn)備過程中訪問備份數(shù)據(jù)的讀寫特點(diǎn),調(diào)整 XtraBackup 和 JuiceFS 的參數(shù)來不斷優(yōu)化數(shù)據(jù)準(zhǔn)備過程的效率。
在實(shí)際生產(chǎn)場景中,情況比我們 SysBench 模擬要復(fù)雜得多,我們上面的線性關(guān)系不一定嚴(yán)格成立,但是我們通過分析 oplog 快速發(fā)現(xiàn)可以優(yōu)化的點(diǎn),進(jìn)而不斷調(diào)整 XtraBackup 和 JuiceFS 的緩存和并發(fā)的思路是通用的。
整個(gè)調(diào)參過程耗時(shí) 1 小時(shí)左右,oplog 分析工具在這個(gè)過程中發(fā)揮了很大的作用,幫助我們快速定位系統(tǒng)性能瓶頸,從而針對性地調(diào)整參數(shù)做優(yōu)化,也希望這個(gè) oplog 分析功能也能幫助大家快速定位和分析遇到的性能問題。
到此這篇關(guān)于利用JuiceFS使MySQL 備份驗(yàn)證性能提升 10 倍的文章就介紹到這了,更多相關(guān) MySQL 性能提升 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL數(shù)據(jù)庫優(yōu)化之索引實(shí)現(xiàn)原理與用法分析
這篇文章主要介紹了MySQL數(shù)據(jù)庫優(yōu)化之索引實(shí)現(xiàn)原理與用法,結(jié)合實(shí)例形式分析了mysql數(shù)據(jù)庫優(yōu)化操作的索引原理、具體實(shí)現(xiàn)與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-01-01DBeaver連接本地MySQL并創(chuàng)建數(shù)據(jù)庫/表的基礎(chǔ)操作教程
DBeaver是一款功能強(qiáng)大的數(shù)據(jù)庫管理工具,支持創(chuàng)建多種數(shù)據(jù)庫,包括達(dá)夢數(shù)據(jù)庫,這篇文章主要給大家介紹了關(guān)于DBeaver連接本地MySQL并創(chuàng)建數(shù)據(jù)庫/表的基礎(chǔ)操作教程,需要的朋友可以參考下2024-02-02MySQL 存儲(chǔ)過程中執(zhí)行動(dòng)態(tài)SQL語句的方法
這篇文章主要介紹了MySQL 存儲(chǔ)過程中執(zhí)行動(dòng)態(tài)SQL語句的方法,需要的朋友可以參考下2014-08-08MySQL復(fù)制表結(jié)構(gòu)和內(nèi)容到另一張表中的SQL語句
這篇文章主要介紹了MySQL復(fù)制表結(jié)構(gòu)和內(nèi)容到另一張表中的SQL語句,需要的朋友可以參考下2014-07-07MySQL UDF調(diào)試方式debugview的相關(guān)方法
MySQL UDF調(diào)試方式debugview的相關(guān)方法...2007-07-07