基準(zhǔn)測(cè)試上 RAM Disk:mako_storage_bench.sh 在 okteto 開發(fā) Pod 上的 tmpfs 實(shí)踐指南)
分布式數(shù)據(jù)庫(kù)KV存儲(chǔ)數(shù)據(jù)庫(kù)后端【免費(fèi)下載鏈接】foundationdbFoundationDB - the open source, distributed, transactional key-value store項(xiàng)目地址https://gitcode.com/gh_mirrors/fo/foundationdb點(diǎn)擊查看免費(fèi)下載mako_storage_bench.sh是 FoundationDB 倉(cāng)庫(kù)中用于捕獲存儲(chǔ)服務(wù)器 CPU 回歸的單機(jī)吞吐基準(zhǔn)腳本其設(shè)計(jì)前提是存儲(chǔ)進(jìn)程的 CPU 成為瓶頸。本文以 contrib/mako_storage_bench-ramdisk-okteto.md 為主體完整講解如何在 okteto 開發(fā) Pod 上把集群數(shù)據(jù)目錄放到 tmpfs內(nèi)存盤使基準(zhǔn)真正跑成 CPU-bound并深入 contrib/mako_storage_bench.sh 及 fdbserver/flow 源碼解釋腳本自動(dòng)注入的 tmpfs knob、redwood 與 rocksdb 引擎的差異、okteto 拓?fù)淇优c容量規(guī)劃。讀完本文你將能夠獨(dú)立完成從給 Pod 掛載 /mnt/ram到跑出可信的 TPS 對(duì)比數(shù)據(jù)的全部步驟。為什么 mako 存儲(chǔ)基準(zhǔn)需要一塊 RAM Diskmako_storage_bench.sh的設(shè)計(jì)目標(biāo)是讓存儲(chǔ)服務(wù)器 CPU成為瓶頸從而檢測(cè)存儲(chǔ)引擎乃至存儲(chǔ)服務(wù)器熱路徑flow、fdbrpc、網(wǎng)絡(luò)、序列化等上的 CPU 回歸。這在數(shù)據(jù)目錄位于快速本地存儲(chǔ)時(shí)成立但在 okteto 開發(fā) Pod 上并不成立Pod 的文件系統(tǒng)是容器 overlay底層是網(wǎng)絡(luò)掛載的 EBS因此基準(zhǔn)被 EBS 的 fsync/IO 延遲所束縛而不是存儲(chǔ) CPU。癥狀非常典型文檔記錄的實(shí)測(cè)吞吐量停留在很低的平臺(tái)在全新 m7a Pod 上約1.5k TPS存儲(chǔ)進(jìn)程 CPU 遠(yuǎn)低于 85%commit 延遲達(dá)到數(shù)十毫秒。解決辦法是把集群數(shù)據(jù)放到tmpfs內(nèi)存支持的目錄上使 commit 不再承擔(dān)磁盤延遲存儲(chǔ)進(jìn)程重新變?yōu)?CPU-bound。腳本已經(jīng)內(nèi)置了自動(dòng)檢測(cè)邏輯當(dāng)/mnt/ram存在且可寫時(shí)它會(huì)自動(dòng)使用它并自動(dòng)附加下述 tmpfs knob因此一旦開發(fā) Pod 擁有了/mnt/ram直接運(yùn)行contrib/mako_storage_bench.sh build_output4就能以 CPU-bound 方式跑起來(lái)。剩下的實(shí)際工作只是給 Pod 提供這塊內(nèi)存目錄——而這在 okteto 上需要一些技巧。補(bǔ)充說(shuō)明build_output4只是示例構(gòu)建目錄作者本機(jī)~/src/fdb4構(gòu)建樹即開發(fā) Pod 上的/root/build_output4請(qǐng)?zhí)鎿Q為你自己的構(gòu)建根目錄。注意mako 默認(rèn)不參與構(gòu)建需要以-D BUILD_MAKOON配置構(gòu)建否則build_output4/bin/mako不存在腳本會(huì)在入口處直接報(bào)錯(cuò)退出contrib/mako_storage_bench.sh 會(huì)對(duì)三個(gè)二進(jìn)制逐一檢查可執(zhí)行性。TL;DR# 一次性 Pod 配置詳見下文給開發(fā) Pod 一個(gè) /mnt/ram tmpfs 內(nèi)存余量。 # 然后直接運(yùn)行——腳本自動(dòng)檢測(cè) /mnt/ram 并附加 tmpfs knob contrib/mako_storage_bench.sh build_output4腳本自動(dòng)做了什么以及如何覆蓋WORKDIR數(shù)據(jù)目錄與輸出目錄集群數(shù)據(jù)目錄和 mako 輸出都位于WORKDIR之下。腳本的判定邏輯在 contrib/mako_storage_bench.shif [[ -z ${WORKDIR:-} -w /mnt/ram ]]; then WORKDIR/mnt/ram/mako_storage_bench fi readonly WORKDIR${WORKDIR:-${PWD}/mako_storage_bench}即當(dāng)/mnt/ram是可寫目錄時(shí)默認(rèn)使用/mnt/ram/mako_storage_bench否則回退到$PWD/mako_storage_bench??梢酝ㄟ^(guò)導(dǎo)出WORKDIR覆蓋例如指向非 tmpfs 路徑強(qiáng)制使用 EBS 數(shù)據(jù)目錄用于對(duì)照實(shí)驗(yàn)。tmpfs knob--knob_disable_posix_kernel_aio1這是腳本在 tmpfs 上能跑起來(lái)的關(guān)鍵。fdbserver 默認(rèn)以O(shè)_DIRECT 內(nèi)核 AIO 打開數(shù)據(jù)文件而tmpfs 拒絕O_DIRECT因此如果沒有回退機(jī)制集群根本啟動(dòng)不起來(lái)。腳本在檢測(cè)到WORKDIR位于 tmpfs 上時(shí)自動(dòng)附加該 knobcontrib/mako_storage_bench.shif [[ $(stat -f -c %T $(dirname ${WORKDIR}) 2/dev/null) tmpfs \ ${KNOBS} ! *disable_posix_kernel_aio* ]]; then KNOBS${KNOBS:${KNOBS} }--knob_disable_posix_kernel_aio1 fi對(duì)應(yīng)源碼在 fdbrpc/Net2FileSystem.cpp當(dāng)文件以O(shè)PEN_UNBUFFERED打開、未禁用 AIO、且FLOW_KNOBS-DISABLE_POSIX_KERNEL_AIO為假時(shí)走AsyncFileKAIO內(nèi)核 AIO要求O_DIRECT否則回退到Net2AsyncFileEIO 緩沖路徑tmpfs 可接受。該 knob 的默認(rèn)值在 flow/Knobs.cpp 中為0即默認(rèn)啟用內(nèi)核 AIO。因此你可以用KNOBS...傳額外的 knobs如果你沒有自己包含 tmpfs knob腳本會(huì)替你追加反過(guò)來(lái)若你想強(qiáng)制 EBS 數(shù)據(jù)目錄非 tmpfs腳本不會(huì)注入該 knob保持默認(rèn)的內(nèi)核 AIO/O_DIRECT 行為。有界時(shí)長(zhǎng)SECONDS_RUN / WARMUP_SECONDS腳本的默認(rèn)值是WARMUP_SECONDS300、SECONDS_RUN600見 contrib/mako_storage_bench.sh均可通過(guò)環(huán)境變量覆蓋縮短測(cè)量窗口例如SECONDS_RUN120 WARMUP_SECONDS60是控制 tmpfs 占用、加快迭代的有效手段詳見下文容量規(guī)劃。存儲(chǔ)引擎redwood默認(rèn)vs rocksdb on tmpfsredwood開箱即用默認(rèn)引擎是redwood映射為ssd-redwood-1。redwood 走 flow 的文件 IO 路徑腳本自動(dòng)附加的 tmpfs knob 已足夠無(wú)需任何KNOBS。引擎到存儲(chǔ)類型的映射在 contrib/mako_storage_bench.sh引擎名configure new存儲(chǔ)類型備注redwoodssd-redwood-1默認(rèn)引擎rocksdbssd-rocksdb-v1需要 RocksDB-enabled 構(gòu)建sharded-rocksdbssd-sharded-rocksdb需要 RocksDB-enabled 構(gòu)建須顯式指定allredwood rocksdb便捷別名不含 sharded-rocksdb集群由 tests/loopback_cluster/run_custom_cluster.sh 以1 stateless / 1 log / 1 storage復(fù)制因子 1的方式拉起腳本通過(guò)--storage_type把引擎?zhèn)魅隿onfigure newcontrib/mako_storage_bench.sh。rocksdb還需要兩個(gè)額外 knobsrocksdb引擎... build_output4 rocksdb需要兩個(gè)額外的 knobs。RocksDB 自行管理文件 IO不經(jīng)過(guò) flow在ssd-rocksdb-v1上默認(rèn)以O(shè)_DIRECT打開數(shù)據(jù)庫(kù)ROCKSDB_USE_DIRECT_READS與ROCKSDB_USE_DIRECT_IO_FLUSH_COMPACTION在 fdbserver/core/ServerKnobs.cpp 中默認(rèn)值均為true并在 fdbserver/kvstore/KeyValueStoreRocksDB.cpp 中直接映射到 RocksDB 的Options::use_direct_reads與use_direct_io_for_flush_and_compaction。tmpfs 拒絕O_DIRECT因此存儲(chǔ)服務(wù)器會(huì)在rocksdb::DB::Open處失敗fdbserver/kvstore/KeyValueStoreRocksDB.cpp 記錄RocksDBError: Invalid argument: Direct I/O is not supported by the specified DB.并崩潰循環(huán)——而且由于這發(fā)生在任何數(shù)據(jù)目錄創(chuàng)建之前基準(zhǔn)會(huì)卡在configure new處腳本的BUILD_TIMEOUT只保護(hù) mako 構(gòu)建階段不覆蓋集群?jiǎn)?dòng)因此不會(huì)自我中止見 contrib/mako_storage_bench.sh 的注釋。自動(dòng)的 tmpfs knob 對(duì) RocksDB 無(wú)效必須單獨(dú)禁用 RocksDB 的直接 IO。這兩個(gè)是運(yùn)行時(shí) knobs無(wú)需重新編譯。腳本仍會(huì)自動(dòng)附加 flow 的 knob所以你只需提供兩個(gè)rocksdb_*knobsKNOBS--knob_rocksdb_use_direct_readsfalse --knob_rocksdb_use_direct_io_flush_compactionfalse \ contrib/mako_storage_bench.sh build_output4 rocksdb這兩個(gè)rocksdb_*knobs 對(duì) redwood 無(wú)害因此同樣的KNOBS也可用于... build_output4 redwood rocksdb的一次性雙引擎跑法。文檔記錄了一次 24Gi tmpfsm7a Pod上完整 300s/600s 跑的觀測(cè)加上 knobs 后 rocksdb 與 redwood 一樣跑成存儲(chǔ) CPU-bound約4.6k vs 4.8k TPS且峰值占用更小約3.3 GB vs redwood 的 5.5 GB——即 rocksdb 并沒有撐爆內(nèi)存盤。不過(guò)它的單次 GET 延遲更高、沖突率也更高這是正?,F(xiàn)象。你無(wú)法直接在 Pod 內(nèi)mount一個(gè) tmpfs開發(fā)容器沒有CAP_SYS_ADMIN所以mount -t tmpfs ...會(huì)以permission denied失敗。/dev/shm存在但被限制為 64 MB你在系統(tǒng)里看到的那些大 tmpfs 掛載如/var/okteto/secret等都是只讀的。因此這塊內(nèi)存目錄只能來(lái)自Pod 規(guī)格spec中的 memory-backedemptyDir。okteto 拓?fù)淇右?patch BASE deployment而不是 cloneokteto up并不是直接運(yùn)行你的 deployment。對(duì)于name: dev的 okteto manifest會(huì)存在兩個(gè) deploymentdev—— base deployment縮容到0/0。這是 okteto 克隆的來(lái)源source of truth。dev-okteto—— okteto 生成并**主動(dòng)調(diào)諧reconcile**的活動(dòng)克隆真正運(yùn)行你的 Pod。關(guān)鍵行為okteto 會(huì)剝掉它不擁有的 volumes對(duì)dev-okteto執(zhí)行kubectl patch deployment dev-okteto ...添加 volume 會(huì)靜默消失但 okteto 克隆時(shí)會(huì)保留 base deployment 的 volumes這正是efs-ccache、fdb cluster 文件等能到達(dá)開發(fā) Pod 的方式。所以 volume 必須加到basedevdeployment 上okteto up隨后會(huì)把它帶進(jìn) Pod。下文示例使用 deployment 名gglass-dev請(qǐng)?zhí)鎿Q為你 okteto manifest 的name:。設(shè)置步驟1. 提高開發(fā)容器內(nèi)存上限okteto.ymlmemory-backedemptyDir的內(nèi)容會(huì)計(jì)入容器的 memory cgroup即占用dev容器的內(nèi)存limit而不是節(jié)點(diǎn)的空閑 RAM。因此 tmpfs 內(nèi)容加上所有 fdbserver/mako 的 RSS 必須落在 limit 之內(nèi)。在okteto.yml中提高它resources: requests: cpu: 4000m memory: 24Gi # was 16Gi limits: cpu: 8000m memory: 48Gi # was 32Gi -- room for a 24Gi tmpfs fdbserver/mako RSS這部分確實(shí)會(huì)跨okteto up持久保存在okteto.yml中。2. 給 base deployment 添加 tmpfs volumeokteto.yml這種 manifest 格式無(wú)法聲明emptyDir因此以 strategic-merge patch 的方式應(yīng)用到basedeployment。保存為fdb-ramdisk.yamlspec: template: spec: volumes: - name: ramdisk emptyDir: medium: Memory sizeLimit: 24Gi containers: - name: dev volumeMounts: - name: ramdisk mountPath: /mnt/ram應(yīng)用到 base它處于 0 副本不影響正在運(yùn)行的東西kubectl patch deployment gglass-dev --patch-file fdb-ramdisk.yaml注意該 patch 修改的是活著的 base deployment。任何供應(yīng)gglass-dev的機(jī)制你的 dev-pod 基礎(chǔ)設(shè)施/manifest在重新應(yīng)用時(shí)都會(huì)覆蓋它。若要永久化請(qǐng)把同樣的volumes/volumeMounts塊加到那個(gè)源 manifest 中。3. 重建 Podokteto upokteto 會(huì)把已 patch 的base 克隆成dev-okteto因此新 Pod 會(huì)擁有/mnt/ram和 48Gi 上限。4. 驗(yàn)證kubectl exec pod -c dev -- df -hT /mnt/ram # 期望tmpfs, 24G kubectl exec pod -c dev -- sh -c touch /mnt/ram/.w rm /mnt/ram/.w echo ok第二條命令驗(yàn)證/mnt/ram可寫。tmpfs 容量規(guī)劃磁盤占用隨總插入量 TPS × 墻鐘時(shí)間增長(zhǎng)默認(rèn)g18ui工作負(fù)載每次事務(wù)插入一個(gè)新 key。內(nèi)存盤提高了 TPS因此同樣的墻鐘時(shí)間會(huì)比 EBS 寫出更多數(shù)據(jù)。作為參考EBS 上 ~1.5k TPS 跑 600 s 大約寫了 ~4 GBredwood 文件是主體考慮 COW/extent 開銷后約~2 KB/次插入。兩個(gè)事實(shí)讓容量規(guī)劃變得簡(jiǎn)單tmpfs 的sizeLimit是硬上限超出寫入會(huì)得到 ENOSPC并且其用量計(jì)入容器內(nèi)存上限超過(guò)即 OOMKill內(nèi)存只在實(shí)際寫入字節(jié)時(shí)消耗而不是預(yù)先保留。建議默認(rèn)的完整 300s/600s 跑在24Gi tmpfs上對(duì) redwood 綽綽有余峰值約 5.5 GB。若引擎更快或跑得更久想控制占用可以用SECONDS_RUN120 WARMUP_SECONDS60縮短一旦 CPU-bound2 分鐘的測(cè)量窗口足夠。sizeLimit: 24Gilimits.memory: 48Gi可從容覆蓋上述場(chǎng)景。對(duì)于極高 TPS 或長(zhǎng)時(shí)間運(yùn)行兩者一起上調(diào)例如 40Gi tmpfs / 64Gi limit并確認(rèn)節(jié)點(diǎn)確實(shí)有這么多 RAM。禁用 / 回退從 base 移除 volume 并重新克隆kubectl patch deployment gglass-dev --typejson \ -p [{op:remove,path:/spec/template/spec/volumes/-}] okteto up或重新應(yīng)用你的 basegglass-devmanifest。如需恢復(fù)原來(lái)的內(nèi)存上限還原okteto.yml中的 memory limits。腳本現(xiàn)在在/mnt/ram存在時(shí)自動(dòng)優(yōu)先使用它所以普通運(yùn)行就會(huì)用內(nèi)存盤。要不刪除 volume 而強(qiáng)制使用 EBS 數(shù)據(jù)目錄可對(duì)該次運(yùn)行導(dǎo)出WORKDIR$PWD/mako_storage_bench任何非 tmpfs 路徑均可。其他坑你會(huì)丟失build_output4。它位于易失的容器 overlay 上而內(nèi)存上限的修改和 volume patch 都會(huì)觸發(fā) Pod 滾動(dòng)更新rollout。之后用run-ccmk4或你自己的構(gòu)建包裝腳本重建——ccache 在持久 EFS volume 上因此熱重建只需幾分鐘而不是冷構(gòu)建。mako鏈接libfdb_c.so且以SKIP_BUILD_RPATH構(gòu)建。mako_storage_bench.sh已經(jīng)設(shè)置LD_LIBRARY_PATHbuild/lib以及LD_BIND_NOW1使 mako 加載匹配的客戶端見 contrib/mako_storage_bench.sh。這與內(nèi)存盤無(wú)關(guān)但正是 mako 能從構(gòu)建樹直接運(yùn)行的原因。mako 退出時(shí)會(huì)在_dl_fini中 abortlibfdb_c 作為共享庫(kù)的 teardown 問(wèn)題但發(fā)生在寫出全部輸出之后。腳本以已完成的報(bào)告文本中檢索Overall TPS見 contrib/mako_storage_bench.sh判斷成功并禁用了 core dumpulimit -c 0所以這是無(wú)害的——看到 abort 信息不必驚慌。附一次跑完后的產(chǎn)物每次引擎跑完成后輸出位于${WORKDIR}/${label}/下mako-run.txt—— mako run 階段的 tee 報(bào)告含Overall TPS等匯總mako.json—— 逐秒采樣與最終統(tǒng)計(jì)--json_reportmako-sketch.json—— 原始延遲 sketch--stats_export_pathcluster-start.log、mako-build.txt—— 集群?jiǎn)?dòng)日志與 mako 構(gòu)建階段輸出。A/B 對(duì)比時(shí)請(qǐng)務(wù)必在同一臺(tái)機(jī)器/實(shí)例上背靠背運(yùn)行基線構(gòu)建與實(shí)驗(yàn)構(gòu)建結(jié)果僅在相同硬件與條件下可比并重點(diǎn)觀察 TPS 差值——任何在存儲(chǔ)服務(wù)器熱路徑上新增的 CPU 開銷都會(huì)與單核存儲(chǔ)進(jìn)程爭(zhēng)搶 CPU通常表現(xiàn)為吞吐下降而非明顯延遲。贊分享分布式數(shù)據(jù)庫(kù)KV存儲(chǔ)數(shù)據(jù)庫(kù)后端【免費(fèi)下載鏈接】foundationdbFoundationDB - the open source, distributed, transactional key-value store項(xiàng)目地址https://gitcode.com/gh_mirrors/fo/foundationdb點(diǎn)擊查看免費(fèi)下載相關(guān)推薦探索未來(lái)開發(fā)Okteto——在Kubernetes上的應(yīng)用開發(fā)利器探索未來(lái)開發(fā)Okteto——在Kubernetes上的應(yīng)用開發(fā)利器 項(xiàng)目簡(jiǎn)介 在云原生時(shí)代Kubernetes的出現(xiàn)讓應(yīng)用程序部署達(dá)到了前所未有的高度但與云原生開發(fā)工具Delta Lake 基準(zhǔn)測(cè)試框架實(shí)戰(zhàn)指南在 AWS EMR 與 GCP Dataproc 上運(yùn)行 TPC-DS 基準(zhǔn)測(cè)試Delta Lake 基準(zhǔn)測(cè)試框架實(shí)戰(zhàn)指南在 AWS EMR 與 GCP Dataproc 上運(yùn)行 TPC DS 基準(zhǔn)測(cè)試 本指南基于 Delta Lake湖倉(cāng)一體數(shù)據(jù)工程數(shù)據(jù)湖30分鐘上手Kubernetes架構(gòu)可視化從Pod到存儲(chǔ)的完整實(shí)踐指南30分鐘上手Kubernetes架構(gòu)可視化從Pod到存儲(chǔ)的完整實(shí)踐指南 diagrams是一個(gè)功能強(qiáng)大的架構(gòu)可視化工具它允許你使用代碼來(lái)創(chuàng)建清晰、專業(yè)的云系數(shù)據(jù)可視化開發(fā)工具文檔上一篇徹底清理Owncast API文檔優(yōu)化實(shí)戰(zhàn)指南下一篇MTKClient項(xiàng)目中Preloader區(qū)域訪問(wèn)問(wèn)題的分析與解決創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考