公司以一种错误的姿式使用了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