本文作者:友盟 + 技术专家 刘章军
前言:App 推送在日常经营场景中常常用到,如:资讯类的新闻及时下发、生存服务类优惠券精准推送、电商类的货品状态或是促销优惠等,通常开发者会依据经营的需要通过自建音讯推送通道或应用第三方音讯推送平台实现,但自建音讯推送的开发成本和人力老本十分高,很多 App 开发者抉择第三方音讯推送。明天就以友盟 + 音讯推送 U -Push,具体解读在海量业务背景下如何保障服务的稳定性以及功能丰富的触达服务。
1. 业务背景
========
友盟 + 音讯推送 U -Push 日均音讯下发量百亿级,其中筛选工作日均数十万,筛选设施每分钟峰值可达 7 亿 +,本文将分享友盟 + 技术架构团队在长期生产实践中积淀的筛选架构解决方案。
如何保障百亿级的下发量?
友盟 +U-Push 筛选是 Push 产品的外围性能,其中实时筛选是面向推送要求较高的付费 Pro 用户提供的外围能力之一,实现了用户实时打标、筛选、散发、触达的性能。友盟 +U-Push 的设施辨认以 device_token 为基准,为保障尽可能的触达咱们留存了近期所有可能触达客户的 device_token,以 10 亿实在设施为例,每个设施装置 10 个集成友盟 +SDK 的利用能够产生 10 个 device_token,牵扯到硬件环境变动导致的 device_token 漂移问题,可能产生更多 device_token。
(图 1.1.1 友盟 +U-Push 业务数据流简图)
图 1.1.2 友盟 +U-Push 性能清单
2. U-Push 筛选架构概览
================
2.1 上下行两个外围链路
U-Push 服务由两个要害链路组成,上行链路保障客户音讯的触达,上行链路承载终端采数和与客户服务端的数据同步。其中上行链路次要分为任务调度、筛选核心,上行链路次要服务是多种收数通道(为兼容历史问题)和设施核心,上行通过设施核心实现跟上行桥接。
图 2.1.1 友盟 +U-Push 筛选业务场景
在 U -Push 服务中,按照业务场景不同定义了多种工作类型,其中除单播、列播间接下发外组播、播送、自定义播、自定义文件播均须要通过筛选服务解决后才可执行下发,上行链路中(如图 2.1.2)优先级最高是的工作受理和工作发送流程(红色链路),即无论产生什么状况都要保障客户音讯的正确下发,是 U -Push 服务稳定性的底线。出于融灾思考,筛选服务在架构上与主链路解耦。
图 2.1.2 筛选和外围链路隔离
2.2 数据架构指标和设计
提到筛选,其本质是通过建设正当的标签索引零碎实现数据的疾速定位。筛选的指标是 U -Push 外围设施库,然而为防止筛选申请影响到外围库稳固须要将待筛选汇合分库冗余存储,与个别 OLAP,OLTP 场景不同,U-Push 筛选的利用场景更加刻薄。
1. 不俗的在线工作并发能力
筛选实质还是在线场景,具备肯定的并发能力,并发压力次要在于压迫零碎 IO 上,通过正当的中间件应用、谨严的服务调度、针对性场景的差异化设计升高单次筛选的执行工夫,进步并发。
2. 实时海量数据分析和传输能力
筛选提供了多种剖析维度(图 2.2.2),反对灵便的语法组合。筛选服务不仅要满足对海量数据的实时查问剖析,还要反对对单次可能破亿的后果集做低成本传输。
图 2.2.2 筛选反对的字段类型
3. 老本可控
========
所有问题都是老本问题,从行业看全民上云后服务架构的老本问题更是备受关注,尤其在友盟 + 宏大的业务量下老本问题更加重要。
4. 为上游工作并行发送创造条件
=================
友盟 +U-Push 的发送层集群用于大量的发送节点,最现实的设计就是在工作筛选阶段即实现数据切片、散发、调度,上游间接并行发送以达到最高效率。
U-Push 筛选在继续的技术迭代中,和多畛域业余团队深度单干,充分利用不同组件的个性,通过整合 Tair、AnalyticDB for MySQL(ADS)、OSS、MaxCompute(ODPS)、Lindorm、HBase、SchedulerX 等产出了一套兼顾稳固、性能、和老本的平衡解决方案。
筛选分为离线和实时两局部,离线通过 ODPS 生成设施主库快照,导入 ADS。实时通过生产数据上行服务的设施信息更新事件,实时更新 ADS 或者 RDB 库。在执行筛选时候,对于较大后果集通过 upload 或者 dump 到 OSS 的形式输入多个小文件,传输给发送链路上游执行并行发送。
图 2.2.4 筛选服务数据流向
上述业务链路和数据结构介绍了筛选目前的整体设计,然而要应酬简单的客情和多变的业务场景还须要做更多细节设计。
3. 设计细节
3.1 筛选库的场景设计
从下面的概览能够看出,筛选架构中的主要矛盾就是音讯上行链路中海量数据的读和上行链路中设施属性更新的高频写的矛盾,解决这个矛盾须要大量的资源来保证数据一致性和性能,在惯例的设计思路中在目前的老本资源下简直是不可行。大数据三大宝,冷热拆散分库分表,通过业务剖析调研,U-Push 将业务分成若干场景,基于客户的不同生命周期的业务诉求和服务能力将客户指向不同场景,尽量优化客户体验。
图 3.1.1 筛选库的场景设计
组播和播送筛选咱们次要围绕 ADS 来建设,ADS 提供了实时和离线两种更新形式,在产品状态上只对 Pro 客户凋谢实时筛选能力,在架构设计上通过分库的形式隔离不同层客户的数据,提供差异化服务,进步稳定性。
离线局部:通过离线主库保障了所有客户的 T + 1 筛选能力。在理论业务中离线主库只有读申请作为所有极其场景下的兜底,离线主库以 device_token 分区,能够实现齐全打散然而聚合查问的时候性能稍差。为了进步局部客户尤其是新客户的体验咱们设计了新客户离线库,批改为客户分区,进步了单客户聚合查问的效率。然而新客户离线库因客户间的规模差别容易引发分区歪斜,生产中这个表须要继续关注,及时清理和转移,否则在跑 ads_loader 的时候可能破线。
图 3.1.2 离线主库的分区状态
图 3.1.3 以客户为分区的分区歪斜状况
实时局部:保障实时筛选服务体验是整个零碎的重点,将实时筛选再细分为 VIP 实时库、测试设施库(不便客户接入阶段实时获取测试成果)、新客户实时库(新增客户个别设施量很小,U-Push 会收费提供一段时间的实时筛选服务)。与离线分区相似,在分区设计上同样对大规模场景数据和较少规模场景的数据分表,特地的测试设施库可能产生大量脏数据,整体隔离进去。
图 3.1.2 客户场景迁徙
新客户接入伊始基于客户规模辨别,在不同的生命周期节点会被引入特定的场景,在保障大盘能力的前提下尽量输入更优质的客户体验。
3.2 利用 OSS 传输和切分文件
在上述设计中通过离线和实时的辨别,升高了高频写可能对设施库造成的影响。然而始终绕不过海量数据的传输问题,为躲避这个问题 U -Push 采纳差异化的设计思路,以后果集规模做辨别,对大后果集间接通过 ADS dump 到 OSS,基于不同客户的并行度做近程切分,在 OSS 实现 upload 和 split 操作后返回文件门路汇合,后续链路只保留文件门路集,直至进入发送层执行并行发送。对小后果集通过 select 拉取到内存整合消息报文传输,后续链路间接发送设施 ID。通过 OSS 做两头存储,极大的升高冗余的 IO 损耗。
ADS3.0 因为整体架构改变改为通过内部表的形式 dump 到 OSS,与 2.0 能够 dump 出单个文件不同 3.0 在 dump 后会产生一系列小文件间接导致原有的计划不可行,在通过和 ADS 团队沟通后 ADS 顺便在 3.0 版本欠缺了 dump 单个文件的性能,致谢 ADS 的同学。
图 3.2.1 筛选查问中的性能瓶颈危险
3.3 查问缓存和预筛选
谈到查问场景,必然会有缓存的一席之地,与个别设计思路不同,U-Push 间接放弃了针对实时筛选能力的查问缓存,因为在这样的设施量级下随时的设施更新是必然。U-Push 的实时筛选库是一个高频写低频读的场景,然而对单次读的要求比拟刻薄,首先对未开启实时性能的离线客户,因为设施库是快照模式,一天内的屡次读拿到的后果必然雷同这时候设置缓存就很有意义,比方新闻、气象、工具类客户的习惯,一天内发送屡次播送,就不用每次再去从新生成筛选集文件。
图 3.3.1 查问缓存逻辑流程图
预筛选性能的开发是个小插曲,后面讲到 U -Push 放弃了对实时的查问缓存,导致客户的每次音讯发送都要从新去生成文件,在保证数据实时性的角度思考无可非议,然而遇到“较真”的客户就很有压力。比方新闻类客户极度关注音讯下发的时效性,通过开发者控制台能够查看每个工作的筛选工夫,有时候同类音讯 2s 的差别也会引发客户在 DING 群的 ” 客诉 ”。客户的诉求能够了解然而这也消耗了团队大量的精力。通过和个别客户沟通 U -Push 开发了预筛选性能,在客户习惯性发送音讯的前一段时间事后调度执行筛选逻辑生成设施 ID 汇合,通过损失大量的数据时效性来压缩音讯下发工夫,争取音讯发送速度。
图 3.3.1 友盟 +U-Push 音讯轨迹
3.4 Alias 筛选的优化
筛选申请能够归类为两种场景:
- Alias 性能依赖的 ID Mapping 场景,NvN 的设施 ID 和 Alias 映射。
- tag 组播和 iOS 播送性能的 select 场景,条件查问,基于 ADS 实现。
Alias 性能简介:Alias 容许开发者为设施绑定别名,别名由 alias_type,alias 两个属性组成,譬如开发者能够标识设施 A,为他减少 alias_type=telephone_number, alias=13900000000 以此来给设施 A 减少手机号的属性。在发送音讯时候能够绕开 device_token,间接通过服务端指定 alias 实现触达,alias 是一个典型的 NVN ID Mapping 场景,一个设施在同一个 alias_type 上面同时只能领有一个 alias。这也是合乎个别业务场景的,比方上例个别一个设施只有一个手机号,设置新手机号后会笼罩原 alias。如果须要满足双卡双待的性能,须要设置两个 alias_type,即 alias_type=telephone_number_main,alias_type=telephone_number_secondary。alias 的个别应用场景是开发者通过自定义文件播上传一批文件,文件内容为某个 alias_type 下若干设施 alias 的汇合(百万千万级)。筛选服务扫描文件后顺次找出 alias 值 mapping 的 device_token。
3.4.1 Alias 的晚期设计
说到 Mapping,轮询,高吞吐查问,首当其冲选 Redis,晚期的 U -Push 也是如此。
图 3.5.1 alias 晚期数据结构设计
alias 利用 Redis 的 Set 和 Hash 构造实现正查和反差的性能,为什么反差用 hash,后面讲到 1 个设施在 1 个 alias_type 下只保留最新的 alias。这也是出于爱护用户的目标,如果 1 个设施同时存在多个 alias 下,在开发者执行圈选的时候可能会屡次选出这个设施造成屡次有效触达。
这个设计平铺直叙,确实也能够满足绝大部分客户的筛选场景,然而随着业务量的减少有几个问题逐步裸露
- 轮询成为海量设施查问的瓶颈,且不可冲破。
- Redis 数据长久化难的问题凸显,数据分析难上加难。
- Alias 无奈很好的满足数据返还链路的需要。
3.4.2 钻研 Alias 的解法
分库确实是很好的思路然而依然无奈满足性能问题和长久化问题,而且随着行业对大数据的关注,数据返还也成为更多开发者的诉求。买通数据返还链路做好客户数据的存、取、管、用曾经是一个重要的行业方向。为了解决这个问题 U -Push 通过离线和实时相结合制订措施
- 分库,减少 KA 级别客户独享库,压缩横向扩容空间。
- 分层,基于 Lindorm 做长久化分层存储。
- 离线留存,通过日志零碎留存上行筛选后果,一方面欠缺统计需要,一方面通过回执返还客户。
3.4.3 基于 Lindorm 宽表的分层设计
用宽表代替 Redis 的 Set 设计做正查,用一般表基于设施 ID 的联结主键做反查,在查问时候通过将单次轮询改为屡次 mget 尽量压缩 IO 损耗寻找响应性能和服务稳固的两头值,Lindorm 的磁盘存储能够满足业务需要的同时通过 exporter 的配置实现 lindorm 数据 T + 1 同步至 ODPS。
图 3.5.2 基于 Lindorm 款表的分层设计
3.4.4 数据迁徙的尝试和思考
数据迁徙是在很多业务架构中都是痛中之痛,如何保障稳固、平滑、平安的迁徙须要付出大量的老本。U-Push 在 Alias 的数据迁徙中做了多种计划的钻研和思考。
- Tair 整体 dump 迁徙,dump 计划实践上可行然而有较大的业务危险,出于稳定性的思考放弃。
- 写申请增量更新,通过客户的写申请逐 key 迁徙,会有漫长的灰度工夫,且无奈执行彻底清理,胜在稳定性强。
- 扫描设施主库,分客户批次灰度迁徙。在 U -Push 的性能中,提供了 appkey 下 alias_type 的性能,客户能够在开发者控制台查问 appkey 下的 alias_type 列表,为实现这个性能对 appkey 和 alias_type 做了汇合索引,这个索引成为数据迁徙的要害。通过扫描设施库获取 appkey 和 device_token,联合 alias_type 去反查库查找 alias,再拿 appkey+alias_type+alias 去正查库查问 device_token 列表实现迁徙。
第三种办法能够实现存量数据的完满迁徙,对线上服务简直没影响,然而在百亿级设施下,以 1wTPS 计算依然须要 10 天的工夫,好在该计划能够实现单个客户的灰度与回滚。
5. 结语
======
U-Push 筛选服务只是 U -Push 泛滥服务中的一环,在友盟 + 微小的业务量下,为满足不拘一格的各行业需要输入了大量粗劣的设计,本文列出的只是冰山一角,日均音讯下发量百亿级做到熟能生巧离不开其余技术架构团队在筛选服务迭代中的独特合作。
目前 U -Push 曾经以 Push 通道为根底,整合了微信、短信、隐衷短信降级为多通道触达服务,为泛滥出名的 App 如:今日头条、磅礴新闻、作业帮、易车等提供了触达能力,后续继续接入支付宝小程序、头条号等更多经营场景通道,继续为客户提供稳固、高性能、低成本的触达能力保障。
友盟 +,国内当先的第三方全域数据智能服务商,截至 2020 年 6 月已累计为 200 万挪动利用和 890 万家网站提供十年的业余数据服务。