Redis的拓展方案
- Redis的拓展方案
- 分区
- 主从
- 哨兵
- 集群
Redis的拓展方案
分区
分区是一种最简单的拓展方式。即将全部数据分散在多个Redis实例中,每个实例不需要关联,可以是完全独立的。
使用方式:
1、客户端处理和传统的数据库分库不一样,可以从key入手,先进行计算,找到对应数据储存的实例在进行操作。
(1)范围角度。比如 orderId:1至orderId:1000放入实例1,orderID:1001至orderId:2000放入实例2…
(2)哈希计算。就像我们的hashmap一样,用hash函数加上位运算或者取模。高机玩法还有【一致性Hash】等操作,找到对应的实例来进行操作。
2、使用代理中间件。我们可以开发独立的代理中间件,屏蔽掉处理数据分片的逻辑,独立运行。Redis也有优秀的代理中间件,比如
【Twemproxy】或者【codis】,可以结合场景选择是否使用。
缺点:
1、无缘多key操作
key都不一定在一个实例上,那么多key操作或者是多key事务自然是不支持的。
2、维护成本
由于每个实例在物理和逻辑上们都属于单独的一个节点,缺乏统一管理。
3、灵活性有限
范围分片还好,比如hash+MOD这种方式,如果想动态调整Redis实例的数量,就要考虑大量数据迁移,这就非常麻烦了。
主从
常说的主从(Master-Slave),也就是复制(Replication)方式,同分区一样,也是Redis高可用架构的基础,但是,这类基础模式并不是高可用。
分区暂时能解决单点无法容纳的数据量问题,但是一个key还是只在一个实例上,在大流量时代显得不那么可靠。
主从就是从另一个维度的拓展,节点将数据同步到从节点,可靠性提高了不少。
使用方式:
1.作为主节点的Redis实例,并不要求配置任何参数,只需要正常启动就行。
2.作为从节点的实例,使用配置文件或者命令方式REPLICAOF 主节点Host 主节点port 即可完成主从配置。
缺点:
1.slave节点都是只读的,如果流量大的场景,就有些力不从心了。数据复制是由主到从,从节点都有数据同步不到主节点,数据就不一致了。
2.故障转移不友好,主节点挂掉之后,写处理就无法执行,需要手工的设定新的主节点,如使用REPLIAOF no one晋升为主节点,在书里其他的slave节点的新主配置,相对来说是很麻烦的。
哨兵
主从的手工故障转移,让人难以接受,自然就会出现高可用的方案—哨兵(Sentinel)
我们可以在主从架构不变的场景,直接加入Redis Sentinel,对节点来进行监控,来完成自动的故障发信与转移。
并且还能够充当配置提供者,提供主节点的信息,就算发生了故障转移,也能提供正确的地址。
哨兵本身也是Redis实例的一种,但不作为数据存储方使用,启动命令也是不一样的。
使用方式
Sentinel的最小配置
sentinel monitor <主节点别名> <主节点host> <主节点端口> <票数>
只需要配置master即可,然后使用 redis-sentinel <配置文件> 命令启动即可。
Redis官网提到的最小配置就是如下:
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5
设置主节点别名就是为了监控多主的时候,与其额外配置项能够与其对应,以继sentinel一些命令,如SENTINEL get-master-addr-by-name 就要用到别名了。
哨兵数量建议在三个以上且为奇数。
拓展
既然是高可用方案,并非有严格意义上的缺点,还需要配合使用场景需要考虑。
1、故障转移期间短暂的不可用,但其实官网的例子也给出了parallel-syncs参数来指定并行的同步实力数量,以免全部实例都在同步出现整体不可用的情况,相对来说要比手工的故障转移更加方便。
2、分区逻辑需要自定义处理,虽然解决了主从下的高可用问题,但是Sentinel并没有提供分区解决方案,还需考虑开发者如何建设。
3、既然是主从,如果异常的写流量搞垮了主节点,那么自动的”故障转移“会不会变成”灾难转移“,即slave提升为Master之后挂掉,又进行提升之后又被挂掉。这只是猜测。
集群
Redis Cluster 是官方在3.0版本后推出的分布式方案。
有了官方正式的集群方案,从请求路由、故障转移、弹性伸缩几个纬度的使用上,将更为容易。
Cluster不同于哨兵,是支持分区的。有说法Cluster是哨兵的升级,这是不严谨的。
而这位都不一样,如果因为Cluster也有故障转移,就说它是哨兵的升级款,略显牵强。
Cluster在分区管理上,使用了”哈希槽“(hash slot),一共16384个槽位,每个实例负责一部分槽,通过CRC16(key)16383这样的公式,计算出来key所对应的槽位。
虽然在节点和key二者中引入了槽的概念,看起来不易理解,实际上因为颗粒更细了,减少了节点的扩容和收缩难度,相比传统策略还是很有优势。
使用方式
Redis集群从配置文件开始
cluster-enabled yes //开启集群
cluster-config-file "redis-node.conf" //指定集群配置文件
集群配置文件(cluster-config-file)为内部使用,可以不去指定,Redis会帮助创减一个。启动方式还是普通的方式
redis-server redis.conf
首先以集群的方式启动了N台Redis实例。然后”牵线搭桥分配槽“
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
--cluster-replicas 1
一行命令完成”三主三从“以及自动分配槽的操作
集群搭建完成后,使用check命令检查一下
redis-cli --cluster check 127.0.0.1:7001
拓展
1、虽然是对分区的良好支持,但也有一些分区的老问题,比如:如果不在同一个槽的数据,是没法使用类似mset的多间操作。
2、在【select 命令页】 有提到,集群模式下只能使用一个库。
3、运维上也要谨慎,启动搭建是很方便,使用时面对宽带消耗,数据倾斜等具体问题,还需人工介入,研究合适的配置参数。