我有一個壞習慣,安裝軟體的時候從來不讀授權條款。那個視窗跳出來,我的手指會自動找到「我同意」,比我的眼睛找到第一行字還快。我相信大部分人都一樣。這篇文章就是這個壞習慣的帳單。
先講 Redis 在 Windows 上的處境
Redis 是一個超級常用的記憶體內鍵值儲存,拿來當快取、當佇列、當計數器,什麼都行。它從 2011 年起就不再支援 Windows,微軟早年維護的移植版也封存多年。所以 Windows 上需要一個 Redis 相容的服務時,選項有兩類:跑在 WSL2 或 Docker 裡的正牌 Redis,或者原生的相容實作。
前者在我的機器上不可行,因為啟用 Hyper-V 會拖慢另一台重要的 VirtualBox 虛擬機,這件事我在別篇講過。所以我看的是後者。
Memurai 的條款
Memurai 是 Windows 原生的 Redis 相容產品,winget 能裝,開箱即用。我裝了免費的 Developer 版,用起來很順,儀表板的資料寫得進去也讀得出來,我很滿意,滿意了兩天。
第三天我不知道為什麼去看了它的日誌,看到一句話:Developer 版在正式環境使用是被禁止的,而且每十天會自動關閉。我盯著那行字看了很久。給自己用的系統算不算「正式環境」可以爭論,每十天停一次不能爭論。我沒有生氣,Memurai 沒有做錯什麼,它的條款寫得很清楚,是我裝之前沒讀。那個「我同意」按太快了。
Garnet 是什麼
微軟研究院在 2024 年 3 月公開的 Redis 相容儲存,MIT 授權,用 .NET 寫,講 RESP 協定,所以既有的 Redis 用戶端和程式不用改任何一行。它的設計目標是高吞吐和低延遲,支援分層儲存,論文裡的效能數字很漂亮,但我用到的只有最基本的鍵值和雜湊操作,那些數字對我來說像是買了一台跑車只拿來去巷口買早餐。
winget 上的版本很舊,直接從 GitHub 的正式發行頁抓 Windows 的壓縮檔,解壓即用,需要 .NET 8 執行環境。
下載時驗雜湊
發行頁公布了每個檔案的 SHA-256。我第一次下載被中斷,檔案不完整,雜湊不符,安裝腳本停在那裡,續傳之後才對上。這種檢查平常像儀式,像出門前摸一下口袋確認鑰匙在,一百次裡有九十九次都在。那天它做了它該做的事,我對所有從網路抓下來的二進位都這樣處理,不管來源多可信,因為「可信的來源」和「完整下載的檔案」是兩件事。
並行比對,再切換
我沒有直接換,這次學乖了。先讓 Garnet 聽另一個埠,跟 Memurai 並行,把應用程式會用到的每一個 Redis 指令對兩邊各打一次,比對回應,六十五個指令全部一致。確認之後才停掉 Memurai 的服務並設成停用,沒有解除安裝,要退回去是兩條指令的事。
「Redis 相容」這四個字在文件上和在你的指令集上是兩回事,只有後者算數。這就像餐廳說「素食可」,你還是要問清楚湯底是什麼。
小劇場:換掉會不會很麻煩
「所以你把整個快取換掉了?程式改了多少?」
「零行。」
「騙人。」
「真的零行。它講的是同一個協定,對程式來說就是換了一個講同樣語言的人接電話。」
「那你花的半天在做什麼?」
「在確認它真的講同樣的語言,六十五句話一句一句對。」
「聽起來很偏執。」
「換掉一個每十天會自己關機的東西,偏執一點是應該的。」
當子程序,不當服務
這是我最喜歡的一個決定。Garnet 沒有註冊成 Windows 服務。啟動應用程式的腳本先看標準埠上有沒有東西回應,沒有就把 Garnet 當子程序帶起來,整組停下時一起停。只綁本機迴路位址,日誌記憶體上限從預設的 16 GB 改成 512 MB,不開持久化,因為它在這裡只是快取,資料源頭在別的資料庫,丟了幾分鐘後會重新灌進來。
不開持久化聽起來很危險,但想一下:替快取做持久化,等於替副本再做一份副本。真正的資料在別的地方好好的,快取丟了就丟了,重新算一次就有。這跟你不會替影印的講義再影印一份備份是一樣的道理。
我對這件事的看法
換到 Garnet 花了半天,大部分時間在那六十五個指令的比對上。如果你在 Windows 上需要 Redis 相容的東西,又不想開 Hyper-V,Garnet 是我現在會先試的那一個。
至於讀授權條款的習慣,我現在至少會搜尋一下「production」這個字。這算不算進步我不確定,但至少下次帳單會小一點。
Redis 這兩年的授權風波
講 Garnet 不能不講 Redis 這兩年發生的事。2024 年 3 月,Redis 公司把授權從 BSD 改成兩個限制較多的授權,理由是不想讓雲端業者白用。社群的反應很快,Linux 基金會在幾週內就支持了一個分支叫 Valkey,很多發行版和雲端業者轉過去。2025 年 5 月,Redis 8 又加回了 AGPL 這個開源授權選項,算是往回走了一步。
這段歷史對用 Windows 的人來說有一個意外的好處:Redis 相容的替代品變多了,Valkey、Garnet、還有幾個更小的專案,大家都講 RESP 協定,用戶端不用改。Garnet 是其中唯一原生跑在 Windows 上的,因為它是 .NET 寫的,而且它從頭到尾都是 MIT,沒有經歷那些風波。
它來自微軟研究院一個做高效能儲存的團隊,他們之前的專案叫 FASTER,Garnet 是在那個基礎上做的。論文裡的吞吐量數字比 Redis 高很多,但那是在他們的測試環境;我自己的用量離那些數字很遠,遠到沒有意義。對我來說,它的價值是「原生 Windows、MIT、講 RESP」這三件事,效能是附贈的。
常見的三個誤會
第一個誤會是「Redis 相容就是 Redis」。相容的是協定和大部分指令,不是全部。Lua 腳本、某些模組、某些新指令可能沒有。這是為什麼要拿自己的指令集去對,而不是看文件上的相容性表格。
第二個誤會是「快取一定要持久化」。看你放什麼。放的是可以重算的東西,持久化只是多一份要管的檔案;放的是 session 或佇列這種丟了會出事的東西,才需要。先問「這個東西丟了會怎樣」,再決定要不要開。
第三個誤會是「Developer 版就是免費版」。有時候是,有時候是「免費但有條件」。Memurai 的條件寫在條款裡、寫在日誌裡,就是沒有寫在下載按鈕旁邊。裝任何東西之前,搜尋一下條款裡的 production 這個字,五秒鐘的事。
一個週末可以試的小練習
從 Garnet 的 GitHub 發行頁下載 Windows 的壓縮檔,對一下 SHA-256,解壓,執行裡面的 GarnetServer.exe。它會聽在標準的 Redis 埠。然後用任何一個 Redis 用戶端連上去,redis-cli 或 Python 的 redis 套件都行,PING 一下,SET 一個鍵,GET 回來。
接著試一個稍微複雜的:HSET 一個雜湊、ZADD 一個有序集合、EXPIRE 一個鍵然後等它消失。這幾個指令涵蓋了大部分快取用途。做完你會發現,「Redis 相容」在這些日常操作上是真的,然後你就可以放心地去對你自己那些比較特別的指令了。
後記
那個「我同意」按太快的習慣,我後來想,其實不只是懶,是一種信任:相信東西既然能下載就能用。這個信任大部分時候沒事,出事的時候帳單就會像這篇一樣長。現在我至少會搜尋一個字,這算不算成長我不確定,但我的快取不會再每十天關機了,這是確定的。
留言(0)
還沒有留言。讀完有想法,歡迎留下第一則。