誰動了我的 Redis ?

快樂的皮拉夫發表於2023-05-03

前幾天寫了一篇文章《誰動了我的 MySQL ?》,反響還不錯。於是心血來潮,把之前遇到的另一個類似的問題整理出來,分享給大家,希望對用到的小夥伴有所幫助。

背景

與溯源 MySQL 的呼叫端場景類似,這個問題也是出現在我們的開發環境中。Redis 服務部署在測試環境,除了測試環境的程式連線 Redis 之外,開發小夥伴為了除錯方便,也會在自己的本地環境連線測試環境的 Redis,這就會造成一個問題:有時候不知道 Redis 的資料到底是被『誰』修改的,這該如何是好呢?

處理思路

處理這種『誰是兇手』的問題,一般都是考慮從『留痕』方面入手。

MySQL 是透過 binlog 來反向推理,那麼 Redis 呢?Redis 有沒有可以追蹤到命令執行痕跡的地方呢?

有,monitor

monitor命令使用檔案

經常操作 Redis 的小夥伴對這個命令肯定不會陌生,在日常除錯和問題定位的時候往往能起到立竿見影的效果。這裡借用使用檔案中的例子來看一下它的用法:

127.0.0.1:6379> MONITOR
OK
# 以第一個列印值為例
# 1378822099.421623 是時間戳
# [0 127.0.0.1:56604] 中的 0 是資料庫號碼, 127...IP 地址和埠
# "PING" 是被執行的命令
1378822099.421623 [0 127.0.0.1:56604] "PING"
1378822105.089572 [0 127.0.0.1:56604] "SET" "msg" "hello world"
1378822109.036925 [0 127.0.0.1:56604] "SET" "number" "123"
1378822140.649496 [0 127.0.0.1:56604] "SADD" "fruits" "Apple" "Banana" "Cherry"
1378822154.117160 [0 127.0.0.1:56604] "EXPIRE" "msg" "10086"
1378822257.329412 [0 127.0.0.1:56604] "KEYS" "*"
1378822258.690131 [0 127.0.0.1:56604] "DBSIZE"

從輸出資訊中我們可以看到,輸出資訊中包含了呼叫客戶端的的 IP埠號,透過這兩個資訊,我們就可以定位到是哪臺機器執行的命令了。

根據埠號定位呼叫程式的命令如下:

lsof -i:{埠號}

在輸出中可以看到呼叫程式的 PID,然後根據 PID 定位到具體的程式:

ps -p {pid} -f

有時如果公司是同一個公網 IP 的話,這時候只能根據埠號的佔用情況在本地機器上進行排查了,只是麻煩了點。

在實際應用中,如果 Redis 操作命令頻繁的話, monitor 記錄的日誌數量會很多,不方便直接查閱。我們一般會先將 monitor 內容輸出到日誌中,命令如下:

redis-cli monitor > ~/redis.log

然後使用 Linux grep 命令進行排查分析就可以了。

cat ~/redis.log | grep '{關鍵字}'

題外話

在開發環境中,儘量不要在本地環境直連測試環境的 Redis ,因為這會導致在本地進行開發過程中,直接修改測試 Redis 的資料。

本地開發的過程中,操作都比較隨意,可能會因為自己本地隨意的除錯行為,讓正在使用測試環境的人痛苦不堪,特別是在本地監聽 Redis 佇列時。

本作品採用《CC 協議》,轉載必須註明作者和本文連結
你應該瞭解真相,真相會讓你自由。

相關文章