|
分发器负责向所有在线的用户推送feed, 即前文中的Push.
用户产生一条新feed, 先同步插入自己的inbox, 然后交给Distributor分发给所有粉丝.
这里worker有2层, worker1负责接收任务, 按照每3000个粉丝一组分拆成很多子任务, 交给下一级worker2处理. worker2并行处理完成后汇报给worker1, 同时做一些计时和延误告警的工作.
worker2负责具体的分发流程, 获取粉丝id->判定online->推送并未读数++. 为了追求速度, online是一次性批量获取的, 这里还碰到过一个坑, 参见 http://littlexiang.me/php/3.html .
同时worker2也有大小两个池, 初步设定threshold是100w, 超过100w粉丝的任务会交给large pool处理, 避免某些大佬发了照片来不及处理导致任务积压, 影响了大部分普通用户的分发.
关于性能, 模拟了100w粉丝全体offline和online的情况. 100个worker+2个redis在普通pc机上的分别是1~2s和10~11s.这里扯一个别的问题, 之前测试1个redis的时候, 分发速度是6~7w/s, 分布到2个redis之后居然还是6~7w/s, 最后发现是计算分布写的太罗嗦了, 后来把floor(crc32(id) % 360 / (360 / N))改成crc32(id) & (N-1), 达到了10w+/s, 缺点就是shard数量只能是2^n. 每次扩容必须翻倍, 不过不一定得加物理机, 直接多开一组redis实例就可以了, 因为是全缓存, 完全不用aof和rdb, 一台物理机上开个4个总是可以的.
关于inbox的分布和扩容, 直接添加配置就可以了. 因为online标志和inbox在一起, 所以不需要人工干预迁移, 失效的部分会在下一次用户操作时自动rebuild. |
|
|