面试题答案
一键面试分库分表策略优化
- 垂直分库:
- 原理:按照业务功能将不同模块的数据划分到不同的数据库中。例如,将用户相关数据存放在用户库,订单相关数据存放在订单库。这样可以减少单个数据库的压力,不同业务模块的数据库可以独立进行扩展。
- 优势:业务模块解耦,每个库的访问量相对降低,提高了整体系统的并发处理能力。同时,不同库可以根据自身特点选择不同的硬件配置,优化资源利用。
- 缺点:跨库操作可能会变得复杂,需要通过接口调用等方式来实现不同库之间的数据交互。
- 垂直分表:
- 原理:将一个表中不常用或大字段(如图片、文本内容等)拆分到另外一个表中。例如,用户表中,将用户基本信息(姓名、年龄等)和用户简历(大文本)分开存储。
- 优势:减少单个表的数据量,提高查询速度。在查询基本信息时,无需加载大字段数据,减少I/O开销。
- 缺点:可能增加关联查询的复杂度,需要通过外键等方式进行关联。
- 水平分表:
- 原理:根据一定的规则(如按时间、按ID取模等)将数据分散到多个表中。例如,按月份将订单数据分散到不同的订单表中,每个表存储一个月的订单。
- 优势:单个表的数据量得到有效控制,查询时可以快速定位到目标数据所在的表,提高查询效率。同时,便于进行数据的归档和清理。
- 缺点:数据分布管理变得复杂,插入、更新、删除操作需要考虑数据的分布规则。
- 水平分库:
- 原理:将数据按照一定规则(如按用户ID范围、按地域等)分布到多个数据库中。例如,按照用户ID的奇偶性将用户数据分布到两个不同的数据库中。
- 优势:有效分散数据库负载,提高系统的整体性能和扩展性。不同数据库可以部署在不同的服务器上,充分利用分布式资源。
- 缺点:跨库事务处理难度增加,数据一致性维护变得复杂。
分布式缓存优化
- 缓存架构选择:
- Memcached:简单高效,适用于缓存一些纯内存数据,如页面片段、查询结果集等。它的优势在于内存管理简单,性能极高,但不支持数据持久化和复杂数据结构。
- Redis:功能丰富,支持多种数据结构(如字符串、哈希、列表、集合等),同时支持数据持久化。适用于缓存需要进行复杂操作的数据,如购物车信息等。它还支持发布订阅、事务等功能,有助于解决分布式系统中的一些协调问题。
- 缓存策略:
- 读写穿透:读操作时先查询缓存,如果缓存中没有则查询数据库,并将结果放入缓存;写操作时先更新数据库,再更新缓存。这种策略简单直接,但可能会出现缓存与数据库数据不一致的短暂时间窗口。
- 写后更新:写操作时先更新数据库,然后异步更新缓存。这种方式可以提高写操作的性能,但可能导致缓存数据长时间不一致,适用于对数据一致性要求不是特别高的场景。
- 失效模式:设置缓存数据的过期时间,当数据过期后,再次查询时从数据库获取并更新缓存。这种方式可以在一定程度上保证数据的时效性,但需要合理设置过期时间,避免频繁的缓存失效导致性能下降。
- 缓存预热:在系统上线或重启后,提前将一些热点数据加载到缓存中,避免用户首次访问时出现缓存穿透,提高系统的响应速度。可以通过定时任务、启动脚本等方式实现缓存预热。
应对跨节点事务问题
- 两阶段提交(2PC):
- 原理:分为准备阶段和提交阶段。在准备阶段,协调者向所有参与者发送准备请求,参与者执行事务操作并记录日志,但不提交。如果所有参与者都准备成功,协调者发送提交请求,参与者正式提交事务;如果有任何一个参与者准备失败,协调者发送回滚请求,参与者回滚事务。
- 优势:保证了事务的原子性,所有参与者要么都提交,要么都回滚。
- 缺点:存在单点故障问题,协调者一旦出现故障,整个事务无法继续;同时,性能较低,因为需要等待所有参与者的响应,并且在准备阶段会锁定资源。
- 三阶段提交(3PC):
- 原理:在2PC的基础上增加了一个预提交阶段。在准备阶段,参与者只需要检查自身是否可以执行事务,而不实际执行。预提交阶段,协调者向所有参与者发送预提交请求,参与者实际执行事务操作但不提交。最后,协调者发送提交请求,参与者提交事务。如果在任何阶段出现问题,协调者发送中断请求,参与者回滚事务。
- 优势:部分解决了2PC的单点故障问题,因为即使协调者在预提交阶段出现故障,参与者也可以根据自身状态进行决策。同时,性能相对2PC有所提高,因为准备阶段不执行实际事务操作。
- 缺点:实现复杂度较高,需要更多的网络交互和状态管理。
- 最终一致性方案(如TCC、Saga等):
- TCC(Try - Confirm - Cancel):业务逻辑被拆分为Try、Confirm、Cancel三个操作。Try操作进行资源预留,Confirm操作确认提交事务,Cancel操作回滚事务。例如,在一个转账业务中,Try操作冻结转出账户资金,Confirm操作完成资金划转,Cancel操作解冻转出账户资金。这种方式对业务侵入性较大,但可以灵活控制事务流程,适用于对性能要求较高、对一致性要求相对宽松的场景。
- Saga:将一个大事务拆分为多个本地小事务,通过事件驱动的方式按顺序执行。如果某个小事务失败,可以通过补偿事务进行回滚。例如,在一个电商订单流程中,下单、支付、发货等操作分别作为独立的小事务,当支付失败时,可以通过取消订单等补偿事务来恢复系统状态。这种方式适用于业务流程复杂、对一致性要求较高的场景,但需要精心设计补偿事务逻辑。