面试题答案
一键面试解决方案
- 读写锁策略
- 在Node.js应用中,对于读操作,使用Redis缓存数据。因为读操作一般不会改变数据,所以可以直接从Redis获取数据,提高响应速度。
- 对于写操作,在更新数据库后,获取一个写锁(可以使用Redis的SETNX命令实现简单的分布式锁)。获取到锁后,更新Redis缓存数据,然后释放锁。这样可以保证在写操作期间,其他写操作被阻塞,避免缓存与数据库数据不一致。
- 消息队列(MQ)
- 当数据库数据发生变化时,Node.js应用向消息队列(如RabbitMQ、Kafka等)发送一条消息,消息内容包含数据变化的相关信息。
- 另外有一个消费者服务监听该消息队列,当收到消息时,消费者从消息中解析出数据变化信息,然后更新Redis缓存。这种方式可以将数据库更新和缓存更新解耦,提高系统的整体性能和稳定性。
- 缓存失效策略
- 给Redis缓存设置合理的过期时间。当数据发生变化时,不立即更新Redis缓存,而是让缓存数据在过期时间后失效。下次读取数据时,由于缓存中没有数据,应用会从数据库读取最新数据并重新写入Redis缓存。这种方式简单但可能会在缓存过期前存在数据不一致的情况,适用于对数据一致性要求不是特别高的场景。
技术原理
- 读写锁原理
- Redis的SETNX(SET if Not eXists)命令用于设置一个键值对,当且仅当键不存在时才会设置成功。通过这个命令可以实现简单的分布式锁。在写操作时获取锁,保证同一时间只有一个写操作能更新缓存,避免并发写导致的缓存与数据库不一致问题。读操作由于不改变数据,所以可以并发执行。
- 消息队列原理
- 消息队列采用生产者 - 消费者模型。Node.js应用作为生产者,在数据库数据变化时向消息队列发送消息。消息队列负责存储和管理这些消息,消费者服务监听队列,按顺序消费消息并更新Redis缓存。这种方式利用消息队列的异步特性,将缓存更新操作异步化,避免影响数据库更新操作的性能,同时保证缓存更新的准确性。
- 缓存失效原理
- Redis的过期时间机制允许为每个缓存键设置一个过期时间。当达到过期时间后,Redis会自动删除该键值对。应用在读取数据时,如果发现缓存中数据不存在,就从数据库读取并重新写入缓存,从而保证数据的最终一致性。