Redis 把資料放在記憶體裡,回應時間約一毫秒,所以它以快取、佇列或工作階段儲存的角色,藏在許許多多應用程式的背後。安裝只要一條指令。真正的工作在預設設定上:沒有記憶體上限,快照可能遺失最近的寫入,還有兩個很容易犯的錯誤,會悄悄刪掉你的資料或讓密碼失效。本文在 Ubuntu 24.04 上把這些都講清楚。每一步我們都在自家映像上跑過,數字來自一台 Micro 伺服器(2 vCPU、2 GB)。
你需要一個具 sudo 權限的使用者。Ubuntu 設定指南會建立一個。
1. 安裝
sudo apt update
sudo apt install -y redis-server
redis-server --version
redis-cli ping
安裝花了 13 秒,裝上的是 Redis 7.0.15。它會立刻啟動,之後每次開機自動執行,回應 PONG,而且只在伺服器本機監聽:127.0.0.1:6379 和 [::1]:6379,並開啟 protected-mode yes。沒有資料時佔用 13.5 MB 記憶體。
記錄裡已經有一則警告:
WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition.
Redis 用 fork 出來的副本把資料寫到磁碟,而在核心的預設設定下,記憶體吃緊時這個 fork 可能失敗。改一次就好:
echo 'vm.overcommit_memory = 1' | sudo tee /etc/sysctl.d/90-redis.conf
sudo sysctl -p /etc/sysctl.d/90-redis.conf
sudo systemctl restart redis-server
重新啟動後警告消失了。
2. 限制記憶體
預設的 maxmemory 是 0,也就是沒有上限,策略是 noeviction。Redis 會一直佔用記憶體,直到伺服器用完。設定一個上限,並決定達到上限時怎麼處理:
redis-cli CONFIG SET maxmemory 256mb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE
我們在 64 MB 上限下寫入 40 萬次,測試了兩種策略:
noeviction(預設):記憶體停在 63 MB,新的寫入出現錯誤OOM command not allowed when used memory > 'maxmemory'。適合佇列,或任何不能遺失的資料。allkeys-lru:Redis 淘汰了最久未使用的鍵,共 48,606 個,所有寫入都成功。適合快取。
CONFIG REWRITE 會把目前的設定寫入 /etc/redis/redis.conf,重新啟動後依然有效。它還會加上一行,第 4 步之前你需要知道。
3. 選擇持久化方式
預設情況下,Redis 在 1 小時內有 1 次、5 分鐘內有 100 次或 1 分鐘內有 1 萬次變更時寫一次快照(/var/lib/redis/dump.rdb)。我們用三種方式讓它停止:
| Redis 如何停止 | 只有快照(預設) | 開啟 AOF |
|---|---|---|
systemctl restart | 沒有遺失:關閉時會儲存 | 沒有遺失 |
用 kill -9 強制結束 | 最後一次快照之後寫入的鍵不見了 | 強制結束前 2 秒寫入的鍵還在 |
兩種情況下,systemd 都在幾秒內自動把 Redis 重新啟動。
如果 Redis 裡存著遺失了會心疼的資料,就開啟 AOF(append-only file)。它會記錄每一次寫入,並每秒寫入磁碟一次。請在執行中的伺服器上開啟,不要去改設定檔:
redis-cli CONFIG SET appendonly yes
redis-cli CONFIG REWRITE
redis-cli INFO persistence | grep aof_
我們一開始走了另一條路,結果遺失了資料。我們把 redis.conf 裡的 appendonly no 改成 appendonly yes 再重新啟動。Redis 帶著一個空的 AOF 啟動,沒有從快照載入任何東西,原本的鍵全部不見。之後它關閉時,又把不含舊鍵的新內容覆寫進 dump.rdb。CONFIG SET 能避免這個問題:Redis 會先用記憶體中的資料產生 AOF。重新啟動後,我們所有的鍵都還在。
如果 Redis 只是可以從空白開始的純快取,那就反過來,用 redis-cli CONFIG SET save "" 關閉持久化。
4. 設定密碼
這是第二個陷阱。只要執行過一次 CONFIG REWRITE,Redis 7 就會在 redis.conf 結尾加上這一行:
user default on nopass ~* &* +@all
它的意思是「預設使用者不需要密碼」。之後我們在檔案上方加了 requirepass 並重新啟動,Redis 仍然不用密碼就回應 PONG,因為 user 這一行的優先順序較高。請改由 Redis 設定密碼:
REDIS_PASS=$(openssl rand -hex 24)
echo "$REDIS_PASS"
redis-cli CONFIG SET requirepass "$REDIS_PASS"
REDISCLI_AUTH="$REDIS_PASS" redis-cli CONFIG REWRITE
把密碼存在安全的地方。現在 Redis 會把它以 SHA-256 雜湊存在同一行 user default 裡。重新啟動後,redis-cli ping 回應 NOAUTH Authentication required.,只有帶上密碼才能使用。傳密碼給 redis-cli 時請用 REDISCLI_AUTH 環境變數;用 -a 的話,密碼會出現在行程清單中,redis-cli 也會發出警告。在應用程式裡,把密碼寫進 Redis 位址:redis://:PASSWORD@127.0.0.1:6379/0。
5. 從自己的電腦存取
讓 Redis 繼續只監聽 127.0.0.1,改用 SSH 通道存取。填入伺服器的 SSH 連接埠,在 NAT 方案上就是你的專屬連接埠:
ssh -N -L 6380:127.0.0.1:6379 deploy@YOUR_SERVER_IP -p 22
通道開著的時候,你電腦上的 redis-cli -p 6380 和桌面工具就能和伺服器上的 Redis 溝通,而網際網路上沒有新開放任何東西。依照 SSH 金鑰指南設定後,通道登入不需要密碼。
速度如何
在 Micro 測試伺服器上,用 50 個用戶端執行 redis-benchmark 的結果:
| 測試 | 每秒請求數 | 延遲中位數 |
|---|---|---|
| SET | 30,303 | 1.0 ms |
| GET | 35,149 | 0.9 ms |
| SET,每次往返 16 條指令 | 272,109 | 2.4 ms |
| GET,每次往返 16 條指令 | 414,938 | 1.3 ms |
對網頁應用程式的快取或工作佇列來說,這遠遠超出需要。多出來的速度來自批次傳送指令(pipelining)。
選哪個方案
Redis 需要的是存放資料的記憶體,其他幾乎不需要。Nano(2 vCPU、1 GB、每月 $3)在 maxmemory 256mb 下可以和小型應用程式一起執行 Redis。Micro(2 GB、每月 $5)能為更大的快取和應用程式留下空間。如果有其他機器需要直接連線 Redis,就使用獨立 IPv4(Nano-IP 起,每月 $8),並在防火牆中只允許那一個位址。所有方案都在 VPS 頁面,付款方式為 Base、Ethereum 或 Polygon 網路上的 USDT、USDC 或 ETH。
評論
目前還沒有評論。歡迎成為第一位。