步驟一:client經過網絡向Redis發送一條命令 步驟二:因爲Redis是單線程應用,能夠把Redis想像成一個隊列,client執行的全部命令都在排隊等着server端執行 步驟三:Redis服務端按順序執行命令 步驟四:server端把命令結果經過網絡返回給client
說明:python
慢查詢發生在命令執行過程當中,不包含網絡延遲時間及排除等待執行的時間 客戶端超時不必定慢查詢,但慢查詢是客戶端超時的一個可能因素
slowlog-max-len 慢查詢隊列的長度 slowlog-log-slower-than 慢查詢閾值(單位:微秒),執行時間超過閥值的命令會被加入慢查詢命令 若是設置爲0,則會記錄全部命令,一般在須要記錄每條命令的執行時間時使用 若是設置爲小於0,則不記錄任何命令 slowlog list 慢查詢記錄
說明:redis
慢查詢是一個先進先出的隊列,若是一條命令在執行過程當中被列入慢查詢範圍內,就會被放入一個隊列,這個隊列是基於Redis的列表來實現 ,並且這個隊列是固定長度的,當隊列的長度達到固定長度時,最早被放入隊列就會被pop出去 慢查詢隊列保存在內存之中,不會作持久化,當Redis重啓以後就會消失
修改/etc/redis.conf配置文件,配置慢查詢 修改配置方式應該在第一次配置Redis中時配置完成,生產後不建議修改配置文件
127.0.0.1:6379> config get slowlog-max-len 1) "slowlog-max-len" 2) "128" 127.0.0.1:6379> config get slowlog-log-slower-than 1) "slowlog-log-slower-than" 2) "10000" 127.0.0.1:6379> config set slowlog-max-len 1000 OK 127.0.0.1:6379> config get slowlog-max-len 1) "slowlog-max-len" 2) "1000" 127.0.0.1:6379> config set slowlog-log-slower-than 1000 OK 127.0.0.1:6379> config get slowlog-log-slower-than 1) "slowlog-log-slower-than" 2) "1000"
slowlog get [n] 獲取慢查詢隊列 slowlog len 獲取慢查詢隊列長度 slowlog reset 清空慢查詢隊列
slowlog-max-len不要設置太小,一般設置1000左右 slowlog-log-slower-than不要設置過大,默認10ms,一般設置1ms 理解命令生命週期 能夠經過slowlog get等命令按期將慢查詢命令持久化到其餘數據源,這樣就能夠查到不少歷史的慢查詢操做命令 在生產環境中,無論slowlog-max-len設置多大,當慢查詢命令逐步增多時,最開始的慢查詢命令會被丟掉 當須要查詢歷史數據時,這些慢查詢命令都是很是關鍵的 能夠使用開源軟件來實現這些功能,對於分析解決Redis問題是很是有幫助的
一次網絡命令通訊模型:網絡
client經過網絡傳輸命令到server端 server端經過計算獲得命令執行結果 server端把命令執行結果給client
此時:併發
一次網絡命令通訊時間=1次網絡時間 + 1次命令時間
此時若是有多條命令呢,那就只能一條一條的輸入命令執行了運維
n次時間 = n次網絡時間 + n次命令時間
Redis執行命令的時間很快,可是網絡傳輸卻可能有很大延遲,ui
pipeline就是把一批命令進行打包,而後傳輸給server端進行批量計算,而後按順序將執行結果返回給client端線程
使用Pipeline模型進行n次網絡通訊須要的時間code
1次pipeline(n條命令) = 1次網絡時間 + n次命令時間
import redis import time client = redis.StrictRedis(host='192.168.81.100',port=6379) start_time = time.time() for i in range(10000): client.hset('hashkey','field%d' % i,'value%d' % i) ctime = time.time() print(client.hlen('hashkey')) print(ctime - start_time)
程序執行結果:server
10000 2.0011684894561768
在上面的例子裏,直接向Redis中寫入10000條hash記錄,須要的時間爲2.00秒生命週期
使用pipeline的方式向Redis中寫入1萬條hash記錄
import redis import time client = redis.StrictRedis(host='192.168.81.100',port=6379) start_time = time.time() for i in range(100): pipeline = client.pipeline() j = i * 100 while j < (i+ 1) * 100: pipeline.hset('hashkey1','field%d' % j * 100,'value%d' % i) j += 1 pipeline.execute() ctime = time.time() print(client.hlen('hashkey1')) print(ctime - start_time)
程序執行結果:
10000 0.3175079822540283
能夠看到使用Pipeline方式每次向Redis服務端發送100條命令,發送100次所須要的時間僅爲0.31秒,能夠看到使用Pipeline能夠節省網絡傳輸時間
首先要注意每次pipeline攜帶數據量不能太大 pipeline能夠提升Redis批量處理的併發的能力,可是並不能無節制的使用 若是批量執行的命令數量過大,則很容易對網絡及客戶端形成很大影響,此時能夠把命令分割,每次發送少許的命令到服務端執行 pipeline每次只能做用在一個Redis節點上
發佈者(publisher) 訂閱者(subscriber) 頻道(channel)
Redis server就至關於頻道 發佈者是一個redis-cli,經過redis server發佈消息 訂閱者也是於一個redis-cli,若是訂閱了這個頻道,就能夠經過redis server獲取消息
說明:
發佈訂閱就是一個生產者消費者模型 每一個訂閱者能夠訂閱多個頻道 發佈者發佈消息後,訂閱者就能夠收到不一樣頻道的消息 訂閱者不能夠接收未訂閱頻道的消息 訂閱者訂閱某個頻道後,Redis沒法作消息的堆積,不能接收頻道被訂閱以前發佈的消息
publish channel message 發佈消息 subscribe [channel] 訂閱頻道 unsubscribe [channel] 取消訂閱 psubscribe [pattern...] 訂閱指定模式的頻道 punsubscribe [pattern...] 退訂指定模式的頻道 pubsub channels 列出至少有一個訂閱者的頻道 pubsub numsub [channel...] 列表給定頻道的訂閱者數量 pubsub numpat 列表被訂閱模式的數量
例子:
打開一個終端1
127.0.0.1:6379> subscribe sohu_tv # 訂閱sohu_tv頻道 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "sohu_tv" 3) (integer) 1
再次打開一個終端2
127.0.0.1:6379> publish sohu_tv 'hello python' # sohu_tv頻道發佈消息 (integer) 1 127.0.0.1:6379> publish sohu_tv 'hello world' # sohu_tv頻道發佈消息 (integer) 3
能夠看到終端1中已經接收到sohu_tv發佈的消息
127.0.0.1:6379> subscribe sohu_tv Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "sohu_tv" 3) (integer) 1 1) "message" 2) "sohu_tv" 3) "hello python" 1) "message" 2) "sohu_tv" 3) "hello world"
打開終端3,取消訂閱sohu_tc頻道
127.0.0.1:6379> unsubscribe sohu_tv 1) "unsubscribe" 2) "sohu_tv" 3) (integer) 0
redis server維護一個隊列 消息發佈者,至關於一個redis-cli,經過redis server發佈消息 消息訂閱者就至關於一個redis-cli,全部的消息訂閱者經過redis server搶消息發佈者發佈的消息