
针对千万级用户短视频推荐页面,采用分层前端架构(客户端+服务端+CDN),结合视频流式加载(HLS/DASH+CDN分片)、个性化分页(用户行为预测)、多级缓存(CDN强缓存+本地存储+Redis),并采用最终一致性(事件溯源+消息队列+冲突检测),确保首屏加载速度、交互流畅性及数据最终一致性。
老师口吻解释关键概念:
Cache-Control: max-age=3600),本地存储缓存视频元数据(列表、用户信息),服务端Redis缓存热点数据(如热门视频列表),减少数据库查询。| 方面 | 视频流式加载(HLS/DASH) | 分页加载(传统) |
|---|---|---|
| 定义 | 视频分片,按需加载 | 一次性加载固定数量数据 |
| 优势 | 减少初始资源占用,播放流畅 | 适合静态内容,初始加载快 |
| 劣势 | 需CDN支持,复杂度高 | 首屏后加载慢,用户体验差 |
| 适用场景 | 千万级用户短视频播放(如抖音、快手) | 小型应用或静态列表 |
GET /api/videos/stream?videoId=123&format=m3u8(CDN返回HLS分片列表,客户端按需请求分片)。GET /api/videos?page=1&limit=20&userBehavior=watched:5,pinned:2(服务端根据用户行为预测加载顺序)。const lazyLoad = () => {
const elements = document.querySelectorAll('.lazy-video');
elements.forEach(el => {
if (el.getBoundingClientRect().top < window.innerHeight && !el.dataset.loaded) {
el.dataset.loaded = true;
fetch(`/api/videos/load?videoId=${el.dataset.id}`)
.then(res => res.json())
.then(data => {
// 渲染视频元素
});
}
});
};
window.addEventListener('scroll', lazyLoad);
Cache-Control: max-age=3600),后续请求直接从缓存获取。{userId: 1, videoId: 123, timestamp: 1678888888888})→发送至Kafka→服务端消费→更新推荐模型(计算用户兴趣向量)→更新数据库(UPDATE videos SET version = version + 1 WHERE id = 123,冲突时比较timestamp,更新较新的记录)。“面试官您好,针对千万级用户短视频推荐页面,我设计的架构核心是分层处理,结合视频流式加载(HLS协议+CDN分片)、个性化分页(用户行为预测)、多级缓存(CDN强缓存+本地存储+Redis),并采用最终一致性(事件溯源+消息队列+冲突检测),确保首屏加载速度、交互流畅性及数据最终一致性。具体来说,页面初始只加载第一页视频(约20条),采用懒加载技术,用户滚动时动态加载后续视频,减少初始资源占用。视频播放时,通过HLS协议将视频分片(1秒/片),CDN缓存分片,用户按需加载,避免卡顿。为了提升首屏速度,采用服务端渲染(SSR),服务器预生成包含视频列表的HTML,客户端无需等待JS渲染。数据一致性方面,由于用户行为高频,采用最终一致性,用户操作通过事件溯源记录,消息队列异步处理,确保数据最终同步。缓存策略上,CDN设置强缓存(如Cache-Control: max-age=3600),本地存储缓存视频元数据,服务端Redis缓存热点数据,减少数据库压力。交互体验上,视频点击后懒加载播放,避免页面卡顿。整体架构通过这些措施,平衡了加载速度、交互体验和数据一致性,适合千万级用户场景。”
Cache-Control: max-age=86400)缓存分片,用户播放时按需请求,减少服务器压力。Cache-Control: max-age=3600),刷新时检查ETag或版本号,不匹配则请求服务器重新获取数据。