组播和广播筛选我们主要围绕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的同学。