面试题答案
一键面试实现基本思路
- 数据存储架构:
- 主数据库(如关系型数据库 MySQL 等)存储用户信息的持久化数据,保证数据的完整性和可靠性。
- 使用内存数据库(如 Redis)作为缓存层,用于快速读取和写入经常访问的用户信息,减少对主数据库的压力。
- 读取流程:
- 应用程序首先尝试从 Redis 缓存中读取用户信息。如果缓存中存在该用户信息,则直接返回给应用程序,这样能快速响应请求。
- 如果缓存中不存在,应用程序从主数据库中查询用户信息,查询到后将数据写入 Redis 缓存,同时返回给应用程序。这样下次相同请求就可以从缓存中获取数据。
- 写入流程:
- 当有用户信息更新操作时,首先更新主数据库中的数据,确保数据的持久化保存。
- 然后根据选择的缓存更新策略,同步更新 Redis 缓存中的数据,保证缓存数据与主数据库数据的一致性。
选择 Redis 的原因
- 高性能:Redis 基于内存存储,读写速度极快,能满足后端开发对缓存系统快速响应的需求。例如,它的读操作速度可达 10 万次/秒以上,写操作速度也能达到 8 万次/秒以上,大大提高了用户信息读取的效率。
- 丰富的数据结构:Redis 支持多种数据结构,如字符串(String)、哈希(Hash)等。对于用户信息缓存,可以使用 Hash 结构,将用户的不同属性存储为 Hash 的字段,方便进行部分更新和查询。例如,用户的姓名、年龄、邮箱等属性可以作为 Hash 的不同字段存储。
- 持久化机制:Redis 提供了 RDB(快照)和 AOF(追加式文件)两种持久化方式。即使服务器重启,也能通过持久化文件恢复数据,保证缓存数据的可靠性,减少因缓存数据丢失导致的大量数据库查询。
- 分布式支持:在大型后端系统中,往往需要分布式缓存。Redis 提供了 Redis Cluster 等分布式解决方案,能方便地进行横向扩展,提高缓存系统的容量和性能。
缓存更新策略
- 读写时同步更新(Write - Through / Read - Through):
- 写操作:当有用户信息更新时,应用程序先更新主数据库,然后立即更新 Redis 缓存。这种方式能保证缓存数据与主数据库数据的强一致性,但在高并发写操作时,可能会因为要同时更新数据库和缓存,导致性能瓶颈。
- 读操作:应用程序先从 Redis 缓存读取数据,如果缓存中没有则从主数据库读取,读取到后将数据写入缓存。
- 异步更新(Write - Behind Caching):
- 写操作:应用程序只更新主数据库,然后将缓存更新操作放入队列(如 RabbitMQ 等消息队列)中。由专门的异步任务从队列中读取缓存更新任务并执行,更新 Redis 缓存。这种方式在高并发写操作时性能较好,因为应用程序不需要等待缓存更新完成。但存在一定时间内缓存数据与主数据库数据不一致的问题,适用于对数据一致性要求不是特别高的场景。
- 失效策略(Cache - Aside):
- 写操作:应用程序更新主数据库后,直接使 Redis 缓存中的对应数据失效(删除缓存数据)。下次读取该用户信息时,缓存中不存在,会从主数据库读取并重新写入缓存。这种方式实现简单,能保证最终一致性,但在缓存失效到重新写入缓存期间,每次读取都需要查询数据库,可能会增加数据库压力。