随着国内移动互联网的逐渐深化,人手一台智能设备成为标配,每人每天都在产生大量的数据。这些数据对于企业来说,如果后台架构能轻松承担,其对于业务来说就是价值;反之如果无法承担这种数据体量,那么对于业务而言就是风险。
因此在现阶段,构建一套强大的、健壮的、可扩展性强的、能够支撑亿级体量的后台架构,对于企业来说是其“必需品”。就在昨天 5 月 14 日,InfoQ 十分荣幸邀请到了极光推送后台技术负责人曾振波老师,以线上直播形式,以极光的真实实践为引,全面阐述了极光是如何在解决其 380 亿注册用户的信息存储问题、面对日均百亿级别推送需求的同时,来实现其后台架构的高性能运转。
以下为曾振波老师的分享的重点内容,经过 InfoQ 编辑整理。
1一款优秀的架构,就是要满足业务和用户的所有需求
搭建企业级后台架构,就要搞明白架构在企业业务中能起到怎样的作用。以极光推送的后台架构为例,其任务就是要满足每一名开发者的请求能够得到及时有效的响应。
首先要找到用户在使用过程中可能存在体验问题的点,要从用户使用产品整个流程出发,以极光为例,其整个流程是:用户发起请求 -API 对用户权限进行验证 - 从多维度数据中筛选出目标用户 - 从分布式存储集群中查询用户信息数据 - 选择对应的推送通道 - 实现消息推送。
那么极光的后台架构作用就是在上述流程过程中,满足用户在使用推送过程中的实时性和触达率的要求。那这个架构的目标就很明确了,接下来就是要分解在架构设计过程中将会面临的棘手的多重挑战。
首先是用户需求,极光的用户就是一线开发者,那么开发者使用推送的诉求就是对消息的实时性和消息触达率的准确性,如开发消息推送时候能不能及时的推送到目标设备,这个推送任务触达率是多少等。
其次就是业务需求,这也是本次曾振波老师分享的重中之重。要明确构建符合企业业务需求的架构,要面临哪些技术层面的挑战?那这就是在做架构设计时,需要重点考虑的方向。以极光为例,其架构主要面临以下三重的业务挑战。
首先是海量数据体量对存储造成的压力,极光拥有几百亿的用户数据,在存储的同时还需要实时推送各个维度的数据,并且这些数据是在持续增加的。如何存储如此大体量的数据?如何在大量数据集中进行增删改查,对后台数据架构来说是很大的一个挑战。
其次是高并发和峰值效应对架构的影响愈发明显,每一款产品都有其特定的用户使用时长高发期,极光也不例外。中午 12 点和晚 8 点 - 晚 11 点,这两个时间段是开发者使用极光推送能力的高峰期。这种时间段往往会产生大量的请求,后台服务往往需要同时处理比往常多达二十倍甚至更多的数据请求,因此需要后台架构能够撑起并提供相对稳定的服务。
最后是移动网络下的亿级长连接管理,面对移动互联网应用,极光的 SDK 产品每天都被曝光在在移动网络的环境下。此类环境不比 PC 端,“不稳定”可以说是移动网络的一个典型特征,经常会涉及到无法访问、弱网以及网络抖动的各种问题,因此需要尽量保证 SDK 能够稳定的连接到极光的后台推送架构之上。
2海量数据存储所带来的架构压力
业务挑战从开发者发起推送请求之时就已经开始了。首先后台架构要能够快速对消息系统内部的数据进行梳理并发送到对应的终端设备之上。上万名用户的需求很简单,百万、千万的需求在当下大环境中也不难实现,但是如果面对的是几百亿的数据体量呢?这就对极光推送后台架构提出了更高的需求。
这种体量的业务,往往会对后台架构提出更多要求,如存储资源、高性能、高可用、可扩展、运维成本等等。面对上面这些问题,极光提出了一系列解决方案。
存储介质的选择
极光采用了 MySQL、Redis、PIKA、CouchBase 以及定制化的一个自研存储,会根据 OPS 数据量和数据特性,结合存储系统本身的特性来选择所对应存储系统。
Redis 的性能很高,但是集群能力很弱,单线程处理很容易造成命令性堵塞;
CouchBase 性能很高,集群能力优势明显,但缺点是对资源的消耗过大;
PIKA 本身是用磁盘作为存储的,因此性能比较低,但相对的成本也较低;
MySQL 主要用于存储几百亿的用户数据,主要负责基础数据的插入和更新。
数据库优化方式
为了提高数据的存储效率,我们还对索引还有 SQL 语句进行了优化,如尽量避免“字符字段”作为主键等。
数据分片存储方式
极光数据存储采用的是分片 + 多副本的存储架构,这种结构适用于 MySQL 或其它第三方存储系统。以自研存储为例,基于 ICE 框架构造出 SDK 用户的状态中心,并将其分为管理节点和数据节点,管理节点主要负责分片策略以及分片的路由信息管理。在数据走到管理节点后,会根据分片策略将数据分发到一个个对应的数据分片,其中包含多个副本节点,这种架构既能做到分片处理数据,也能够利用多个副本分散处理请求,极大提升了数据存储能力。
读写分离策略
极光采用一主多从、写主读从的策略,进行读写分离,只要能确保数据一致性的目的即可。并且极光大量采用批量的数据处理方式,例如说合并查询、合并写 Pipeline 等等。减少接口的调用次数还有请求在网络上面的一个传输时间,提升极光系统的整体性能。
对于非活跃数据的处理
极光的系统经过了几年的积累,目前数据已达到百亿级别,这当中有很多数据是不太活跃的,对于存储资源来说是极大的浪费,并且大量的非活跃数据也影响到了后台系统的整体性能,因此需要对活跃数据和非活跃数据进行区分处理,使用不同的存储进行分开保存。同时注意活跃数据和非活跃数据的转换机制,每家企业都有自己的衡量标准。对于不活跃的数据,极光会把这类用户关联在各个维度的数据之下,再全部都转化为非活跃的一个数据。
3高并发与业务峰值对架构的影响
极光的服务是 24 小时的,也就意味着每分每秒都有大量用户在同时使用极光的服务。从时间上来看,一般来说中午和晚上这两个时间段是极光的业务高峰期。从业务角度来看,开发者使用广播和标签对于业务峰值的影响最高。期间业务峰值和低谷期的差距非常大,甚至多达几十倍。
(极光业务峰值)
这对于无论是存储资源的访问,还是对于计算资源的使用,期间都存在非常大的落差。但是作为服务方,要在业务高峰期时保证服务质量,提供稳定服务,并且不同业务之间不能产生影响,因此对系统架构整体的能力要求就很高。
极光采用了以下几种解决方案
业务隔离
对于极光而言,影响较大的业务类型是广播和标签推送。可以将广播和标签这类目标数较多的推送进行单独隔离,避免影响到其他业务类型的推送。
存储资源隔离
对特殊的热点数据进行隔离存储。一般来说当开发者发起推送请求后,系统内部会查询大量的数据。但是如果每个数据都去查的话,会极大影响交付效率,无法确保消息的实时性。因此需要提前存储一些热点数据。
因为在极光的业务系统中会有部分开发者将两三千万用户关联到一个标签下,当使用这样一个标签进行推送的时候,极光后台架构就需要查询这个标签下所有的用户,这对后台系统带来了很大的压力。因此,就需要提前存储一些热点数据,对这一类资源进行隔离部署。
活跃数据 / 非活跃数据的处理
在前面处理数据存储的时候已经做了一个活跃数据和非活跃数据的存储隔离,但是在查询数据的时候,还是会查询到非活跃数据。例如广播推送需要查询到该应用下所有用户,对于其中的非活跃数据会显示推送失败,但是这期间从数据查询到后续的推送处理都是很大的资源浪费。因此需要对活跃和非活跃数据做出分离,推送时只需要查询活跃数据,从而节省数据查询时间和后续流程处理时间,加快了整个推送链路的处理;另外对于活跃比例不大的数据可以采用多级缓存(内存 + 磁盘)的方式来提高访问效率。
异步处理
极光目前的系统中包含数十个模块,每天需进行千亿次内部服务请求。如果后台架构仍采用同步方式进行服务请求,那么同步请求所产生的等待时间必然严重影响到实时性。因此需要采用异步的方式进行服务请求,除非有一些必须使用同步请求的情况才用同步请求。
对于极光的业务来说,很多业务逻辑都是流水线,这时可以把请求封装为消息再发送到 MQ。业务的下游再到 MQ 去消费消息,再来处理对应的业务逻辑。只要 MQ 能高效稳定的运行,就能够保证业务的正常运行。同时使用 MQ 时候也能够使各个模块间进一步解耦,减少相互依赖。
对于需要返回结果的请求来说,极光通过使用 ICE 框架来搭建 RPC 业务服务,确保能够对服务端发起的请求做出实时负载均衡,实现客户端异步调用请求和服务端的异步处理请求。
4移动网络下的亿级长链接管理
极光架构下的长链接在高峰期的连接数能够超过一个亿,在凌晨 2 点到 6 点的低谷期也有七、八千万的体量,为了支撑如此多的长链接,极光需要大量使用虚拟机资源。此外 SDK 的大部分链接都是使用 2G、3G、4G 等移动网络,且同时覆盖了移动、联通、电信三大运营商。
在这种亿级链接的情况下,如果架构不成熟,就会暴露出一系列问题。比如需要避免使用太多的虚拟机资源;如此多的虚拟机资源在建立连接时,要确保各个虚拟机之间的负载要能达到相对平衡的状态;此外在使用移动网络时还会面临弱网和网络抖动、连接不稳定等情况的出现。
首先 SDK 向极光调度中心发起请求,调度中心充分考虑运营商网络、SDK 的地域和接入网关本身的负载因素,分配一个接入网关的 IP 地址,SDK 获得返回接入网关地址后,向对应的接入网关发起请求建立长链接。此外极光配有健康检测服务模块,定时检测各个接入网关状态并上报到管理中心,管理中心会根据网关的状态来决定该网关是否是可以被调度。如果受到攻击等因素导致接入网关大范围不可用的情况下,接入网关还可以借助于云主机来实现自动扩容接入网关,以满足日常大量的 SDK 接入需求。
在这样一个架构之下,极光采用了以下 4 点技术能力来解决长链接管理的问题。
单机性能优化
极光目前的业务代码基本上都采用了模块化处理,模块的功能需要尽可能简单。让接入网关只负责 SDK 端的数据收发,具体的业务逻辑都放在后端的业务模块进行处理,不在接入网关处理业务逻辑。
此外在接入网关层面通过采用静态内存分配来管理各个 SDK 的连接信息以提高内存的访问效率,同时对内存进行对齐数据,尽可能减少数据从内存加载到 CPU 缓存的次数,以提高 CPU 访问内存的效率。
此外,通过实现网卡多队列来并行处理网络消息来加快网络数据包的处理。同时需要单独进行参数调优,例如增加网络收发缓冲区。另外需要关闭防火墙,避免 conntrack 内核模块影响网络数据的处理效率。
自动化管理接入网关
由于接入网关面向的是 C 端用户,经常会因为受到攻击导致接入网关不可用,因此需要能够自动化管理接入网关,定时检测接入网关的健康状况,当接入网关不可用的时候,要做到自动化下线该网关,当接入网关重新恢复可用时,能够实现自动化上线。
自动扩容 / 缩容能力
面临比较大规模的网络攻击时,运营商往往因为攻击量过大直接将一整个 IP 段封禁,这时就会使得大量接入网关被波及导致不可用。因此自动扩容和缩容能力对于任何一家企业后台架构来说,都是非常需要的功能之一。
采用 K8s 部署接入网关
目前极光通过 180 台虚拟机来接入网关,这是一个相对比较繁杂的工作,特别是在升级部署的时候,不仅涉及到程序升级,还要涉及到配置管理,因此会消耗很大的精力去管理程序和配置的版本。因此就需要采用 K8S 能力来部署接入网关,在节省了程序和配置管理的同时,接入网关的自动升级扩容的自动扩容也变得更为便捷。
5经验总结
在极光构造架构系统的过程中,曾老师从技术角度和业务角度两个层面总结了架构设计的经验和方法论。
首先从技术角度来看,一款优秀的架构的标准是一定要具备高性能、高并发、高可用以及高可运维这四个特性,帮助企业在出现问题后能够做到及时的调整。其次是要使用经过验证的开源组件,并充分利用该开源组件给架构设计所带来的一个便利。但是开源产品毕竟存在场景的局限性,当该开源组件无法满足业务需求时,就需要技术团队自研相关的能力组件。同时在设计多模态能力时,要尽量保持模块功能的简单化,坚持快速迭代升级的方法。
从业务角度来看,能够并行处理就不要串行处理,能够异步处理就不用同步处理。借由建立完善的基础监控和业务监控来确保应急状况的及时发现,根据系统的应急状况进行如资源隔离、业务隔离等系统调优,确保系统的稳定运行。
关于极光
极光(Aurora Mobile,纳斯达克股票代码:JG)成立于2011年,是中国领先的开发者服务提供商。极光专注于为移动应用开发者提供稳定高效的消息推送、即时通讯、统计分析、极光分享、短信、一键认证、深度链接等开发者服务。截止到2019年12月份,极光已经为超过50万移动开发者和145.2万款移动应用提供服务,其开发工具包(SDK)安装量累计336亿,月度独立活跃设备13.6亿部。同时,极光持续赋能开发者和传统行业客户,推出精准营销、金融风控、市场洞察、商业地理服务产品,致力于为社会和各行各业提高运营效率,优化决策制定。