
1) 【一句话结论】为支持高并发写入(每秒数千次任务提交)并保证状态一致性,推荐采用TiDB(分布式事务型关系型数据库)结合Redis缓存的混合方案,通过TiDB的事务保证状态转换的原子性,Redis缓存状态变更并分担写入压力,同时利用TiDB的version字段实现乐观锁,结合数据库事件通知(或消息队列)实现缓存与数据库的强同步。
2) 【原理/概念讲解】面试官您好,我们来拆解核心需求:视频处理任务的状态(待处理、处理中、已完成、失败)属于状态机模式,每个任务的状态转换有严格顺序(如待处理→处理中→(完成/失败)),需要保证状态变更的原子性和一致性。高并发写入(每秒数千次)意味着数据库需要支持高吞吐,而传统单机数据库(如MySQL)在高并发下行级锁会导致性能瓶颈,分布式数据库(如TiDB)通过分片(水平拆分数据)和多副本复制将写入压力分散,提升并发能力。Redis作为内存数据库,具备低延迟、高并发写入特性,适合作为状态变更的缓存层,减少数据库压力。状态机表设计核心是唯一标识(task_id)和状态枚举(status),通过事务保证状态转换原子性。此外,为避免并发冲突,引入乐观锁(版本号),通过检查版本号是否一致来确保同一时间只有一个线程更新状态。为保持缓存与数据库一致,采用数据库事件通知(如TiDB的触发器)或消息队列(如Kafka),当数据库状态更新时,通知Redis更新缓存,实现强同步。
3) 【对比与适用场景】以下是不同数据库方案的对比:
| 方案 | 定义 | 关键特性 | 适用场景 | 注意点 |
|---|---|---|---|---|
| 分布式事务型关系型(TiDB) | 基于MySQL协议的分布式数据库,支持分片、复制、ACID事务、版本号乐观锁 | ACID事务、高并发写入(分片后QPS可达数万)、强一致性、分布式存储、内置乐观锁(version字段) | 状态机、需要事务的复杂业务(如任务调度、订单处理)、高并发写入场景 | 部署复杂,分片策略影响写入性能,需合理设计分片 |
| NoSQL(如Cassandra) | 分布式NoSQL数据库,最终一致性 | 最终一致性、高写入吞吐、分布式存储、无事务或弱事务 | 大规模数据写入,对一致性要求不高的场景(如日志、缓存) | 状态转换复杂时,事务支持弱,可能导致数据不一致 |
| Redis | 内存数据库,支持事务(简单) | 低延迟、高并发、内存存储、支持发布订阅 | 状态变更的快速写入、缓存 | 内存限制,持久化需额外考虑(如RDB/AOF),不支持复杂事务 |
| 传统单机MySQL | 单机关系型数据库 | ACID事务、行级锁、单节点存储 | 低并发场景,数据量不大 | 高并发写入时,行级锁导致性能急剧下降,无法满足数千次/秒 |
4) 【示例】表结构设计(以TiDB为例):
-- 提交任务(待处理)
INSERT INTO video_task_status (task_id, status, version, created_at)
VALUES ('task-20240101-001', 'pending', 1, NOW());
-- 更新为处理中(乐观锁检查)
UPDATE video_task_status
SET status='processing', version=version+1, updated_at=NOW()
WHERE task_id='task-20240101-001' AND version=1;
-- 处理失败(更新为失败并记录错误)
UPDATE video_task_status
SET status='failed', version=version+1, updated_at=NOW(), error_msg='处理超时'
WHERE task_id='task-20240101-001' AND version=2;
5) 【面试口播版答案】面试官您好,针对视频处理任务的状态存储,我建议采用TiDB(分布式事务型关系型数据库)结合Redis缓存的方案。核心思路是:用TiDB保证状态转换的强一致性(通过ACID事务),用Redis缓存状态变更并分担数据库写入压力。表结构设计为状态机表,包含task_id(唯一标识)、status(枚举状态)、版本号(乐观锁)、时间戳等字段,并建立复合索引覆盖状态查询。具体来说,任务提交时写入TiDB的pending状态,处理中时更新为processing(检查版本号避免冲突),完成后或失败则更新为completed或failed,同时记录错误信息。数据库更新状态时,通过事件通知(或消息队列)同步到Redis,确保缓存与数据库一致。这样既能满足每秒数千次的高并发写入,又能保证状态一致性。
6) 【追问清单】
7) 【常见坑/雷区】