線上升級Redis紀實

菩提樹下的煮茶小童子發表於2017-10-27

hello world!
hello world!

##QPS相關

QPS,每秒處理請求數。可以在一定程度上反映某個服務此時的壓力情況。下面可以通過一個案例來分析下如何大致的估算一個服務的QPS。

背景:昨天上線的一個活動,會根據唱歌時間來進行送券行為,計算下此送券行為的QPS。

分析:每隔送券行為都會有一條日誌進行記錄,如下。

2017-10-27 15:10:16    songtime=355 userid=56135899 giftid=20331 addednumbers=1複製程式碼

因此計算出每秒的songtime請求就可以作為目標值了。

因此可以使用如下命令:

developer@hosttx:~$ sudo devpssh -i -h /opt/iplist.all.svn 'grep songtime /home/log/baofang-yanzhishengdian.log' | grep 10-27 | cut -d " " -f 2  | uniq -c複製程式碼

由於訪問人數比較少,所以基本上QPS為2~3。

解釋:也許你會好奇,這是怎麼計算出來的呢?下面來解釋一下,我們的目標就是檢視某一秒下有songtime日誌的條數。

  • 判斷一條日誌中是否包含songtime ,可以使用grep命令。
  • 線上上多臺GET機之間查詢日誌記錄,可以使用sudo devpssh -i -h /opt/iplist.all.svn 'grep songtime /home/log/baofang-yanzhishengdian.log'
  • 切分出秒級日誌可以使用cut命令,-d "delimiter"用於指定分隔字元, -fN用於顯示哪一個field欄位,預設從1開始計數。
  • uniq命令短小精悍,-c引數就是用於統計的,但是隻有相鄰的兩行同樣的日誌才會被累加在第一條前面的序號上。

模擬一下Redis的同步流程

先看看目前電腦上有沒有啟動redis服務:

ps aux | grep redis-server
ps aux | grep redis-server

看來是沒有,那麼我們就可以啟動幾個redis-server,因為是在一臺機器上,所以指定不同的埠就好了。

redis-server --port 6666
redis-server --port 6666

同樣,使用redis-server --port 7777 再開啟一個redis服務。

最後再來看下服務到底有沒有啟動吧。

ps aux | grep redis-server
ps aux | grep redis-server

好了,現在是兩個全新的redis服務了,在開始準備具體的主從複製,同步操作前,先指定下主從關係。

  • 埠為6666的作為master
  • 埠為7777的作為slave

然後通過一個redis-cli的monitor命令監視下slave,看看在master中的某些key發生變化的時候,slave會做出什麼樣的反應。

對slave使用monitor監視
對slave使用monitor監視

下面讓7777作為6666的slave。

slaveof 127.0.0.1 6666
slaveof 127.0.0.1 6666

同時在7777server的終端下會出現其作為6666的slave的一些輸出。

7777終端輸出
7777終端輸出

而同時刻作為master的6666也會對7777發來的同步請求做出相應的反應。

6666終端輸出
6666終端輸出

確認同步結果
確認同步結果

模擬同步,這個時候只需要在master中隨便set幾個key,看看slave的monitor視窗中的輸出即可。

slave實時同步master
slave實時同步master

可以看出,slave會實時將master上的資料同步過來,達到資料的一致性。這樣,簡單的主從同步,就算是完成了。

但是需要注意的是,作為slave的redis是不能被寫入的。比如我們隨便在slave上set幾個key,看看能否成功,不出意外的話,你會看到如下結果。

slave狀態下不能寫入資料
slave狀態下不能寫入資料

這是因為redis的從slave-read-only預設是yes即只讀狀態的,所以同步完成後要修改這個變數,config set slave-read-only no就可以。

config set slave-read-only no
config set slave-read-only no

對slave的操作不會對master產生影響,這是必須的了。

對slave的操作不會影響master
對slave的操作不會影響master

最後同步完成之後,如果不想讓7777作為6666的slave了,就可以使用slaveof no one來實現。

停止slave模式可以使用slaveof no one 來實現
停止slave模式可以使用slaveof no one 來實現

線上升級redis

線上跑的redis一般為了穩定性,版本都不會很高。但是也不能太低了不是,因此有時候升級redis是很有必要的,這也是不可避免的。但是線上的redis通常會包含大量的資料,有可能多達N個多G,而且不能直接進行主從同步,這樣來自slave的同步請求會擠垮來自外部的使用者請求。導致服務出現報警。

通常對線上Redis做升級的話,有這樣的思路: 找個替身,然後做如下步驟。

  • 讓替身slave成為線上機器,同步完成後,將slave-read-only 設定為no
  • 將線上流量引入到slave上, 此時slave成為線上機器,檢視線上機器的QPS,直至為0。
  • 趁此時,解除安裝線上的舊Redis,然後安裝新版本的Redis
  • 新版本的Redis作為slave同步線上Redis的資料,同步完成後同樣將slave-read-only設定為no, 然後將線上流量引回來,此時檢視剛才的替身RedisQPS為0即可。

在這個過程中,檢視redis請求的QPS最好的方法就是通過monitor來實現。

redis-cli -h 127.0.0.1 -p 6379 monitor | cut -d "." -f1 | uniq -c複製程式碼

而在升級線上Redis的時候,尤其要注意外部連線數,有時是正常的業務請求,有時是crontab統計資料跑的指令碼,反正情況多樣,可以通過ss -anp | grep redis:port 命令 檢視連線情況。

需要注意的是要使用root許可權,才能看得到具體的PID資訊。

ss -anp | grep .7777
ss -anp | grep .7777

然後可以通過ps aux命令找到具體是那條命令在跑著。然後對症下藥,完成整個操作。

檢視具體是什麼命令在連線redis
檢視具體是什麼命令在連線redis


總結

回顧一下,這篇文章主要是為了談談對線上redis升級的體會,以及一些常識性的內容的敘述。為了循序漸進,講了QPSRedis的主從同步的具體操作步驟,最後引出升級的步驟和過程。

其實步驟什麼的不重要,重要的在於整體的思路,還有對工具的使用的熟練程度。

相關文章