大型互动平台中好友动态系统架构设计与实现

2011-06-25 09:39王治国
电视技术 2011年15期
关键词:队列好友消息

刘 平,王治国,曹 刚,吴 迪,彭 升

(中国网络电视台,北京 100142)

0 引言

《第27次中国互联网络发展状况统计报告》显示,截至2010年12月,中国网民规模达到4.57亿,较2009年底增加7330万人;互联网普及率攀升至34.3%,较2009年提高5.4个百分点。另外,《报告》显示,中国网民的互联网应用表现出商务类应用用户规模继续领涨、网络娱乐渐入平稳期、社交类应用保持较快发展速度的特点[1]。

Web2.0[2]的浪潮席卷了整个互联网,带来了人们对互联网应用的彻底转变。基于六度空间理论发展起来的社会化网络服务或社交网站(Social Network Service,SNS),是Web2.0的典型代表。SNS通过网络服务不仅帮助人们找到朋友、合作伙伴,而且能够实现个人数据处理、个人社会关系管理、信息共享和知识分享,最终帮助用户利用信任关系拓展自己的社交网络,达成更有价值的沟通和协作,从而带来丰富的商业机会和巨大的社会价值。

从2005年开始,以Facebook为代表的SNS类网站在一夜之间火遍全球,无数类似的网站出现在互联网上。2010年上半年,Facebook的访问量首次超过Google,成为全球流量最大的网站。在国内,SNS也在蓬勃发展,成为过去两年最热门的网站类型之一。

动态(feeds)是将用户在网站的活动进行记录并推送到其好友主页的功能,目前已经广泛用于社交网站。动态功能很好地把用户和内容结合起来,大幅提高了用户的互动。当用户在站内进行某些操作行为后,该用户相关的好友会收到相应的此用户行为的消息通知。笔者认为用户看见好友的行为通知后很可能也跟进一个的类似或相关的行为,这就是“黏度”的体现。因此,好友动态系统是大型互动平台的核心,承载着各个业务系统与用户之间的互动。

本文分析了大型互动平台中好友动态系统架构面临的调整,确定了架构设计的模式和原则,并详细介绍了好友动态系统架构的设计与实现。

1 架构挑战

对于网站运营来说,以下场景在网站的整个生命周期里很有可能出现,而且一旦出现都是系统的噩梦:

1)场景一:某硬件或服务故障可能导致整个网站不可用

系统上线运营后,各项业务都逐渐进入上升轨道,活跃用户也稳步增加,各项数据都表明网站在年轻人群中的社会影响力与日俱增,此时系统中一个机器发生宕机,开始有用户的某些操作无响应,然后更多相关的服务获取不到数据,最后甚至用户根本无法登录系统。故障已经发生,用户已受到影响,当务之急是快速恢复机器工作,缩短故障时间。如果机器只是掉电宕机,设备并无大碍,重新启动系统后一切恢复正常;如果磁盘等硬件发生故障,需要将应用迁移到备份服务器,快速启动备用服务器。

如何避免单点故障或者将单点故障的影响降到最低呢?

2)场景二:新增业务规则或对以前业务规则的升级导致重新开发系统

系统经过一两年的运营逐步趋于稳定,但产品团队和开发团队之间的争论却越来越多,产品团队开始抱怨新的创意无法得到快速响应,开发团队没日没夜加班仍然有干不完的活,对系统功能的改造总是牵一发动全身,更别说开发新的业务。

如何让架构能够适应未来业务的发展,为潜在的扩展点进行设计?

3)场景三:春节期间活跃用户激增导致系统性能下降

春节前,营销团队在电视媒体、平面媒体、网络媒体等进行了全方位的营销宣传,而且效果非常明显,春节期间活跃用户数快速增长,甚至超过去年整年的增长,但随之而来的是,随着用户数的增长,以前没有发现的问题开始暴露出来,运营团队不得不每天坚守岗位,甚至采用轮班制,但网站的响应时间还是下降了,而且开始出现间隔性的中断服务,用户开始抱怨,开始选择其他平台。

如何应对潜在的用户数激增对系统服务质量的影响?

