面试题答案
一键面试可能出现数据不一致的场景:
- 缓存更新与数据库更新顺序问题:
- 先更新缓存,后更新数据库失败:若先更新了缓存中的数据,但在更新数据库时出现故障,此时其他请求读取到的是缓存中已更新但数据库中未更新的数据,造成数据不一致。
- 先更新数据库,后更新缓存失败:更新数据库成功后,更新缓存操作失败,后续请求从缓存读取到旧数据,而数据库是新数据,导致不一致。
- 缓存删除策略不当:
- 缓存删除失败:在更新数据库后尝试删除缓存,若删除缓存操作失败,缓存中依旧保存旧数据,后续请求读取到旧数据造成不一致。
- 删除缓存的粒度问题:如果缓存删除的粒度不准确,例如本应删除某条数据对应的缓存,却错误地删除了一批数据的缓存,可能导致其他不应更新的缓存被误删,后续填充缓存时可能引入不一致数据。
- 高并发读写场景:
- 并发写操作:多个请求同时对同一数据进行写操作,在缓存和数据库更新过程中,由于操作顺序和时间差,可能导致最终缓存和数据库数据不一致。例如,请求A先更新数据库,请求B后更新数据库但先更新缓存,此时缓存中的数据是请求B的结果,而数据库是请求A和B先后操作的结果,出现不一致。
- 读写并发:一个请求正在读取缓存数据,同时另一个请求正在更新数据库并删除缓存。若读请求在缓存删除前读取到旧数据,而此时数据库已更新,就会出现数据不一致。
保证数据一致性的策略:
- 更新顺序策略:
- 先更新数据库,再删除缓存:更新数据库成功后删除缓存,这样后续请求读取时会发现缓存不存在,从而从数据库读取最新数据并重新填充缓存。这种方式避免了先更新缓存后数据库更新失败的问题,但要确保删除缓存操作的可靠性。可以采用重试机制,若删除缓存失败,进行多次重试,或者将删除缓存失败的任务记录到消息队列,由专门的服务进行处理。
- 缓存删除策略优化:
- 使用缓存版本号:在数据库中增加一个版本号字段,每次数据更新时版本号递增。缓存中存储数据的同时也存储版本号。读取数据时,先检查缓存中的版本号与数据库中的版本号是否一致,不一致则从数据库读取最新数据并更新缓存。这样即使缓存删除失败,通过版本号也能保证数据一致性。
- 精准删除缓存:采用合适的缓存键设计,确保在更新数据时能够精准地删除对应的缓存。例如,使用对象ID作为缓存键,避免误删其他无关数据的缓存。
- 高并发场景处理策略:
- 读写锁:在高并发读写场景下,对数据的读写操作加锁。读操作加读锁,写操作加写锁。写锁优先级高于读锁,当有写操作时,读操作等待写操作完成后再进行,从而避免读写并发导致的数据不一致。
- 使用队列:将并发的写请求发送到消息队列,由消息队列按顺序处理写操作,确保数据库和缓存更新的顺序一致性。这样可以避免并发写操作造成的不一致问题。同时,对于读请求,可以在队列处理写操作完成后,强制更新缓存,保证读请求获取到最新数据。