面试题答案
一键面试锁机制困难
- 锁争用:高并发下大量请求竞争同一数据页的锁,导致性能瓶颈。例如多个事务同时尝试更新同一数据页,频繁的锁等待会降低系统吞吐量。
- 死锁风险:不同事务对多个数据页按不同顺序加锁,可能形成死循环等待,如事务A持有数据页1的锁并请求数据页2的锁,而事务B持有数据页2的锁并请求数据页1的锁。
缓存机制困难
- 缓存命中率降低:高并发读写可能使缓存中的数据频繁被替换,刚读入缓存的数据很快被其他请求挤出,导致频繁从磁盘读取数据,增加I/O开销。例如在高并发写场景下,新写入的数据频繁更新缓存,使得其他热点读数据被淘汰。
- 缓存一致性问题:当数据发生变化时,需要及时更新缓存以保证数据一致性。但在高并发场景下,可能出现缓存更新不及时,导致读操作读到旧数据。
数据一致性维护困难
- 并发修改冲突:多个事务并发修改同一数据页,若没有合适的并发控制,可能导致数据不一致。如两个事务同时对账户余额进行增减操作,最终结果可能不符合预期。
- 崩溃恢复一致性:系统崩溃后,需要保证已提交的事务数据已持久化,未提交的事务数据不被写入,在高并发环境下确保这一点更为复杂。
优化角度
锁机制优化
- 锁粒度调整:
- 原理:从表级锁、页级锁调整为行级锁,减少锁争用范围。行级锁只锁定具体操作的行数据,而不是整个页或表,使得其他事务可以同时访问同一页或表中的其他行。
- 示例:在电商库存管理中,对商品库存数量的修改,使用行级锁只锁定该商品对应的库存行记录,其他商品库存的操作不受影响。
- 死锁检测与预防:
- 原理:死锁检测算法定期检查系统中是否存在死锁,一旦发现死锁,选择牺牲一个事务(通常选择回滚代价较小的事务)来释放锁资源,打破死锁。死锁预防则通过对加锁顺序进行限制,避免死锁的产生。
- 示例:使用Wait - Die算法,年轻的事务等待年老的事务释放锁,年老的事务不会等待年轻事务,这样可以避免形成死锁环。
缓存机制优化
- 优化缓存淘汰策略:
- 原理:采用更适合业务场景的缓存淘汰算法,如LRU(最近最少使用)的变体,考虑读写频率、数据访问时间等因素,使热点数据更不容易被淘汰。
- 示例:在社交平台中,对于用户的基本信息和近期频繁访问的动态数据,通过调整缓存淘汰策略,使其在缓存中保留更长时间,提高缓存命中率。
- 缓存更新策略优化:
- 原理:采用合适的缓存更新策略,如Write - Through(写穿透)、Write - Back(写回)等。Write - Through在更新数据库的同时更新缓存,保证数据一致性;Write - Back则先更新缓存,标记为脏数据,在合适时机批量更新到数据库,提高写性能。
- 示例:对于实时性要求高的数据,如银行账户余额,采用Write - Through策略;对于一些对一致性要求相对不那么高的统计数据,可采用Write - Back策略。
数据一致性维护优化
- 并发控制协议:
- 原理:使用严格的并发控制协议,如两阶段锁协议(2PL),分为加锁阶段和解锁阶段,保证事务的隔离性和数据一致性。在加锁阶段,事务获取所需的所有锁,在解锁阶段,事务释放所有锁。
- 示例:在转账事务中,通过2PL协议,在开始转账前获取转出账户和转入账户的锁,转账完成后释放锁,确保转账过程中数据的一致性。
- 日志与恢复机制:
- 原理:利用日志记录事务的操作,在系统崩溃后,通过重放日志恢复已提交的事务,回滚未提交的事务。例如Redolog用于崩溃恢复,记录数据库物理层面的修改操作;Undolog用于事务回滚,记录数据修改前的版本。
- 示例:在系统崩溃重启后,InnoDB通过Redolog将已提交但未持久化的事务重新应用到数据库,通过Undolog回滚未提交的事务,保证数据一致性。