Redis的拓展方案

  • Redis的拓展方案
  • 分区
  • 主从
  • 哨兵
  • 集群


Redis的拓展方案

分区

分区是一种最简单的拓展方式。即将全部数据分散在多个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还是只在一个实例上,在大流量时代显得不那么可靠。

主从就是从另一个维度的拓展,节点将数据同步到从节点,可靠性提高了不少。

redis增量扩容机制 redis扩展_数据库_02

使用方式:

1.作为主节点的Redis实例,并不要求配置任何参数,只需要正常启动就行。

2.作为从节点的实例,使用配置文件或者命令方式REPLICAOF 主节点Host 主节点port 即可完成主从配置。

缺点:

1.slave节点都是只读的,如果流量大的场景,就有些力不从心了。数据复制是由主到从,从节点都有数据同步不到主节点,数据就不一致了。

2.故障转移不友好,主节点挂掉之后,写处理就无法执行,需要手工的设定新的主节点,如使用REPLIAOF no one晋升为主节点,在书里其他的slave节点的新主配置,相对来说是很麻烦的。

哨兵

主从的手工故障转移,让人难以接受,自然就会出现高可用的方案—哨兵(Sentinel)

我们可以在主从架构不变的场景,直接加入Redis Sentinel,对节点来进行监控,来完成自动的故障发信与转移。

并且还能够充当配置提供者,提供主节点的信息,就算发生了故障转移,也能提供正确的地址。

哨兵本身也是Redis实例的一种,但不作为数据存储方使用,启动命令也是不一样的。

redis增量扩容机制 redis扩展_数据库_03

使用方式

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所对应的槽位。

redis增量扩容机制 redis扩展_Redis_04

虽然在节点和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、运维上也要谨慎,启动搭建是很方便,使用时面对宽带消耗,数据倾斜等具体问题,还需人工介入,研究合适的配置参数。