前幾天寫了一篇文章《誰動了我的 MySQL ?》,反響還不錯。於是心血來潮,把之前遇到的另一個類似的問題整理出來,分享給大家,希望對用到的小夥伴有所幫助。
背景
與溯源 MySQL 的呼叫端場景類似,這個問題也是出現在我們的開發環境中。Redis 服務部署在測試環境,除了測試環境的程式連線 Redis 之外,開發小夥伴為了除錯方便,也會在自己的本地環境連線測試環境的 Redis,這就會造成一個問題:有時候不知道 Redis 的資料到底是被『誰』修改的,這該如何是好呢?
處理思路
處理這種『誰是兇手』的問題,一般都是考慮從『留痕』方面入手。
MySQL 是透過 binlog
來反向推理,那麼 Redis 呢?Redis 有沒有可以追蹤到命令執行痕跡的地方呢?
有,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 協議》,轉載必須註明作者和本文連結