Feed流系统重构:架构篇
在当今移动互联网时代,Feed流产品已成为各类应用的标配,如微博、微信朋友圈、头条资讯推荐等。Feed流系统的核心在于持续更新并呈现给用户内容的信息流,每个用户都能在其关注页或朋友圈中看到最新的动态。然而,随着业务的发展和用户规模的扩大,原有系统架构可能面临性能瓶颈和代码维护困难等问题,这时就需要进行架构重构。
一、背景与挑战
一个典型的Feed流系统可能面临以下挑战:
- 性能瓶颈:随着用户量和数据量的增加,查询速度变慢,用户体验下降。
- 代码腐化:原有代码可能因多次修改和新增功能而变得难以维护。
- 扩展性差:系统难以适应新业务和新功能的接入。
例如,一个家校朋友圈应用,服务端代码已有四年历史,随着人员变动和不断的新功能添加,代码可读性越来越差,查询效率低下,DBA反馈SQL频繁超时。这时,重构就显得尤为必要。
二、重构目标
在进行重构前,需要明确目标,以确保重构的有效性:
- 功能模块化:便于扩展和维护。
- 灵活扩展Feed类型:支撑新业务接入。
三、重构步骤
1. 梳理业务与模块拆分
首先,需要梳理朋友圈业务,将单个家校服务端拆分成多个模块。例如,可以拆分为两个模块:
- space-app:提供REST接口,供APP调用。
- space-task:推送消息,任务处理。
2. 分库分表设计
由于Feed表数据已达两千万,Feed详情表达七千万,为了提升查询效率,需要进行分库分表。考虑到数据写入量每天才两万,因此选择分表策略。
sql复制代码
|---|---------------------------------------------------------------|
| | -- 示例:创建Feed表(简化版)
|
| | CREATE TABLE `t_feed` (
|
| | feedId` BIGINT NOT NULL PRIMARY KEY, `` | | |
userId BIGINT NOT NULL COMMENT '创建人ID', `` | | | ```content
TEXT, | | | ```recordStatus` TINYINT NOT NULL DEFAULT 0 COMMENT '记录状态'
|
| | ) ENGINE=InnoDB;
|
为了提升数据库表设计效率,需要整理核心接口调用存储过程逻辑,并去除存储过程。在设计表时,需要考虑shardingKey冗余。
3. 架构设计
在梳理业务和设计数据库表的过程中,并行完成各个基础组件的研发,包括:
- 分库分表组件
- Id生成器
- Spring Boot Starter
- RocketMQ Client封装
- 分布式缓存封装
在选择分库分表方案时,可以采用ShardingSphere的sharding-jdbc,因其轻便简单且原理易于理解。
java复制代码
|---|----------------------------------------------------|
| | // 示例:Sharding-JDBC配置
|
| | ShardingRule shardingRule = new ShardingRule(
|
| | shardingRuleConfiguration,
|
| | customShardingConfig.getDatasourceNames()
|
| | );
|
| | DataSource dataSource = new ShardingDataSource(
|
| | dataSourceMap,
|
| | shardingRule,
|
| | properties
|
| | );
|
分库分表的核心算法包括DataSourceHashSlotAlgorithm和TableHashSlotAlgorithm,这两个类的核心算法基本是一样的。
4. 数据存储与查询优化
Feed流系统的数据存储设计主要包括三个部分:
- Feed存储:用户发布的内容存储,需要永久保存。
- 关注关系存储:用户之间的关系存储,控制用户能够看到Feed的范围,同样需要永久保存。
- 收件箱:用于Feed流展示,可以理解为是一个收件箱,关注的人发布了Feed,就要向其中投递。可以根据业务场景保存一段时间内的内容,冷的数据可以进行归档或直接删除。
sql复制代码
|---|------------------------------------------------|
| | -- 示例:创建收件箱表(简化版)
|
| | CREATE TABLE `t_inbox` (
|
| | id` BIGINT NOT NULL PRIMARY KEY, `` | | |
userId BIGINT NOT NULL COMMENT '收件人ID', `` | | | ```feedId
BIGINT NOT NULL COMMENT '内容ID', | | | ```createTime` DATETIME NOT NULL
|
| | ) ENGINE=InnoDB;
|
查询优化方面,可以采用ES(Elasticsearch)进行模糊查询,并通过MQ(Message Queue)消息形式,将数据同步到ES,这种方式虽然稍有延迟,但延迟可控且可接受。
四、总结
Feed流系统的重构是一个复杂而细致的过程,需要综合考虑业务需求、性能瓶颈、代码可维护性和扩展性等多方面因素。通过模块化设计、分库分表、基础组件封装和查询优化等措施,可以显著提升系统的性能和可维护性,为业务的持续发展提供有力保障。
在重构过程中,务必遵循"不要为了重构而重构"的原则,确保重构工作能够切实解决核心问题,提升系统整体效能。