混合持久化

混合持久化

Redis4.0 后大部分的使用场景都不会单独使用 RDB 或者 AOF 来做持久化机制,而是兼顾二者的优势混合使用。
其原因是 RDB 虽然快,但是会丢失比较多的数据,不能保证数据完整性;AOF 虽然能尽可能保证数据完整性,但是性能确实是一个诟病,比如重放恢复数据混合持久化通过 aof-use-rdb-preamble yes 开启,Redis 4.0 以上版本默认开启推荐是 AOF 和 RDB 两者均开启
如果对数据不敏感,可以选单独用 RDB
不建议单独用 AOF,因为可能会出现 Bug
如果只是做纯内存缓存,可以都不用

Redis 事务

事务是指一个完整的动作,要么全部执行,要么什么也没有做。redis 事务相关的四个 redis 指令,即 multi、exec、discard、watch。这四个指令构成了 redis 事务处理的基础。
1、multi 用来组装一个事务;
2、exec 用来执行一个事务;
3、discard 用来取消一个事务;
4、watch 用来监视一些 key,一旦这些 key 在事务执行之前被改变,则取消事务的执行。
redis> multi
redis> INCR id
redis> INCR id
redis> exec

用 multi 组装事务时,每一个命令都会进入内存中缓存起来,QUEUED 表示缓存成功,在 exec 时这些被 QUEUED的命令都会被组装成一个事务来执行。
对于事务的执行来说,如果 redis 开启了 AOF 持久化的话,那么一旦事务被成功执行,事务中的命令就会通过write 命令一次性写到磁盘中去,如果在向磁盘中写的过程中恰好出现断电、硬件故障等问题,那么就可能出现只有部分命令进行了 AOF 持久化,这时 AOF 文件就会出现不完整的情况,这时可以使用 redis-check-aof 工具来修复这一问题,这个工具会将 AOF 文件中不完整的信息移除,确保 AOF 文件完整可用。
遇到的两类错误有调用 EXEC 之前的错误和调用 EXEC 之后的错误。
调用 EXEC 之前的错误是有可能是由于语法有误导致的,也可能时由于内存不足导致的。只要出现某个命令无法成功写入缓冲队列的情况,redis 都会进行记录,在客户端调用 EXEC 时,redis2.6.5 版本之后会拒绝执行这一事务。在 2.6.5 之前的版本中 redis 会忽略那些入队失败的命令,只执行那些入队成功的命令。
对于调用 EXEC 后的错误 redis 则采取了完全不同的策略,即 redis 不会理睬这些错误,而是继续向下执行事务中的其他命令。这是因为对于应用层面的错误,并不是 redis 自身需要考虑和处理的问题,所以一个事务中如果某一条命令执行失败,并不会影响接下来的其他命令的执行。
127.0.0.1:6379> set age 23
127.0.0.1:6379> watch age //开始监视 age
127.0.0.1:6379> set age 24 //在 EXEC 之前,age 的值被修改了
127.0.0.1:6379> multi
127.0.0.1:6379> set age 25
127.0.0.1:6379> get age
127.0.0.1:6379> exec //触发 EXEC,返回 nil

指令 watch 可以实现类似于乐观锁的效果,即 CAS。watch 本身的作用是监视 key 是否被改动过,而且支持同时监视多个 key,只要还没真正触发事务,watch 都会尽职尽责的监视,一旦发现某个 key 被修改了,在执行exec 时就会返回 nil,表示事务无法触发。
如果在 WATCH 执行之后,EXEC 执行之前,有其他客户端修改了 key 值,那么当前客户端的事务就会失败。 程序需要做的, 就是不断重试这个操作, 直到没有发生碰撞为止。这种形式的锁被称作乐观锁, 它是一种非常强大的锁机制。 并且因为大多数情况下, 不同的客户端会访问不同的键, 碰撞的情况一般都很少, 所以通常并不需要进行重试。

Redis 集群

Redis 单节点存在单点故障问题,为了解决单点问题,一般都需要对 Redis 配置从节点,然后使用哨兵来监听主节点的存活状态,如果主节点挂掉,从节点能继续提供缓存功能,主从配置结合哨兵模式能解决单点故障问题,提高 Redis 可用性。从节点仅提供读操作,主节点提供写操作。对于读多写少的状况,可给主节点配置多个从节点,从而提高响应效率。

redis 主从读写

与 mysql 相同,redis 也提供了主从的功能,更加非常简单。Mysql 的一主多从不能达到主高可用,只能提高并
发,高可用不能直接依赖于 mysql 主从复制,需要依赖于集群;redis 的主从通过哨兵机制可以达到高可用
高并发:单位时间内可以接收的请求数量
高可用:服务器的服务质量
应用场景:
1、在生产中难以避免单台 redis 出现故障,保证高可用可以用主从
2、单台 redis 官网说能抗住 11w 并发量,超过了 10w 高并发,就可以主从
3、QPS 瓶颈。其中 QPS 每秒处理的查询次数、TPS 每秒处理的事务数。从请求到获得数据为一个完整事务过程
注意:一个 master 可以有多个 slave,一个 slave 只能有一个 master,数据流向是单向的 master 到 slave
主从复制的作用:
1、读写分离:master 写,slave 读,提高服务器的读写负载能力
2、负载均衡:基于主从架构,配合读写分离,由 slave 分担 master 负载,并根据需求的变化,改变 slave 的
数量,通过多个从节点分担数据读取负载,大大提高 redis 服务器并发量和数据吞吐量
3、故障恢复:当 master 出现问题时,由 slave 提供服务,实现快速的故障恢复
4、数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式
5、高可用基石:基于主从复制,构建哨兵模式与集群,实现 redis 的高可用方案。

