社交产品后端架构设计.docx
- 文档编号:8279771
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:7
- 大小:110.26KB
社交产品后端架构设计.docx
《社交产品后端架构设计.docx》由会员分享,可在线阅读,更多相关《社交产品后端架构设计.docx(7页珍藏版)》请在冰豆网上搜索。
社交产品后端架构设计
社交产品后端架构设计
LT
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,这是一个分布式的,容错和高度可扩展的系统。
它可以负责生成索引的逻辑。
索引系统:
由于Lucene受欢迎程度和其性能,因此,Lucene是一个显而易见的好选择;它的性能是无与伦比的。
我们可以使用SolrCloud。
它已经透明的支持分片,复制和读写方面的容错。
队列&消息推送
每次我们的应用程序被触发一个事件,我们将需要向他/她的追随者/朋友推送消息。
重要的是,我们的系统不能错过任何这些信息,更重要的是,能够在发生故障时恢复这些事件。
为了达到这些要求,我们必须寻找一个队列解决方案。
我们可以使用ActiveMQ,这是最可靠的队列软件。
它支持集群的高可用性,支持分布式队列。
消息推送是另一个领域,要把通知发送给我们的用户。
在这里我们需要估计一下规模。
我们应该准备好支持像nps这样上亿的规模。
这里有许多选择,但也许pyapns、CommandIQ和APP Booster才是最流行的。
我们需要自己管理一些事情,特别是要保证消息传递可靠性,即使用户的设备处于离线状态。
我建议我们实现一个双向的系统,保持状态的通知,并在后台持久化到磁盘。
所以每次一个通知失败时,它的状态都被处理并标上状态码,添加到重试队列中。
最后,当通知被送达,移出重试出列。
缓存策略
像我们这样的系统,我们的目标是使其支撑十亿RPS,因此,好的缓存策略是极重要的。
我们的业务逻辑会在多层缓存中,并且能够智能的清除失效缓存。
让我们看看最顶层缓存。
应用层缓存(内容缓存):
为了最大限度地减少缓存未命中,并确保缓存始终是最新的数据,我们必须寻找一个从未过期的缓存,并始终保持数据。
这基本上意味着在一般使用情况下,我们将永远不用查询我们的数据库,因此节省了大量的资源。
我们还应该确保我们缓存的数据总是以一种不需要额外处理的格式,随时准备好呈现。
这基本上意味着将我们的在线负载转换为离线负载,从而节省了延迟。
要做到这一点,我们必须确保每一次的内容被输入到系统中,我们要做两件事情:
a)原内容是非规格化形式保存在缓存。
为了安全起见,我们将永远设置一个有效的期限。
b)原内容也写在我们的数据存储区中。
我们使用Redis来做这个缓存,Redis是一种具有良好故障恢复的内存缓存。
它具有高度的可扩展性,较新的版本透明的支持了数据分片。
支持主从节点配置。
最好的部分是,我们能够保存任何格式的数据,这使得它很容易做增量写,这是至关重要的,我们支持内容feeds
还值得指出的是,我们需要支持对大内容对象进行大量的读 - 修改 - 写操作和少量读,Redis是已知的,对这些操作在性能方面是最好的。
缓存代理:
反向代理层的缓存也是至关重要的。
它有助于减少直接请求我们服务器的负载,从而减少延迟。
为了使代理服务器缓存更有效,需要正确设置HTTP响应头。
代理服务器有很多种,但最受欢迎的是nginx和ATS。
二级缓存(代码级缓存):
这是一个实体数据的本地存储,用于提高应用程序的性能。
它有助于通过减少昂贵的数据库调用以提高性能,保持实体数据的本地化。
EhCache是一个很受欢迎的选择。
客户端缓存:
这实际上是设备或浏览器缓存。
所有静态项目都应该尽可能地缓存。
如果API响应HTTP缓存头已经被合理设置,很多相关资源的内容都会被缓存。
我们应确保其如预期的那样工作。
除此之外,我们应该尽可能缓存其他内容,可以使用设备自己的内存,或使用SQLite。
所有昂贵的对象都应该缓存。
例如NSDateFormatter和NSCalendar,初始化缓慢,应该尽可能多的重用。
iOS Lot可以调整和应用,但是在这里,它是超出我们的研究范围。
数据压缩
考虑到我们的用户主要是要处理大量的图像和视频,需要下载大量的数据,所以优化下载大小是非常重要的。
它将节省用户的数据量,提高应用程序的性能体验。
其他要考虑的方面,如我们的网络,我们的用户主要是在非LTE网络,使用2.5G或3G,需要考虑带宽,并且连接通常是不可靠的,数据使用成本高。
在这种情况下,智能压缩是一个关键的需求。
但是实际上图像压缩和视频压缩并不是想象中那么直接简单,往往需要进行深入的分析。
我们所处理的图像和视频,可以无损和有损,这取决于用户的设备质量。
所以我建议使用多个压缩技术来处理这种情况。
在这种情况下,我们可以尝试帧内压缩和帧间压缩技术。
但总的来说我们可以采用zpaq和fp8来应对所有压缩需求。
我们也可以尝试非常适合我们业务场景的WebP。
一般情况下,我们的API会使用gzip,我们API response总是经过gzip压缩过的。
数据转码
考虑到我们需要处理多个设备,多个操作系统和屏幕分辨率,我们的内容存储和处理时应与设备无关。
但服务层应该基于用户的设备,理解并调整响应的内容。
所以,图像和视频的转码是必不可少的。
我们的应用程序需要收集设备的配置,如内存、编码和屏幕分辨率,作为API的上下文。
我们的API应该使用此上下文来修改/选择内容版本。
基于我们接受到的设备上下文,我们可以预先准备好一些最频繁被请求的版本的内容。
我们可以使用FFMPEG转码,FFMPEG是最可靠和应用最广的转码框架。
我们可以修改FFMPEG,使其满足我们的需求。
转码是在数据输入端完成的。
传输协议
考虑到我们的网络场景(非LTE,不可靠的连接等),关键是要尽可能地节省资源,使通信尽可能地轻量。
我建议我们所有的HTTP请求都使用okhttp客户端,okhttp使用SPDY协议,能够弹性处理连接失败,透明恢复。
我们所有的通讯需求,都应该切换到MQTT,这是一个轻量级的机器对机器的连接协议。
安全问题
保证我们应用程序的安全是非常重要的。
我们整体架构都要有安全上的考虑。
我在这里只谈架构为满足安全要求做出的改变,我们不谈实施过程的改变。
这里是一些必须添加到架构里的:
1. 我们所有的用户数据必须加密。
MongoDB和Neo4j已经支持存储加密。
在这基础上,我们可以决定加密哪些用户关键信息。
所有与数据库相关的传输调用必须启用加密。
2. 安全套接字层:
所有代理服务器的访问都应该使用SSLed。
代理服务器可以充当SSL终止点。
3. 我们所有的API端点应该运行在非默认端口,并且必须实现OAuth。
4. 所有的DB读取都应该通过Rest endpoints。
5. 有关密码的配置必须特殊处理。
密码必须hashed,文件应该被限制只能在应用启动时读取。
这允许我们通过文件系统权限来控制应用程序身份实例。
只有应用程序用户可以读,但不能写,其他用户不可以读取。
所有类似的配置都要用keydb打包并需要密码。
组件
以下是我们架构用到的组件:
1. 负载均衡器:
这层是用来转发所有对代理服务器的请求,基于定制的策略。
这一层也将有助于我们通过基于容量重定向的方式来保障可用性。
2. 代理服务器:
所有即将到来的调用都必须以这里为入口。
这也是我们SSL的终止点。
它缓存所有基于策略定义的HTTP请求。
FE层:
该层运行一个node服务器。
3. 数据输入引擎:
这个组件涉及所有内容的输入,它做了一系列的工作:
非规范化模型,转码,缓存等。
将来如果可以的话,所有内容的处理,都可以在这里完成。
4. Rest服务:
这层负责与所有DB交互,并返回数据。
它的访问是受OAuth保护的。
这可以用Tomcat容器以及edge缓存来实现。
5. 事件处理:
这层处理所有的事件,主要负责分发的功能。
它读取ActiveMQ并使用通知引擎生成通知。
6. 推荐引擎:
这个组件通过分析所有收集到的用户动态来做推荐。
根据实际收集到的动态,我们可以部署各种基于亲和力的算法。
我们可以使用Apache Mahout提供的各种算法接口
系统的逻辑视图:
结语
本篇文章更像是对关键组件高抽象层次的分析。
如果需要实施的建议,可以做一个阶段性的方式,但如果我们需要扩展性并支持真正的用例,必须遵循我提出的这些规范。
我没有提起任何设计领域相关的内容。
这只是设计阶段,需要更深入的分析和了解系统的当前状态。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 社交 产品 后端 架构 设计