社交产品后端架构设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
社交产品后端架构设计
摘要:本篇文章会向读者展示几个架构设计的关键点,使一个社交应用能够成为真正的下一代社交产品。但这只是设计阶段,需要更深入的分析和了解系统的当前状态。
本篇文章会向读者展示几个架构设计的关键点,使一个社交应用能够成为真正的下一代社交产品。以下几个属性将会影响到架构的设计:
a)可用性
b)可扩展性
c)性能和灵活性可扩展
目标
a)确保用户的内容数据能够很方便的被其他用户发现和获取.
b)确保内容推送是相关的,不仅在语义上,也是从用户设备的角度。
c)确保实时更新生成、推送和分析。
d)尽可能地节省用户的资源。
e)不论服务器负载变化如何,用户体验应保持不变。
f)确保应用整体上是安全的
总之,我们要处理一个相当大的挑战,我们必须处理不断扩大的海量用户生成的内容数据,不断增长的用户,和一个不断迭代的新项目,同时必须确保性能足够出色。为了应对上述的挑战,我们必须学习架构某些关键的元素,这将影响到系统的设计。以下是一些关键的决定和分析。
数据存储
数据和数据模型的存储是一个好架构的关键设计之一。一个社交产品应该能够处理多种类型的数据,因此首先得充分分析数据并透彻理解,之后再设计数据模型和数据存储。
第一步,我们要确定哪些数据是经常查询的热点数据,哪些不是经常需要的那些数据(如归档数据用于分析)。对于高频访问的数据,它必须总是可用,能够快速读写和水平可扩展。目前我们所有业务场景使用的都是MySQL,即使我们
的用例不一定需要使用关系数据库系统。随着我们数据的增长,我们的读写将成为我们应用程序性能瓶颈。我们应该为每秒钟数十亿的查询做好准备。
让我们对我们的数据进行分类:
a)主要的数据或静态形式的数据,如用户资料
b)语义数据
c)用户产生的内容数据
d)会话数据
找到一个高效的数据存储方式,满足所有这些类型的数据,真的很难。因此,我们将为每个数据类型选择特定的数据存储方式。
静态数据:对于静态数据,最好是选择基于文档的存储方式,其中键和值都是可查询的。我们可以选择如MongoDB这种文档型数据库,选择MongoDB最大的优势是它提供了在文档级别的ACID。
MongoDB可以在多个分布式数据中心的范围内进行缩放。它将允许我们使用副本集来保持冗余,从而解决我们的可用性问题。
数据分片是一个重要的考虑因素,数据分片可以确保数据的扩展与查询速度。幸运的是,MongoDB透明的支持了数据分片。
关联的或关系数据(核心数据):我们大部分数据本质上是关联的,例如,A 是B的朋友,C是A和B的朋友,这样高度语义的数据最适合图处理模型。我们应将这样的数据存储在图数据库,如 Neo4j。这样做的优势很明显;我们可以存储所有关联数据的节点,从而节省了计算数据之间连接关系的额外步骤。图形数据模型也将有助于我们捕捉到属性之间的关系。当试图探索关联数据时,丰富的属性关系绝对是关键。图数据库支持ACID规则以及自动索引。
再次声明,我们的要求是达到可用性和可扩展性。我们可能会有成百上千的并发事务,同时写入数据库,同时会有数百和数千查询请求。它应该能够处理一个数据集上的许多字节,超过十亿每秒的读取速度。
我们将会需要一个系统,帮助我们自动伸缩写入和读取。其他需要考虑的因素是数据分片,这是系统可伸缩的关键。
Neo4j已经被设计为可水平扩展,并且有数据冗余功能来保证可用性。但到目前为止,它还不支持数据分片。我们可能需要更多的分析,才能做出抉择。其他可供选择的图数据库有FlockDB、AllegroGraph和InfiniteGraph。
二进制数据(UGC):我们还必须处理大量的与用户相关的二进制数据。处理二进制数据不太容易,考虑到它们的规模。上面已经讨论过,我们需要一个系统可
以运行相当高的性能,秒级别(尖峰),当决定在哪里存储时,可伸缩和可用性是最关键的素。我们不能依靠磁盘文件系统来存储我们的二进制数据。我们必须考虑可用性和可扩展性,文件系统的缓存会消耗大量的CPU。相反的,我们应该依靠一个现有的可用的系统,例如亚马逊S3,S3是非常流行的对象存储系统,具有可用性和弹性存储。
我们也可以考虑谷歌云存储或Rackspace的云文件等,但S3似乎是明显的赢家,它提供更优质的服务。
S3 已经支持数据分区。S3能够水平伸缩,冷热数据拆分,并根据keys分区。但是只实现存储数据是不够的,与这些内容相关的元数据必须能够被搜索,并且搜索可伸缩,速度够快。我们也可以尝试一些新的东西,如图像的自动维度识别,基于内容自动打标签等。这是一个潜在的知识产权领域。我们将在文章的索引部分讨论索引需求。但现在,让我们只需要注意,我们将用标识符存储内容,并且在某个地方做了索引。似乎亚马逊的S3最适合这种情况。
Session数据
正确的认识和理解session数据是非常重要的。Session数据将帮助我们保持用户的状态。Session数据必须使用与服务器无关的方式,方便我们服务端可伸缩部署。这将有助于保持我们的设计灵活,确保session不会绑定到特定的节点或服务器。
我们得用一种新的方式来更新用户的实际session,如果用户的session终止,我们仍然可以帮助用户从一个地方,他离开的地方重新恢复信息。
这是特别重要的,在我们的场景中,连接是不可靠的,数据丢包是很正常的。数据必须能够被跨节点访问,因此需要可用性和可扩展性。我们可以很好的使用MongoDB本身来保存数据。后来,我们想转移到纯粹的键值存储,如Redis。
注:所有推荐和离线作业都应该只运行在非服务节点上。
索引
索引是我们系统的关键。用户可以搜索任何内容,这是我们的主要用例之一。为了提升搜索性能,我们必须非常认真地对待索引。这里有两点需要考虑:首先是,创建索引本身,然后就是索引系统本身。
为了做一个有意义的搜索系统,我们必须设计一个实时索引,针对一段时间窗口的实时数据进行处理。首先,我们可以写一个非常简单的系统,对产生的内容数据做倒排索引。后来,随着输入数据的增加,我们可以方便地用实时数据处理引擎取代它,如Apache的Storm,这是一个分布式的,容错和高度可扩展的系统。它可以负责生成索引的逻辑。