1. 程式人生 > >Redis分散式部署,一致性hash;分散式與快取佇列

Redis分散式部署,一致性hash;分散式與快取佇列

最近研究redis-cluster,正好搭建了一個環境,遇到了很多坑,系統的總結下,等到redis3 release出來後,換掉memCache 叢集. 轉載請註明出處哈:http://hot66hot.iteye.com/admin/blogs/2050676

一:關於redis cluster

1:redis cluster的現狀

作者的目標:Redis Cluster will support up to ~1000 nodes. 贊...

目前redis支援的cluster特性(已測試):

1):節點自動發現

2):slave->master 選舉,叢集容錯

3):Hot resharding:線上分片

4):叢集管理:cluster xxx

5):基於配置(nodes-port.conf)的叢集管理

6):ASK 轉向/MOVED 轉向機制.

2:redis cluster 架構

1)redis-cluster架構圖

架構細節:

(1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協議優化傳輸速度和頻寬.

(2)節點的fail是通過叢集中超過半數的節點檢測失效時才生效.

(3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可

(4)redis-cluster把所有的物理節點對映到[0-16383]slot上,cluster 負責維護node<->slot<->value

2) redis-cluster選舉:容錯

(1)領著選舉過程是叢集中所有master參與,如果半數以上master節點與master節點通訊超過(cluster-node-timeout),認為當前master節點掛掉.

(2):什麼時候整個叢集不可用(cluster_state:fail)? 

    a:如果叢集任意master掛掉,且當前master沒有slave.叢集進入fail狀態,也可以理解成叢集的slot對映[0-16383]不完成時進入fail狀態. ps : redis-3.0.0.rc1加入cluster-require-full-coverage引數,預設關閉,開啟叢集相容部分失敗.

    b:如果叢集超過半數以上master掛掉,無論是否有slave叢集進入fail狀態.

  ps:當叢集不可用時,所有對叢集的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)錯誤

二:redis cluster的使用

1:安裝redis cluster

1):安裝redis-cluster依賴:redis-cluster的依賴庫在使用時有相容問題,在reshard時會遇到各種錯誤,請按指定版本安裝.

(1)確保系統安裝zlib,否則gem install會報(no such file to load -- zlib)
  1. #download:zlib-1.2.6.tar  
  2. ./configure  
  3. make  
  4. make install  
 (2)安裝ruby:version(1.9.2)
  1. # ruby1.9.2   
  2. cd /path/ruby  
  3. ./configure -prefix=/usr/local/ruby  
  4. make  
  5. make install  
  6. sudo cp ruby /usr/local/bin  
(3)安裝rubygem:version(1.8.16)
  1. # rubygems-1.8.16.tgz  
  2. cd /path/gem  
  3. sudo ruby setup.rb  
  4. sudo cp bin/gem /usr/local/bin  
(4)安裝gem-redis:version(3.0.0)
  1. gem install redis --version 3.0.0  
  2. #由於源的原因,可能下載失敗,就手動下載下來安裝  
  3. #download地址:http://rubygems.org/gems/redis/versions/3.0.0  
  4. gem install -l /data/soft/redis-3.0.0.gem  
(5)安裝redis-cluster
  1. cd /path/redis  
  2. make  
  3. sudo cp /opt/redis/src/redis-server /usr/local/bin  
  4. sudo cp /opt/redis/src/redis-cli /usr/local/bin  
  5. sudo cp /opt/redis/src/redis-trib.rb /usr/local/bin  

2:配置redis cluster

1)redis配置檔案結構:


 使用包含(include)把通用配置和特殊配置分離,方便維護.

2)redis通用配置.

  1. #GENERAL  
  2. daemonize no  
  3. tcp-backlog 511  
  4. timeout 0  
  5. tcp-keepalive 0  
  6. loglevel notice  
  7. databases 16  
  8. dir /opt/redis/data  
  9. slave-serve-stale-data yes  
  10. #slave只讀  
  11. slave-read-only yes  
  12. #not use default  
  13. repl-disable-tcp-nodelay yes  
  14. slave-priority 100  
  15. #開啟aof持久化  
  16. appendonly yes  
  17. #每秒一次aof寫  
  18. appendfsync everysec  
  19. #關閉在aof rewrite的時候對新的寫操作進行fsync  
  20. no-appendfsync-on-rewrite yes  
  21. auto-aof-rewrite-min-size 64mb  
  22. lua-time-limit 5000  
  23. #開啟redis叢集  
  24. cluster-enabled yes  
  25. #節點互連超時的閥值  
  26. cluster-node-timeout 15000  
  27. cluster-migration-barrier 1  
  28. slowlog-log-slower-than 10000  
  29. slowlog-max-len 128  
  30. notify-keyspace-events ""  
  31. hash-max-ziplist-entries 512  
  32. hash-max-ziplist-value 64  
  33. list-max-ziplist-entries 512  
  34. list-max-ziplist-value 64  
  35. set-max-intset-entries 512  
  36. zset-max-ziplist-entries 128  
  37. zset-max-ziplist-value 64  
  38. activerehashing yes  
  39. client-output-buffer-limit normal 0  
  40. client-output-buffer-limit slave 256mb 64mb 60  
  41. client-output-buffer-limit pubsub 32mb 8mb 60  
  42. hz 10  
  43. aof-rewrite-incremental-fsync yes  

