隊列 管道 python使用redis

消息通知

任務隊列

優點: 1.松耦合 2.易於擴展

BRPOP

功能:當列表中沒有元素時BRPOP命令會一直阻塞住連接,直到有新元素加入.

  • BRPOP接受兩個參數,第一個是鍵名,第二個是超時時間,單位是秒.當超過了此時間仍然沒有獲得新元素就回返回nil.
    當超時時間爲0時,表示不限制等待的時間,即如果沒有新元素加入列表就會永遠阻塞下去
  • 當獲得一個元素後BRPOP命令返回兩個值,分別是鍵名和元素值.
打開兩個實例:
redisA> BRPOP queue 0   這時會陷入阻塞狀態
redisB> LPUSH queue task 實例B向queue中加入一個元素
LPUSH命令執行完後實例A馬上就返回了結果 "queue" "task"
  • 除了BRPOP命令從隊列右側取數據外,BLPOP從隊列左側取值

優先級隊列

  • BRPOP命令可以接收多個鍵,其完整的格式爲BLPOP key [key…] timeout
例: BLPOP queue:1 queue:2 queue:3
不論queue:3,queue:2中有多少值,都會優先彈出最前面的key值的隊列中的值,由此可以配置取值優先級

"發佈/訂閱"模式

  1. 發佈者發佈消息(返回值表示接收到這條消息的訂閱者數量)
publish channel message
  1. 訂閱頻道
subscribe channel_name channel_name channel_name...

進入訂閱狀態客戶端可能收到三種類型的回覆,每種類型包含3個值,第一個是消息的類型,根據消息類型的不同,第二,三個值的含義也不同,
消息類型取值

  • subscribe.表示訂閱成功的反饋信息,第二個值是訂閱成功的頻道名稱,第三個值是當前客戶端訂閱的頻道數量
  • message.這個類型表示接收到的消息,第二個值表示產生消息的頻道名稱,第三個值是消息的內容
  • unsubscribe.表示成功取消訂閱某個頻道.第二個值是對應的頻道名稱,第三個值是當前客戶端訂閱的頻道數量,當此值爲0時客戶端會退出訂閱狀態,
    之後就可以執行其他非"發佈/訂閱"模式的命令了

按照規則訂閱

psubscribe channel.?* 訂閱指定的規則

  • channel.?*可以匹配channel.1和channel.10,但是不會匹配channel.
  • 收到的結果爲第一個值"pmessage"是通過psubscribe命令訂閱頻道得到的
  • 第二個值"channel.?*" 表示訂閱時使用的通配符
  • 第三個值表示實際收到信息的頻道命令
  • 第四個值則是消息內容
    注意:
  • 使用PSUBSCRIBE命令可以重複訂閱一個頻道,如某客戶端執行PSUBSCRIBE channel.? channel.?*的話,向channel1.10發送命令該客戶端也會收到兩個消息,
    而同時PUBLISH命令返回的值也是2而不是1.
  • 如果有另一個客戶端執行了SUBSCRIBE channel.10和PSUBSCRIBE channel.?*的話,向channel.10發送該命令該客戶端也會收到兩條消息
    (但是是兩種類型:message和pmessage),同時PUBLISH命令會返回2
  • PUNSUBSCRIBE命令可以退訂指定的規則,用法是PUNSUBSCRIBE pattern pattern …沒有參數會退訂所有規則
  • 使用PUNSUBSCRIBE只能退訂通過PSUBSCRIBE命令訂閱的規則,不會影響SUBSCRIBE命令訂閱的頻道;UNSUBSCRIBE同理;
  • 使用PUNSUBSCRIBE命令退訂某個規則是時不會將其中的通配符展開,而是進行嚴格的字符串匹配,所以PUNSUBSCRIBE * 無法退訂channel.*規則,
    而是必須使用 PUNSUBSCRIBE channel.*才能退訂

管道

  • 通過管道可以一次性發送多條命令並在執行完後一次性將結果返回,當一組命令中每條命令都不依賴於之前命令的執行結果時,就可以將這組命令一起通過管道發出,
  • 管道通過減少客戶端與Redis的通信次數來實現降低往返時延累計值的目的
## python使用Redis

# 導入redis包
import redis
# 創建一個默認連接到127.0.0.1,端口爲6379的redis連接
r = redis.StrictRedis()
# 也可以顯示的指定需要連接的地址
r = redis.StrictRedis(host='127.0.0.1', port=6379, db=0)
# 使用set和get
r.set('foo', 'bar')
r.get('foo')
# 使用hmset和hset
#hset參數爲(name, key, value)
r.hset('dict', 'name', 'bob')
# hmset參數爲(key, mapping)
r.hmset('dict', {'name': 'bob', 'color': 'red'})
r.hgetall('dict')
# 使用事務
pipe = r.pipeline()
pipe.set('foo', 'bar')
pipe.get('foo')
result = pipe.execute()  # result == [True, b'bar']
# 使用管道 管道的使用方式和事務相同,只不過需要在創建時加上參數transaction=False
pipe = r.pipeline(transaction=False)
# 事務和管道都支持鏈式調用
result = r.pipeline().set('foo', 'bar').get('foo').execute()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章