Feed服务架构
新浪微博 新员工培训
洪小军 @XiaoJunHong
2013.08
课前准备
• Feed业务介绍
课前准备
• Feed业务介绍
课前准备
• Feed业务介绍
精简Feed系统 = 用户 + 关系 + 内容
课前准备
• 分组设计Feed架构方案
• 数据指标:
每秒万级的调用量,每秒新增千级数据,现有百亿级数
据,每个用户平均关注好友数为100,要求平均响应时间
控制在30ms以内
• 设计要求:
业务实现上主要包括发布Feed和展示好友Feed列表。请
同时结合可用性、成本因素,设计Feed架构方案。需要
涵盖数据库和缓存设计
• 注:不需要考虑用户、关系、计数相关设计
课前准备
• 参考资料:
• Brewer's CAP Theorem
•思考Feed架构中权衡点是什么?
• Jeff Dean:Numbers Everyone Should Know
•思考所设计的Feed架构需要多少服务器资源?
• memcached全面剖析
课前准备
• 参考资料:相关系统设计方案
• Facebook :Facebook news-feed(QCon 2012)
• Twitter:Timelines-Twitter(Qcon 2012)
• Sina Weibo:《构建可扩展的微博架构》、《新浪微
博cache设计谈》
• Tencent Weibo:《腾讯微博架构介绍》
• RenRen:《人人网Feed系统结构浅析》
课前准备
• 参考资料:服务器机型
• 前端机型:2 * intel E5-2620 6核、12G内存、1 *
300G SAS
• 缓存机型:2 * Intel E5- 2620 6核、128G内存、4 *
300G SAS
• 数据库机型(SAS):2 * Intel E5- 2603 4核、64G
内存、12 * 300G SAS
• 数据库机型(SSD):2 * Intel E5- 2609 4核、64G
内存、2 * 300G SSD
课前准备
• 课前准备
• 了解Feed业务
• 使用现有的组件类库(Memcached、Mysql等)
• 多线程、异步编程模型(BlockingQueue、Future等)
• 预习参考资料
Feed服务架构
• Feed设计方案讨论
• 讨论点:
各组展示设计方案
要求:能明确说明关注点、权衡点、优缺点
关注点包括性能、一致性、稳定性、架构简单性、成本等
Feed服务架构
• CAP原则
Feed服务架构
• CAP原则
Feed服务架构
• 推拉模式探讨 – 推模式
• 写入消息
insert into feeds(user_id, author_id, feed_id)
select $user_id, follwer_id, $feed_id from followers
• 获取消息
select * from feeds where user_id = $user_id
user_id author_id feed_id
10001 20001 1111111111
10002 20001 1111111111
10003 20001 1111111111
Feed服务架构
• 推拉模式探讨 – 推模式
• 空间换时间:存储容量瓶颈?
• 粉丝越多推送量越大:姚晨5000万粉丝怎么推送?
• 延迟推送?延迟是否可接受?
• 变更通知成本高:加关注、取消关注、删除Feed?
• 系统复杂度变高?
Feed服务架构
• 推拉模式探讨 – 拉模式
• 写入消息
insert into feeds(user_id, feed_id)
values($user_id, $feed_id)
• 获取消息
select * from feeds where user_id in
(select following_id from following)
user_id feed_id
10001 1111111111
10002 222222222
Feed服务架构
• 推拉模式探讨 – 拉模式
• 时间换空间?
• 动态聚合怎么保证响应时间?
• 并行获取?存储靠近计算?
Feed服务架构
• 推拉模式对比
推 拉
获取Feed 简单、高效 实时计算量大,与好友数量
相关
发表Feed 推送给所有粉丝 不推送
变更通知 加关注、取消关注、删除
Feed等都需要变更
不需要
好友多、粉丝少 适合 不适合
好友少、粉丝多 不适合 适合
好友多、粉丝多 ? ?
Feed服务架构
• 请求量统计
• 拉模式:
• Read:请求量(1w)* 好友数(100) = 100w
• Write:写入量(1000)
• 推模式:
• Read:请求量(1w)
• Write:写入量(1000) * 粉丝数(100?)= 10w
需要多少服务器资源?
Feed服务架构
Feed服务架构
• Mysql Performance
Feed服务架构
Feed服务架构
• Memcached
Free & open source, high-performance, distributed
memory object caching system, generic in nature, but
intended for use in speeding up dynamic web
applications by alleviating database load.
Feed服务架构
Mysql
Web
Memcached
• 节点故障?
• Failover
• 一致性hash
• Master/Slave
• 节点hang住、网络延迟?
• Failover
• 打造高可用缓存
Feed服务架构
Mysql
Web
Memcached
• 命中率低?
• 预热、防止雪崩
• 过期策略、剔除率
• 容量瓶颈?
• 分布式多节点部署
• 压缩存储
• 带宽瓶颈?
• 网卡、交换机
• 连接数瓶颈?
• 打造高可用缓存 – 容量规划
• 微博的实践
– 数据库发展历程
– 缓存发展历程
微博发展历程
• 第一版本Feed快速搭建完成并上线
Mysql
Web
content
id long
content varchar
timeline
uid long
id long
微博数据库发展历程
但是随着用户和流量的不断增长,开始出现
各种各样的问题……
微博数据库发展历程
• 问题出现
– 读请求很慢,大量mysql慢查询和超时情况
– 前端和缓存层面也都做了扩容,但是问题依旧
– 高峰期间写请求较多慢的情况
微博数据库发展历程
• Scale Up
– 硬件升级(Cpu、磁盘和内存等)
– 同时开始准备扩展mysql及其做sql优化
微博数据库发展历程
• 传统关系型数据库选择CAP中的CA
– 保证了高可用性和数据一致性
– 实现分布式数据库集群相对比较困难
– 扩展时面临更多的挑战
微博数据库发展历程
• 数据库Scalability
– Scale Up(集中式)
• 简单快速实现,不需要改造程序
• 较低运维成本,节省机架和能耗成本
• 高端服务器
• 将会碰到瓶颈点
– Scale Out(分布式-Sharding)
• 需要程序和数据库设计层面支持
• 较高运维成本,占用更多机架和耗费更多能耗
• 普通服务器
• 可持续性的水平扩展方式
– Scale Up & Scale Out
微博数据库发展历程
• 扩展前准备工作
– select t.id, c.content from timeline t
left join content c where t.uid=?
– 这样的sql语句假定content和timeline在同一
数据库中,并且是单表结构。
• 如果content和timeline拆分到不同数据库?
• 如果content和timeline要分库和分表?
微博数据库发展历程
• 数据库只是存储
– 在数据库层面没有业务逻辑
– 业务逻辑在应用端处理
– sql语句应该是
• select id from timeline where uid =?
• select id,content from content where id in (?)
微博数据库发展历程
• 优化sql语句
– 简单的sql语句
• 避免join、子查询、游标等复杂操作
• 只返回需要的数据
– 合理的使用索引
• 减少随机读,提高性能
– 避免分布式事务
• BASE原则
微博数据库发展历程
• 问题出现
– mysql读写再次出现瓶颈
– 出现瓶颈时各业务互相影响
微博数据库发展历程
• 垂直拆分
– 按业务拆分到不同的端口和数据库中
content
Web
timeline
微博数据库发展历程
• 问题出现
– mysql读成为瓶颈
微博数据库发展历程
• 读写分离
master
Web
slave
Read
Replication
Write
微博数据库发展历程
• 问题出现
– mysql读再次成为瓶颈
微博数据库发展历程
• 加slave
master
Web
Write
slave
slave
Replication
Read
微博数据库发展历程
• 问题出现
– mysql写成为瓶颈
微博数据库发展历程
• 水平拆分
Web
master
slave
master
slave
master
slave
微博数据库发展历程
• 水平拆分
– 分库
• 物理库和逻辑库
– 分表
• hash分布和时间分布
微博数据库发展历程
• 一些注意事项
– 拆分为足够多的逻辑库(如32)
• 方便后续扩容为物理库
– 避免更改字段
• 百亿级数据量的库表更改字段会是怎么样?
– 节省存储空间
• 选择合适的数据类型,能选tinyint就不选int…
• 合理的压缩存储,如pb替换json等
微博数据库发展历程
• 问题出现
– mysql出现慢查询
– 更多是发生在查看历史发博量非常大的用户的
微博列表的时候
微博数据库发展历程
• 一级索引按月拆分
– 增加二级索引
timeline
uid long
id long
timeline_si
uid long
stat_date date
count int
微博数据库发展历程
• 一级索引按月拆分
– 通过二级索引获取对应月份
– 通过一级索引获取具体数据
timeline_si
uid stat_date count
100001 2013-08-01 2
100001 2013-07-01 2
100001 2013-06-01 1
…… …… ……
timeline_1308
uid id
100001 555555
100001 444444
…… ……
timeline_1307
uid id
100001 333333
100001 222222
…… ……
timeline_1306
uid id
100001 111111
…… ……
微博数据库发展历程
• Sharding小结
– 垂直拆分
• 实现简单
• 扩展能力有限,并且强关联的业务不容易再细拆
– 读写分离
• 主要缓解读压力,读节点可扩展
• 存在主从同步问题,最终体现在一致性问题上
– 水平拆分
• 扩展性强,但是需要预先规划好分库分表策略
• 实现相对比较复杂
微博数据库发展历程
• 问题出现
– 为了抗更大的读写压力,采用更多更好的设备
(ssd等),但是每次扩容都需要扩容整个数据
库(包括所有历史数据),服务器成本非常高
微博数据库发展历程
• 按年归档-冷热数据分离
Web
2012年
master
slave
slave
slave
2011年
master
slave
slave
2010年
master
slave
2009年
master
slave
slave
slave
slave slave
微博数据库发展历程
• 数据库发展历程小结
– 扩展性:Scale Up -> Scale Out -> Scale Up
– 系统设计:简单 -> 复杂 -> 简单
– 水平扩展:垂直拆分 -> 读写分离 ->
水平拆分 ->冷热分离
– 权衡出最合适的方案
微博数据库发展历程
• 集中式缓存
Mysql
Web
Memcached
微博缓存发展历程
• 问题出现
– Mysql出现性能瓶颈,读取压力过大
• 单台mc容量有限,缓存数据大量过期
• 缓存命中率下降,进而导致大量请求穿透到mysql
– memcached出现慢查询情况
• mc单机吞吐量有限,读压力超过可支撑最大限度
• 带宽成为瓶颈
微博缓存发展历程
• 分布式memcached
Mysql
Web
MemcachedMemcached ......
微博缓存发展历程
• 问题出现
– 某memcached crash,读写此mc报错
• 可能是硬件或其它原因导致crash
• 典型的单点问题
微博缓存发展历程
• 防单点
– failover
– 一致性哈稀
微博缓存发展历程
• 如果有资源:master/slave
Mysql
Web
Memcached
Master Cluster
Memcached
Slave Cluster
微博缓存发展历程
• 问题出现
– mysql压力再次过大,性能出现瓶颈
– mc容量出现瓶颈,命中率降低
微博缓存发展历程
• 在线扩容memcached
– 保证高可用,注意命中率
Slave
node1 node2 node3
Backup(old master)
node1 node2 node3
Master(new master-empty)
node1 node2 node3Client
(get)
node4
微博缓存发展历程
• 问题出现
– memcached读再次成为瓶颈
– 读取量会持续成倍增长
– 期望有线性扩容的方案
微博缓存发展历程
• 线性扩展-L1 Cache
Slave
node1 node2 node3
Master
node1 node2 node3
L1 cache
node1 node2 node3
Client
(get)
微博缓存发展历程
• 打造高可用缓存-容量规划
– 请求量
– 命中率
• 预热,防止雪崩
– 带宽
• 网卡、交换机
– 存储容量
• 预估存储大小
• 过期策略、剔除率
– 连接数
微博缓存发展历程
• 小结
无cache 进程内 集中式 分布式 master/slave L1 cache
微博缓存发展历程
• 架构在不断演化中
– 没有永恒的和一成不变的方案
– 合适的场景使用合适的技术和方案
– 力求简单可靠
– 为未来一段时间考虑但不过度设计
课前准备
• 课后作业 – 功能说明
• 发布Feed
• 查看关注的好友Feed列表
• 实现上需要包括数据库和缓存相关的,关系列表可以
是程序内部硬编码
• 相关业务数字:
每秒万级的调用量,每秒新增千级数据,现有百亿级数
据,每个用户平均关注好友数为100,要求平均响应时间
控制在30ms以内
课前准备
• 课后作业 – 必须实现
• 推拉实现(至少选其一)
• 缓存数据结构设计及其容量预估
• 数据库结构设计
• 性能相关评估(内存占用、QPS等)
• 多线程、异步编程模型
课前准备
• 课后作业 – 加分项
• 数据库分库分表
• 分布式缓存
• 缓存高可用设计
• 压缩存储(Protocol Buffer、ByteBuffer等)
• 比较JVM参数在默认情况下与参考资料情况下差异
QA
Thank You

Feed服务架构-新浪微博新员工培训议题