# AppsFlyer 如何通过迁移到 Amazon Athena 现代化其互动工作负载并节省 80
AppsFlyer如何通过转向Amazon Athena实现交互工作负载现代化,并节省80的成本
关键要点
AppsFlyer成功从Apache HBase迁移到Amazon Athena,提升了Audiences Segmentation产品的性能和稳定性。此次迁移实现了查询性能提升10、降低了服务延迟,并使每月成本降低了80。采用了多种优化技术,包括分区投影、数据合并、目录模式重新设计和并行查询。本文由Nofar Diamant和Matan Safri与AppsFlyer共同撰写。
AppsFlyer开发了一种基于隐私的领先测量解决方案,使营销人员能够评估其营销活动的有效性,并将其与更广泛的营销世界相结合,每天处理1000亿事件的庞大数据量。AppsFlyer通过深入分析,帮助数字营销人员准确识别并分配导致应用安装的各种消费者互动。
AppsFlyer的一部分产品是受众分割工具,允许应用拥有者根据用户的行为和人口统计进行精确的目标和重新吸引。这包括一个实时评估特定用户群体大小的功能,称为“评估功能”。
为了向用户提供实时的受众大小评估,AppsFlyer团队最初使用了Apache HBase,一个开源的分布式数据库。然而,随着工作负载增长到23 TB,HBase架构需要重新审视,以满足响应时间和可靠性的服务水平协议SLA。
本文探讨了AppsFlyer如何通过使用Amazon Athena来现代化其受众分割产品。Athena是AWS提供的一种强大且多功能的无服务器查询服务,旨在使用户能够使用标准SQL查询分析存储在Amazon S3中的数据。
我们详细介绍了AppsFlyer采用的各种优化技术,例如分区投影、排序、并行查询运行和查询结果重用。我们分享了团队面临的挑战以及他们为在低延迟需求的用例中释放Athena的真正潜力而采取的策略。此外,我们讨论了彻底的测试、监控和部署过程,这一过程促成了成功迁移到新的Athena架构。
受众分割的传统架构和现代化驱动因素
受众分割涉及在AppsFlyer的用户界面中定义目标受众,以有向树结构表示,节点和叶子分别为集合操作和原子标准。
以下图示展示了在AppsFlyer受众管理控制台上进行受众分割的示例及其与上述树结构的转换,其中两个原子标准为叶子,并且它们之间的集合操作为节点。
为了实时评估受众规模,AppsFlyer团队使用了一种名为Theta Sketches的框架,这是一种高效的数据结构,用于计算不同元素的数量。这些草图增强了可扩展性和分析能力。最初,这些草图存储在HBase数据库中。
HBase是一个开源的、分布式的、列式数据库,旨在通过横向扩展在商品硬件上处理大量数据。
原始数据结构
在本文中,我们重点关注events表,这是最初存储在HBase中的最大表。该表的模式为date appid eventname eventvalue sketch,并按date和appid进行分区。
下图展示了AppsFlyer估算系统的高层次原始架构。
该架构特征是一个Airflow ETL进程,该进程启动作业以从源数据集创建草图文件,然后将这些文件导入HBase。用户可以使用API服务查询HBase,并根据在用户界面中设定的受众群体标准检索用户计数的估算值。
若需了解有关之前HBase架构的更多信息,请参见Applied Probability Counting Large Set of Unstructured Events with Theta Sketches。
随着时间推移,工作负载超出了原本为HBase实施设计的大小,达到23 TB的存储规模。因此,为了满足AppsFlyer对响应时间和可靠性的SLA,HBase架构显然需要重新审视。
如前所述,此用例的重点在于客户与用户界面的每日交互,必须遵循提供快速响应时间的用户界面标准SLA,并能够处理大量的每日请求,同时适应当前的数据量和潜在未来扩张。
此外,由于与HBase相关的高维护成本,团队的目标是找到一种经过管理、简单且经济高效的替代方案,使现有系统架构不会显著复杂化。
在经过深入的团队讨论和与AWS专家的咨询后,团队得出的结论是,使用Amazon S3和Athena的解决方案是最具成本效益和最简单的选择。主要关注点是查询延迟,团队特别谨慎地避免对整体客户体验产生负面影响。
以下图示展示了使用Athena的新架构。注意importsketchestohbase和HBase被省略,并添加了Athena以查询Amazon S3中的数据。
模式设计和性能提升的分区投影
在本节中,我们讨论了新架构中模式设计的过程及团队采用的不同性能优化方法,包括分区投影。
合并数据以减少分区
为了评估Athena能否支持受众分割,进行了初步的概念验证。范围限制在来自三个appids约3 GB数据的事件上,采用与HBase实现相同的分区模式按appid和date进行分区。随着团队扩大到包含全数据集的10000个appids,时间范围为1个月达到约150 GB的数据,团队开始遇到更多的慢查询,尤其是跨越较长时间跨度的查询。团队深入分析后发现,由于从AWS Glue数据目录加载的分区数量730万个,Athena在查询规划阶段花费了大量时间有关如何将Athena与AWS Glue结合使用的信息,请参见Integration with AWS Glue。
这促使团队审查分区索引。Athena分区索引提供了一种在分区列上创建元数据索引的方式,使Athena能够在分区层面修剪数据扫描,从而减少需要从Amazon S3读取的数据量。分区索引缩短了查询规划阶段的分区发现时间,但改善程度不足以满足所需的查询延迟SLA。
作为针对分区索引的替代方案,团队评估了一种通过将数据颗粒度从日报减少到月报的策略,以减少分区数量。这种方法通过使用Theta Sketches联合能力将日级草图合并为月级综合草图来合并每日数据。例如,处理一个时间段的数据,团队将30行数据合并为单行,有效地将行数减少了97。
这种方法大幅减少了初始需要约1015秒的分区发现阶段所需的时间,减少了必须扫描的数据量。然而,基于用户界面的响应标准所期望的延迟目标仍不理想。

