主从模式
1.1 简介
主从模式是三种模式中最简单的,在主从复制中,数据库分为2类:主数据库和从数据库
* 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库
* 从数据库一般都是只读的,并且接收主数据库同步过来的数据
* 一个master可以拥有多个slave,但是一个slave只能对应一个master
* slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来
* master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务
* master挂了以后,不会在slave节点中重新选一个master
1.2 工作机制
当slave启动后,主动向master发送SYNC命令。master接受到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave收到快照文件和命令后加载快照文件和缓存的执行命令。复制初始化后,master每次收到的写命令都会同步发送给slave,保证主从数据一致性。
缺点:
从上面可以看出,master节点在主从模式中唯一,若master挂掉,则redis无法对外提供写服务。
哨兵模式
2.1 简介
主从模式的弊端就是不具备高可用性,当master挂掉以后,Redis将不能再对外提供写入操作,因为哨兵应运而生。
哨兵的作用就是监控redis集群的运行状况。特点如下:
* sentinel模式是建立在主从模式的基础上,如果只有一个Redis节点,sentinel就没有任何意义
* 当master挂了以后,sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master
* 当master重新启动后,它将不再是master而是做为slave接收新的master的同步数据
* sentinel因为也是一个进程有挂掉的可能,所以sentinel也会启动多个形成一个sentinel集群
* 多sentinel配置的时候,sentinel之间也会自动监控
* 当主从模式配置密码时,sentinel也会同步将配置信息修改到配置文件中,不需要担心
* 一个sentinel或sentinel集群可以管理多个主从Redis,多个sentinel也可以监控同一个redis
* sentinel最好不要和Redis部署在同一台机器,不然Redis的服务器挂了以后,sentinel也挂了
2.2 工作机制
- 每个sentinel以每秒钟一次的频率向它所知的master,slave以及其他sentinel实例发送一个 PING 命令
- 如果一个实例距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被sentinel标记为主观下线。
- 如果一个master被标记为主观下线,则正在监视这个master的所有sentinel要以每秒一次的频率确认master的确进入了主观下线状态
- 当有足够数量的sentinel(大于等于配置文件指定的值)在指定的时间范围内确认master的确进入了主观下线状态, 则master会被标记为客观下线
- 在一般情况下, 每个sentinel会以每 10 秒一次的频率向它已知的所有master,slave发送 INFO 命令
- 当master被sentinel标记为客观下线时,sentinel向下线的master的所有slave发送 INFO 命令的频率会从 10 秒一次改为 1 秒一次
- 若没有足够数量的sentinel同意master已经下线,master的客观下线状态就会被移除;
- 若master重新向sentinel的 PING 命令返回有效回复,master的主观下线状态就会被移除
2.3 注意点
当使用sentinel模式的时候,客户端就不要直接连接Redis,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。
Cluster模式
3.1 简介
哨兵模式基本可以满足一般生产的需求,具备高可用性。但是当数据量过大到一台服务器存不下的情况时,主从模式或sentinel模式就不能满足需求了,这个时候需要对存储的数据进行分片,将数据存储到多个Redis实力中,cluster模式的出现就是为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。
3.2 工作机制
cluster可以说是sentinal和主从模式的结合体,通过cluster可以实现主从和master重选功能,所以如果配置两个副本三个分片的话,就需要六个Redis实例。因为Redis的数据是根据一定规则分配到cluster的不同机器的,当数据量过大时,可以新增机器进行扩容。
使用集群,只要将redis配置文件中的cluster-enable配置打开即可。每个集群中至少需要3个主数据库才能正常运行,新增节点非常方便。
3.3 cluster集群优点
- 多个redis节点网络互联,数据共享
- 所有的节点都是一主一从(也可以是一主多从),其中从不提供服务,仅作为备用
- 支持在线增加、删除节点
- 客户端可以连接任何一个主节点进行读写
3.4 cluster集群缺点
- 不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上,
- 并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为
代理模式
目前比较流行的代理框架如下 :
- twemproxy:快速、轻量级memcached和redis代理,Twitter推特公司开发
- codis:redis集群代理解决方案,豌豆荚公司开发,需要修改redis源码
- predixy:高性能全特征redis代理,支持Redis Sentinel和Redis Cluster
- Redis-cerberus: Redis Cluster代理
对比:
4.1 Twemproxy
4.1.1 工作机制
Twemproxy是一种代理分片机制,由Twitter开源。Twemproxy作为代理,可接受来自多个程序的访问,按照路由规则,转发给后台的各个Redis服务器,再原路返回。该方案很好的解决了单个Redis实例承载能力的问题。通过Twemproxy可以使用多台服务器来水平扩张redis服务,可以有效的避免单点故障问题。
4.1.2 缺点
- Twemproxy本身也是单点(需要用Keepalived做高可用方案)
- 使用Twemproxy需要更多的硬件资源和在redis性能有一定的损失(twitter测试约20%)
4.1.3 不支持的命令
https://github.com/twitter/twemproxy/blob/master/notes/redis.md
4.2 Codis
Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说,连接到 Codis Proxy 和连接原生的 RedisServer 没有明显的区别 (部分命令不支持),上层应用可以像使用单机的 Redis 一样使用,Codis 底层会处理请求的转发,不停机的数据迁移等工作,所有后边的一切事情,对于前面的客户端来说是透明的,可以简单的认为后边连接的是一个内存无限大的 Redis 服务。
4.2.1 工作机制
Codis包含如下组件
- Codis Proxy (codis-proxy)
- Codis Manager (codis-config)
- Codis Redis (codis-server)
- ZooKeeper
codis-proxy 是客户端连接的 Redis 代理服务, codis-proxy 本身实现了 Redis 协议, 表现得和一个原生的 Redis 没什么区别 (就像 Twemproxy), 对于一个业务来说, 可以部署多个 codis-proxy, codis-proxy 本身是无状态的。
codis-config 是 Codis 的管理工具, 支持包括, 添加/删除 Redis 节点, 添加/删除 Proxy 节点, 发起数据迁移等操作. codis-config 本身还自带了一个 http server, 会启动一个 dashboard, 用户可以直接在浏览器上观察 Codis 集群的运行状态。
codis-server 是 Codis 项目维护的一个 Redis 分支, 基于 2.8.13 开发, 加入了 slot 的支持和原子的数据迁移指令. Codis 上层的 codis-proxy 和 codis-config 只能和这个版本的 Redis 交互才能正常运行.
Codis 依赖 ZooKeeper 来存放数据路由表和 codis-proxy 节点的元信息, codis-config 发起的命令都会通过 ZooKeeper 同步到各个存活的 codis-proxy。
Codis 支持按照 Namespace 区分不同的产品, 拥有不同的 product name 的产品, 各项配置都不会冲突。
4.2.2 优点
- 自动平衡
- 使用非常简单
- 图形化的面板和管理工具
- 支持绝大多数 Redis 命令,完全兼容twemproxy
- 支持 Redis 原生客户端
- 安全而且透明的数据移植,可根据需要轻松添加和删除节点
- 提供命令行接口
- RESTful API
4.2.3 不支持的命令
代码语言:javascript复制KEYS, MOVE, OBJECT, RENAME, RENAMENX, SORT, SCAN, BITOP,MSETNX, BLPOP, BRPOP, BRPOPLPUSH, PSUBSCRIBE,PUBLISH, PUNSUBSCRIBE, SUBSCRIBE, UNSUBSCRIBE, DISCARD, EXEC, MULTI, UNWATCH, WATCH, SCRIPT EXISTS, SCRIPT FLUSH, SCRIPT KILL, SCRIPT LOAD, AUTH, ECHO, SELECT, BGREWRITEAOF, BGSAVE, CLIENT KILL, CLIENT LIST, CONFIG GET, CONFIG SET, CONFIG RESETSTAT, DBSIZE, DEBUG OBJECT, DEBUG SEGFAULT, FLUSHALL, FLUSHDB, INFO, LASTSAVE, MONITOR, SAVE, SHUTDOWN, SLAVEOF, SLOWLOG, SYNC, TIME
https://github.com/CodisLabs/codis
https://github.com/CodisLabs/codis/blob/master/doc/tutorial_zh.md
4.3 predixy
在redis 3.0推出redis cluster之前,代理层实现redis集群是首选方案,twemproxy和codis是最常见的两个代理 。然而Twemproxy不支持的redis功能太多,像列表的阻塞命令、事物、发布订阅等都不支持,而且也没有直接支持redis的高可用
4.3.1 工作机制
predixy既支持Redis Sentinel也支持Redis Cluster
- 后端为Redis Sentinel监控的一组Redis,功能完全等同于原始Redis
- 后端为Redis Sentinel监控的多组Redis,则有部分功能受限
- 后端为Redis Cluster,功能完全等同于Redis Cluster
4.3.2 特点
- 高性能并轻量级
- 支持多线程
- 多平台支持:Linux、OSX、BSD、Windows
- 支持Redis Sentinel,可配置一组或者多组redis
- 支持Redis Cluster
- 支持redis阻塞型命令,包括blpop、brpop、brpoplpush
- 支持scan命令,无论是单个redis还是多个redis实例都支持
- 多key命令支持: mset/msetnx/mget/del/unlink/touch/exists
- 支持redis的多数据库,即可以使用select命令
- 支持事务,当前仅限于Redis Sentinel下单一redis组可用
- 支持脚本,包括命令:script load、eval、evalsha
- 支持发布订阅机制,也即Pub/Sub系列命令
- 多数据中心支持,读写分离支持
- 扩展的AUTH命令,强大的读、写、管理权限控制机制,健空间限制机制
- 日志可按级别采样输出,异步日志记录避免线程被io阻塞
- 日志文件可以按时间、大小自动切分
- 丰富的统计信息,包括CPU、内存、请求、响应等信息
- 延迟监控信息,可以看到整体延迟,分后端redis实例延迟
PS:以上内容参考多处资料,如有侵权请联系我