面试题-Redis和MySQL如何保证数据一致性

一般情况下,Redis是用来实现应用和数据库之间的一个读操作的缓存层,主要目的是减少数据库的IO,还可以提升数据的IO性能。(mysql是以文件的形式存储的;mysql的IO是指数据库文件的读写,也就是检索数据和插入数据)

当应用程序需要去读取某个数据时,首先尝试去Redis中去加载,如果缓存中有数据,直接返回,如果没有数据,就从数据库中查询,查询数据判断是否为空,没有数据直接返回给应用,有数据之后,将数据写入缓存,并将数据返回给应用。

面试题-Redis和MySQL如何保证数据一致性_第1张图片

在这样的一个流程当中会出现一个问题,就是一份数据同时保存在数据库和Redis里面,当数据发生变化的时候,需要同时去更新数据库和Redis,由于更新操作是有先后顺序的,并且他并不像MySQL中的多表事务操作,可以满足ACID的特性,

ACID:是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)

所以就会出现数据一致性的问题,再这样的情况下,能够选择的方法有以下几种:

1.先更新数据库,再更新缓存

2.先删除缓存,再更新数据库

        如果先更新数据库,再更新缓存,如果更新缓存失败,就会导致数据库和Redis中数据不一致;

        如果是先删除缓存,再更新数据库,理想情况下是应用下次访问Redis的时候,发现Redis里面的数据是空的,那么就会从数据库加载,保存到Redis里面,也就是说数据理论上保持一致的。但是在极端情况下,由于删除缓存和更新数据库,这两个操作并不是一个原子操作,所以在这个过程中,出现其他的线程来访问,还是会出现数据不一致的问题。

面试题-Redis和MySQL如何保证数据一致性_第2张图片

        所以在极端情况下,仍然保证数据一致性,就只能采用最终一致性的方案,比如基于RocketMQ的可靠性消息通信,来实现最终数据的一致性;还可以通过Canal组件,监控MySQL中binlog的日志,把更新后的数据同步到Redis里面。因为这里是基于最终一致性来实现的,如果业务场景不能去接受数据的短期不一致性,那么就不能使用这样的方案。

---如果,面试官问:最终一致性方案还存在数据不一致性问题,那么怎么解决呢???

---先不要慌,我们可以反问,具体是什么业务场景下,因为一个方案是不能cover所有场景的,再临场发挥

你可能感兴趣的:(mysql,redis)