知乎feed流架构演进

如果无法正常显示,请先停止浏览器的去广告插件。
分享至:
1. 知乎Feed流架构演进
2.
3.
4.
5. 姚钢强 2013 年年加⼊入知乎,知乎 Feed 流技术负责⼈人,负责期间 Server 端 P95 响应时间从 1.6S 降低到 700Ms,稳定性由 99.9% 提升到 99.995%
6. 提纲 A. Feed 流的需求和特点 B. ⽼老老 Feed 流的构架遇到的问题 C. 新构架 Redis module 技术⽅方案 D. Redis module ⽅方案遇到的问题 E. 新的问题与挑战
7. 知乎 Feed 流的需求和特点 A. DAU 2600万(2017.9) B. 个性化推荐,每次请求返回内容不不同(与搜索不不同, cache 难做) C. ⽤用户动态准实时分发
8. ⽆无 个 性 化 ( 热 ⻔门 榜 单 )
9. ⽤用 户 个 性 化 p u s h
10. push 存在的问题 A. 资源消耗严重,计算量量⼤大,存储量量⼤大 B. 智能推荐,排序难以实时调整 C. 过滤⽐比较难做(关注 or 被删除) D. 动态准实时分发难以达到 (⾼高粉丝⽤用户)
11. 实时 pull
12. pull 计算流程(慢) client member 推荐的相关源 拼装 meta 从指定的源拉取条⽬目 N 选前 10 条 过滤条⽬目 条⽬目 够⽤用 Y 算法排序
13. 提前计算,做缓存 client member 相关的源 N 缓存 从指定的源拉取条⽬目 Y 拼装 meta 前 10 条 后 10 条 缓存 N 选前 20 条 过滤条⽬目 条⽬目 够⽤用 Y 算法排序
14. 提前计算的问题 • 存在冗余计算,占⽤用资源多 • 冷启动 P95 响应时间⻓长 • ⽤用户⾏行行为分发延迟,体验差 • 离线计算策略略复杂,难以维护 • 推荐算法难以实时调整
15. 如 何 优 化 , 难 点 ⼉儿 在 哪 ⼉儿 ? • 依赖服务响应慢 • • gevent 并发 • • redis cache + local cache 超时做降级 Python 计算太慢 • • Cython 模块替换 由于条⽬目不不够,反复访问底层源的存储 feesource
16. 可 能 的 解 决 ⽅方 案 • 拉取出更更多的条⽬目,防⽌止被过滤掉? • • 拉取更更多的条⽬目也会浪费时间,过滤压⼒力力⼤大 根据算法拉取出更更精准的条⽬目? • 算法期望召回池越⼤大越好
17. 计算下推,接近存储
18. 新 feed 计算逻辑
19. Redis Module Redis modules make possible to extend Redis functionality using external modules, implementing new Redis commands at a speed and with features similar to what can be done inside the core itself.
20. Redis Module • 加载定制命令(MODULE LOAD module load lib_path/xx.so) • 执⾏行行定制命令 • 卸载定制命令(MODULE UNLOAD mymodule)
21. 加载定制命令 Client module load lib_path/xx.so START handle = dlopen("lib_path/XX.so") dlsym(handle,"RedisModule_OnLoad") RedisModule_Init 初始化模块 RedisModule_CreateCommand 注册定制命令 ... RedisModule_CreateCommand 注册定制命令 END redisServer attributes + modules: dict + commands: dict operations
22. 执 ⾏行行 定 制 命 令 Client AxxCmd argv1 argv2 … START 查找命令 RedisModuleCommandDispatcher 执⾏行行命令 模块 callback moduleHandlePropagationAfterCommandCallback 回收内存 moduleFreeContext END redisServer attributes + modules: dict + commands: dict operations
23. 卸载定制命令 Client module unload ModuleName START 清空注册符号 dictDelete(server.commands,cmdname) dlclose redisServer attributes + modules: dict + commands: dict operations 卸载模块 moduleFreeModuleStructure END
24. 定制的命令 • open_core, close_core • • Redis module 更更新时打开 core dump,如果 crash ⽅方便便分析 ts_query • Redis 内部的过滤,归并流程
25. t s _ q u e r y 接 ⼝口 设 计 • Request • • black_items: 需要过滤的⿊黑名单条⽬目 • merge_strategy: 合并策略略 • • [source_type, source_id]: 需要拉取 source required_number: 需要返回的条⽬目数量量 Response • [item_type, item_id, item_action, item_score]: 返回需要数⽬目的 feed 条⽬目
26. 带来的收益 • 响应时间 P95 降低 300ms • 去掉了了离线计算,节省 60% 的计算资源 • 内容候选池更更⼤大,为算法提供了了更更⼤大的空间 • ⽤用户动态实时分发,算法实时调整
27. 遇到的问题 • Module 更更新不不⽣生效,继续调⽤用⽼老老 Module • Redis 单线程 CPU 瓶颈,⾼高可⽤用 • Redis 的内存浪费
28. M o d u l e 更更 新 不不 ⽣生 效 • 加载新的 so 后,发现调⽤用的还是⽼老老逻辑 • • GDB 发现存在符号被标记 DF_1_NODELETE dlcose 仅仅声明 so 不不在被系统使⽤用,so 内存占⽤用依旧存在 • gcc 编译使⽤用 STB_GNU_UNIQUE ,防⽌止符号被标记为 DF_1_NODELETE • 按照依赖路路径加载 so,不不直接加载定制的 so
29. R e d i s 单 线 程 C P U 瓶 颈 , ⾼高 可 ⽤用 • 采⽤用 Redis Sentinel 部署集群,保证⾼高可⽤用 • ⼀一致性哈希 Redis shard,每个 shard 采⽤用 master slave 的⽅方式部署
30. Redis 内存浪费 • 采⽤用 protobuf 和 Redis ziplist 数据压缩 ,减少 shard • 有多个 slave ,还是浪费内存,没有根本解决问题 • Redis 仅仅作为任务队列列,任务分派给其他进程处理理? • 同⼀一台机器器伴随 Redis 部署计算节点?
31. Feed 架构的历程 • Feed 都⼀一样 • Feed 个性化,推模型 • Feed 个性化,拉模型 + 离线计算 • Feed 个性化,拉模型,采⽤用 Redis Module,计算接近存储
32. 参 考 资 料料 • Serving Facebook Multifeed: Efficiency, performance gains through redesign • dlclose - close a symbol table handle • dlclose doesn't really unload shared object, no matter how many times it is called • Redis Modules: an introduction to the API • Redis Loadable Modules System
33.

Home - Wiki
Copyright © 2011-2024 iteam. Current version is 2.138.0. UTC+08:00, 2024-12-21 23:42
浙ICP备14020137号-1 $Map of visitor$