挑战
Facebook 在 2016 年底时的月活用户数有 1860 万,Facebook live 的压力很大,有大量的人开直播,有大量的用户观看直播
整体来看,直播的挑战在于:
- 需要能够同时支持数百万的直播流
- 对于同一个直播流,需要能够支持数百万的用户
而且直播有一个非常明显的特点,就是非常集中的流量峰值,例如某个名人开了直播,很快就会有大量的用户进来,产生巨大的流量峰值
架构
当很多请求一起进来时,会引发惊群效应,导致严重的流问题,例如延迟、丢包、新用户无法连接 ……
对于这种情况,首先要做的就是阻止请求直接进入流服务器,可以使用多层结构,对请求进行过滤,确保只让必要的请求进入流服务器
其中,Edge Cache 是散布在全球的,Edge Cache 与 Origin Server 是 多对一 的关系,多个 Edge Cache 可以发送请求到同一个 Origin Server
工作过程:
- 用户的请求首先到达离自己最近的 Edge Cache server,这个服务器本质上就是一个cache层,不做复杂的处理工作
- 如果用户请求的数据包就在 Edge Cache 中,那么直接返回给用户
- 如果不在 Edge Cache 中,那么请求会被转到 Origin Server,它也是一个类似 Edge Cache 的缓存服务器
- 如果请求的数据包在 Origin Server 中,就返回给 Edge Cache,Edge Cache 再返回给用户,Edge Cache 同时会自己缓存一份
- 如果 Origin Server 中没有,请求就会被转到 Streaming Server,然后数据返回给 Origin Server,再经由 Edge Cache 返回给用户,同时,Origin Server 和 Edge Cache 都会进行缓存
- 以后有相同的请求时,Edge Cache 和 Origin Server 就可以轻松处理
这个架构极大的减少了 Streaming Server 处理的请求数量,例如有5个请求顺序达到 Edge Cache,只有第一个请求走遍了全程,从 Streaming Server 拿数据,其他4个请求都可以直接从 Edge Cache 中拿到数据
如何防止请求渗漏?
这个架构虽然非常有效,但还有一定的问题,据统计,有 1.8% 的请求会渗漏到 Streaming Server,对于 Facebook 的规模而言,1.8% 也是一个非常大的数字,会给 Streaming Server 造成极大压力
渗漏原因
问题来自并发,当有多个请求一起到达某个 Edge Cache,都要请求数据包A,如果没有命中,那么这几个请求就都会转到 Origin Server
同样的,如果多个 Edge Cache 一起请求同一个 Origin Server,请求也会被转到 Streaming Server
所以,Facebook 的高并发特点就会导致有大量的请求渗漏下去
解决办法
Facebook 的处理办法非常简单,当有多个请求同时到达 Edge Cache,如果他们请求的是相同的数据包,那么就把他们归为一组,放到一个请求队列中,并且只让一个进入到 Origin Server(称为请求合并),当响应回来后,先缓存,然后返回给队列中的各个请求
这个策略同样也在 Origin Server 层进行应用,如果多个 Edge Cache 并发请求相同数据,也会进行合并,只有一个会进入 Streaming Server
这样就很好的解决了并发产生的问题
在 Nginx 中,请求合并可以这样设置:
代码语言:javascript复制proxy_cache_lock = on
负载均衡
还有一点很重要,对 Edge Cache servers 进行负载均衡
在流量高峰期,Edge Cache server 的压力会很大,需要使用负载均衡器对请求进行调配,例如离你最近的那个 Edge Cache 已经在处理20万请求,那么负载均衡器就会把你分配到离你稍远一点,但处理压力较小的按个 Edge Cache
负载均衡器会根据距离与压力进行综合权衡,把用户分配到最合适的 Edge Cache server
小结
本文翻译整理自:
https://designingforscale.com/how-facebook-live-scales
其中的核心思路非常值得借鉴:通过多层结构来过滤请求,从而提高服务器的性能和可用性