redis-lua(三): 類比生產者-消費者

來源:互聯網
上載者:User
文章目錄
  • BLPOP key1 [key2 ...] timeout

redis提供比較豐富的資料結構, 如string, list, set, sorted set, hashs. 其中幾個較複雜的資料結構, 如list,
set, sorted, hashs, 內部都是存放的string. 這裡的string其實可以理解為一個帶長度的byte數組,
在實際使用可以存放或轉換為自己需要的資料類型, 比如可以用於放一張圖片, 一段視頻…

list是複雜資料結構中最常用的一種, redis的list實際上一個雙向鏈表, 內部存放的元素是string. 可以看看redis的原始碼,
使用git下載原始碼:

git clone git://github.com/antirez/redis.git
redis-master

完成後, 在redis-master目錄中的src目錄, 有adlist.h與adlist.c源檔案.

開啟adlist.h, 可以看到list的定義是:

而listNode的定義是:

 

從代碼中可以看到, 每一個list使用len成員存放了元素的個數, 因而使用redis提供的llen命令取列表長度的時間複雜度是O(1).
list還記錄了隊列的頭與尾, 因而針對隊列頭與尾的push, pop系列的命令, 它們的時間複雜度也是O(1).

redis提供了一系列的命令操作list, 詳細的說明見:

http://www.redis.io/commands#list

其中最有意思的是由b開頭的三個命令: BLPOP, BRPOP, BRPOPLPUSH, 這三個命令是涉及到從隊列中彈出元素的阻塞版本,
當隊列中沒有元素時, 調用這三個命令會一直等待, 直到有元素進入到隊列中, 或者達到逾時條件. 阻塞版本的POP命令可以避免對資料庫的輪詢操作,
從而減少一些壓力.

BLPOP, BRPOP, BRPOPLPUSH三個命令的格式比較相似, 以BLPOP為例, 其格式是:

BLPOP key1 [key2 ...] timeout

timeout用於指定這個命令的逾時時間, 以秒為單位, 當這個值指定為0時, 表示無限阻塞, 直到有元素返回為止.

key1, key2, … 是指本命令可以同時查看多個key是否有元素, 查看的方式從前往後按順序, 首先查看key1是否有元素, 有則返回,
沒有則查看key2, 以此類推, 如果指定了key的所有隊列都是空的, 則進入阻塞模式, 在阻塞的過程中, 任何一個list有內容, 將馬上返回.

由於BLPOP可以指定多個key, 因而命令在返回時, 需要說明返回的是那個key的元素. 這個命令的傳回值有兩個, 當有元素返回時,
第1個值表示list的key名稱, 第2值存放了元素的內容; 當使用逾時模式, 沒有元素返回時, 第1個值是nil, 第二值是阻塞的時間.

 

有了阻塞版本的POP命令, 我們可以使用redis來實現生產者-消費者的模式. 生產者往redis資料庫中特定的隊列存放資料, 消費者從隊列中取出資料,
當資料為空白時, 消費者進入阻塞狀態.

下面的例子, 使用兩個lua程式類比一個網購網站的訂單系統, 在執行時可以在兩個終端中分別執行, 下面是終端1執行生產者的:

下面終端2執行消費者的:

相應的代碼, 生產者:

-- producer.lua

require "redis"

local myclient = Redis.connect()
assert( myclient)
local orderId = 0

while true do
    print("Please Input Order ID:")
    orderId =
io.read( "*number")
    if orderId == nil or orderId < 0 then
       
break
    else
        myclient:rpush( "orders", orderId) 
--往orders隊列放訂單ID
        print( "Order Sucess.")
    end
end

 

消費者:

-- consumer.lua

require "redis"

myclient = Redis.connect()
assert( myclient)

while true do
    orderIds = myclient:blpop( "orders", 0)
    if
orderIds[1] ~= nil then
        print( "Pop a value form ", orderIds[1])

        print( "/tProcessing Order, ID: ", orderIds[2])
    end

end

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.