主从复制实现步骤:
1、复制 redis 为 2 个,对应的端口号分别为 6379 和 6380,通过启动两个进程以模拟两个节点的情形
2、设置主从关系,例如 6379 为 master,可以通过 info replication 查看节点角色
3、slaveof localhost 6379 将一个节点转换为从节点。打开从节点配置文件 redis.conf 文件,找到#slaveof
这个地方,添加 slaveof master 的 ip 地址 master 的端口
4、从节点配置文件 slave-read-only 为 yes 则从节点只能读。注意如果配置从节点可以写的化主节点不会获取数据
5、可以在 redis-cli -p 6379 的客户端使用 shutdown 关闭主节点,这时候从节点不会自动转换为主节点,重启主节点后它仍旧是 master
主从复制实现原理:
主从复制过程主要可以分为 3 个阶段:连接建立阶段、数据同步阶段、命令传播阶段
1、连接建立阶段:在主从节点之间建立连接,为数据同步做准备
2、数据同步阶段:执行数据的全量(或增量)复制(复制 RDB 文件)
3、命令传播阶段:主节点将已执行的命令发送给从节点,从节点接收命令并执行,从而实现主从节点的数据一致性
主从模式中,一个主节点可以有多个从节点。为了减少主从复制对主节点的性能影响,一个从节点可以作为另外一个从节点的主节点进行主从复制。
不足之处:主节点宕机之后,需要手动拉起从节点来提供业务,不能达到高可用

哨兵模式 Sentinel

Redis Sentinel 是 Redis 的高可用实现方案,它可以实现对 redis 的监控、通知和自动故障转移,当 redis master挂掉之后,可以自动拉起 slave 提供业务,从而实现 redis 的高可用。为了避免 Sentinel 本身出现单点故障,Sentinel 自己也可采用集群模式

哨兵模式的原理

Sentinel 是一种特殊的 redis 节点,每个 sentinel 节点会维护与其他 redis 节点,包括 master、slave、sentinel的心跳。
1、当一个 sentinel 节点与 master 节点的心跳丢失时,这个 sentinel 节点就会认为 master 节点出现了故障,处于不可用的状态,这种判定叫作主观下线,即 sentinel 节点自己主观认为 master 下线了。
2、之后,这个 sentinel 节点会与其他 sentinel 节点交换信息,如果发现认为主节点发生故障的 sentinel 节点的个数超过了某个阈值(通常为 sentinel 节点总数的 1/2+1,即超过半数),则 sentinel 会认为 master 节点已经处于客观下线的状态,即大家都认为 master 故障不可用了。
3、之后,sentinel 节点中会选举处一个 sentinel leader 来执行 redis 主节点的故障转移。

被选举出的 Sentinel 领导者进行故障转移的具体步骤
1、在从节点列表中选出一个节点作为新的主节点过滤不健康或者不满足要求的节点,选择 slave-priority 优先级最高的从节点,如果存在则返回,不存在则继续选择复制偏移量最大的从节点,如果存在则返回,不存在则继续选择 runid 最小的从节点
2、Sentinel 领导者节点会对选出来的从节点执行 slaveof no one 命令让其成为主节点
3、Sentinel 领导者节点会向剩余的从节点发送命令,让他们从新的主节点上复制数据
4、Sentinel 领导者会将原来的主节点更新为从节点, 并对其进行监控, 当其恢复后命令它去复制新的主节点。
集群架构
Redis 集群使用数据分片 sharding 而非一致性哈希 consistency hashing 来实现
1、一个 Redis 集群包含 16384 个哈希槽 hash slot,数据库中的每个键都属于这 16384 个哈希槽的其中一个
2、集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key)语句用于计算键 key的 CRC16 校验和
3、集群中的每个节点负责处理一部分哈希槽
Redis 集群不支持那些需要同时处理多个键的 Redis 命令,因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的错误。Redis 为了兼容 multi-key 操作,提供了 hash tags 操作,每个 key 可以包含自定义的 tags,在存储的时候根据 tags 计
算此 key 应该映射到哪个 node 上
1、Redis 集群通过分区 partition 来提供一定程度的可用性 availability:即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求
2、Redis 集群尽可能保证数据的强一致性,但在特定条件下会丢失数据,原因有两点:异步 replication 机制以及 network partition
3、Redis Cluster 提供了 replicas migration 机制,当 Master 节点发生 failover 后,集群会动态重新分配、平衡Slaves 的分布,有效地提高了集群的可用性

你可能感兴趣的:(redis)