MySQL与redis如何保证数据一致性问题,很多程序员在去面试的过程当中,被面试官们问到都不知道如何回答。
本文就针对该问题,做个详细的解决方案总结,其实这道题基本上正常,你去面试3~5年工作经验的岗位可以说是必问的,如果这道题答不出来的话,那说明你对分布式如何去同步数据可能不是很了解。
注意,只要我们在做分布式系统中做一些数据同步都是会有延迟的,短暂的延迟,这都是属于允许的,但是最终一致性是必须要实现的,至于能延迟多久,这个看不同业务系统场景,大多情况是延迟越低越好。
MySQL与redis怎么做数据同步?
很多小公司会这么做,在改了mysql数据库之后,就直接人工手动去把redis缓存中给清掉,然后第二个查询是不是可以查询到最新MySQL中的数据,在同步到redis当中,这种做法适合于小项目。
大项目怎么办?我们可以通mq异步的形式来实现。说白了只要在业务代码里面在更新我们的DB操作情况下再做写操作,然后我们再send message,通过mq消费者异步的形式进行同步到redis当中,但是这种做法有一个很大的缺陷,就是我们需要保证消息顺序一致问题,所以效率上来说有可能偏低了,而且延迟可能会更大,但是它的解耦性比较强,为什么?因为就算同步失败情况下,会不断重试。
可能有同学会想到延迟双删,延迟双删也是有bug的,为什么?因为第二次删除时间无法控制,很难控制,小项可以用大项目不建议用,那还可以通什么方式实现MySQL与redis怎么做数据同步?
有人想到双写,就是更新完db之后,再更新一下redis,双写的话在并发的时候是会存在一个问题的,为什么?
因为可能在写DB的时候可能有MySQL innoDB存储引擎行锁能够去保证多线程同时写DB的线程安全性问题,但是如果在并发更新到redis的时候,这个过程就会存在问题,所以一般我们可以使用MySQL的行锁来做分布式锁,来保证我们的双写的线程安全问题,或者我们可以整合zk、redis实现分布式锁,这也是可以保证的。
ok,除了上面这些还有其它什么方案?
其实以上这些方案都是在业务层面来进行做同步的,那如果我人工手动去改MySQL了,咋办呢?
我们可以订阅MySQL的binlog文件,把它伪装成一个mysql从节点,然后拿到binlog数据之后,再把它转换成json数据,然后再整个mq异步的形式,同步到redis里面去,这种架构就是canal框架底层实现的原理。
要在分布式领域当中做数据同步,必然会延迟,为什么?
因为传输的过程当中是需要时间的,只不过时间它有短有长,一般可能都是几十毫秒,所以一般我们在做分布式领域数据同步延迟个几十毫秒都是允许的,不过如果延迟个几分钟那说明有bug了。
本文由《MySql教程网》原创,转载请注明出处!https://mysql360.com