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