
1) 【一句话结论】:针对TB级用户行为日志,采用宽表模型结合时间分区+用户ID哈希分库的分库分表策略,通过虚拟节点技术减少数据倾斜、批量写入控制延迟,复合索引加速查询,预聚合表(增量更新)减少实时计算,冷热分离(数据恢复)优化存储成本,并辅以Redis缓存热点数据,降低跨分片查询压力。
2) 【原理/概念讲解】:用户行为日志属于宽表场景(所有行为字段存于一张表,适合关联查询,如用户点击路径分析)。分库分表是解决数据量大的核心手段:
user_id + event_time保证数据有序,便于关联查询。类比:超市的“行为货架”,所有商品(行为字段)放一起,方便找关联。20240101),避免单库压力。虚拟节点技术(如ShardingSphere的哈希分片)通过增加虚拟节点数量,将实际节点映射到虚拟空间,确保数据均匀分布,减少数据倾斜风险。event_time + user_id复合索引,加速时间范围查询(如最近7天行为)。索引列顺序影响性能,时间列在前,用户ID在后,适合范围查询。daily_behavior_stats),减少实时计算压力。增量更新通过CDC捕获新增数据,按时间/用户ID过滤,仅更新预聚合表,避免全量重建。3) 【对比与适用场景】:
| 方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 宽表模型 | 所有行为字段存一张表,主键复合 | 适合关联查询,减少JOIN | 用户行为分析(点击路径、扫描记录关联) | 字段多,存储成本高 |
| 分库分表(水平) | 按时间/用户ID拆分表 | 扩展性好,按分区查询 | 日志数据量大(按天/小时拆分) | 分区键选择影响查询效率 |
| 复合索引 | 多列组合索引(如时间+用户ID) | 提升范围查询性能 | 时间范围查询(最近7天行为) | 索引列顺序影响性能 |
| 预聚合表 | 按天/小时统计行为量 | 减少实时计算压力 | 高频统计查询(如日活、行为量) | 更新策略(增量更新)需合理设计 |
| 冷热分离 | 旧数据迁移至冷存储 | 降低存储成本 | 数据量持续增长 | 数据访问频率变化需动态调整 |
4) 【示例】:
CREATE TABLE user_behavior (
user_id BIGINT NOT NULL,
event_time TIMESTAMP NOT NULL,
action_type VARCHAR(20),
device_info JSON,
location VARCHAR(100),
PRIMARY KEY (user_id, event_time)
) ENGINE=InnoDB
SHARDING_KEY(user_id) SHARDING_COUNT 16 -- 分16库(虚拟节点技术)
PARTITION_BY_RANGE (event_time) PARTITIONS 365 -- 按天分区(一年365天)
CREATE INDEX idx_time_user ON user_behavior (event_time, user_id);
CREATE TABLE daily_behavior_stats (
day DATE NOT NULL,
user_id BIGINT,
action_count INT,
PRIMARY KEY (day, user_id)
) ENGINE=InnoDB
PARTITION_BY_RANGE (day) PARTITIONS 365;
-- CDC捕获新增数据,每小时更新预聚合表
INSERT INTO daily_behavior_stats (day, user_id, action_count)
SELECT DATE(event_time), user_id, COUNT(*)
FROM user_behavior
WHERE event_time >= now() - interval 1 hour
GROUP BY day, user_id
ON CONFLICT (day, user_id) DO UPDATE SET action_count = EXCLUDED.action_count;
-- 从HDFS读取冷数据
INSERT INTO user_behavior (user_id, event_time, action_type, device_info, location)
SELECT user_id, event_time, action_type, device_info, location
FROM hdfs_behavior_logs WHERE event_time < now() - interval 30 day;
-- 删除原表分区
ALTER TABLE user_behavior DROP PARTITION (event_time < now() - interval 30 day);
5) 【面试口播版答案】:面试官您好,针对TB级用户行为日志,我设计思路是采用宽表模型+分库分表+预聚合+冷热分离。首先,表结构用宽表存储所有行为字段(用户ID、时间戳、操作类型等),主键为user_id + event_time保证数据有序。分库分表上,按时间按天拆分表(如20240101),按用户ID哈希分库(库0-库N),用虚拟节点技术(如ShardingSphere的哈希分片)避免数据倾斜,批量写入(每批1万条)减少延迟。索引方面建event_time + user_id复合索引,加速时间范围查询。查询优化用预聚合表(按天统计行为量),通过CDC捕获新增数据增量更新,减少实时计算压力,同时缓存热点数据(如Redis)。冷热分离上,将30天前的日志迁移到HDFS,数据恢复时从HDFS读取并重新导入数据库。这样既能支持实时查询(如用户点击路径),又能应对TB级数据扩展,写入延迟控制在秒级,且存储成本显著降低。
6) 【追问清单】:
7) 【常见坑/雷区】: