社交产品后端架构设计

本篇文章会向读者展示几个架构设计的关键点,使一个社交应用能够成为真正的下一代社交产品。以下几个属性将会影响到架构的设计:

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,这是一个分布式的,容错和高度可扩展的系统。它可以负责生成索引的逻辑。

索引系统:由于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提供的各种算法接口

系统的逻辑视图:

结语

本篇文章更像是对关键组件高抽象层次的分析。如果需要实施的建议,可以做一个阶段性的方式,但如果我们需要扩展性并支持真正的用例,必须遵循我提出的这些规范。我没有提起任何设计领域相关的内容。这只是设计阶段,需要更深入的分析和了解系统的当前状态。

来自HackerNews的评论:https://news.ycombinator.com/item?id=9930752

原文链接:Architecting Backend For A Social Product(译者/施聪羽 审校/朱正贵 责编/仲浩 )

原文地址:https://www.cnblogs.com/dwxt/p/8983860.html

时间: 2024-09-28 10:08:41

社交产品后端架构设计的相关文章

app后端架构设计(转)

(1)Restful设计原则 Restful风格:RESTfu设计原则,它被Roy Felding提出(在他的”基于网络的软件架构“论文中第五章).而REST的核心原则是将你的API拆分为逻辑上的资源.这些资源通过http被操作(GET ,POST,PUT,DELETE). 但现在看,一般的操作只有两种:GET ,POST. 这个设计原则最简单的应用就是根据object而不是页面来设计api.最开始的时候,app的一个页面需要什么数据,api就返回什么数据.结果随着app的UI不断改版,需要的数

我的架构经验系列文章 - 后端架构 - 设计层面

设计层面: 分层架构 分层架构是项目设计中很重要的一点,从根本的目的上来说就是为了职责的分离.最经典的三层架构,到四层五层六层,甚至有人开玩笑说十八层的分层,根据项目的需要可以分不同的层.这里说的层其实是逻辑层,从物理层的角度来说也有三层.四层五层的分层架构.之所以三层架构这么流行是因为它的分层把大的关注点进行了分离,层数恰到好处,表现层.业务逻辑层和数据访问层,分别处理面向用户呈现的.面向逻辑处理的和面向数据库存取数据的三大关注点.UI前端框架最新力作!有奖试读! 在分层架构中除了分层之外还需

软件产品线架构设计

摘要 1.介绍行业应用软件背景,对比汽车行业和软件行业. 2.概念导入,从软件项目逐步引申到软件产品.软件产品线.软件平台.软件生产线等概念 3.管理和运营软件产品线 4.组织和构建一条软件生产线 5.提高生产力(Merge平台) 参考资料: 1. 软件产品线设计思想. 2. 关于平台的设计参考: 认识大众汽车平台 https://wenku.baidu.com/view/52118fe171fe910ef12df8d8.html MQB.MLB.MEB 大众家的平台 http://www.pc

从概念到底层技术,一文看懂区块链架构设计

转自:http://www.8btc.com/ebook-blockchain https://blog.csdn.net/lucky_greenegg/article/details/52821924 前言 区块链作为一种架构设计的实现,与基础语言或平台等差别较大.区块链是加密货币背后的技术,是当下与VR虚拟现实等比肩的热门技术之一,本身不是新技术,类似Ajax,可以说它是一种技术架构,所以我们从架构设计的角度谈谈区块链的技术实现. 无论你擅长什么编程语言,都能够参考这种设计去实现一款区块链产

架构设计:前后端分离之Web前端架构设计

在前面的文章里我谈到了前后端分离的一些看法,这个看法是从宏观的角度来思考的,没有具体的落地实现,今天我将延续上篇文章的主题,从纯前端的架构设计角度谈谈前后端分离的一种具体实现方案,该方案和我原来设想有了很大的变化,但是核心思想没变,就是控制层是属于Web前端的. 在以前文章里我说道前后端分离的核心在于把mvc的控制层归为前端的一部分,原方案的构想在实际的生产开发里很难做到,我觉得核心还是控制层和视图层的技术异构性,这样后果使得系统改造牵涉面太大,导致在项目团队里,沟通.协调以及管理成本相对较高,

5.2.产品设计之产品架构设计

了解市场→了解需求→产品设计→产品运营 产品设计:产品理念,产品方案及规划,产品架构设计,交互设计,原型及需求,项目管理,验收及发布,用户体验,实战点评. 综述:01.产品规划 产品设计理念:02.产品设计基本理念 产品设计的术:03.产品结构.04.交互原型.05.需求设计 项目管理:06.产品研发过程管理.07.产品发布及反馈 08.用户体验 产品结构: 01.课程回顾与作业点评 02.解读产品结构 03.常见产品结构 04.常见的构建方式 01.课程回顾与作业点评 02.解读产品结构 用户

mysql性能调优与架构设计笔记

1.mysql基本介绍 mysql支持多线程高并发的关系型数据库; 数据库存储引擎InnoDB.MyISAM; mysql快速崛起的原因就是他是开源的; 性能一直是mysql自豪的一大特点; 2.mysql架构组成 麻雀虽小五脏俱全,mysql虽然简单但其内部结构并不简单; mysql物理文件组成之日志文件: 错误日志error log这里记录mysql运行时严重的警告和错误,以及mysql启动和关闭的日志信息 二进制日志 binary log 记录mysql运行时所有的query和query执

.NET应用架构设计—用户端的防腐层作用及设计

阅读目录: 1.背景介绍 2.SOA架构下的显示端架构腐化 3.有效使用防腐层来隔离碎片服务导致显示端逻辑腐烂 4.剥离服务调用的技术组件让其依赖接口 5.将服务的DTO与显示端的ViewModel之间的转换放入防腐层 5.1.转换逻辑过程化,直接写在防腐层的方法中 5.2.转换逻辑对象化,建立起封装.重用结构,防止进一步腐化 6.防腐层的两种依赖倒置设计方法 6.1.事件驱动(防腐层监听显示逻辑事件) 6.2.依赖注入接口 7.总结 1.背景介绍 随着现在的企业应用架构都在向着SOA方向转变,

某移动社交应用服务端架构浅析

原文http://blog.csdn.net/lvjin110/article/details/12958463 TA是一款是基于地理位置的社交应用,帮助你与你不认识的.但就在附近的人进行即时沟通.TA是一款陌生人约会交友应用,无论你在银行排队.乘坐公交.咖啡厅或公园散步等任何地方,随时随地就能与附近有趣的陌生人进行即时沟通.分享照片.约会和交友-- 转眼间,离开该研发团队快半年了,在此期间不少网友问到后端架构,及技术细节.出于技术分享为目的,现将服务端架构及设计思路分享给大家. 如下图: 上图