17 | 大厂都是怎么做MySQL to Redis同步的?
17 | 大厂都是怎么做MySQL to Redis同步的?
讲述:李玥
时长14:18大小13.09M
缓存穿透:超大规模系统的不能承受之痛
使用 Binlog 实时更新 Redis 缓存
小结
思考题
赞 29
提建议
精选留言(35)
- 李玥置顶2020-04-07Hi,我是李玥。 这里回顾一下上节课的思考题: 课后请你再去看一下 HDFS,它在解决分片、复制和高可用这几方面,哪些是“抄作业”,哪些又是自己独创的。 HDFS集群的构成,和我们之前讲解的几个分布式存储集群是类似的。主要分为NameNode,也就是存放元数据和负责路由的节点,以及用于存放文件数据的DataNode。在HDFS中,大文件同样被划分为多个块,每个块会有多个副本来保证数据可靠性。但HDFS没有采用复制状态机的方式去同步数据,这块它实现了自己的复制算法,感兴趣的同学可以进一步去了解一下。展开25
- 每天晒白牙2020-04-04我们的系统也采用了 canal 监听 binlog 变更来异步更新 ES 和 redis 中的数据的方式 不过我们的方案多了3个步骤 1.canal 把消息发到 kafka 中,应用程序监听 topic 2.应用程序收到消息后,根据 id 重新读 mysql 3.增加定时任务来对比数据库和 ES ,redis 中的数据 https://mp.weixin.qq.com/s/DPBgXftVE_cigSzzpA484w展开共 11 条评论63
- learn more2020-05-23老师你好,这种方案是不是数据写走MySQL,数据读走redis?如果是这样的话,是不是高并发的写也会出现问题?问一下,为什么不把读写全部放到redis操作呢?这样读和写都得到改善,最后使用消息队列批量从redis获取数据同步MySQL,希望得到老师的解答,谢谢。
作者回复: 写不放在Redis中有几个原因: 1. Redis不是可靠的存储,存在丢数据的风险; 2. Redis不支持事务; 3. Redis的查询能力太弱,没法满足各种各样的业务需求。
共 4 条评论21 - Dovelol2020-04-04老师好,用binlog方式同步mysql数据到redis,如果是已经在线运行很久的表数据,也适合转到这个方案吗?需要把之前的数据全部同步到redis中,重要的是该从binlog中的哪个位置开始呢。
作者回复: 这种情况需要先做一次全量同步,之后再开启binlog做增量同步。
共 2 条评论20 - Mq2020-04-061.可以增加一个对账功能,对数据库跟缓存的数据,数据最好有个版本号或时间,把不一致把数据库的数据刷进缓存 2.提供刷用户缓存的服务,对投訴用户可以优先刷下18
- 😚 462020-04-26“还有一个问题是,如果 Redis 本身出现故障,写入数据失败,还会导致下单失败,等于是降低了下单服务性能和可用性,这样肯定不行。” 看到这段话,想问老师一个问题,应该如何避免 Redis 本身的故障对系统造成的影响呢?
作者回复: 绝对避免是很难做到的,更多的是想办法去减轻这个影响。比如Redis配置一主一从的高可用方式。
14 - C J J2020-04-05全量数据缓存,缓存同步有个时间差,请问老师这该如何处理?
作者回复: 就行MySQL主从同步时延一样,只能接受它。一般这个时延都是毫米级的,不会对业务有很大影响。
14 - 飞翔2020-04-07老师 canal 是不是也的做的集群 防止它当机了 redis 不同步了
作者回复: Canal也支持主备的方式来解决高可用的问题。
12 - 芒果2020-04-04思考题我的想法是: 1.如果缓存存在不同步的情况,那么客户端的数据就不是最新数据。如果用户不能接受数据不同步(比如:刚刚下的订单但是购物记录里面没有),作为用户一般都会进行手动刷新,服务端接收到用户手动刷新的请求时,直接去查数据库,然后通过老师之前讲的cache aside pattern的方式更新缓存。 2.为了防止手动刷新的请求太多,减少对数据库的压力,可以考虑对这个接口做一个限流。通过监控这个接口,如果长时间访问压力都很大,那么很有可能是缓存同步出现了问题。这时候赶紧上线解决问题吧。 其他的暂时也没想到什么了,期待听听老师的思路。展开10
- C J J2020-04-06老师,我还有个疑问。用mq去更新缓存数据,如若上面所说Redis出现故障,这应如何处理?我想到的是重试机制,但超过次数应当如何处理?
作者回复: MQ消费的时候有自动重试机制,并且不建议这个地方加重试次数的限制。如果Redis故障,就让同步卡在那儿,等Redis恢复之后,就可以继续同步,这样不会丢数据。
共 2 条评论7 - 川杰2020-04-04老师好,想问一个redis很基础的问题。 假设我们要对交易数据进行缓存。后端调用时,既有根据交易编号查找单个对象的方法,又有查询批量交易的方法。那我该怎么缓存交易数据呢? 利用key-value的方式可以解决根据交易编号查找的情况。那批量查询怎么处理?用队列吗?如果用队列,那岂不是一个交易数据要缓存两遍?(一个是队列,一个是key-value) 请回答下,谢谢展开
作者回复: 一般批量查询的时候可以用Redis的集合数据结构,比如SET,SET中的Value可以保存交易编号,而不用保存交易数据。
共 2 条评论7 - aoe2020-04-17原来大厂是这样避免缓存穿透的!有钱任性共 4 条评论6
- 一剑2020-04-05这里有个问题,就是我们一般是把计算结果缓存到redis,但是基于日志的同步方式是直接同步了原始表数据,这中间是不是少了一环?
作者回复: 这里面需要注意一下,Binlog中记录的是“数据变化”,而不仅仅是数据。
6 - Lywane2020-05-01求问老师,"负责更新缓存的服务,把自己伪装成一个 MySQL 的从节点,从 MySQL 接收 Binlog,解析 Binlog 之后,可以得到实时的数据变更信息,然后根据这个变更信息去更新 Redis 缓存。" 什么叫伪装呀?还是说负责更新的服务本身就是mysql从节点之一?
作者回复: 它使用MySQL主从同步的协议来从主库接收Binlog,对于主库“看起来,缓存更新服务就像是一个从库一样”。
4 - sea5202020-04-28如何只把mysql中的部分热数据更新到redis呢,而不是全部? 如何只把redis中的部分冷数据更新到mysql呢?
作者回复: 第一个问题,如果你能定义好冷热数据的严格界限(对于一条数据,在任何一个节点判断冷热的结果都是相同的,并且这个判断不能依赖于本地时钟),是可以做到的。但在实际生产中,很难做到“定义好冷热数据的严格界限”。 第二个问题,不推荐二个存储互相更新数据,这样很难保证数据一致性。
4 - 水蒸蛋2020-05-31老师,请问下现在的数据量都是T级别的,那如果同步到redis这么大的量不是要T级别的内存,这个要多大的集群规模,而且不便宜啊,这个是不是还会加入ssd之类的?
作者回复: 对于硬件的需求其实还好。目前主流的X86服务器256GB内存是比较正常的配置,10台就可以达到2.5T内存了。SSD也基本上是标配,很少新采购的服务器还使用传统机械硬盘了。 一般大型互联网公司服务器规模,约在几万台起步。
共 3 条评论3 - sea5202020-04-26想问下redis数据同步mysql该怎么做么呢?
作者回复: 理论上可以把同步程序伪装者Redis的一个从节点,从Redis接收更新命令,但很少有系统这么做。原因是Redis的性能比MySQL要高出很多,这个数据同步很可能由于MySQL的性能问题,延迟很多。
共 3 条评论3 - 正在减肥的胖籽。2020-04-07数据同步到redis中,但是redis突然down丢失一些数据,或者redis也会设置缓存时间。那么还是会打到库中?老师你们这里的方案是?或者说你们的redis过期时间怎么平衡?
作者回复: 在这种情况下,Redis需要做主从来保证高可用,不设数据过期时间,最好还要有补偿机制。
共 4 条评论3 - 衹是一支歌2020-06-10数据更新到缓存中,结构不一样了,有的关联查询怎么做呢。
作者回复: 这是NoSQL固有的限制,没办法。 只能是将最常用的C端查询打到缓存上,其他的查询再想其它办法处理。
2 - new life2020-04-111、感觉使用 canal 通过binlog 的方式,防止了缓存穿透,起到了数据最终一致性的作用,但在缓存数据的时效性方面不能保证; 2、通过binlog同步的数据库,应该是专门为缓存使用的吧,否则数据库里数据量很大,会占用Redis大量缓存; 3、思考:如果发现数据不一致,应该触发更新缓存的操作,并且限制只有一个线程去更新;展开共 1 条评论2