目录
集群的引入
集群概念
搭建集群
什么是slots
查询集群中的值
集群的故障恢复
问题1:当一台redis的容量不够,redis如何进行扩容?
问题2:并发写操作,redis的写操作压力过大,如何进行分摊?
问题3:主从模式,薪火相传模式,主机宕机,会导致IP地址发生变化,应用程序中配置需要修改对应的主机地址,端口等信息。修改起来很不方便。
上面的问题都可以通过集群进行处理。
之前是通过代理主机的集群方式来处理,但是在redis3.0中提供了一种无中心化集群配置。
redis中推荐使用无中心化集群方式来搭建集群。
代理主机:
比如有多种信息:用户信息,商品信息,订单信息。分别保存到redis中。当客户端需要访问用户信息时,怎么知道访问哪一台服务器呢?
于是在客户端和redis服务器之间增加了一台代理主机。客户端将请求发送给代理主机,代理主机再将请求转发到对应的redis服务器。
每一个redis服务器包含保存数据的服务器和代理服务器都可以使用主从复制的模式,防止宕机数据保存不了了。
但是这样会有一个缺点:使用到的redis服务器太多了。
无中心化集群
和上面情况一样,当有多台redis保存不同的数据时。
任何一台服务器都可以作为集群的入口。当访问的不是当前redis保存的数据时,该服务器会将请求转发给另外一台服务器。
即集群中的redis服务器之间可以互相进行访问。
同样每台服务器可以使用主从复制的模式,下面可以连接多台从服务器。防止宕机。
redis集群实现了对redis的水平扩容,即启动N个redis节点,将全部数据分别存储在N个节点中,每一个节点存储总数数据1/N。
redis集群通过分区来提供一定程度的可用性:即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。一个区出现问题,不会影响另外一个区。
我们是在一台服务上搭建,redis服务都部署在一台linux服务器上。在实际中,一个redis服务是部署在一台linux上的。
搭建6个redis服务分别以6379,6380,6381,6389,6390,6391端口启动。以端口6389启动的redis服务作为以端口6379启动redis服务的从服务器。以端口6390启动的redis服务作为以端口6380启动redis服务的从服务器。以端口6391启动的redis服务作为以端口6381启动redis服务的从服务器。
其他配置文件只需要将6379改成自己对应的端口即可。
生成了节点文件说明启动成功了。
找到redis的/src文件,找到redis-cli可执行文件。执行命令:
#--cluster 表示集群操作
# create 表示创建集群
#--cluster-replicas 1:集群方式 1表示以最简单的方式配置集群,一台主机,一台从机,正好3组。
#ip 如果在本地不要使用127.0.0.1,用真实ip
redis-cli --cluster create --cluster-replicas 1 ip:port ip:port ip:port ... ...
如果执行上面命令报错,被拒绝连接。则需要修改include的redis的配置文件。
将bind字段设置文件0.0.0.0,允许所有ip连接。将protected-mode设置文件no,取消保护模式。
一个集群至少要有三个主节点。
选项--cluster-replicas 1表示我们希望为集群中的每一个主节点创建一个从节点。
分配原则尽量保证每一个主数据库运行在不同的ip地址,每一个从数据库和主数据库运行在不同的IP地址。
slots表示当前集群的插槽。当集群启动完毕后,会打印出插槽数。
上面说明当前集群有16384个插槽。数据库中的每一个键都属于哲16384个插槽中的一个。编号是0-16383。
集群通过公式CRC16(key)%16384来计算key属于哪一个槽。其中CRC(key)语句用于计算键key的CRC16的校验和。
集群中的每一个节点负责一部分的插槽。
举个例子:当我们往集群中插入一个数据:set k1 v1。redis会通过CRC算法计算出k1所在插槽。再向插槽位置中插入数据。插槽也对应了哪一个节点。
插槽的作用就是将数据平均分担到不同的节点中去。需要查找和插入某个数据,需要通过redis会通过算法计算出插槽,找到对应的节点,切换到对应节点去做对应的事(删除/查找/插入)。由于是无中心化的集群,所以无论从哪个节点进入的,都i可以在不同节点间切换。
由于键值不同,计算的插槽可能不同,所以redis集群不允许一次性插入多个键值。
如何一次性插入多个键值呢?设置一个组,将需要插入的多个键值归类于同一组。redis集群会通过组来计算插槽,在切换到对应几点进行操作。
需要看配置中的cluster-require-full-coverage字段。该字段设置为yes,那么整个集群都会挂掉。如果是no,那么当前节点的插槽全部不能使用,也无法储存。但是不会影响其他节点。