redis5.0集群部署
一、集群介紹
Redis 集群是一個可以在多個 Redis 節點之間進行數據共享的設施(installation)。
Redis 集群不支持那些需要同時處理多個鍵的 Redis 命令, 因為執行這些命令需要在多個 Redis 節點之間移動數據, 並且在高負載的情況下, 這些命令將降低 Redis 集群的性能, 並導致不可預測的行為。
Redis 集群通過分區(partition)來提供一定程度的可用性(availability): 即使集群中有一部分節點失效或者無法進行通訊, 集群也可以繼續處理命令請求。
Redis 集群提供了以下兩個好處:
將數據自動切分(split)到多個節點的能力。
當集群中的一部分節點失效或者無法進行通訊時, 仍然可以繼續處理命令請求的能力。
二、Redis 集群數據共享
Redis 集群使用數據分片(sharding)而非一致性哈希(consistency hashing)來實現: 一個 Redis 集群包含 16384 個哈希槽(hash slot), 數據庫中的每個鍵都屬於這 16384 個哈希槽的其中一個, 集群使用公式 CRC16(key) % 16384 來計算鍵 key 屬於哪個槽, 其中 CRC16(key) 語句用於計算鍵 key 的 CRC16 校驗和 。
集群中的每個節點負責處理一部分哈希槽。 舉個例子, 一個集群可以有三個哈希槽, 其中:
- 節點 A 負責處理 0 號至 5500 號哈希槽。
- 節點 B 負責處理 5501 號至 11000 號哈希槽。
- 節點 C 負責處理 11001 號至 16384 號哈希槽。
這種將哈希槽分布到不同節點的做法使得用戶可以很容易地向集群中添加或者刪除節點。 比如說:
如果用戶將新節點 D 添加到集群中, 那么集群只需要將節點 A 、B 、 C 中的某些槽移動到節點 D 就可以了。
與此類似, 如果用戶要從集群中移除節點 A , 那么集群只需要將節點 A 中的所有哈希槽移動到節點 B 和節點 C , 然后再移除空白(不包含任何哈希槽)的節點 A 就可以了。
因為將一個哈希槽從一個節點移動到另一個節點不會造成節點阻塞, 所以無論是添加新節點還是移除已存在節點, 又或者改變某個節點包含的哈希槽數量, 都不會造成集群下線。
三、Redis 集群中的主從復制
為了使得集群在一部分節點下線或者無法與集群的大多數(majority)節點進行通訊的情況下, 仍然可以正常運作, Redis 集群對節點使用了主從復制功能: 集群中的每個節點都有 1 個至 N 個復制品(replica), 其中一個復制品為主節點(master), 而其余的 N-1 個復制品為從節點(slave)。
在之前列舉的節點 A 、B 、C 的例子中, 如果節點 B 下線了, 那么集群將無法正常運行, 因為集群找不到節點來處理 5501 號至 11000 號的哈希槽。
另一方面, 假如在創建集群的時候(或者至少在節點 B 下線之前), 我們為主節點 B 添加了從節點 B1 , 那么當主節點 B 下線的時候, 集群就會將 B1 設置為新的主節點, 並讓它代替下線的主節點 B , 繼續處理 5501 號至 11000 號的哈希槽, 這樣集群就不會因為主節點 B 的下線而無法正常運作了。
不過如果節點 B 和 B1 都下線的話, Redis 集群還是會停止運作。
四、創建並使用 Redis 集群
必須使用六個節點: 其中三個為主節點, 而其余三個則是各個主節點的從節點。否則集群無法正常運行!!
安裝過程
1. 下載並解壓
cd /root/software wget http://download.redis.io/releases/redis-5.0.0.tar.gz tar -zxvf redis-5.0.0.tar.gz
2. 編譯安裝
cd redis-5.0.0 make && make install
3. 將 redis-trib.rb 復制到 /usr/local/bin 目錄下
cd src cp redis-trib.rb /usr/local/bin/
4. 創建 Redis 節點
首先在 10.90.6.157 機器上 /root/software/redis-5.0.0 目錄下創建 redis_cluster 目錄;
mkdir redis_cluster
在 redis_cluster 目錄下,創建名為6379的目錄,並將 redis.conf 拷貝到這個目錄中
mkdir 6379 cp redis.conf redis_cluster/6379
分別修改這三個配置文件,修改如下內容
port 6379 //端口默認 #bind 127.0.0.1 //注釋掉默認ip為127.0.0.1 需要改為其他節點機器可訪問的ip 否則創建集群時無法訪問對應的端口,無法創建集群 daemonize yes //redis后台運行 pidfile /var/run/redis_6379.pid //pidfile文件對應6379 cluster-enabled yes //開啟集群 把注釋#去掉 cluster-config-file nodes_6379.conf //集群的配置 配置文件首次啟動自動生成 6379 cluster-node-timeout 15000 //請求超時 默認15秒,可自行設置 appendonly yes //aof日志開啟 有需要就開啟,它會每次寫操作都記錄一條日志
集群的完整配置文件如下:
protected-mode no port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile "" databases 16 always-show-logo yes save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir ./ replica-serve-stale-data yes replica-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no replica-priority 100 lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no appendonly yes appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes lua-time-limit 5000 cluster-enabled yes cluster-config-file nodes-6379.conf cluster-node-timeout 15000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 stream-node-max-bytes 4096 stream-node-max-entries 100 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 dynamic-hz yes aof-rewrite-incremental-fsync yes rdb-save-incremental-fsync yes
Redis 官方提供了 redis-trib.rb 這個工具是用 ruby 實現的,所以需要安裝 ruby。安裝命令如下:
yum -y install ruby ruby-devel rubygems rpm-build gem install redis
其中 gem install redis命令執行時出現了:
redis requires Ruby version >= 2.2.2的報錯,查了資料發現是Centos默認支持ruby到2.0.0,可gem 安裝redis需要最低是2.2.2
解決辦法是 先安裝rvm,再把ruby版本提升至2.3.3
1.安裝curl sudo yum install curl 2. 安裝RVM curl -L get.rvm.io | bash -s stable 3. 加載配置 source /usr/local/rvm/scripts/rvm 4. 查看rvm庫中已知的ruby版本 rvm list known 5. 安裝一個ruby版本 rvm install 2.3.3 6. 使用一個ruby版本 rvm use 2.3.3 7. 設置默認版本 rvm remove 2.0.0 8. 卸載一個已知版本 ruby --version 9. 再安裝redis就可以了 gem install redis
好了,重復以上的安裝步湊把剩下的5個節點部署好!!!
10.創建集群
在6個節點中執行以下命令啟動redis:
src/redis-server ./redis_cluster/6379/redis.conf &
在1個節點上執行以下創建集群命令:
src/redis-cli --cluster create 10.90.6.156:6379 10.90.6.157:6379 10.90.6.158:6379 10.90.6.159:6379 10.90.6.160:6379 10.90.6.161:6379 --cluster-replicas 1
[root@Redis1 redis-5.0.0]# src/redis-cli --cluster create 10.90.6.156:6379 10.90.6.157:6379 10.90.6.158:6379 10.90.6.159:6379 10.90.6.160:6379 10.90.6.161:6379 --cluster-replicas 1 >>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 10.90.6.159:6379 to 10.90.6.156:6379 Adding replica 10.90.6.160:6379 to 10.90.6.157:6379 Adding replica 10.90.6.161:6379 to 10.90.6.158:6379 M: ddebff330f23552db26eadb51c4f9926473cb485 10.90.6.156:6379 slots:[0-5460] (5461 slots) master M: 4256ffaa3ad3d1c8ad3174898f97114629922a8e 10.90.6.157:6379 slots:[5461-10922] (5462 slots) master M: 9b7c727852f4bde936b8bb8f6cbda2cf621b7c9b 10.90.6.158:6379 slots:[10923-16383] (5461 slots) master S: e52195f35519ac8c360b008a354415ad39190027 10.90.6.159:6379 replicates ddebff330f23552db26eadb51c4f9926473cb485 S: 06d022e927a8f166cd08e333e8723d4c5b5a1092 10.90.6.160:6379 replicates 4256ffaa3ad3d1c8ad3174898f97114629922a8e S: b57ebc5c247f01e9e35cf798bd6932bdaee04098 10.90.6.161:6379 replicates 9b7c727852f4bde936b8bb8f6cbda2cf621b7c9b Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join .. >>> Performing Cluster Check (using node 10.90.6.156:6379) M: ddebff330f23552db26eadb51c4f9926473cb485 10.90.6.156:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) S: b57ebc5c247f01e9e35cf798bd6932bdaee04098 10.90.6.161:6379 slots: (0 slots) slave replicates 9b7c727852f4bde936b8bb8f6cbda2cf621b7c9b S: e52195f35519ac8c360b008a354415ad39190027 10.90.6.159:6379 slots: (0 slots) slave replicates ddebff330f23552db26eadb51c4f9926473cb485 S: 06d022e927a8f166cd08e333e8723d4c5b5a1092 10.90.6.160:6379 slots: (0 slots) slave replicates 4256ffaa3ad3d1c8ad3174898f97114629922a8e M: 4256ffaa3ad3d1c8ad3174898f97114629922a8e 10.90.6.157:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) M: 9b7c727852f4bde936b8bb8f6cbda2cf621b7c9b 10.90.6.158:6379 slots:[10923-16383] (5461 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
如果報錯,請看下面!!
[root@Redis1 redis-5.0.0]# src/redis-cli --cluster create 10.90.6.156:6379 10.90.6.157:6379 10.90.6.158:6379 10.90.6.159:6379 10.90.6.160:6379 10.90.6.161:6379 --cluster-replicas 1
[ERR] Node 10.90.6.157:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
的問題
解決辦法:
1)將每個節點下aof、rdb、nodes.conf本地備份文件刪除;
[root@redis-5.0.0]# rm -fr appendonly.aof dump.rdb nodes-*
[root@redis-5.0.0]# pwd
/fs01/redis-5.0.0
2)10.90.6.157:6379> flushdb #清空當前數據庫
3)之后再執行腳本,成功執行;
這里解釋一下dump.rdb文件:
dump.rdb是由Redis服務器自動生成的 默認情況下 每隔一段時間redis服務器程序會自動對數據庫做一次遍歷,把內存快照寫在一個叫做“dump.rdb”的文件里,這個持久化機制叫做SNAPSHOT。有了SNAPSHOT后,如果服務器宕機,重新啟動redis服務器程序時redis會自動加載dump.rdb,將數據庫狀態恢復到上一次做SNAPSHOT時的狀態。
SNAPSHOT即快照
重新連接redis集群,成功
8. 集群驗證
在一台機器上連接方式為 redis-cli -h -c 10.90.6.157 ,加參數 -c 可連接到集群,因為上面 redis.conf 將 bind 改為了ip地址,所以 -h 參數不可以省略。
[root@Redis2 src]# ./redis-cli -c -h 10.90.6.157 10.90.6.157:6379> get hello "2" 10.90.6.157:6379>