- 具有高可用,持久化的特性。
- 数据可以设置失效时间,方便自动数据清理。
- 支持常用数据结构,如集合,有序集合,Hash map,列表等。
- 支持事务操作,方便原子化的对多个key进行操作。
- 有Python,Golang语言的客户端。
Redis的典型使用方式:
非持久化的独立部署方式:
这种使用方式主要的使用场景是使用Redis做为Cache集群,存储可以丢失的cache数据,首要考虑目标是速度,不考虑持久化。典型的使用方式如下:
所有数据都在内存中,不落盘,集群中实例之间相互无感知,每个实例都是对等的,在客户端做基于一致性hash的数据分配。用户只需要告诉客户端所有可用的集群实例列表,由客户端对key做一致性hash来决定key会落到那个redis实例上,从而决定会对哪个实例进行读写。
除了在客户端做hash还有一种方式是使用Proxy代理,由代理来负责对key做hash决定客户端的请求会落到哪个实例,客户端只需要连接到proxy就行了。Twemproxy 就是一个开源的实现了Redis和Memecached协议的Proxy。
持久化方案:
Redis有两种持久化方案: RDB和AOF, 说白了前者就是dump全量数据做snapshot,后者是记录增量操作日志。
两者的优缺点也很明显: RDB适合做数据备份和数据快速恢复,但是做snapshot是一个很费时的过程,不可能做到频率很高,一般是每几分钟进行一次,所以不能保证最近几分钟之内的数据不会丢。
AOF做增量操作日志的代价不是很高,一般是每秒一次,所以能保证最多只丢一秒的数据。
不过需要指出的是这两种方式并不冲突,可以同时开启,我们在部署的时候也是这么做的。
社区也在考虑结合RDB和AOF,达到类似PostgreSQL的数据安全性(有点小期待呢)。
主从复制(Replication):
Redis采用1:N主备结构来实现replication。但是需要注意的是为了提高效率,Master和Slave之间是异步进行数据同步的,这也就意味着主备之间可能存在数据不一致的情况,但是有配置可以指定主备之间的最大数据延时,需要用户自己根据业务场景进行配置。
使用Sentinel哨兵实现HA:
Sentinel是Redis提供的一个哨兵组件,主要实现了两个功能:
1. Master和slave监控,一旦Master不可用,则Sentinel集群会进行投票,进行failover,选举新的master。
2. Master和Slave的配置提供,客户端只需要从sentinel即可读取当前的主从配置即可,不需要主动连接Master和Slave。
Redis Cluster集群部署方式:
Redis Cluster使用多个Redis实例进行容量扩展。这种方式同独立部署方式的区别是集群的实例之间不是相互独立的,是相互感知的,每个实例都知道其他实例的存在,并会进行通信同步全局的sharding和集群配置。
此模式下如何对数据进行切分(sharding):
1. 客户端不会进行一致性hash,而是会对key做CRC16运算,然后将产生的值%16384, 从而产生一个0~16383的值。
2. 集群会将所有key切分成16384个hash slot, 并根据集群中redis实例的个数将hash slot均分到所有的实例中。
3. 将1中产生的值直接对应到相同值的hash slot,而集群中包含此hash slot的机器既是包含此key的机器
4. 当3中客户端计算出的机器因进行过人工resharding而不在包含3中的slot时,此机器会根据自己感知的集群sharding配置返回redirect告知真正包含所需hash slot的机器。
不过有几个需要注意的地方:
1. 当需要对集群进行扩容时,将新机器加到集群中之后其实新机器并没有包含任何hash slot,需要手动重新进行sharding分配hash slot并进行数据迁移。
2. 连接Redis Cluster的客户端和标准客户端是不一样的,不能混用。
3. Transaction支持受限:当transaction中涉及的key不属于同一个redis实例时无法完成transaction。
4. 多key操作受限:如取两个集合的交集操作,若两个集合的key属于不同的机器,则无法完成。
最终选定的部署方式:
由于Redis Cluster部署方式下transaction和多key操作受限,而单台机器的容量能满足我们的业务需求,所以没有选择Redis Cluster部署方式,最终选择的部署方式如下:
1. 采用一台Master加两台slave做replication。
2. 采用三台机器搭建sentinel集群,保证高可用性。
3. 将sentinel部署在使用的redis服务的三台Tesla API后端机,使得sentinel能反映API到Master/slave的真实可用性。
在这种部署方式下再加上针对redis server和redis sentinel的配置和运维控制脚本即可完成服务的搭建。