大型互动平台中好友动态系统的架构挑战主要来自于设备、服务和用户,因此假设:1)所有的硬件和服务总会有故障;2)业务规则在运营过程总会发生变化;3)用户数会在某个时间呈现爆炸式增长。

2 架构模式和设计原则

2.1 架构模式选择

好友动态的架构实现有两种选择:拉模式和推模式(见表1)。推模式,指用户发表一条动态时,动态系统将这条动态拷贝N次分发给他的粉丝或好友;用户读取时,直接从“我的动态”和“好友动态”中读取动态列表。拉模式,指当用户查询动态消息时,从所有好友的动态队列中获取动态,拿到这些动态后再做排序和合并操作;用户发表动态时,直接发布到自己的队列中。

表1 推模式与拉模式的比较

结合项目的实际需求,项目组认为推模式架构简单,能够给用户提供更好的产品体验,而多占用的存储空间是可以接受的。

2.2 架构设计原则

针对好友动态系统架构面临的调整,项目组为架构设计确定如下架构原则[3]:

1)可靠性

可靠的服务是系统的基础,随着系统中设备数量、服务数量的增加,服务大规模分布式部署,可靠性的成本越来越高。服务的可靠性也不再局限于设备的可靠,设计可靠的软件架构才能从根本上提高系统可靠性。

2)可伸缩性

可伸缩性就是通过增加资源使服务容量产生线性(理想情况下)增长的能力。可伸缩应用程序的主要特点是:附加负载只需要增加资源,而不需要对应用程序本身进行大量修改。可伸缩性包括两个方面,向上伸缩(Scale-Up)和水平伸缩(Scale-Out)。

向上伸缩指通过使用性能更好、速度更快和成本更高的硬件来实现可伸缩性。包括添加更多内存、添加更多或更快的处理器,或者只是将应用程序迁移到功能更强大的单个计算机。通常,该方法能够在不改变源代码的情况下增加容量。从管理角度而言,情况并未发生变化,因为要管理的仍然只是一台计算机。

水平伸缩的实现需要使用多台计算机,但计算机集合本质上是作为单个计算机运行的。通过使若干台计算机专门执行常见的任务,增加了应用程序容错。当然,从管理员的角度看,外扩使计算机的数目增多,从而提出了更大的管理挑战。

考虑到高性能设备成本昂贵,服务器都采用普通的PC或PC服务器,可伸缩性需要更多依赖水平伸缩,即通过更多的普通设备扩展系统整体容量。

3)高并发性

系统的注册用户数决定了必须解决大量用户并发访问系统的问题,而且随着网站整体影响力的扩展,用户数会更大。此外,为了提供更丰富的用户体验,在用户登录网站期间会定期访问好友动态系统,获得更新的数据。以1000万注册用户为例,10万用户同时在线,每个用户10 s刷新一次动态数据,那么每秒将会有10000个并发请求,这样的规模是传统网络不可比拟的,也是好友动态系统架构的重点。

4)大数据量

一个用户的每一个操作都会以消息的形式通知给其全部数量的好友;同样其全部好友的每一个操作也将以消息的形式通知给用户。好友动态系统的特点决定了好友越多系统的数据量就会越大。数据显示,在Facebook网站等级的粉丝,全球最具人气的人物是当红女歌星La⁃dy Gaga,她的注册粉丝达到了2200万。

5)业务规则可扩展

好友动态系统是互动平台的核心引擎,几乎所有应用都需要通过好友动态系统与用户进行互动,每个应用的业务逻辑和数据标准又有很大的差异;而且为了保证消息质量,具有良好的可阅读性必须对用户的消息进行合并。因此需要架构设计支持灵活的业务规则。

3 架构设计

3.1 整体架构

