去应聘了TX(腾迅)的架构师职位,面试官很得意地问:要支持1亿的访问量应该怎样设计这架构?
有意思了, 刚开始还真是有点懵。确实1亿同时在线,这数字确超乎想象,如果只是查询的还好,还有大量的增删改操作,天才的TX构架师是怎样实现的呢?
不行,不能这样就被那家伙给阴了!于是静下心来,想了片刻......
突然感觉其实也并不是那么难的事,哈哈:
只要一个核心的算法就可以了:如果将QQ号根据某种算法F(当然不能太复杂,最好是O(n)的^_^)把它分为N块每块m条记录,每一块放在一台服务器上,这样就相当于一台服务器只服务m条记录,这样想的话就简单多了。最简单的算法就是按顺序放,1~m, m+1~2*m...还有一种简单的就是取余,不过为了让用户感觉不出这样的构架或者说不这么容易被破解,所以会有点点混淆,无论怎样,总之就是达到同样的目的:用个快速的算法,找到它的服务器!这样,即使是用什么数据库、什么语言都影响不大,即时查询即时更新的难度也小很多了。
好,按这种思路试试几个操作的请求流向吧:
1. 注册
通过各种终端注册完成一个QQ号码以后,根据算法F找到为此号码服务的服务器IP,将对应的QQ号码及基本信息发送过去(注册过程)。完成注册操作
2. 登录
第一次登录,通过一台统一的寻址服务器C,服务器C根据算法F将请求路由到对应的服务器S1上,让S1为此Q服务
此过程如果是C/S结构的话,算法可以在客户端完成。或者第一次登录时才访问这台共用服务器C,第一次连接以后,客户端获取到服务器S1以后,之后的操作全部直接发送到S1.这样就完成了登录的操作,当然对于S1来说,服务的客户永远不会超过m个。我还没有去验证这个过程,可以通过抓包去查看远程服务器的地址。有空的同学可以帮忙验证一下。
3. 获取好友列表
某个QQ号码的所有信息都应该放在同一台服务器上,第一次登录是,会把S1上的所有好友信息下载下来。
每次更改状态,得向所有的好友(登录后向所有好友,之后可以向在线(包括隐身的)好友)发送一条指令。(这个可能会是)
4. 向好友发送信息
因为上一个操作已经完成,所以可以知道好友所在的服务器,这时可以直接向好友所有服务器S2发送信息。
5.查找好友(这一点是TX用类似构架的证据)
QQ上提供的查找好友功能比较有限。当然全部会员的查询对于几亿条数据来说,简直是恶梦!因为之前的算法,把各个号码段的用户混在一起,而且单台服务器会员数量够多时,查询时并不需要对整个用户群进行查询(当然精确查询可以直接根据上面的算法F快速查找到好友)。模糊查询时只需要对随机的服务器(或者对会员所在服务器)进行查询就足够了,所以用用户昵称查询时,会查询不到的原因应该就是这样吧。或许,它还会有一些算法,比如在一台服务器上查询不到时可以到另一台服务器查找,不清楚了......
6. 会员服务
貌似没什么特别的,多半是多了些数据保存在服务端
7. 其它
思路差不多就是这样
这样下来,这种C/S结构远比B/S轻松多了,这个大概就是TX这么迟才推出WebQQ的原因之一吧(或许还是为了争夺桌面)。 如果只是Web构架的话,无论是用Nginx还是Apache,要支持这么庞大的用户量,估计都得跨掉!
因为是线性的关系,可以无限地添加服务器以支持更大量的在线会员。瓶颈就在于这台共用的服务器C了。当然,还应该有一个数据中心,会定时把各个服务器的数据收集起来,用于防止服务器当机重启或坏掉时可以重新加载数据。
如果服务器C支持保存各子服务器的状态,如果发现某服务器当掉时,立即转向备用服务器,这样就可以保证服务器的不间断运行。
PS:本方案只是可以支持1亿个会员同时在线的一种貌似可行的方案,TX的具体怎样,天知道呢~~~ 欢迎一起讨论