上篇我们介绍了下面这个简单的语音聊天室的架构,遗留了两个问题。首先,语音服务器是怎么转发语音数据的?
我们直接上图。图中虚线框表示连接到同一台语音服务器。当A说话的时候,客户端将语音数据上传到A所连接的语音服务器;语音服务器向房间服务器查询A所在房间的其他用户(B-E)所在的语音服务器IP,分几种情况:对于同服务器用户B只需要下发语音数据,对于其他服务器上的用户(C-E)需要转发给相应的语音服务器,其他语音服务器收到转发数据后,根据房间信息,下发给同房间的用户。
有一个细节需要注意,房间服务器是主动给语音服务器同步房间架构的。因为语音服务请求量非常大,如果每次转发的时候都查询房间架构信息,那么房间服务器/数据库将成为瓶颈。因此语音服务器本地缓存了房间架构信息(当然缓存也会导致其他的问题,以后会专门讨论)。缓存的同步机制采用用户进退房主动触发房间服务器广播和房间服务器定期推送相结合,这样可以有效保证网络丢包情况下的数据一致性。
另外一个问题是目录服务器是否有点多余?答案自然是否定的。当同一房间用户量还比较少的情况下,目录服务器的确可以省略,客户端可以通过DNS解析域名得到语音服务器的IP地址进行连接。
但是,当用户量非常大的时候,DNS缓慢的刷新机制不能满足快速扩容和缩容。目录服务器还有一个重要的作用是负载均衡,相比DNS手工配置的简单的负载均衡策略,增加目录服务器可以实现更加高效的复杂均衡策略。例如下面要介绍的分SET部署。
上图展示了同一房间的用户连接语音服务器的两种分布:对于A-E用户散落在5台语音服务器,而A’-E’则连接到2台语音服务器。我们觉得,第二种分布更好。为什么?因为服务器数量更少,语音服务器之间的转发数据量更少。要知道在百万级甚至千万级别的语音服务系统中,机器成本和带宽成本是主要的成本。
如何实现第二种分布呢?这就有赖于目录服务器的负载均衡策略。其中一条策略是同一房间的用户优先分配到相同的语音服务器。当然还有其他的一些策略,我们先不展开。
除了通过负载均衡策略实现更聚集的分布以外,还有一种更常用的手段——分SET部署。如图所示,其实就是增加了一个虚拟SET的概念,一个SET是一个小的服务器集群。SET之间互相隔离,对于小房间(大房间后面再讨论),一个房间只能分布在一个SET内。
这样做有什么好处呢?首先,分SET部署天然可以实现同一房间用户的聚集分布。一个SET一般是10台语音服务器,如果按照单台能承载2万用户来计算,对于房间容量在20万以下的小房间,同一房间的用户都分布到一个SET上。其次,分SET部署更便于版本发布和日常运维。试想一下,同样是有几百台机器的语音服务器集群,分SET发布更新和不分SET发布更新哪个更容易?
增加SET以后,房间的架构信息增加了SET和房间的映射关系:
SET被赋予一组房间的概念,同一个SET内的房间类型可以多种多样,但是一般还是把同类型的房间放在一个SET,因为这样便于管理,发布更新也会比较简单。通常新扩容一个SET的时候,我们会设置SET的一些属性,例如这个SET只支持游戏开黑,那后续游戏开黑的新房间就会分配到这个SET。SET的扩容缩容和房间的新建和销毁我们将在后面的文章中具体介绍。
简单总结一下,本篇主要解答了上篇文章提到的两个问题:语音服务器之间是平行转发数据的;目录服务器除了有路由的功能还可以实现复杂高效的负载均衡策略。而从目录服务器的功能又引出了业界常用的分SET部署的概念。本文介绍的都是一些比较基础的概念,主要为后面的内容做铺垫。