好友动态系统整体上采用分布式系统架构方法,消息按流水线的方式进行处理,分别由转发服务器、分发服务器和消息服务器处理,其中最重要的好友关系信息从好友关系系统获得,并缓存在关系缓存集群中。另外,为了实现自动化运营,好友动态系统提供了服务监视系统和配置管理系统,如图1所示。转发服务器将客户端发布的动态消息转发到分发服务器;分发服务器对客户端的消息进行预处理,并根据好友关系将动态消息推送到各个好友的消息服务器;好友关系缓存服务器为分发服务器提供好友关系缓存,提高分发服务器消息推送性能;消息服务器接收分发服务器推送的消息,对消息进行合并处理,存储用户的动态消息,并为用户提供动态检索服务。

3.2 关键架构点

3.2.1 水平伸缩

大型互动系统的特点是用户基数大,而且无法预测将来的用户数会达到什么水平,因此设计之初就考虑采用水平伸缩方案。当用户规模增长后,不需要修改系统的源代码,只需要增加普通的PC或PC服务器,部署更多的分布式服务,就可以扩充系统的容量,提升系统的性能。

系统的整体架构上,各个关键服务都支持水平伸缩,包括转发服务器、分发服务器、消息服务器。

客户端随机选择转发服务器发布消息。当用户数增加,要求转发服务器集群提供更高的并发,更快的响应时间时,可以部署更多的转发服务器,降低单个服务器的负载,提升响应时间。

用户ID与分发服务器进行绑定,绑定的算法有静态绑定算法、哈希求余算法、一致性哈希算法等,这些算法的复杂度依次提高,而进行依次下降,但服务器数量扩展的友好型也依次提高。根据好友动态系统用户ID线性增长的特点,最终采用简单有效的静态绑定算法。转发服务器将用户的消息发布到该用户绑定的分发服务器。当用户数增加,要求分发服务器集群提供更高的并发,更快的响应时间时,可以部署更多的分发服务器,这样单个分发服务器承载的用户数没有变化,响应时间也不会受到影响。

用户ID与消息服务器进行绑定,仍然采用静态绑定,一个消息服务器只为某个号段的用户提供服务。当新注册用户增加时,最后一个服务器的压力会不断增加,再增加一台服务器将新注册的用户号段划分到这个服务器,从而控制最后一台服务器的压力;当某个号段的用户活跃程度显著增加时,可以将该号段重新划分,进行负载均衡。

3.2.2 消息队列

队列使系统的各个模块之间实现松耦合,将同步业务调用转化为异步处理过程。在系统架构方面,关键业务模块之间都是通过消息队列实现异步消息处理,如图2所示。

在此架构中,因为各个服务只关心与其交换的消息队列,中间处理的各个服务的故障都不会影响都之前或之后的业务处理,而且服务恢复后能够继续提供服务。因此消息中间件的稳定性和性能是衡量中间件的关键指标。Kestrel是twitter开源的消息队列中间件[4],在twit⁃ter以及大量网站中经过实践检验,稳定性和性能都非常不错,内部测试也证明可以满足项目的需求,因此项目组选择kestrel作为消息中间件。而且Kestrel采用mem⁃cached兼容的协议,这也是大多消息队列中间件支持的协议接口,即使系统运行中发现Kestrel队列存在问题,也可以快速迁移到其他消息中间件。

各个服务模块采用无状态的服务模式,即服务模块每次都根据消息队列中的消息进行处理,这样即使遇到一些恶意的非法消息也能够正常处理,不会影响其他消息的处理。

此外消息队列还有蓄洪的作用。好友动态系统中,当发生特殊事件时用户会有一个爆发效应,比如世界杯期间活跃用户数会有爆炸式增长。消息队列的作用是,当洪峰到来时,快速容纳大量请求,从而不影响队列前端应用的性能,然后队列后端的应用慢慢处理队列中的消息。对于动态系统来说,只是延迟了动态被好友感知的时间,而且这种延迟好友是很难感知的,但对系统的负载能力的提升非常明显。

3.2.3 缓存机制

众所周知,内存的访问速度远远高于硬盘的访问速度,因此缓存的效果对网站的响应时间至关重要。缓存将系统中需要大量计算或频繁访问的资源由硬盘转移到内存中,降低系统IO的处理的时间,从而提高访问的响应时间。

系统架构方面缓存主要应用在分发服务器和消息服务器。

