Redis分散式部署,一致性hash;分散式與快取佇列
一:關於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)
- #download:zlib-1.2.6.tar
- ./configure
- make
- make install
(2)安裝ruby:version(1.9.2)
- # ruby1.9.2
- cd /path/ruby
- ./configure -prefix=/usr/local/ruby
- make
- make install
- sudo cp ruby /usr/local/bin
(3)安裝rubygem:version(1.8.16)
- # rubygems-1.8.16.tgz
- cd /path/gem
- sudo ruby setup.rb
- sudo cp bin/gem /usr/local/bin
(4)安裝gem-redis:version(3.0.0)
- gem install redis --version 3.0.0
- #由於源的原因,可能下載失敗,就手動下載下來安裝
- #download地址:http://rubygems.org/gems/redis/versions/3.0.0
- gem install -l /data/soft/redis-3.0.0.gem
(5)安裝redis-cluster
- cd /path/redis
- make
- sudo cp /opt/redis/src/redis-server /usr/local/bin
- sudo cp /opt/redis/src/redis-cli /usr/local/bin
- sudo cp /opt/redis/src/redis-trib.rb /usr/local/bin
2:配置redis cluster
1)redis配置檔案結構:
使用包含(include)把通用配置和特殊配置分離,方便維護.
2)redis通用配置.
- #GENERAL
- daemonize no
- tcp-backlog 511
- timeout 0
- tcp-keepalive 0
- loglevel notice
- databases 16
- dir /opt/redis/data
- slave-serve-stale-data yes
- #slave只讀
- slave-read-only yes
- #not use default
- repl-disable-tcp-nodelay yes
- slave-priority 100
- #開啟aof持久化
- appendonly yes
- #每秒一次aof寫
- appendfsync everysec
- #關閉在aof rewrite的時候對新的寫操作進行fsync
- no-appendfsync-on-rewrite yes
- auto-aof-rewrite-min-size 64mb
- lua-time-limit 5000
- #開啟redis叢集
- cluster-enabled yes
- #節點互連超時的閥值
- cluster-node-timeout 15000
- cluster-migration-barrier 1
- slowlog-log-slower-than 10000
- slowlog-max-len 128
- notify-keyspace-events ""
- hash-max-ziplist-entries 512
- hash-max-ziplist-value 64
- list-max-ziplist-entries 512
- list-max-ziplist-value 64
- set-max-intset-entries 512
- zset-max-ziplist-entries 128
- zset-max-ziplist-value 64
- activerehashing yes
- client-output-buffer-limit normal 0 0 0
- client-output-buffer-limit slave 256mb 64mb 60
- client-output-buffer-limit pubsub 32mb 8mb 60
- hz 10
- aof-rewrite-incremental-fsync yes
3)redis特殊配置.
- #包含通用配置
- include /opt/redis/redis-common.conf
- #監聽tcp埠
- port 6379
- #最大可用記憶體
- maxmemory 100m
- #記憶體耗盡時採用的淘汰策略:
- # volatile-lru -> remove the key with an expire set using an LRU algorithm
- # allkeys-lru -> remove any key accordingly to the LRU algorithm
- # volatile-random -> remove a random key with an expire set
- # allkeys-random -> remove a random key, any key
- # volatile-ttl -> remove the key with the nearest expire time (minor TTL)
- # noeviction -> don't expire at all, just return an error on write operations
- maxmemory-policy allkeys-lru
- #aof儲存檔案
- appendfilename "appendonly-6379.aof"
- #不開啟rdb儲存,只用於新增slave過程
- dbfilename dump-6379.rdb
- #cluster配置檔案(啟動自動生成)
- cluster-config-file nodes-6379.conf
- #部署在同一機器的redis例項,把auto-aof-rewrite搓開,因為cluster環境下記憶體佔用基本一致.
- #防止同意機器下瞬間fork所有redis程序做aof rewrite,佔用大量記憶體(ps:cluster必須開啟aof)
- auto-aof-rewrite-percentage 80-100
3:cluster 操作
- 叢集
- CLUSTER INFO 列印叢集的資訊
- CLUSTER NODES 列出叢集當前已知的所有節點(node),以及這些節點的相關資訊。
- 節點
- CLUSTER MEET <ip> <port> 將 ip 和 port 所指定的節點新增到叢集當中,讓它成為叢集的一份子。
- CLUSTER FORGET <node_id> 從叢集中移除 node_id 指定的節點。
- CLUSTER REPLICATE <node_id> 將當前節點設定為 node_id 指定的節點的從節點。
- CLUSTER SAVECONFIG 將節點的配置檔案儲存到硬盤裡面。
- 槽(slot)
- CLUSTER ADDSLOTS <slot> [slot ...] 將一個或多個槽(slot)指派(assign)給當前節點。
- CLUSTER DELSLOTS <slot> [slot ...] 移除一個或多個槽對當前節點的指派。
- CLUSTER FLUSHSLOTS 移除指派給當前節點的所有槽,讓當前節點變成一個沒有指派任何槽的節點。
- CLUSTER SETSLOT <slot> NODE <node_id> 將槽 slot 指派給 node_id 指定的節點,如果槽已經指派給另一個節點,那麼先讓另一個節點刪除該槽>,然後再進行指派。
- CLUSTER SETSLOT <slot> MIGRATING <node_id> 將本節點的槽 slot 遷移到 node_id 指定的節點中。
- CLUSTER SETSLOT <slot> IMPORTING <node_id> 從 node_id 指定的節點中匯入槽 slot 到本節點。
- CLUSTER SETSLOT <slot> STABLE 取消對槽 slot 的匯入(import)或者遷移(migrate)。
- 鍵
- CLUSTER KEYSLOT <key> 計算鍵 key 應該被放置在哪個槽上。
- CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的鍵值對數量。
- CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 個 slot 槽中的鍵。
4:redis cluster 運維操作
1)初始化並構建叢集
(1)啟動叢集相關節點(必須是空節點,beta3後可以是有資料的節點),指定配置檔案和輸出日誌
- redis-server /opt/redis/conf/redis-6380.conf > /opt/redis/logs/redis-6380.log 2>&1 &
- redis-server /opt/redis/conf/redis-6381.conf > /opt/redis/logs/redis-6381.log 2>&1 &
- redis-server /opt/redis/conf/redis-6382.conf > /opt/redis/logs/redis-6382.log 2>&1 &
- redis-server /opt/redis/conf/redis-7380.conf > /opt/redis/logs/redis-7380.log 2>&1 &
- redis-server /opt/redis/conf/redis-7381.conf > /opt/redis/logs/redis-7381.log 2>&1 &
- redis-server /opt/redis/conf/redis-7382.conf > /opt/redis/logs/redis-7382.log 2>&1 &
(2):使用自帶的ruby工具(redis-trib.rb)構建叢集
- #redis-trib.rb的create子命令構建
- #--replicas 則指定了為Redis Cluster中的每個Master節點配備幾個Slave節點
- #節點角色由順序決定,先master之後是slave(為方便辨認,slave的埠比master大1000)
- redis-trib.rb create --replicas 1 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):檢查叢集狀態
- #redis-trib.rb的check子命令構建
- #ip:port可以是叢集的任意節點
- redis-trib.rb check 10.10.34.14:6380
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
2):新增新master節點
(1)新增一個ma