3)redis特殊配置.

  1. #包含通用配置  
  2. include /opt/redis/redis-common.conf  
  3. #監聽tcp埠  
  4. port 6379  
  5. #最大可用記憶體  
  6. maxmemory 100m  
  7. #記憶體耗盡時採用的淘汰策略:  
  8. volatile-lru -> remove the key with an expire set using an LRU algorithm  
  9. # allkeys-lru -> remove any key accordingly to the LRU algorithm  
  10. volatile-random -> remove a random key with an expire set  
  11. # allkeys-random -> remove a random key, any key  
  12. volatile-ttl -> remove the key with the nearest expire time (minor TTL)  
  13. # noeviction -> don't expire at all, just return an error on write operations  
  14. maxmemory-policy allkeys-lru  
  15. #aof儲存檔案  
  16. appendfilename "appendonly-6379.aof"  
  17. #不開啟rdb儲存,只用於新增slave過程  
  18. dbfilename dump-6379.rdb  
  19. #cluster配置檔案(啟動自動生成)  
  20. cluster-config-file nodes-6379.conf  
  21. #部署在同一機器的redis例項,把auto-aof-rewrite搓開,因為cluster環境下記憶體佔用基本一致.  
  22. #防止同意機器下瞬間fork所有redis程序做aof rewrite,佔用大量記憶體(ps:cluster必須開啟aof)  
  23. auto-aof-rewrite-percentage 80-100  

3:cluster 操作

  1. 叢集  
  2. CLUSTER INFO 列印叢集的資訊  
  3. CLUSTER NODES 列出叢集當前已知的所有節點(node),以及這些節點的相關資訊。  
  4. 節點  
  5. CLUSTER MEET <ip> <port> 將 ip 和 port 所指定的節點新增到叢集當中,讓它成為叢集的一份子。  
  6. CLUSTER FORGET <node_id> 從叢集中移除 node_id 指定的節點。  
  7. CLUSTER REPLICATE <node_id> 將當前節點設定為 node_id 指定的節點的從節點。  
  8. CLUSTER SAVECONFIG 將節點的配置檔案儲存到硬盤裡面。  
  9. 槽(slot)  
  10. CLUSTER ADDSLOTS <slot> [slot ...] 將一個或多個槽(slot)指派(assign)給當前節點。  
  11. CLUSTER DELSLOTS <slot> [slot ...] 移除一個或多個槽對當前節點的指派。  
  12. CLUSTER FLUSHSLOTS 移除指派給當前節點的所有槽,讓當前節點變成一個沒有指派任何槽的節點。  
  13. CLUSTER SETSLOT <slot> NODE <node_id> 將槽 slot 指派給 node_id 指定的節點,如果槽已經指派給另一個節點,那麼先讓另一個節點刪除該槽>,然後再進行指派。  
  14. CLUSTER SETSLOT <slot> MIGRATING <node_id> 將本節點的槽 slot 遷移到 node_id 指定的節點中。  
  15. CLUSTER SETSLOT <slot> IMPORTING <node_id> 從 node_id 指定的節點中匯入槽 slot 到本節點。  
  16. CLUSTER SETSLOT <slot> STABLE 取消對槽 slot 的匯入(import)或者遷移(migrate)。  
  17. 鍵  
  18. CLUSTER KEYSLOT <key> 計算鍵 key 應該被放置在哪個槽上。  
  19. CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的鍵值對數量。  
  20. CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 個 slot 槽中的鍵。  
 

4:redis cluster 運維操作

1)初始化並構建叢集

(1)啟動叢集相關節點(必須是空節點,beta3後可以是有資料的節點),指定配置檔案和輸出日誌

  1. redis-server /opt/redis/conf/redis-6380.conf > /opt/redis/logs/redis-6380.log 2>&1 &  
  2. redis-server /opt/redis/conf/redis-6381.conf > /opt/redis/logs/redis-6381.log 2>&1 &  
  3. redis-server /opt/redis/conf/redis-6382.conf > /opt/redis/logs/redis-6382.log 2>&1 &  
  4. redis-server /opt/redis/conf/redis-7380.conf > /opt/redis/logs/redis-7380.log 2>&1 &  
  5. redis-server /opt/redis/conf/redis-7381.conf > /opt/redis/logs/redis-7381.log 2>&1 &  
  6. redis-server /opt/redis/conf/redis-7382.conf > /opt/redis/logs/redis-7382.log 2>&1 &  

(2):使用自帶的ruby工具(redis-trib.rb)構建叢集

  1. #redis-trib.rb的create子命令構建  
  2. #--replicas 則指定了為Redis Cluster中的每個Master節點配備幾個Slave節點  
  3. #節點角色由順序決定,先master之後是slave(為方便辨認,slave的埠比master大1000)  
  4. redis-trib.rb create --replicas 10.10.34.14:6380 10.10.34.14:6381 10.10.34.14:6382 10.10.34.14:7380 10.10.34.14:7381 10.10.34.14:7382  

(3):檢查叢集狀態

  1. #redis-trib.rb的check子命令構建  
  2. #ip:port可以是叢集的任意節點  
  3. redis-trib.rb check 10.10.34.14:6380  
 最後輸出如下資訊,沒有任何警告或錯誤,表示叢集啟動成功並處於ok狀態
  1. [OK] All nodes agree about slots configuration.  
  2. >>> Check for open slots...  
  3. >>> Check slots coverage...  
  4. [OK] All 16384 slots covered.  

2):新增新master節點

(1)新增一個ma