EQVPS
控制台開始使用

如何在 VPS 上安裝 Redis:記憶體上限、持久化與不會失效的密碼

在 Ubuntu 24.04 上安裝 Redis,限制它的記憶體以免佔滿整台伺服器,在不刪除資料的前提下開啟 AOF,並設定一個重新啟動後依然有效的密碼。其中兩步藏著陷阱,我們在自己的測試伺服器上踩過。

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 的結果:

測試每秒請求數延遲中位數
SET30,3031.0 ms
GET35,1490.9 ms
SET,每次往返 16 條指令272,1092.4 ms
GET,每次往返 16 條指令414,9381.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。

常見問題

Redis 需要多少記憶體?

Redis 本身很小:在我們的伺服器上剛裝好時只佔 13.5 MB。它真正需要的是存放資料的空間,因為資料都在記憶體裡。把 maxmemory 設成伺服器能騰出的量,例如 1 GB 的伺服器設 256 MB,並選好記憶體滿了之後怎麼辦。

選 Redis 還是 Valkey?

Valkey 是從 Redis 7.2 分出來的 Redis 分支,協定相同,所以大多數用戶端兩者都能用。Ubuntu 24.04 只提供 Redis 7.0.15。Debian 13 同時有 Redis 8.0 和 Valkey 8.1,Debian 12 可以從 backports 安裝 Valkey 8.0。本文的步驟兩者都適用。

為什麼 Redis 當機後會遺失資料?

預設情況下,Redis 會依變更的鍵數量,每隔幾分鐘把快照存到磁碟。我們強制結束行程後,最後一次快照之後寫入的鍵不見了。開啟每秒寫入一次的 AOF,當機時最多只會遺失大約一秒的寫入。

我在 redis.conf 裡加了 requirepass,為什麼 Redis 還是不用密碼就接受指令?

很可能之前某個時候執行過 CONFIG REWRITE。在 Redis 7 中,它會在 redis.conf 結尾加上一行 user default on nopass ~* &* +@all,這一行會讓寫在上方的 requirepass 失效。先用 CONFIG SET requirepass 設定密碼,再執行 CONFIG REWRITE,Redis 就會把密碼存進這一行。

可以把 6379 連接埠開放到網際網路嗎?

不要。開放的 Redis 連接埠時時刻刻被掃描,是入侵伺服器的常見途徑。從自己的電腦透過 SSH 通道連線 Redis,或把它和使用它的應用程式放在同一台伺服器上。

評論

目前還沒有評論。歡迎成為第一位。

發表評論

評論在顯示前會經過審核。