面试题答案
一键面试- 使用缓存更新策略:
- 读写穿透:
- 读操作:应用程序先从Redis读取数据,如果读取到则直接返回;如果未读取到,则从MySQL读取,将数据写入Redis并返回。这样可以保证读取的数据是最新的。
- 写操作:应用程序先更新MySQL,然后再更新Redis。为了确保一致性,在更新MySQL成功后,需要立即更新Redis。若Redis更新失败,需要有重试机制或者记录日志,后续人工介入处理。
- 双写模式:
- 写操作:应用程序同时更新MySQL和Redis。为保证一致性,需要使用事务机制(在支持事务的Redis客户端中,如Jedis等),将对MySQL和Redis的写操作封装在事务中,确保要么都成功,要么都失败。但这种方式对性能有一定影响,因为需要等待两个写操作都完成。
- 读写穿透:
- 利用MySQL的binlog:
- 原理:MySQL的二进制日志(binlog)记录了数据库的所有写操作。通过解析binlog,可以获取到MySQL数据的变更信息。
- 实现思路:使用如Canal这样的工具,它模拟MySQL从库的交互协议,伪装成MySQL从库向主库发送dump协议,主库收到请求后,开始推送binlog给Canal。Canal解析binlog,将数据变更事件发送给对应的处理程序,处理程序根据变更类型(增、删、改),对Redis进行相应的更新操作,从而保证Redis数据与MySQL数据一致。
- 设置合理的缓存过期时间:
- 对于一些读多写少的数据,可以设置较短的缓存过期时间。在缓存过期后,下次读操作会从MySQL重新读取数据并更新到Redis,保证数据一致性。但设置过期时间需要权衡,过短会导致频繁从MySQL读取数据,影响性能;过长则可能在数据更新后,长时间内Redis数据与MySQL不一致。
- 使用分布式锁:
- 场景:在高并发读写场景下,为防止多个写操作同时更新MySQL和Redis导致数据不一致。
- 实现思路:在进行写操作前,先获取分布式锁(如使用Redis的SETNX命令实现简单的分布式锁)。只有获取到锁的线程或进程才能进行MySQL和Redis的更新操作,操作完成后释放锁。其他未获取到锁的请求等待锁的释放,重新尝试获取锁并进行更新操作。这样可以保证同一时间只有一个写操作,从而确保数据一致性。但要注意分布式锁的超时时间设置,避免死锁问题。