公司以一種錯誤的姿式使用了redis的功能,並且業務框架已經變得很大,雖然你們也都認爲不合理,可是暫時看不到重構但願,可苦逼了後端人員,索性看看redis cluster能不能解決個人顧慮,redis 3出來也一段時間了,網上的文章也不少了,生產上大規模使用的公司很少,並且由於要對cluster的支持,致使不少原有lib庫都沒法使用了,不過這並不妨礙咱們追索知識的步伐....css
Redis很早的時候已經提供了Master-Slave功能,直到3.0版本的時候才提供了cluster功能,仍是alpha版本,cluster並不支持多個鍵的操做,這樣會致使須要在多個節點間移動數據,由於cluster中數據是被自動的分配到多個redis節點的。在cluster中部分節點出現不可用的時候,cluster仍是能夠繼續提供正常服務的(固然要看你的集羣配置)。node
下面聊聊關於redis cluster的一些信息,每一個在cluster中的redis節點都會監聽兩個端口,一個是和客戶端通信的TCP端口(6379),一個是用做cluster內部數據傳輸的,好比錯誤檢測、cluster配置更新、故障轉移等等(16379)。這樣cluster的通信問題就解決了,但數據是怎麼在cluster中存放的?redis cluster沒有采用一致性哈希,而是採用hash slot。一個redis cluster有固定的16384個hash slot,這麼多slot被均勻的分配到cluster中的master節點上,而一個key具體的存儲在哪一個slot上,則是經過key的CRC16編碼對16384取模得出的。上面提到了cluster中的master節點,估計不少人就迷糊了,爲了當部分節點失效時,cluster仍能保持可用,Redis 集羣採用每一個節點擁有 1(主服務自身)到 N 個副本(N-1 個附加的從服務器)的主從模型。是否是和master/slave很像。可是redis cluster卻不是強一致性的,在必定的條件下,cluster可能會丟失一些寫入的請求命令,由於cluster內部master和slave之間的數據是異步複製的,好比你給master中寫入數據,返回ok,可是這時候該數據並不必定就徹底的同步到slave上了(採用異步主要是提升性能,主要是在性能和一致性間的一個平衡),若是這時候master宕機了,這部分沒有寫入slave的數據就丟失了,不過這種可能性仍是很小的。上面這些信息都來自官方解釋,只是大概的描述了redis cluster的一些基本信息。python
其實我的以爲redis以前也有單獨的數據分片功能和主從功能,cluster只是把這些功能合併在一塊兒,外加一些集羣的狀態檢測。下面看看redis cluster的集羣架構圖:nginx
客戶端鏈接在cluster中的任何一個節點上均可以獲取到其餘節點的數據,不過這幅圖看着有點亂,通常cluster內部不會這麼多節點互爲主從的。redis
下面咱們簡單的使用一下,操做系統是一臺ubuntu14.04系統(啓動6個實例,3 Master/3 Slave):sql
1 下載最新版redisshell
wget 'http://download.redis.io/releases/redis-3.0.4.tar.gz'
2 編譯安裝ubuntu
#安裝到/opt/redis-cluster目錄 tar zxvf redis-3.0.4.tar.gz cd redis-3.0.4/ make make PREFIX=/opt/redis-cluster install #建立配置目錄,拷貝相關文件 mkdir /opt/redis-cluster/{log conf rdb run} cp src/redis-trib.rb /opt/redis-cluster/bin/
3 安裝其餘依賴包後端
apt-get install ruby1.9.1 gem install redis
4 建立配置文件ruby
看看6379的具體信息:grep -v -E '(^#|^$)' redis-6379.conf
daemonize yes
pidfile /opt/redis-cluster/run/redis-6379.pid
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/opt/redis-cluster/log/redis-6379.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump-6379.rdb dir /opt/redis-cluster/rdb slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 appendonly yes appendfilename "redis-6379.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated 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-entries 512 list-max-ziplist-value 64 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 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
其實大部分都是原有的配置信息,不須要作大的改動,與端口相關的都須要調整,與集羣相關的配置以下:
cluster-enabled yes
cluster-config-file nodes-6379.conf cluster-node-timeout 15000
注意其中的nodes-6379.conf這個文件不須要建立,在初始化集羣的時候會自動建立的。
5 在啓動redis實例前先修改一些系統級別的配置
echo never > /sys/kernel/mm/transparent_hugepage/enabled # 打開/etc/sysctl.conf,追加以下內容 vm.overcommit_memory = 1 #使配置生效 sysctl -p
6 啓動全部redis實例
cd /opt/redis-cluster/bin ./redis-server /opt/redis-cluster/conf/redis-6379.conf ./redis-server /opt/redis-cluster/conf/redis-6380.conf ./redis-server /opt/redis-cluster/conf/redis-6381.conf ./redis-server /opt/redis-cluster/conf/redis-7379.conf ./redis-server /opt/redis-cluster/conf/redis-7380.conf ./redis-server /opt/redis-cluster/conf/redis-7381.conf
7 redis-trib.rb
redis-trib.rb是一個官方提供的用來操做cluster的ruby腳本,咱們後面管理cluster會常用到這個腳本
Usage: redis-trib <command> <options> <arguments ...> create host1:port1 ... hostN:portN --replicas <arg> check host:port fix host:port reshard host:port --from <arg> --to <arg> --slots <arg> --yes add-node new_host:new_port existing_host:existing_port --slave --master-id <arg> del-node host:port node_id set-timeout host:port milliseconds call host:port command arg arg .. arg import host:port --from <arg> help (show this help) For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
8 初始化啓動cluster
./redis-trib.rb create --replicas 1 172.16.1.100:6379 172.16.1.100:6380 172.16.1.100:6381 172.16.1.100:7379 172.16.1.100:7380 172.16.1.100:7381
結果以下:
>>> Creating cluster Connecting to node 172.16.1.100:6379: OK Connecting to node 172.16.1.100:6380: OK Connecting to node 172.16.1.100:6381: OK Connecting to node 172.16.1.100:7379: OK Connecting to node 172.16.1.100:7380: OK Connecting to node 172.16.1.100:7381: OK >>> Performing hash slots allocation on 6 nodes... Using 3 masters: ###注意三個6xxx的都被定義爲master的了 172.16.1.100:6379 172.16.1.100:6380 172.16.1.100:6381 Adding replica 172.16.1.100:7379 to 172.16.1.100:6379 ###注意三個7xxx的都被定義爲相關的slave了 Adding replica 172.16.1.100:7380 to 172.16.1.100:6380 Adding replica 172.16.1.100:7381 to 172.16.1.100:6381 M: cdb8b1fe29feb9a564fbfed6599aa61dda250eb1 172.16.1.100:6379 slots:0-5460 (5461 slots) master ###6379被分配了0-5460個slots M: a188b59b30056f61c1cf55ff5072d60b6f8ce5d7 172.16.1.100:6380 slots:5461-10922 (5462 slots) master ###6380被分配了5461-10922個slots M: fada90b0520d5aa3305bc89651cc7bb5de9b2a16 172.16.1.100:6381 slots:10923-16383 (5461 slots) master ###6381被分配了10923-16383個slots S: 818fb192631cf8c34bc58f24d2538444abe7d995 172.16.1.100:7379 ###剩餘的三個slave replicates cdb8b1fe29feb9a564fbfed6599aa61dda250eb1 S: 1cf6ed9f8a5049513fb631e78207c7f0b1ba6674 172.16.1.100:7380 replicates a188b59b30056f61c1cf55ff5072d60b6f8ce5d7 S: bc09734e243b9b2e9fe2f64c55aaf72073c6918b 172.16.1.100:7381 replicates fada90b0520d5aa3305bc89651cc7bb5de9b2a16 Can I set the above configuration? (type 'yes' to accept): yes ###是否在nodes配置文件中保存更新配置 >>> 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 172.16.1.100:6379) M: cdb8b1fe29feb9a564fbfed6599aa61dda250eb1 172.16.1.100:6379 slots:0-5460 (5461 slots) master M: a188b59b30056f61c1cf55ff5072d60b6f8ce5d7 172.16