为什么要用 Redis 实现事务的 ACID
如何用 Redis 实现事务的 ACID ?在 Redis 主从切换的时候有那些坑?极客时间《Redis 核心技术与实战》专栏学习笔记 18,部分已经作为留言发布,但是留言太多,排在后面的一般很难被大家看到,所以集中发布在这里,欢迎讨论。
题图来自网络
31 | 事务机制:Redis 能实现 ACID 属性吗?
还是那个问题,为什么需要用 Redis 实现事务的 ACID ?
复习了一遍事务的 ACID 属性。
原子性 Atomicity:要么都做,要么都不做
一致性 Consistency:事务前后的数据保持一致
隔离性 Isolation:You Can You UP
持久性 Durability:数据修改必须落盘
Redis 是没有回滚机制的,通过 WATCH、MULTI、EXEC、DISCARD 四个命令,勉强实现了原子性、一致性和隔离性,因为是内存缓存,所以持久性是没法保证的。
关于课后题,如果使用 RDB 机制,在执行事务时,Redis 发生了故障,原子性应该是没有办法保证的,假设入队的操作命令没有错误,这个和文中例子里面的第三种情况类似,如果开启了 AOF,那么有可能可以保证原子性,但是如果只有 RDB,没有 AOF,那么应该是无法保证原子性的。
看了课代表的答案,很大概率应该是我错了,可能是我缺少了:RDB 不会在事务执行的时候执行,这个知识点。
另外课代表还补充了关于 Pipeline 的用法。
32 | Redis 主从同步与故障切换,有哪些坑?
Redis 主从同步有三个坑:主从数据不一致、读到过期数据、配置不合理服务挂掉。
为了避免主从数据不一致,一方面要保证主从之间的网络状况良好,另外主从服务器的配置也不能相差太远;另一方面,可以写一个外部程序,监控 master_repl_offset 和 slave_repl_offset 之间的差值,如果差值过大,就先不让客户端和这个从库连接。
读到过期数据是因为 Redis 本身的过期删除策略(惰性删除和定期删除)引起的,主库上的过期数据被惰性删除了,但是从库上没有(从库只读)。
为了避免读到过期数据,一方面是尽量使用 Redis 3.2 以后的版本,另外一条就是尽量使用 EXPIREAT/PEXPIREAT 命令,指定具体的过期时间点。
因为配置不当,导致在主从切换的过程中服务挂掉的参数主要是两个,protected-mode 和 cluster-node-timeout。
为了让哨兵之间可以互相访问,那么 protected-mode 需要设置为 no,并且将哨兵的 IP 都列在 bind 里。
为了避免实例主从切换,导致集群心跳超时,需要把 cluster-node-timeout 配置的大一点 (10~20 秒)
最后,将 slave-serve-stale-data 设置为 no,从库只能服务 INFO、SLAVEOF 命令,可以避免从库中读到不一致的数据;而 slave-save-only 设置为 yes,从库只能处理读请求。
对于课后题,将 slave-read-only 设置为 no,从库也能处理写命令,肯定不是一个好办法,这样一来主从之间的同步就变得复杂无比,或者说就干脆变成了双主结构了。
课代表补充,slave 不会主动删除由 master 同步过来的带有过期时间的 key,删除由 master 自己维护。
老师的补充,主从复制中的增删改都需要在主库执行。
版权声明: 本文为 InfoQ 作者【escray】的原创文章。
原文链接:【http://xie.infoq.cn/article/0c418d30d74e6b80954a48aa8】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论