dsh-session-repacker:把 DSH 會話日誌重打包爲官方兩幀形態,舊會話打開提速約 6 倍

前言

如果你用 DSH 跑過長會話,大概率遇到過這種情況:點開一箇舊會話,要等上好幾秒纔有反應。問題出在存儲層——DSH 的 JSONL 會話後端每次寫入批處理都會單獨壓縮成一個 zstd 幀再追加到文件尾部,一個長會話動輒上萬個幀;而讀取時必須逐幀解壓,後端又沒有 seek 式後綴讀取,無論只要尾部還是全部,都得解碼整個文件。

幀數是歷史寫入定形的,事後無法自己收縮。kkishapppy/dsh-session-repacker 就是針對這個問題:把散落的萬幀日誌重打包成官方原生形態,實測最大會話打開耗時從約 661ms 降到約 126ms。

這是什麼

dsh-session-repacker 是一個 DSH 插件(MIT 許可證,版本 0.1.0),由 kkishapppy 維護。它把 DSH JSONL 會話後端逐批寫入產生的成千上萬個獨立 zstd 幀重打包爲官方原生兩幀形態:頭部幀恰好一行 header,其餘全部明文拼接後重壓爲單個事件幀。

兩個關鍵點:

1、重打包後的明文逐字節不變。dsh 讀取路徑完全兼容,讀取側的 assertZstdHeaderFrame 只要求第一幀恰爲一行 header,重打包結果滿足這一要求。

2、插件只做維護,不改變任何讀取 API 與數據語義。覆蓋一切從磁盤讀舊會話的路徑:GUI 打開、新對話接續/分支、子會話繼承。

效果數據

作者給出的實測結果:

對象 重打包前 重打包後
最大單個會話 14,467 幀 / 5.49MB / 約 661ms 2 幀 / 2.09MB / 約 126ms(約 6 倍)
全量 24 箇舊會話 39,911 幀 / 20.08MB 48 幀 / 10.67MB

除了打開速度,壓縮體積也約減半——單個大幀的壓縮率遠好於上萬個獨立小幀。

安裝與啓用

作爲 DSH 插件安裝(推薦):

dsh plugin --profile web add dsh-session-repacker

也可以克隆到 plugins/ 目錄後 link 進 profile。如果要自己構建,在倉庫目錄執行:

npm i
npx -y tsdown@0.22.2 --config ./tsdown.config.ts

產物爲 lib/index.mjs

啓用需要在 profiles/<profile>/cordis.patch.yml 裏配置插件和參數:

- id: session-repacker
  config:
    root: 'E:\DeepSeekHarness\sessions'   # 會話根目錄(必填)
    minFrames: 200        # 幀數低於此值不處理(默認 200)
    minAgeMs: 600000      # mtime 距今不足此值不處理(默認 10 分鐘)
    intervalMs: 3600000   # 週期維護間隔毫秒(默認 1 小時)

重啓服務器後生效:插件啓動時做一次全量掃描,之後按 intervalMs 週期維護。root 是唯一必填項,其餘三項都有默認值,不配也能跑。

獨立 CLI

如果不想掛插件跑後臺任務,倉庫提供獨立 CLI,不需要 DSH 服務:

node tools/repack.mjs <root>                  # 掃描並重打包
node tools/repack.mjs <root> --dry-run        # 只統計不落盤
node tools/repack.mjs <root> --file <path>    # 只處理指定文件(可多次)
node tools/repack.mjs <root> --min-frames 64 --min-age-ms 60000

建議先跑一次 --dry-run 看統計,確認範圍和預期收益後再實際執行。--file 可以重複傳入,適合只處理某幾個重點會話;--min-frames--min-age-ms 用於自定義閾值。

安全設計

重打包會替換磁盤上的會話文件,安全性是這個插件的着力點,措施包括:

1、只處理 .jsonl.zstd 文件,跳過 mtime 距今小於 minAgeMs 的文件,避開活躍寫入。

2、跳過當前 live 會話。

3、替換前做字節級等價校驗:新文件解壓出的明文必須與原始明文完全一致。

4、替換前再次 stat 比對 size/mtime,如果文件在此期間被併發追加,放棄本次操作。

5、torn tail(未寫完的幀)直接跳過,交給 dsh 自身的修復路徑處理。

6、寫入採用臨時文件 + fsync + 原子 rename,Windows 下與官方後端同構。

另外,服務器對重打包後的文件追加新幀(如 session/end-seed 等)實測兼容,追加後的文件還可以被再次重打包,操作是冪等的。

適用場景與注意

適合的場景:會話歷史長、打開慢,且舊會話幀數已經定形無法自行收縮的部署。配合後臺週期維護,可以讓這件事自動化。

幾個注意點:

  • 已產生的舊文件幀數定形後無法回溯壓縮,只能靠本插件或 CLI 重打包。如果想讓未來日誌少產生幀,可以調大 writeBatchMaxDelayMs(默認 200ms),這是耐久性上的權衡。
  • 插件以當前 dsh 進程的權限運行,會直接替換會話文件。安裝前建議檢查源碼與許可證,先在測試環境用 --dry-run 驗證。

結尾

dsh-session-repacker 解決的問題很具體:DSH 逐批寫入留下的萬幀 zstd 日誌拖慢舊會話讀取。它不改數據語義,只把文件恢復成官方原生兩幀形態,換來約 6 倍的打開提速和約一半的體積,同時給出了一套完整的安全防護。在 DSH「一切皆插件」的思路下,這是一個典型的存儲層維護型插件。

  • 目錄頁:https://www.skillhub.cn/plugins/kkishapppy/dsh-session-repacker
  • GitHub:https://github.com/kkishapppy/dsh-session-repacker
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