iT邦幫忙

DAY 20
2

建立API為中心的輕量級網站系列 第 20

redis 多重指令 MULTI 及 ruby 裡的 pipeline 的使用

  • 分享至 

  • xImage
  •  

通常 redis 是一個指令一個回應,
若一次要下多個指令,
就需要靠MULTI或pipeline來整批整行。
如果redis一次有好幾個指令要指行,
在 client 端可利用 MULTI 的指令來進行:

$ redis-cli
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> set i5:user:1 twtw
QUEUED
redis 127.0.0.1:6379> set i5:user:2 wtwt
QUEUED
redis 127.0.0.1:6379> EXEC
1) OK
2) OK[code]
在MULTI之後所下的指令,
都被QUEUE住未執行,
一直到下了 EXEC 的指令,
才把所有QUEUE住的指令一次再執行,
回應的結果都在最後獲得回應。

而在ruby裡要執行multi的功能
[code]$ irb --simple-prompt
>> require 'redis'
>> redis = Redis.new
>> redis.multi do
?> redis.set 'i5:user:3','wtwt'
>> redis.get 'i5:user:3'
>> end
=> ["OK", "wtwt"]

另外也可以用把 multi 替換成 pipelined,
其他語法都一樣,
差別是什麼?
這篇裡面 https://github.com/redis/redis-rb 有提到
兩者的差異,
基本上是 pipelined 比 multi 快,
pipelined 是整批指令送出回應,
multi 看似整批,但還是一個個送,
但最後回應是從multi整個回來。
在這篇文章Request/Response protocols and RTT
主要是測試 有用 pipelined 跟沒有使用的回應的效能差別,
利用該文的程式碼,
我再加上一段有關 with multi 的測試來比較:

require 'redis'

def bench(descr)
    start = Time.now
    yield
    puts "#{descr} #{Time.now-start} seconds"
end

def without_pipelining
    r = Redis.new
    10000.times {
        r.ping
    }
end

def with_pipelining
    r = Redis.new
    r.pipelined {
        10000.times {
            r.ping
        }
    }
end

def with_multi
  r = Redis.new
  r.multi {
    10000.times {
      r.ping
    }
  }
end

bench("without pipelining") {
    without_pipelining
}
bench("with pipelining") {
    with_pipelining
}
bench("with multi") {
    with_multi
}

執行的結果會發現:

$ ruby bench.rb
without pipelining 0.572608852 seconds
with pipelining 0.205889869 seconds
with multi 0.20942385 seconds
$ ruby bench.rb
without pipelining 0.571904261 seconds
with pipelining 0.187799676 seconds
with multi 0.193023878 seconds

速度上 pipelined > multi > without pipelined。

如果在程式語言裡,處理獲得一堆的陣列或hash,
需把資料塞入 redis 裡的 Sets 或 Lists,
用 pipelined 能較快地處理完成:

redis.pipelined{arr.each{|x| redis.lpush 'pg:1',x}}

系列文章列表


上一篇
redis 應用:resque 的基本使用
下一篇
為何採用 Knockout.js (KO)?
系列文
建立API為中心的輕量級網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

我要留言

立即登入留言