当一个redis数据库不能承载所有的应用程序的缓存数据时,需要将对redis的缓存数据进行分布式存储。分布式存储涉及到存和取的问题,就是存储后,再次取的时候要能知道到哪个服务器上去取。本节重点讨论redis分布式缓存的问题。
在redis3.0之前,redis数据库侧不提供数据的分布式存储技术,数据的分片存储靠客户端自己去控制,即把数据存储在哪个节点上,自己去掌控。一般客户端会采用一致性哈希算法对数据进行分布式存储,这种技术存在单调性,即使有新的节点加进来,最多只会破坏一个节点的数据存储,即影响到的那个节点,数据不在老的节点上就在新加入的节点上,不会影响其他数据的存储,但是依然需要将影响到的数据迁移到新的节点上。如果有节点下线,也需要手工对数据进行迁移。
后来慢慢出现了预分片技术,考虑到redis实例本身占用很少的内存,可以提前批量分配好1000个实例,开始时数据比较少,可以用一台会几台机器承载这几个实例,等后面数据量慢慢上来,可以将这些实例迁移至其他的机器上,实例的迁移相对比较容易。
者两种技术,实际上属于客户端分片技术,当节点增加或者删除,需要大量的手工操作,维护成本较高。
redis3.0以后支持服务器侧集群技术,即数据的存储与获取,有服务器端负责,当客户端向服务器发起数据存储或查询命令时,节点会查看key对应的插槽号码是否在本节点上,如果本节点没有该插槽,会发起MOVE命令进行重定向,告诉客户端,插槽在哪个节点上,有些语言的客户端支持自动代理,即重定向后自动再次发起命令,这样就使得使用集群版的redis和使用普通的单机版的redis没有什么区别。而且服务器上如果新加入节点或者移除节点,只需要执行部分命令将插槽和数据迁移过去就ok,无需太多手工操作,也不需要暂停redis服务,高效安全。
key对应的插槽号可以用CRC16算法对16384取余求的。
A)创建6个节点
三主三从,6380 6381 6382主,6384 6385 6386 从
cd /usr/local/
mkdir redis_cluster
mkdir 6380 6381 6382 6384 6385 6386
cp /usr/local/redis/redis.conf ./redis_cluster/7000/
cp /usr/local/redis/redis.conf ./redis_cluster/7001/
cp /usr/local/redis/redis.conf ./redis_cluster/7002/
分别对6380 6381 6382文件夹中的3个文件修改对应的配置
daemonize yes
pidfile /var/run/redis_6380.pid
port 6380
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 5000
分别对6384 6385 6386 文件夹中的3个文件修改对应的配置
daemonize yes
pidfile /var/run/redis_6384.pid
port 6384
cluster-enabled yes
cluster-config-file nodes_6384.conf
cluster-node-timeout 5000
slaveof 127.0.0.1 6380
启动6个节点
cd /usr/local
redis-server redis_cluster/6380/redis.conf
redis-server redis_cluster/6381/redis.conf
redis-server redis_cluster/6382/redis.conf
redis-server redis_cluster/6383/redis.conf
redis-server redis_cluster/6384/redis.conf
redis-server redis_cluster/6385/redis.conf
创建集群
yum -y install ruby ruby-devel rubygems rpm-build
gem install redis
/usr/local/redis/src/redis-trib.rb create --replicas 1 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385
查看集群信息:
redis 6380> CLUSTER NODES
给集群增加实例:
./redis-trib add-node 127.0.0.1:6386 to cluster 127.0.0.1:6380
移动插槽:
这是一个交互式的命令,会问你需要移动多少个插槽,从哪些节点移除。
./redis-trib.rb reshard 127.0.0.1:6386
增加备份节点:
./redis-trib.rb add-node --slave 127.0.0.1:6387 127.0.0.1:6386
删除从节点:
./redis-trib.rb del-node 127.0.0.1:6387 65e123456925326as5432185433112347d2d9
删除主节点:
首先先转移插槽,会让你输入移除多少个插槽,移到什么节点上去
/redis-trib.rb reshard 127.0.0.1:6386
删除主节点:
./redis-trib.rb del-node 127.0.0.1:6386 65e123451234526as5xxx185433tt1117d2d9
如果集群内部有任意一个主数据库节点宕机,需要进行故障恢复,故障恢复的实质就是选举从数据库替代主数据库,选举选之前已经提过,此处不在多说。
集群的主数据库之间定期进行PING操作,一旦有一个数据库发现其他节点下线,就认为他疑似下线,然后将此消息广播给其他节点,如果其他节点有超过半数认为该节点下线,那么认定此节点主观下线。如果主观下线就需要进行故障恢复。
如果故障恢复失败,默认情况集群不再提供服务,可以打开一个配置开关,让集群能继续服务:
cluster-require-full-coverage no