Redis入门总结(二):主从复制,事务和发布订阅

(尊重劳动成果,转载请注明出处:https://yangwenqiang.blog.csdn.net/article/details/90414751冷血之心的博客)

关注微信公众号(文强的技术小屋),学习更多技术知识,一起遨游知识海洋~

快速导航:

Redis入门总结(一):redis配置文件,五种数据结构,线程模型和持久化方式

Redis入门总结(二):主从复制,事务和发布订阅

Redis入门总结(三):redis实现分布式锁的正确姿势

这篇文章主要总结了:redis的主从复制,redis的事务以及redis实现发布订阅。

  1. 主从复制:

    1. 背景:

      1. 随着项目访问量的增加,对Redis服务器的操作也越加频繁,虽然Redis读写速度都很快,但是一定程度上也会造成一定的延时,那么为了解决访问量大的问题,通常会采取的一种方式是主从架构Master/Slave,Master 以写为主,Slave 以读为主,Master 主节点更新后根据配置,自动同步到从机Slave 节点。

    2. 通过  info replication 命令查看节点角色

    3. 哨兵模式:

      1. 解决了主节点挂掉之后,从节点还是从节点,无法自动转为主节点,导致系统无法正常工作的问题

      2. 哨兵模式监控redis是否按照预期良好地运行(至少是保证主节点是存在的),若一台主机出现问题时,哨兵会自动将该主机下的某一个从机设置为新的主机,并让其他从机和新主机建立主从关系。

      3. 哨兵模式也可以设置为集群模式,解决哨兵的单节点故障

    4. 主从复制原理:

      1. 旧版同步:

        1. 当从节点发出 SLAVEOF 命令,要求从服务器复制主服务器时,从服务器通过向主服务器发送 SYNC 命令来完成。该命令执行步骤:

          1. 从服务器向主服务器发送 SYNC 命令

          2. 收到 SYNC 命令的主服务器执行 BGSAVE 命令,在后台生成一个 RDB 文件,并使用一个缓冲区记录从开始执行的所有写命令

          3. 当主服务器的 BGSAVE 命令执行完毕时,主服务器会将 BGSAVE 命令生成的 RDB 文件发送给从服务器,从服务器接收此 RDB 文件,并将服务器状态更新为RDB文件记录的状态。

          4. 主服务器将缓冲区的所有写命令也发送给从服务器,从服务器执行相应命令。

      2. 命令传播:

        1. 当同步操作完成之后,主服务器会进行相应的修改命令,这时候从服务器和主服务器状态就会不一致。

        2. 为了让主服务器和从服务器保持状态一致,主服务器需要对从服务器执行命令传播操作,主服务器会将自己的写命令发送给从服务器执行。从服务器执行相应的命令之后,主从服务器状态继续保持一致。

        3. 问题:

          1. 如果从服务器正在同步,但是断开了连接,在其恢复之前,主服务器又进行了一系列的写操作,那么我们需要重新生成RDB文件来进行同步操作,这样会导致效率降低。

          2. 这样虽然能够保证一致性,但是其实断开连接之前主从服务器状态是保持一致的,不一致的是从服务器断开连接,而主服务器执行了一些写命令,那么从服务器恢复连接后能不能只要断开连接的哪些写命令,而不是整个RDB快照呢?

        4. 解决办法:

          1. Redis从2.8版本之后,使用了新的同步命令 PSYNC 来代替 SYNC 命令。该命令的部分重同步功能用于处理断线后重复制的效率问题。也就是说当从服务器在断线后重新连接主服务器时,主服务器只将断开连接后执行的写命令发送给从服务器,从服务器只需要接收并执行这些写命令即可保持主从一致。

      3. 主从复制的缺点:

        1. 当系统繁忙的时候,主从延迟会比较大。

  2. redis对事务的支持:

    1. redis 是单进程程序,并且它保证在执行事务时,不会对事务进行中断,事务可以运行直到执行完所有事务队列中的命令为止。因此,Redis的事务支持隔离性

    2. redis会将一个事务中的所有命令序列化,然后按顺序执行。Redis不可能在一个Redis事务的执行过程中插入执行另一个客户端发出的请求。这样便能保证Redis将这些命令作为一个单独的隔离操作执行。

    3. 操作事务的相关命令:

      1. MULTI  :标记一个事务块的开始。

      2. EXEC :执行所有事务块内的命令。

      3. DISCARD :取消事务,放弃执行事务块内的所有命令。

      4. UNWATCH :取消 WATCH 命令对所有 key 的监视。

      5. WATCH key [key ...] :监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

    4. redis事务不支持回滚:

      1. 只有当被调用的Redis命令有语法错误时,这条命令才会执行失败(在将这个命令放入事务队列期间,Redis能够发现此类问题),或者对某个键执行不符合其数据类型的操作:实际上,这就意味着只有程序错误才会导致Redis命令执行失败,这种错误很有可能在程序开发期间发现,一般很少在生产环境发现。

      2. Redis已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为Redis不需要事务回滚的能力。

    5. redis以 MULTI 开始一个事务,然后将多个命令入队到事务中,最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:

    6. 单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的

      1. 当EXEC调用之后,开始从队列里边取出命令执行,一条命令执行失败,并不会影响到其余命令的继续执行。

      2. redis事务为什么不支持原子性?

        1. 当我们开启事务时,将一系列的命令都封装塞进了一个队列,当EXEC开始执行的时候,只有错误的命令才会导致执行失败,而这通常在将该命令塞进队列的时候已经报错,我们应该可以提前发现该错误才对。

    7. 事务内部错误如何处理?

      1. 错误分类:

        1. 一个命令可能会在被放入队列时失败。因此,事务有可能在调用EXEC命令之前就发生错误。例如,这个命令可能会有语法错误(参数的数量错误、命令名称错误,等等),或者可能会有某些临界条件(例如:如果使用maxmemory指令,为Redis服务器配置内存限制,那么就可能会有内存溢出条件)。

        2. 在调用EXEC命令之后,事务中的某个命令可能会执行失败。例如,我们对某个键执行了错误类型的操作(例如,对一个字符串(String)类型的键执行列表(List)类型的操作)。

      2. 解决办法:

        1. 可以使用Redis客户端检测第一种类型的错误,在调用EXEC命令之前,这些客户端可以检查被放入队列的命令的返回值:

          1. 如果命令的返回值是QUEUE字符串,那么就表示已经正确地将这个命令放入队列;

          2. 否则,Redis将返回一个错误。如果将某个命令放入队列时发生错误,那么大多数客户端将会中止事务,并且丢弃这个事务。

        2. 在Redis 2.6.5版本之前,如果发生了上述的错误,那么在客户端调用了EXEC命令之后,Redis还是会运行这个出错的事务,执行已经成功放入事务队列的命令,而不会关心先前发生的错误。从2.6.5版本开始,Redis在遭遇上述错误时,服务器会记住事务积累命令期间发生的错误。然后,Redis会拒绝执行这个事务,在运行EXEC命令之后,便会返回一个错误消息。最后,Redis会自动丢弃这个事务。这样便能轻松地混合使用事务和管道。在这种情况下,客户端可以一次性地将整个事务发送至Redis服务器,稍后再一次性地读取所有的返回值。

        3. 相反,在调用EXEC命令之后发生的事务错误,Redis不会进行任何特殊处理:在事务运行期间,即使某个命令运行失败,所有其他的命令也将会继续执行。

    8. redis通过WATCH监视命令实现乐观锁:

      1. redis使用 check-and-set 操作实现乐观锁。WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。

      2. 类似Java中的CompareAndSet机制,被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。

      3. 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回空多条批量回复(null multi-bulk reply)来表示事务已经失败。

    9. redis事务总结:

      1. 单独的隔离操作:事务中的所有命令会被序列化、按顺序执行,在执行的过程中不会被其他客户端发送来的命令打断

      2. 没有隔离级别的概念:队列中的命令在事务没有被提交之前不会被实际执行

      3. 不保证原子性:redis中的一个事务中如果存在命令执行失败,那么其他命令依然会被执行,没有回滚机制

  3. redis信息通知(发布/订阅模式):

    1. 优点:

      1. 松耦合。生产者和消费者无需知道彼此的实现细节,只需要约定好任务的描述格式。这使得生产者和消费者可以由不同的团队使用不同的编程语言编写

      2. 易于扩展。消费者可以有多个,而且可以分布在不同的服务器中, 借此可以轻易地降低单台服务器的负载

    2. 使用LPUSH和RPOP命令实现队列

    3. 利用BRPOP命令可以检测多个key的功能。如果多个键都有元素,则按照从左到右顺序取第一个键中的一个元素。因此,要实现优先级队列,把优先级高的key放到前面就ok了。

    4. 发布订阅模式:

      1. "发布/订阅"模式中包含两种角色,分别是发布者和订阅者。

      2. 订阅者可以订阅一个或若干个频道(channel)

      3. 发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都会收到此消息。

以上内容摘抄总结与网络,感谢各位前辈的总结与铺垫。接下来我会继续更新Redis相关文章,全部会以这种笔记形式给出,大家对笔记中不太懂的地方,可以发表评论,我们一起研究学习,此处权当给大家列个学习提纲了。

如果对你有帮助,记得点赞哦~欢迎大家关注我的博客,可以进群366533258一起交流学习哦~

本群给大家提供一个学习交流的平台,内设菜鸟Java管理员一枚、精通算法的金牌讲师一枚、Android管理员一枚、蓝牙BlueTooth管理员一枚、Web前端管理一枚以及C#管理一枚。欢迎大家进来交流技术。

关注微信公众号(文强的技术小屋),学习更多技术知识,一起遨游知识海洋~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 Redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。   本课程主要讲解以下内容:1. Redis的基本使用2. Redis数据库的数据类型3. Redis数据库数据管理4. Redis主从复制5. Redis数据库的持久性6. Redis的高可靠性和集群7. Redis的优化和性能测试8. Redis服务器的维护和管理9. Redis服务器的常见问题排错 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温柔狠角色

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值