
核心采用微服务分布式架构,通过分库分表(MySQL存储题目元数据)、分布式文件系统(MinIO存储题目文本)、Redis缓存、Elasticsearch检索、Kafka消息队列(推荐),结合负载均衡和限流,实现百万级题库的高并发支持,数据一致性通过最终一致性(事务+补偿机制)保障,推荐算法优化(预计算+近似)提升实时性。
针对百万级题库系统,需解决高并发读写、快速检索、实时推荐三大核心问题,各组件作用如下:
id取模后对应表,如id % 8对应表0-7),将数据分散存储,支持读写分离(主库写,从库读),提升读性能。题目元数据表需创建多列索引(如difficulty, tags联合索引),加速按条件检索。text_url字段(指向MinIO文件路径),文本内容通过文件系统存储,避免数据库存储大文本导致性能下降。关键优化点:
以**MySQL(元数据)与MinIO(文本)**为例,对比题目内容存储:
| 组件 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| MySQL | 关系型数据库,支持事务、ACID | 事务一致,持久化存储,适合结构化元数据 | 题目元数据(需持久化,如题目修改、用户答题记录) | 分库分表后需维护一致性,复杂检索效率低 |
| MinIO | 分布式对象存储,高吞吐、低延迟 | 存储大文本(如题目内容),支持版本控制 | 题目文本内容(避免数据库存储大文本) | 无事务,需结合元数据(MySQL)管理文件路径 |
| Elasticsearch | 分布式搜索引擎 | 支持复杂全文检索、多条件查询(倒排索引) | 按标签、难度等条件检索题目(如“算法”标签、“中等”难度) | 不支持事务,数据最终一致性,需结合数据库存储元数据 |
/minio/questions/1001.html,元数据表questions中text_url字段为该路径。GET /questions/_search
{
"query": {
"bool": {
"must": [
{ "term": { "tags": "算法" } },
{ "term": { "difficulty": "中等" } }
]
}
},
"size": 10
}
返回结果包含题目ID、标题、难度、标签等,再从Redis获取文本内容(若缓存命中)。面试官您好,针对百万级题库系统,我设计的架构是微服务分布式架构,核心是通过分库分表、分布式文件系统存储题目文本、Redis缓存、Elasticsearch检索,以及Kafka消息队列处理实时推荐,确保高并发下的快速响应。首先,题目元数据(如ID、标题、标签)存MySQL,通过哈希分库分表,创建联合索引加速检索;题目文本存储在MinIO,文本内容通过文件路径关联,用布隆过滤器减少缓存穿透。热门题目和用户历史数据缓存到Redis,减少数据库压力。检索时用ES,支持按标签、难度等复杂条件秒级返回结果。用户答题后,答题数据写入Kafka,消费者实时分析用户行为(正确率、用时),生成推荐列表并更新用户数据。考试期间,通过Nginx负载均衡分发请求,应用层限流,数据库分库分表,提前缓存热门题目(缓存预热),确保数千学生并发访问。数据一致性采用最终一致性,用户答题后先写入数据库,再异步更新缓存,失败时重试。推荐算法通过预计算用户画像(如协同过滤的相似度矩阵提前计算),减少实时计算开销,延迟控制在秒级内。这样能高效支持百万级题目的增删改查、检索和推荐,满足竞赛场景的高并发需求。
如何保证数据一致性?(如用户答题后推荐更新失败)
缓存穿透或雪崩怎么办?
推荐算法的实时性如何优化?(如用户答题后推荐延迟)
系统如何水平扩展?(如考试流量激增)
题目文本修改后如何回溯?