1. 程式人生 > >Redis Cluster處理MULTI/EXEC事務以及Multiple主鍵命令時的限制

Redis Cluster處理MULTI/EXEC事務以及Multiple主鍵命令時的限制

在上一篇博文中,本博主介紹了Redis Cluster的搭建方法,從中可以看出其使用方法與單機版Redis確實存在著不小的差異。實際上,除了搭建配置方法以外,Redis Cluster還具有一些其他方面的不同,譬如它不支援多個數據庫,不支援select命令等等,但其中最大的不同還是Redis Cluster不支援複雜的多主鍵操作。關於這一點,Redis Cluster的官方文件有這樣一段描述,現摘錄如下:Commands performing complex multi key operations like Set type unions or intersections are not implemented, and in general all the operations where in theory keys are not available in the same node are not implemented。由這段描述可知,在Redis Cluster中任何跨節點的命令都是不允許的,但是落實到具體的系統實現中,Redis Cluster又是如何去處理這些命令的呢?我們不妨通過兩種典型的命令來驗證一下,其中一種是MULTI/EXEC事務命令,該命令可以將多條Redis命令一次執行,所以這類命令可能同時操作多個主鍵,另外一種是本身就支援多主鍵的命令如mset和mget等。下面,本博主就在之前搭建的Redis Cluster上,分別嘗試了以上兩類命令的不同執行場景,以此來感性地認識Redis Cluster的反應!
情景一:MULTI/EXEC事務中的所有命令均操作相同的主鍵,且該主鍵就在當前連線的Redis節點上
  1. [[email protected] ~]# /usr/local/redis/bin/redis-cli
  2. redis 127.0.0.1:6379> multi
  3. OK
  4. redis 127.0.0.1:6379> set hello world
  5. QUEUED
  6. redis 127.0.0.1:6379> set hello earth
  7. QUEUED
  8. redis 127.0.0.1:6379> set hello china
  9. QUEUED
  10. redis 127.0.0.1:6379> exec
  11. 1) OK
  12. 2) OK
  13. 3) OK
複製程式碼

執行結果:事務中的每條命令都可以正確執行!

情景二:MULTI/EXEC事務中的所有命令均操作相同的主鍵,但該主鍵不在當前連線的Redis節點上
  1. redis 127.0.0.1:6379> multi
  2. OK
  3. redis 127.0.0.1:6379> get foo
  4. (error) MOVED 12182 192.168.32.4:6379
  5. redis 127.0.0.1:6379> set foo bar
  6. (error) MOVED 12182 192.168.32.4:6379
  7. redis 127.0.0.1:6379> exec
  8. (empty list or set)
複製程式碼

執行結果:事務中的任何命令都無法執行,對於每條命令均返回MOVED資訊!

情景三:MULTI/EXEC事務中的所有命令操作不同的主鍵,且某些主鍵不在當前連線的Redis節點上
  1. redis 127.0.0.1:6379> multi
  2. OK
  3. redis 127.0.0.1:6379> set hello america
  4. QUEUED
  5. redis 127.0.0.1:6379> set foo rab
  6. (error) MOVED 12182 192.168.32.4:6379
  7. redis 127.0.0.1:6379> exec
  8. 1) OK
  9. redis 127.0.0.1:6379> get hello
  10. "america"
複製程式碼

執行結果:主鍵在當前連線的Redis節點上的命令可以正確執行,主鍵不在當前連線的Redis節點上的命令返回MOVED資訊!

情景四:MULTI/EXEC事務中的所有命令操作不同的主鍵,且所有主鍵均在當前連線的Redis節點上
  1. redis 192.168.32.3:6379> multi
  2. OK
  3. redis 192.168.32.3:6379> set id 10003
  4. QUEUED
  5. redis 192.168.32.3:6379> set number 20004
  6. QUEUED
  7. redis 192.168.32.3:6379> set student 30098
  8. QUEUED
  9. redis 192.168.32.3:6379> exec
  10. 1) OK
  11. 2) OK
  12. 3) OK
複製程式碼

執行結果:事務中的所有命令均可以成功執行!

情景五:Multiple主鍵命令包含了不同的主鍵,且所有主鍵均在當前連線的Redis節點上
redis 192.168.32.3:6379> mset id 10004 number 20005 student 30099
(error) ERR Multi keys request invalid in cluster
redis 192.168.32.3:6379> mget id number student
(error) ERR Multi keys request invalid in cluster
執行結果:命令無效,無法執行!

情景六:Multiple主鍵命令包含了多個相同的主鍵,且該主鍵在當前連線的Redis節點上
  1. redis 192.168.32.3:6379> mset id 10004 id 20005 id 30099
  2. OK
  3. redis 192.168.32.3:6379> mget id id id
  4. 1) "30099"
  5. 2) "30099"
  6. 3) "30099"
複製程式碼

執行結果:命令有效,成功執行!

情景七:Multiple主鍵命令包含了多個相同的主鍵,但該主鍵不在當前連線的Redis節點上
  1. redis 192.168.32.3:6379> mset hello world hello earth hello universe
  2. (error) MOVED 866 192.168.32.2:6379
  3. redis 192.168.32.3:6379> mget hello hello hello
  4. (error) MOVED 866 192.168.32.2:6379
複製程式碼

執行結果:命令有效,返回MOVED資訊!


 基於以上執行結果,我們可以知道對於MULTI/EXEC事務來說,執行效果與逐條處理單個命令一樣,被事務包裹的Redis命令連線節點能夠處理就處理,無法處理的就返回MOVED資訊。但是對於Multiple主鍵的命令來說,只要在命令中包含了多個不同的主鍵,那麼無論這些主鍵能不能被連線節點所處理,命令都是無效的!當然,以上只是通過一些具體的命令執行例項來看Redis Cluster的執行效果,如果想對Redis Cluster的命令處理有更詳細的瞭解,那麼推薦的方法還是去看原始碼中的cluster.c檔案。