分发服务器中,每个消息的处理都需要用户的好友关系,这些信息存储在好友关系数据库中,如果每次处理都直接访问数据库,每秒大概需要2000次并发的数据库访问,这样的压力对数据库来说是致命的,很快就会发现已经连不上数据库,而且查询数据库的响应时间也会很长。因此将好友关系加载到内存中,将极大地提升查询性能,而且好友关系的缓存命中率也决定了分发服务器的消息处理性能。

为用户关系缓冲设计了两个功能模块,缓存服务器集群和用户关系变更通知服务。前者将好友关系数据库中的好友信息缓存在内存中;后者在好友关系数据库发生变更时,及时将变更的信息更新到缓存服务器集群。

消息服务器一方面接收分发服务器写入的消息,另一方面响应客户端的查询消息,而且两者都存在大量的并购,对响应时间也有一定要求,因此都设计了缓存机制。

为了提高分发服务器写入消息的性能,消息服务器在接收消息后立即将消息写入内部的消息缓存队列中,而不用等待消息合并到用户的消息队列中。

在大量注册用户中,有一部分用户比较活跃,另外一部分用户相对沉寂,客户端的查询请求大并发是活跃用户的请求,而且活跃用户往往会连续发送多次查询请求,因此消息服务器会缓存活跃用户的消息队列。对活跃用户判断是否准确也决定了缓存的效果,那么如何判断活跃用户?本文采用最近访问作为判断依据,即如果用户访问时用户的消息队列不在内存中,那么访问过后将会被加载到内存中,下次访问时直接从内存中读取。当内存不足时,将会替换内存中最长时间未被访问的内容。

3.2.4 数据格式

数据采用互联网广泛应用的JSON格式,在流水线的处理过程中数据格式也在不断发生变化。

客户端采用转发服务器的数据格式发送消息,格式如图3所示。

分发服务器将转发服务器的数据结构转换成分发服务器数据机构,并分发到消息服务器,格式如图4所示。

分发服务器的消息经消息服务器处理后,转换成消息服务器的数据格式,格式如图5所示。

3.2.5 协议接口

各个服务模块主要提供对动态消息读写、删除接口,而且动态消息的排序、合并都按内部确定的合并规则执行。此外,服务器内部状态的监视接口为服务器状态监视提供了方便,控制接口则让服务升级更加安全。

通信协议有很多选择,如支持REST架构风格的HTTP协议、SOAP协议和memcached协议,即时通信领域的XMPP协议等,但最终本文选择了memcached协议,其一该协议支持REST架构风格,适合于资源访问类服务;其二该协议支持广泛的客户端开发语言,如Java、C++、Php、Python、Perl等;其三,系统中消息队列和内存缓存中间件支持该协议,因此采用memcached协议的开发成本和风险是最小的。

4 核心服务的设计与实现

4.1 转发服务器

转发服务器的主要难点在于支持大量客户端并发访问。Apache Mina是一个Java NIO框架,为用户开发高性能和高扩展的网络应用服务器带来的方便,因此本文选择基于Mina框架设计转发服务器。本文的测试数据显示,基于Mina的转发服务器可以支持每秒1000次网络消息处理,通过接收缓冲区大小还可以进一步提高消息的吞吐量。

4.2 分发服务器

分发服务器中最重要的设计是消息处理扩展框架,支持灵活的业务扩展。

消息的预处理框架,需要针对每种业务类型进行单独的处理,并且要考虑以后新增业务类型或修改业务处理规则时,尽可能不影响系统其他组件。因此消息处理扩展框架基于OSGi框架进行设计。

OSGi又叫做Java语言动态模块系统[5-6],它为模块化应用的开发定义了一个基础架构。在OSGi中,软件是以Bundle的形式发布的。一个Bundle由Java类和其他资源构成,它可为其他的Bundle提供服务,也可以导入其他Bundle中的Java包。

消息处理流程如图6所示,各个Business Processor组织成一个处理链,有Message Processor Center进行调度,并根据当前Business Processor的处理返回值决定下一步调用哪个Processor,最后一个Business Processor将处理后的消息写入输出消息队列。

