Redis集群Cluster+首页分类+跨域Jsonp
RedisCluster集群
概述
Redis在3.0版正式引入了集群特性。Redis集群是一个分布式(distributed)、容错(fault-tolerant)的 Redis内存K/V服务, 集群可以使用的功能是普通单机 Redis 所能使用的功能的一个子集(subset),比如Redis集群并不支持处理多个keys的命令(mset、mget),因为这需要在不同的节点间移动数据,从而达不到像Red
去中心化架构
- 去中心化,客户端与redis节点直连,不需要中间proxy层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
- 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
- 分片,把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value
- 节点的fail是通过集群中超过半数的节点检测失效时才生效。
- 选举容错,自动将节点分成主从,形成主从复制,数据备份容灾,同时实现读写分离。
- 集群最少6个节点,3主3从。
容错机制
选举过程是集群中所有master参与,如果半数以上master节点与master节点通信超过(cluster-node-timeout),认为当前master节点挂掉。
什么时候整个集群不可用(cluster_state:fail),当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误:
a: 如果集群任意master挂掉,且当前master没有slave。集群进入fail状态,也可以理解成进群的slot映射[0-16383]不完成时进入fail状态。
b: 如果集群超过半数以上master挂掉,无论是否有slave集群进入fail状态。
支持分片
Redis 集群的键空间被分割为 16384 (2^14)个槽(slot), 集群的最大节点数量也是 16384 个(推荐的最大节点数量为 1000 个),同理每个主节点可以负责处理1到16384个槽位。
当16384个槽位都有主节点负责处理时,集群进入”稳定“上线状态,可以开始处理数据命令。当集群没有处理稳定状态时,可以通过执行重配置(reconfiguration)操作,使得每个哈希槽都只由一个节点进行处理。
重配置指的是将某个/某些槽从一个节点移动到另一个节点。一个主节点可以有任意多个从节点, 这些从节点用于在主节点发生网络断线或者节点失效时, 对主节点进行替换。
计算key属于哪个槽:
HASH_SLOT = CRC16(key) mod 16384
CRC16其结果长度为16位。
CRC是通信领域中用于校验数据传输正确性的最常用机制,也是Hash算法的一个典型应用,就是把任意长度的输入(又叫做预映射,pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是散列值的空间通常远小于输入空间,不同的输入可能会散列成相同的输出,而不可能从散列值唯一的确定输入值。
Cluster安装配置
安装Ruby
yum install ruby
ruby –v #ruby 1.8.7
yum install rubygems #也可以一句执行 yum install ruby rubygems -y
gem install redis #安装redis的接口包
gem list #查看是否安装了gem相关的接口包,检查redis是否已经存在
创建节点
创建目录
由于cluster的特点,与redis传统主从不同的是,cluster中的节点需要配置在不同的文件夹,否则无法创建集群(尝试过一次,失败)。进入redis根目录,创建节点文件夹,同一个服务器上的不同节点文件夹可以用端口号来命名即可。
mkdir 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 #创建多个目录
:%s/7000/7001/g #替换所有7000为7001
修改配置文件redis.conf
复制redis.conf到各个的目录,并对应修改下面内容
P61 bind 127.0.0.1//默认ip为127.0.0.1改为其他节点机器可访问的ip
P80 protected-mode no //yes修改为no
P84 port 7000 //端口7000
P128 daemonize yes //后台运行
//P150 pidfile /var/run/redis_7000.pid //pidfile文件对应7000
P593 appendonly yes //默认是rdb方式持久化要改成AOF模式
P163 logfile "/usr/local/src/redis/redis-3.2.8/7000/redis.log" //相对路径,启动时在redis的根目录
P721 cluster-enabled yes //开启集群
P729 cluster-config-file nodes_7000.conf //集群的配置
P735 cluster-node-timeout 15000 //请求超时 默认15秒,可自行设置
启动
启动每个节点实例
先为每个节点创建一个目录,复制redis.conf进去,然后按上面修改内容,修改好后,启动每个实例。
vim start.sh #创建脚本文件方便启动
bash start #执行shell脚本
#!/bin/sh
redis-server 7000/redis.conf &
redis-server 7001/redis.conf &
redis-server 7002/redis.conf &
redis-server 7003/redis.conf &
redis-server 7004/redis.conf &
redis-server 7005/redis.conf &
redis-server 7006/redis.conf &
redis-server 7007/redis.conf &
redis-server 7008/redis.conf &
启动集群
Redis Cluster集群需要ruby来运行其脚本
./src/redis-trib.rb create --replicas 1 192.168.163.201:7000 192.168.163.201:7001 192.168.163.201:7002 192.168.163.201:7003 192.168.163.201:7004 192.168.163.201:7005 192.168.163.201:7006 192.168.163.201:7007 192.168.163.201:7008
--replicas 1 表示希望为集群中的每个主节点创建一个从节点(一主一从)
前几个自动做为主,后面几个做为从,主节点少于从节点,个数不对应时,多从挂接都一个主上。
注意:提示必须敲入yes,不能是y,y则按不接受处理。
注意:redis-trib-rb的路径,可以配置环境变量来解决
export PATH=/usr/local/ruby-2.1.2/bin;&PATH
#检查节点
./src/redis-trib.rb check 192.168.163.201:7001
启动失败重新启动
启动后会自动产生这些文件,重新启动时需要删除!
rm -rf dump.rdb #删除redis的备份文件,redis节点中有数据,无法建立集群
rm -rf nodes-700* #删除没有建立成功集群时遗留的文件
登录集群
redis-cli -c -p 7000 #任何一个端口都可以,执行命名会自动跳转
查看集群状态
127.0.0.1:7000> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:9
cluster_size:4
cluster_current_epoch:9
cluster_my_epoch:1
cluster_stats_messages_sent:9154
cluster_stats_messages_received:9154
127.0.0.1:7000> cluster nodes #查看集群节点状态
841b3e80f22c869ba4cf4a1a9829e3711ddcc74e 192.168.163.201:7001 master - 0 1488180921550 2 connected 4096-8191
182c2a3991c331e4e9222f40d33566c63c32be61 192.168.163.201:7007 slave f3b337f67349232c446b9fc1369ae73fe494a48e 0 1488180923571 8 connected
22a9bdce45393c94252524e06952894c096053cb 192.168.163.201:7004 slave 6a455332e5943d627e8cc1e0aa6b81a63e0e0457 0 1488180925089 5 connected
6a455332e5943d627e8cc1e0aa6b81a63e0e0457 192.168.163.201:7000 myself,master - 0 0 1 connected 0-4095
2cb201fc6cce0566d7d664bb5ce4a6899056ff62 192.168.163.201:7002 master - 0 1488180924585 3 connected 8192-12287
e15d5c2ea222ae4c038a009d319ca126a9a5dbd2 192.168.163.201:7008 slave 6a455332e5943d627e8cc1e0aa6b81a63e0e0457 0 1488180927617 9 connected
9c8747f55ffd27681f8191b7b2ff0f298602a236 192.168.163.201:7006 slave 2cb201fc6cce0566d7d664bb5ce4a6899056ff62 0 1488180925596 7 connected
f3b337f67349232c446b9fc1369ae73fe494a48e 192.168.163.201:7003 master - 0 1488180928632 4 connected 12288-16383
c2a9b43e3d91e7f1bc484836cfc59cfd2ed96a49 192.168.163.201:7005 slave 841b3e80f22c869ba4cf4a1a9829e3711ddcc74e 0 1488180926606 6 connected
cluster nodes 命令的输出有点儿复杂, 它的每一行都是由以下信息组成的:
节点 ID :例如 3fc783611028b1707fd65345e763befb36454d73 。
ip:port :节点的 IP 地址和端口号, 例如 127.0.0.1:7000 , 其中 :0 表示的是客户端当前连接的 IP 地址和端口号。
flags :节点的角色(例如 master 、 slave 、 myself )以及状态(例如 fail ,等等)。
如果节点是一个从节点的话, 那么跟在 flags 之后的将是主节点的节点 ID : 例如 127.0.0.1:7002 的主节点的节点 ID 就是 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 。
master节点最后有一个值的范围,就是hash槽,0~16383(2^14),平均的分配到各master节点。
启动后自动配置主从
redis cluster自动,9个redis实例,4主,5从
slave后的uuid就是指主的id值,从这关系中可以看出主从关系
7000的从是:7004,7008
7001的从是:7005
7002的从是:7006
7003的从是:7007
形成主从复制,数据分片存放
[root@localhost redis-3.2.6]# redis-cli -c -p 7000
127.0.0.1:7000> keys *
(empty list or set)
[root@localhost redis-3.2.6]# redis-cli -c -p 7001
127.0.0.1:7001> keys *
1) "name"
127.0.0.1:7001> exit
[root@localhost redis-3.2.6]# redis-cli -c -p 7002
127.0.0.1:7002> keys *
(empty list or set)
127.0.0.1:7002> exit
[root@localhost redis-3.2.6]# redis-cli -c -p 7003
127.0.0.1:7003> keys *
(empty list or set)
127.0.0.1:7003> exit
[root@localhost redis-3.2.6]# redis-cli -c -p 7004
127.0.0.1:7004> keys *
(empty list or set)
127.0.0.1:7004> exit
[root@localhost redis-3.2.6]# redis-cli -c -p 7005
127.0.0.1:7005> keys *
1) "name"
127.0.0.1:7005> exit
[root@localhost redis-3.2.6]# redis-cli -c -p 7006
127.0.0.1:7006> keys *
(empty list or set)
127.0.0.1:7006> exit
[root@localhost redis-3.2.6]# redis-cli -c -p 7007
127.0.0.1:7007> keys *
(empty list or set)
127.0.0.1:7007> exit
[root@localhost redis-3.2.6]# redis-cli -c -p 7008
127.0.0.1:7008> keys *
(empty list or set)
127.0.0.1:7008> exit
验证高可用
杀掉一个7001,集群继续运行
[root@localhost redis-3.2.6]# ps -ef |grep redis
root 5394 1 0 21:59 ? 00:00:50 redis-server 192.168.163.201:7000 [cluster]
root 5398 1 0 21:59 ? 00:00:46 redis-server 192.168.163.201:7001 [cluster]
root 5402 1 0 21:59 ? 00:00:46 redis-server 192.168.163.201:7002 [cluster]
root 5406 1 0 21:59 ? 00:00:46 redis-server 192.168.163.201:7003 [cluster]
root 5410 1 0 21:59 ? 00:00:44 redis-server 192.168.163.201:7004 [cluster]
root 5414 1 0 21:59 ? 00:00:46 redis-server 192.168.163.201:7005 [cluster]
root 5418 1 0 21:59 ? 00:00:45 redis-server 192.168.163.201:7006 [cluster]
root 5422 1 0 21:59 ? 00:00:44 redis-server 192.168.163.201:7007 [cluster]
root 5426 1 0 21:59 ? 00:00:44 redis-server 192.168.163.201:7008 [cluster]
root 6002 2543 0 23:55 pts/0 00:00:00 grep redis
[root@localhost redis-3.2.6]# kill 5398
[root@localhost redis-3.2.6]# ps -ef |grep redis
root 5394 1 0 21:59 ? 00:00:50 redis-server 192.168.163.201:7000 [cluster]
root 5402 1 0 21:59 ? 00:00:46 redis-server 192.168.163.201:7002 [cluster]
root 5406 1 0 21:59 ? 00:00:47 redis-server 192.168.163.201:7003 [cluster]
root 5410 1 0 21:59 ? 00:00:44 redis-server 192.168.163.201:7004 [cluster]
root 5414 1 0 21:59 ? 00:00:46 redis-server 192.168.163.201:7005 [cluster]
root 5418 1 0 21:59 ? 00:00:45 redis-server 192.168.163.201:7006 [cluster]
root 5422 1 0 21:59 ? 00:00:45 redis-server 192.168.163.201:7007 [cluster]
root 5426 1 0 21:59 ? 00:00:44 redis-server 192.168.163.201:7008 [cluster]
root 6004 2543 0 23:55 pts/0 00:00:00 grep redis
[root@localhost redis-3.2.6]# redis-cli -c -p 7000
127.0.0.1:7000> cluster nodes
841b3e80f22c869ba4cf4a1a9829e3711ddcc74e 192.168.163.201:7001 master,fail - 1488182142448 1488182136758 2 disconnected
182c2a3991c331e4e9222f40d33566c63c32be61 192.168.163.201:7007 slave f3b337f67349232c446b9fc1369ae73fe494a48e 0 1488183066434 8 connected
22a9bdce45393c94252524e06952894c096053cb 192.168.163.201:7004 slave c2a9b43e3d91e7f1bc484836cfc59cfd2ed96a49 0 1488183067873 10 connected
6a455332e5943d627e8cc1e0aa6b81a63e0e0457 192.168.163.201:7000 myself,master - 0 0 1 connected 0-4095
2cb201fc6cce0566d7d664bb5ce4a6899056ff62 192.168.163.201:7002 master - 0 1488183068484 3 connected 8192-12287
e15d5c2ea222ae4c038a009d319ca126a9a5dbd2 192.168.163.201:7008 slave 6a455332e5943d627e8cc1e0aa6b81a63e0e0457 0 1488183067462 9 connected
9c8747f55ffd27681f8191b7b2ff0f298602a236 192.168.163.201:7006 slave 2cb201fc6cce0566d7d664bb5ce4a6899056ff62 0 1488183069499 7 connected
f3b337f67349232c446b9fc1369ae73fe494a48e 192.168.163.201:7003 master - 0 1488183070541 4 connected 12288-16383
c2a9b43e3d91e7f1bc484836cfc59cfd2ed96a49 192.168.163.201:7005 master - 0 1488183069914 10 connected 4096-8191
可以看到7001被关闭后,7005自动成为master
同时会根据set时的分片,自动转向到对应的主节点
127.0.0.1:7000> set name 123
-> Redirected to slot [5798] located at 192.168.163.201:7005
OK
192.168.163.201:7005> get name
"123"
192.168.163.201:7005> set n 123
-> Redirected to slot [3432] located at 192.168.163.201:7000
OK
192.168.163.201:7000> get n
"123"
重新启动7001节点,自动回到集群,成为从节点,挂接到7005上
[root@localhost redis-3.2.6]# redis-server 7001/redis.conf
[root@localhost redis-3.2.6]# ps -ef|grep redis
root 5394 1 0 Feb26 ? 00:01:08 redis-server 192.168.163.201:7000 [cluster]
root 5402 1 0 Feb26 ? 00:01:04 redis-server 192.168.163.201:7002 [cluster]
root 5406 1 0 Feb26 ? 00:01:05 redis-server 192.168.163.201:7003 [cluster]
root 5410 1 0 Feb26 ? 00:01:01 redis-server 192.168.163.201:7004 [cluster]
root 5414 1 0 Feb26 ? 00:01:04 redis-server 192.168.163.201:7005 [cluster]
root 5418 1 0 Feb26 ? 00:01:02 redis-server 192.168.163.201:7006 [cluster]
root 5422 1 0 Feb26 ? 00:01:02 redis-server 192.168.163.201:7007 [cluster]
root 5426 1 0 Feb26 ? 00:01:01 redis-server 192.168.163.201:7008 [cluster]
root 6122 1 1 00:14 ? 00:00:00 redis-server 192.168.163.201:7001 [cluster]
root 6128 2543 0 00:14 pts/0 00:00:00 grep redis
[root@localhost redis-3.2.6]# redis-cli -c -p 7000
127.0.0.1:7000> cluster nodes
841b3e80f22c869ba4cf4a1a9829e3711ddcc74e 192.168.163.201:7001 slave c2a9b43e3d91e7f1bc484836cfc59cfd2ed96a49 0 1488183297831 10 connected
182c2a3991c331e4e9222f40d33566c63c32be61 192.168.163.201:7007 slave f3b337f67349232c446b9fc1369ae73fe494a48e 0 1488183298846 8 connected
22a9bdce45393c94252524e06952894c096053cb 192.168.163.201:7004 slave c2a9b43e3d91e7f1bc484836cfc59cfd2ed96a49 0 1488183294789 10 connected
6a455332e5943d627e8cc1e0aa6b81a63e0e0457 192.168.163.201:7000 myself,master - 0 0 1 connected 0-4095
2cb201fc6cce0566d7d664bb5ce4a6899056ff62 192.168.163.201:7002 master - 0 1488183293778 3 connected 8192-12287
e15d5c2ea222ae4c038a009d319ca126a9a5dbd2 192.168.163.201:7008 slave 6a455332e5943d627e8cc1e0aa6b81a63e0e0457 0 1488183295809 9 connected
9c8747f55ffd27681f8191b7b2ff0f298602a236 192.168.163.201:7006 slave 2cb201fc6cce0566d7d664bb5ce4a6899056ff62 0 1488183296819 7 connected
f3b337f67349232c446b9fc1369ae73fe494a48e 192.168.163.201:7003 master - 0 1488183298346 4 connected 12288-16383
c2a9b43e3d91e7f1bc484836cfc59cfd2ed96a49 192.168.163.201:7005 master - 0 1488183299860 10 connected 4096-8191