Skip to content

面试速答(先看这里)

**一句话结论:**首先,在非并发的场景中,出现不一致的问题大家都能比较容易的理解,因为缓存的操作和数据库的操作是存在一定的时间差的。

60秒标准回答:

首先,在非并发的场景中,出现不一致的问题大家都能比较容易的理解,因为缓存的操作和数据库的操作是存在一定的时间差的。而且这两个操作是没办法保证原子性的,也就是说,是有可能一个操作成功,一个操作失败的。所以,这就必然会存在不一致的情况

如果在并发场景中,如果两个线程,同时进行先写数据库,后更新缓存的操作,就可能会出现不一致

写数据库,更新成20

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**如果在并发场景中,如果两个线程,同时进行先写数据库,后更新缓存的操作,就可能会出现不一致:
  • **要点2:**如果在并发场景中,如果两个线程,同时进行先更新缓存,后写数据库的操作,同理,也可能会出现不一致:
  • **要点3:**在并发场景中,还有一种容易忽略的并发场景,那就是读写并发。
  • **要点4:**我们知道,当我们使用了缓存之后,一个读的线程在查询数据的过程是这样的:
  • **要点5:**所以, 对于一个读线程来说,虽然不会写数据库,但是是会更新缓存的 ,所以,在一些特殊的并发场景中,就会导致数据不一致的情况。

**记忆锚点:**的查询结果更新到缓存 → 那么就导致最终缓存 → 但是是会更新缓存 → 在一些特殊的并发 → 那就是读写并发 → 对于一个读线程

易错提醒:

  • 首先,在非并发的场景中,出现不一致的问题大家都能比较容易的理解,因为缓存的操作和数据库的操作是存在一定的时间差的。
  • 而且这两个操作是没办法保证原子性的,也就是说,是有可能一个操作成功,一个操作失败的。

加分表达:

  • 我们知道,当我们使用了缓存之后,一个读的线程在查询数据的过程是这样的: 1、查询缓存,如果缓存中有值,则直接返回 3、把数据库的查询结果更新到缓存中 所以, 对于一个读线程来说,虽然不会写数据库,但是是会更新缓存的 ,所以,在一些特殊的并发场景中,就会导致数据不一致的情况。
  • 当然,根据墨菲定律,只要有可能发生的事情,就一定会发生。

追问准备:

  • 围绕「的查询结果更新到缓存」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「那么就导致最终缓存」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「但是是会更新缓存」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

首先,在非并发的场景中,出现不一致的问题大家都能比较容易的理解,因为缓存的操作和数据库的操作是存在一定的时间差的。而且这两个操作是没办法保证原子性的,也就是说,是有可能一个操作成功,一个操作失败的。所以,这就必然会存在不一致的情况。

如果在并发场景中,如果两个线程,同时进行先写数据库,后更新缓存的操作,就可能会出现不一致:

WW
写数据库,更新成20
写数据库,更新成10
写缓存,更新成10
写缓存,更新成20(数据不一致)

如果在并发场景中,如果两个线程,同时进行先更新缓存,后写数据库的操作,同理,也可能会出现不一致:

WW
写缓存,更新成20
写缓存,更新成10
写数据库,更新成10
写数据库,更新成20(数据不一致)

在并发场景中,还有一种容易忽略的并发场景,那就是读写并发。

我们知道,当我们使用了缓存之后,一个读的线程在查询数据的过程是这样的:

  • 1、查询缓存,如果缓存中有值,则直接返回
  • 2、查询数据库
  • 3、把数据库的查询结果更新到缓存中

所以,对于一个读线程来说,虽然不会写数据库,但是是会更新缓存的,所以,在一些特殊的并发场景中,就会导致数据不一致的情况。

读写并发的时序如下:

WR
读缓存,缓存中没有值
读数据库,数据库中得到结果为10
写数据库和缓存,更新成20
写缓存,更新成10(数据不一致)

也就是说,假如一个读线程,在读缓存的时候没查到值,他就会去数据库中查询,但是如果自查询到结果之后,更新缓存之前,数据库被更新了,但是这个读线程是完全不知道的,那么就导致最终缓存会被重新用一个”旧值”覆盖掉。

这也就导致了缓存和数据库的不一致的现象。

但是这种现象其实发生的概率比较低,因为一般一个读操作是很快的,数据库+缓存的读操作基本在十几毫秒左右就可以完成了。

而在这期间,刚好另一个线程执行了一个比较耗时的写操作的概率确实比较低。

当然,根据墨菲定律,只要有可能发生的事情,就一定会发生。所以我们也要引起重视。

扩展知识 ​

如何解决 ​

📄 ✅如何解决Redis和数据库的一致性问题?

打开文档:✅如何解决Redis和数据库的一致性问题?