Business Processor支持两种范围类型:Next、Term和ProcessorID。 当 Business Processor返 回 Next,Message Processor Center调用预定义的下一个Business Proces⁃sor;当 Business Processor返回 Term,Message Processor Center终止当前消息处理链,处理下一条消息。

消息处理过程中,Business Processor可以将消息输出到其他系统,并不影响下一步业务的处理;也可以将消息丢弃,从而实现消息过滤器的作用。

4.3 消息服务器

4.3.1 动态消息数据库

动态消息数据库通过分库来优化性能,包括缓存库、索引库和消息库。

消息分发时,首先将消息分发到缓存库,然后由消息处理进程分批处理;而在动态查询时,首先访问索引库获取用户的消息队列(我的动态队列或好友动态队列)获取动态的索引,然后根据动态ID从消息库中获取动态消息,并将结果合并返回给用户。

采用增加消息缓存库主要出于两方面考虑,一方面隔离了分发系统和消息服务器,分发服务器发布消息与消息服务器处理消息可以异步处理,只需要将消息发布到缓存库,而不必等待消息服务器处理消息,提高分发系统的性能。另一方面缓存库在不影响消息读写性能的情况下,又保证了消息可靠性,消息被持久化保存在缓存库。

将索引库和消息库分离,降低了推模式下消息数据库中重复消息的数量。一个动态的索引大约23~42 byte,而一个动态消息平均大小是1 kbyte,这样一个消息库只保存一份动态消息,每个消息将节约980 byte。比如一个名人在消息服务器上的好友10万个,那么该名人每条动态将节约98 Mbyte数据。

4.3.2 备份与迁移

采用NoSQL数据库带来了高性能,同时也要面临NoSQL数据库备份迁移工具缺乏的现状,为此开发了针对动态消息数据库的备份和迁移工具。

备份工具支持动态消息数据库热备份、增量备份,因此设置计划任务每天执行本机备份,并将备份数据自动迁移到备份服务器。消息服务器故障时,可以快速部署消息服务器应用,并从备份服务器下载相应的动态消息数据库,快速恢复服务。

迁移工具支持根据用户空间进行消息数据库合并。由于用户ID与消息数据库采用静态绑定策略,重新划分用户空间将涉及到历史数据的迁移,比如系统运行一段时间后,发现某些消息服务器中活跃用户数少,负载小,可以将这些消息服务器合并成一台消息服务器。

5 小结

系统测试数据显示,好友动态系统架构能够满足大量用户并发访问、响应时间较快,而且架构能够通过水平伸缩快速扩容系统支持用户规模,在稳定性方面单个服务或硬件的故障对系统影响较小或只影响一定范围的用户。到目前为止,好友动态系统已经上线运行两个多月,表现稳定可靠,友好地支撑了互动平台好友动态的分发。

[1]CNNIC第27次互联网报告:个人互联网应用状况[EB/OL].(2011-01-19)[2011-04-01].http://it.people.com.cn/GB/119390/118340/212787/212790/13765052.html.

[2]中国互联网协会.中国Web2.0发展状况和调查报告[R].北京:中国互联网协会,2006.

[3]郭欣.构建高性能Web站点[M].北京:电子工业出版社,2009.

[4]邓侃.解剖Twitter:Twitter系统架构设计分析[EB/OL].(2010-03-27)[2011-04-01].http://www.tektalk.org.

[5]基于OSGi实现分布式服务框架历程[EB/OL].(2008-01-14)[2011-02-01].http://www.blogjava.net/BlueDavy/archive/2008/01/14/175054.html.

[6]Oracle.Oracle Berkeley DB Java editionhigh availability-large configuration and scalability testing[EB/OL].[2011-03-25].http://www.oracle.com/technetwork/database/berkeleydb/bdb-je-highavailabilitywhitepaper--129298.pdf.

猜你喜欢
队列好友消息
队列里的小秘密
基于多队列切换的SDN拥塞控制*
一张图看5G消息
属羊
在队列里
删除好友
丰田加速驶入自动驾驶队列
消息
消息
消息