本篇文章著眼于 Linux 頁面大小對數(shù)據(jù)庫性能的影響,以及如何優(yōu)化數(shù)據(jù)庫 Kubernetes 節(jié)點(diǎn)。
大多數(shù)流行的數(shù)據(jù)庫都受益于 Linux 大頁面。
Kubernetes 最初旨在大規(guī)模編排容器的生命周期,用于輕量級(jí)、無狀態(tài)應(yīng)用程序,如 Ngnix、Java 和 Node.js。對于這個(gè)用例,Linux 4K 頁面是正確的選擇。
最近,通過添加Statefulsets、Persistent Volumes和大頁面等功能,Kubernetes 得到了增強(qiáng),以支持大型、有狀態(tài)、持久性數(shù)據(jù)庫。
下圖顯示了使用 Linux 大頁面對數(shù)據(jù)庫性能的影響有多大。
上圖顯示,對于相同的數(shù)據(jù)庫,相同的數(shù)據(jù),相同的工作負(fù)載,使用Linux 2MB頁面而不是4K頁面時(shí)吞吐量可以提高8倍。該圖還顯示,隨著并發(fā)水平的提高,大頁面的好處也隨之增加。
文章的其余部分介紹了一些背景概念,并著眼于影響數(shù)據(jù)庫工作負(fù)載的 Linux 頁面大小的因素。
Linux 頁面大小
所有現(xiàn)代多用戶操作系統(tǒng)都使用虛擬內(nèi)存來使不同的進(jìn)程能夠使用內(nèi)存而不必?fù)?dān)心底層細(xì)節(jié)。Linux x86 64 的系統(tǒng)使用分頁進(jìn)行虛擬內(nèi)存管理。
Linux x8664 支持以下頁面大?。?/p>
4K
2MB
1GB
頁大小是可用于虛擬內(nèi)存管理的連續(xù)數(shù)據(jù)的最小單位。?
頁面的大小是一種權(quán)衡。4K 頁面最大限度地減少了小內(nèi)存分配的內(nèi)存浪費(fèi)。對于大內(nèi)存分配,使用 2MB 或 1GB 頁面總共需要更少的頁面,而且速度會(huì)明顯更快,因?yàn)?strong>將虛擬內(nèi)存轉(zhuǎn)換為物理內(nèi)存地址會(huì)產(chǎn)生相關(guān)成本。?
TLB 緩存命中和未命中
Linux 上任何進(jìn)程的每次內(nèi)存訪問(例如,無論是 Nginx、Node.js 還是 MySQL)都需要從虛擬內(nèi)存轉(zhuǎn)換為物理內(nèi)存。由于這是一個(gè)常規(guī)的操作,所有 CPU 都有某種形式的轉(zhuǎn)換后備緩沖區(qū)[TLB],它充當(dāng)最近轉(zhuǎn)換的內(nèi)存地址的緩存。
所有從虛擬內(nèi)存到物理內(nèi)存的轉(zhuǎn)換首先查看 TLB 中是否已經(jīng)存在映射。如果映射已經(jīng)存在,則稱為 TLB 緩存命中。TLB 緩存命中非???,并且發(fā)生在硬件中。當(dāng) TLB 緩存中不存在從虛擬內(nèi)存到物理內(nèi)存的轉(zhuǎn)換時(shí),稱為 TLB 緩存未命中。TLB 緩存未命中需要通過頁面遍歷在 Linux 內(nèi)核頁表中的軟件中解決映射。盡管頁面遍歷是高效的 C 代碼,但它比通過 TLB 緩存在硬件中進(jìn)行映射要慢得多。
為什么 TLB 緩存未命中對數(shù)據(jù)庫很重要
所有數(shù)據(jù)庫最終都需要訪問內(nèi)存中的數(shù)據(jù)進(jìn)行讀取或?qū)懭?。所有這些數(shù)據(jù)庫讀取或?qū)懭攵夹枰辽龠M(jìn)行一次 TLB 查找。TLB 緩存未命中會(huì)顯著減慢數(shù)據(jù)庫的讀寫速度:
數(shù)據(jù)庫越大,訪問的不同頁面越多,需要的 TLB 查找就越多。這實(shí)際上是數(shù)據(jù)庫工作集大小。
并發(fā)越大,單位時(shí)間需要的 TLB 查找越多
如果您有具有可變長度數(shù)據(jù)類型(例如字符串、JSON、CLOB 或 BLOB)的行/記錄,那么這些行/記錄的寬度很容易超過 4KB。當(dāng) Linux 頁面大小為 4KB 時(shí),訪問寬度為 20KB 的單行/記錄通常需要至少五次 TLB 查找。如果使用 2MB 或 1GB Linux 頁面,訪問相同的 20KB 行/記錄通常只需要一次 TLB 查找。所以一般來說,數(shù)據(jù)庫行(rows)/記錄(record)越寬,大頁面與 4K Linux 頁面的優(yōu)勢就越大。
挑戰(zhàn)在于 CPU 具有少量 TLB 緩存條目:
4K 頁面的 L1 TLB 中64個(gè)條目,2MB 頁面的 32 個(gè)條目,1G 頁面的 8 個(gè)條目
4K + 2MB 頁面的 L2 TLB 中有1024個(gè)條目
4K + 1GB 頁面的 L2 TLB 中有1024個(gè)條目
AMD EPYC Zen 3
4K + 2MB 頁面 + 1GB 頁面的 L1 TLB 中的64 個(gè)條目
4K 和 2MB 頁面的 L2 TLB 中的512 個(gè)條目
由于 L1 CPU 緩存通常只有大約 64 個(gè) TLB 4K 條目,而最新的 Intel 和 AMD CPU 上的 L2 緩存則有 512 到 1024 個(gè) 4K 條目,如果您的數(shù)據(jù)庫具有寬行/記錄并訪問許多不同的行/記錄,那么它幾乎總是會(huì)得到 TLB 緩存未命中。
如果您使用 2MB 頁面,那么您不太可能遇到 TLB 緩存未命中,因?yàn)槟行У厥?TLB 緩存更大:
AMD EPYC Zen 3 CPU 比?L1 和 L2 CPU?緩存大?512 倍
英特爾 Ice Lake CPU 的 L1 CPU 緩存大 256 倍,L2 CPU 緩存大 512 倍
減少 TLB 緩存未命中的數(shù)量可以對數(shù)據(jù)庫性能產(chǎn)生顯著的積極影響。
基準(zhǔn)
Linux 并不關(guān)心你的數(shù)據(jù)庫是 MySQL、PostgreSQL 還是 Oracle。Linux 并不關(guān)心您的應(yīng)用程序是用 Node.js、Java、Go、Rust 還是 C 編寫的。Linux 性能取決于諸如工作負(fù)載每單位時(shí)間發(fā)生多少 TLB 緩存未命中等指標(biāo)。
以下基準(zhǔn)測試著眼于幾種配置:
窄行(Narrow)/記錄 [128 字節(jié)],訪問 1 億條不同的行/記錄的概率均勻
整個(gè)行/記錄應(yīng)適合單個(gè) 4KB Linux 頁面
中等行(Medium)/記錄 [8 KB],平均訪問 1 億條不同的行/記錄的概率
行/記錄應(yīng)至少適合兩個(gè) 4KB Linux 頁面
更寬的行(Wider)/記錄 [16 KB],甚至有可能訪問 1 億條不同的行/記錄
行/記錄應(yīng)至少適合四個(gè) 4KB Linux 頁面
16 KB 不是很寬,但結(jié)果很顯著
要最小化變量的數(shù)量:
只執(zhí)行數(shù)據(jù)庫讀取,數(shù)據(jù)庫中的所有 1 億行都可以輕松放入 DRAM 并且數(shù)據(jù)庫被“預(yù)熱”
數(shù)據(jù)庫客戶端使用 IPC 而不是 TCP 套接字來訪問數(shù)據(jù)庫
這種配置意味著沒有磁盤 IO 或網(wǎng)絡(luò)處理,因此工作負(fù)載會(huì)在 CPU 和/或內(nèi)存訪問上出現(xiàn)瓶頸。
128 字節(jié)行/記錄的4K Linux 頁面
上圖顯示,在 AMD EPYC 7J1C3 @ 2.55 GHz 處理器上使用 4K Linux 頁面和 128 個(gè)數(shù)據(jù)庫連接,在單臺(tái) Linux 機(jī)器上每秒可以執(zhí)行超過 350 萬次數(shù)據(jù)庫讀取。
128 字節(jié)行/記錄的4K 與 2MB 頁面
上圖顯示,對于相同的硬件、相同的數(shù)據(jù)庫、相同的表、相同的數(shù)據(jù)、相同的查詢,2 MB 的大頁面可以實(shí)現(xiàn)比使用 4K Linux 頁面時(shí)多出 8 倍的吞吐量。
對于窄行/記錄,吞吐量提高 8 倍是一個(gè)顯著的結(jié)果。
8 KB行/記錄的4K 與 2MB 頁面
對于 8KB 寬的數(shù)據(jù)庫行/記錄,2MB 頁面可以提供比 4K 頁面多 8 倍的吞吐量。
對于中等寬度的行/記錄,吞吐量提高 8 倍是一個(gè)重要的結(jié)果。
16 KB行/記錄的4K 與 2MB 頁面
上圖顯示,對于相同的硬件、相同的數(shù)據(jù)庫、相同的表、相同的數(shù)據(jù)、相同的查詢,2 MB 的大頁面可以實(shí)現(xiàn)比使用 4K Linux 頁面時(shí)多出 5 倍的吞吐量。
對于更寬的行/記錄,吞吐量提高 5 倍是一個(gè)重要的結(jié)果。
2MB 和 1GB Linux 頁面怎么樣
很容易看出 2MB Linux 頁面與 4K 頁面的優(yōu)勢,例如提高 8 倍。您是否還希望看到 2MB 和 1GB Linux 頁面之間的顯著差異?
由于所有測試的行寬都可以放入 2MB 頁面,唯一的變量是 2MB 與 1GB Linux 頁面的 TLB 緩存未命中率,用于 1 億不同的行/記錄。
對于所有經(jīng)過測試的行寬 [128 字節(jié)、8KB 和 16KB],1GB Linux 頁面的吞吐量比 2MB Linux 頁面高 1% 到 21%。
雖然高達(dá) 21% 的吞吐量改進(jìn)不如 8 倍令人印象深刻,但它仍然存在一些差異。
也許行/記錄寬于 2MB 的測試會(huì)顯示顯著差異?
Kubernetes 節(jié)點(diǎn)專業(yè)化
在 Kubernetes 的早期,工作負(fù)載往往用于小型、無狀態(tài)的“基于 Web”的應(yīng)用程序,例如負(fù)載均衡器、Web 服務(wù)器、代理和各種應(yīng)用程序服務(wù)器。對于這個(gè)用例,使用 Linux 4K 頁面是一個(gè)合適的選擇。
最近,更專業(yè)的工作負(fù)載正在 Kubernetes 集群中運(yùn)行,這些集群具有不同的硬件和/或軟件要求。例如,機(jī)器學(xué)習(xí)工作負(fù)載可以在通用 x86 64位 CPU 上運(yùn)行,但在具有 GPU 或 ASIC 的 Kubernetes 節(jié)點(diǎn)上運(yùn)行速度往往要快得多。此外,某些 Kubernetes 節(jié)點(diǎn)可能專門用于具有快速本地存儲(chǔ)、更多 RAM 或可能運(yùn)行 ARM 64 CPU。
因此,并非所有 Kubernetes 節(jié)點(diǎn)都具有完全相同的 CPU、RAM、存儲(chǔ)等,一些節(jié)點(diǎn)可以使用守護(hù)程序集或節(jié)點(diǎn)標(biāo)簽來定義和公開這些節(jié)點(diǎn)的特定功能。使用POD 標(biāo)簽[使用選擇器來匹配節(jié)點(diǎn)標(biāo)簽],允許 Kubernetes 調(diào)度程序在最合適的節(jié)點(diǎn)上自動(dòng)運(yùn)行 POD。
上圖顯示了具有四種類型的專用節(jié)點(diǎn)的 Kubernetes 集群。
你可以做些什么來優(yōu)化 Kubernetes 上的數(shù)據(jù)庫性能
通常不在您控制范圍內(nèi)的事情:
數(shù)據(jù)庫行/記錄的寬度
您的數(shù)據(jù)庫中有多少行/記錄
您的數(shù)據(jù)庫工作集大小
數(shù)據(jù)庫中數(shù)據(jù)訪問的并發(fā)性和頻率
CPU 的 TLB 緩存大小
在范圍內(nèi)可以控制你的Kubernetes集群的事情:
Linux 內(nèi)核在 Linux x8664 Kubernetes 節(jié)點(diǎn)上使用 4KB、2MB 還是 1GB Linux 頁面
您配置了多少 Linux 大頁面 [2MB 或 1GB]
Kubernetes 應(yīng)用程序的內(nèi)存和大頁面資源?的請求和限制
數(shù)據(jù)庫被認(rèn)為是 Kubernetes 中的一個(gè)應(yīng)用程序
您可以選擇為要在其上運(yùn)行數(shù)據(jù)庫工作負(fù)載的一組機(jī)器配置具有 2MB 或 1GB 大頁面的 Kubernetes 節(jié)點(diǎn) [即 Linux 主機(jī)]。
在 Linux上配置大頁面的方式與Kubernetes 無關(guān)。您必須在 Linux 內(nèi)核中配置大頁面,因?yàn)槟鸁o法在 Kubernetes 或容器級(jí)別執(zhí)行此操作。通常你想關(guān)閉透明大頁面,因?yàn)樗鼈兺ǔ2粫?huì)提高數(shù)據(jù)庫性能,只會(huì)浪費(fèi)內(nèi)存。
在 Linux x8664 上配置 2MB 頁面對于任何 Linux 發(fā)行版都相當(dāng)簡單,通常無需更改啟動(dòng)時(shí)間參數(shù)即可完成。
配置 1GB Linux 頁面的步驟因發(fā)行版而略有不同,并且需要啟動(dòng)時(shí)間參數(shù)。我能夠在最近的 Intel Xeon 和 AMD CPU 上配置 1 GB Linux 頁面,用于:
紅帽企業(yè) Linux 7.9 和 8.4
Oracle Linux 7.9 和 8.4
CentOS 7 和 8
Ubuntu 18.04 和 20.04
SuSE 12 和 SuSE 15
您應(yīng)該為 Kubernetes 上的數(shù)據(jù)庫配置多少大頁面
這個(gè)問題是特定于數(shù)據(jù)庫的。這取決于您的 Kubernetes 節(jié)點(diǎn)有多少 RAM、您希望在該節(jié)點(diǎn)上運(yùn)行多少其他 [非數(shù)據(jù)庫] POD、這些 POD 需要多少 RAM,以及最終您的數(shù)據(jù)庫通過使用更多內(nèi)存而受益多少。
總結(jié)
大多數(shù)流行的數(shù)據(jù)庫在 Linux x86 64 上看到了大頁面的性能優(yōu)勢
Kubernetes 支持 4KB、2MB 和 1GB 的 Linux 頁面
由于歷史原因,大多數(shù) Kubernetes 集群使用 4KB Linux 頁面
許多 Kubernetes 集群根據(jù)工作負(fù)載優(yōu)化一些節(jié)點(diǎn) [例如機(jī)器學(xué)習(xí)、快速本地存儲(chǔ)、通用無狀態(tài) Web 應(yīng)用程序等]
考慮添加另一類經(jīng)過優(yōu)化以提高數(shù)據(jù)庫性能的節(jié)點(diǎn)。
使用 2MB 或 1GB 頁面在某些 Kubernetes 節(jié)點(diǎn)上配置 Linux 內(nèi)核以優(yōu)化它們的數(shù)據(jù)庫性能
根據(jù)您的數(shù)據(jù)庫為這些機(jī)器選擇適當(dāng)數(shù)量的大頁面和 4K Linux 頁面
編輯:黃飛
?
評(píng)論
查看更多