此外,合并过程无意中损害了数据的精确性,导致探索其他解决方案。
作为增强因子的分区投影
此时,团队决定探索Athena中的分区投影。
Athena中的分区投影允许通过投影分区的元数据来提高查询效率。无需将分区在数据库目录中显式定义,它可以虚拟生成和发现分区。
该功能在处理大量分区或快速创建分区时尤为有用,例如流数据的情况。
正如我们之前所解释的,在此特定用例中,每个叶子是通过包含date范围、appid和eventname的查询转化而来的访问模式。这促使团队定义通过日期类型进行投影,以用于date范围,并通过注入类型进行appid和eventname的注入。
Athena能够根据配置的规则和查询中的值生成分区,而无需从目录加载和过滤分区,从而避免了查询运行过程中因发现分区而带来的性能问题。
由于分区投影消除了分区数量与查询运行时之间的依赖,团队可以尝试添加额外的分区:eventname。通过三个列date、appid和eventname进行分区,减少了扫描的数据量,导致查询性能比使用仅按date和appid分区的分区投影提升了10。
下图展示了草图文件创建的高层次数据流。关注草图写入过程writeeventsestimationsketches到Amazon S3中的三个分区字段,导致该过程相比原始架构运行时间延长了一倍,因为要写入的草图文件数量增加了20倍。
这促使团队放弃了eventname分区,并在date和appid的两个分区上妥协,形成了以下分区结构:
s3//bucket/tableroot/date={day}/appid={appid}
使用Parquet文件格式
在新架构中,团队使用了Parquet文件格式。Apache Parquet是一种开源的列式数据文件格式,旨在高效存储和检索数据。每个Parquet文件包含诸如列的最小和最大值等元数据,允许查询引擎快速跳过不必要的数据。此优化减少了必须扫描的数据量,因为Athena可以跳过或快速导航到与查询无关的Parquet文件的部分。结果,查询性能显著提升。
Parquet在查询排序字段时特别有效,因为它允许Athena进行谓词下推优化,快速识别和访问相关数据段。有关这种能力的更多信息,请参见理解列存储格式。
意识到这个优势后,团队决定按eventname进行排序来提高查询性能,与未排序的数据相比提升了10。最初,他们试图按eventname进行分区以优化性能,但这种方法导致写入到Amazon S3的时间增加。排序在没有增加摄取开销的情况下显示了查询时间的改善。
查询优化和并行查询
团队发现可以通过运行并行查询进一步提高性能。未采用单个跨越长时间窗口的查询,而是运行多个短时间窗口的查询。尽管这增加了解决方案的复杂性,但平均性能提高了约20。
例如,考虑一种情况,用户请求估算在2024年4月到2024年6月底comdemo应用的afpurchase事件的大小如前所述,分割由用户定义并转化为原子叶子,接着根据日期范围分解为多个查询。以下图示展示了如何将最初的3个月查询分解为两个最多60天的查询,同时运行它们并合并结果。
减少结果集大小
在分析性能瓶颈、检查不同类型和属性的查询以及分析查询运行的不同阶段时,显然某些查询在获取查询结果时较慢。该问题并非源于实际查询运行,而是在GetQueryResults阶段从Amazon S3进行数据传输,因查询结果包含大量行单个结果可能包含数百万行。
最初处理多个关键值排列的草图膨胀了行数。为此,团队引入了新的eventattrkey字段,以将草图分离为不同的关键值对。
最终模式如下:
date appid eventname eventattrkey eventattrvalue sketch
这种重构显著减少了结果行数,从而显著加快了GetQueryResults过程,使总体查询运行时间提高了90。
Athena查询结果重用
为了处理受众分割GUI中用户经常进行微小调整的常见用例,例如调整过滤器或略微改变时间窗口,团队利用了Athena的查询结果重用功能。该功能通过缓存和重用先前查询的结果来提高查询性能并降低成本。考虑到最近涉及分割日期范围的优化,这一功能发挥了重要作用。能够重用和快速检索结果,意味着这些小而频繁的修改不再需要整个查询重新处理。
因此,重复查询运行的延迟减少了多达80,提升了用户体验,提供了更快的洞察。这一优化不仅加速了数据检索,还显著降低了成本,因为无需为每个小变化重新扫描数据。
解决方案部署:测试和监控
在本节中,我们讨论了新架构的部署过程,包括测试和监控。
解决Amazon S3减速错误
在解决方案的测试阶段,团队开发了一种自动化流程,旨在评估系统中的不同受众,使用在新实现模式中组织的数据。该方法涉及比较从HBase获得的结果与从Athena得出的结果。
在运行这些测试时,团队检查了所提取估算的准确性以及延迟变化。
在此测试阶段,团队在同时运行多次并发查询时遇到了一些失败。这些失败是由于Amazon S3限流,由于多个Athena查询对同一前缀产生了过多的GET请求。
为了处理限流减速错误,团队在查询运行中增加了重试机制,并采用指数退避策略等待时间以随机偏移进行指数增长,以防止并发重试。
部署准备
最初,团队启动了1个月的回填过程,作为节约成本的方法,在全面回填2年历史数据之前优先考虑准确性验证。
回填过程包括在所需时间范围内运行Spark作业writeeventsestimationsketches。该作业从数据仓库中读取数据,创建合成草图,并按照团队定义的具体模式将其写入文件。此外,由于团队使用了分区投影,他们可以跳过每增加一个分区时更新数据目录的过程。
这种逐步的方法使团队能够在继续整个历史数据集之前确认解决方案的正确性。
一元机场com软件在对初步阶段取得的准确性具有信心后,团队系统地扩大了回填过程,以涵盖完整的2年时间表,确保实施的全面性和可靠性。
在正式发布更新的解决方案之前,实施了稳健的监控策略,以保障稳定性。设置了关键监控点以评估关键方面,例如查询和API延迟、错误率、API可用性。
在数据被存储为Parquet文件后,以下的部署过程被设计为:
保持HBase和Athena的写入流程运行,停止从HBase读取并开始从Athena读取。停止写入HBase。逐步淘汰HBase。Athena带来的改进和优化
从HBase迁移到Athena,通过使用分区投影和优化数据结构,不仅在查询性能上提高了10,还大幅提升了整体系统的稳定性,仅扫描所需的数据分区。此外,转向Athena的无服务器模式使每月成本显著降低了80,这源于消除基础设施管理成本,并使成本与使用量直接相关,从而为组织提供了更高效的运营、改善数据分析和更优的商业成果。
以下表格总结了团队实施的改进和优化。
改进领域 采取的行动 衡量的改善