淡水网络公司做网站,中国人做英文网站,上海装修公司一览表,网站建设电话销售说不需要本文已发表在《程序员》杂志2016年4月期。 前言 美团是数据驱动的互联网服务#xff0c;用户每天在美团上的点击、浏览、下单支付行为都会产生海量的日志#xff0c;这些日志数据将被汇总处理、分析、挖掘与学习#xff0c;为美团的各种推荐、搜索系统甚至公司战略目标制定提… 本文已发表在《程序员》杂志2016年4月期。 前言 美团是数据驱动的互联网服务用户每天在美团上的点击、浏览、下单支付行为都会产生海量的日志这些日志数据将被汇总处理、分析、挖掘与学习为美团的各种推荐、搜索系统甚至公司战略目标制定提供数据支持。大数据处理渗透到了美团各业务线的各种应用场景选择合适、高效的数据处理引擎能够大大提高数据生产的效率进而间接或直接提升相关团队的工作效率。 美团最初的数据处理以Hive SQL为主底层计算引擎为MapReduce部分相对复杂的业务会由工程师编写MapReduce程序实现。随着业务的发展单纯的Hive SQL查询或者MapReduce程序已经越来越难以满足数据处理和分析的需求。 一方面MapReduce计算模型对多轮迭代的DAG作业支持不给力每轮迭代都需要将数据落盘极大地影响了作业执行效率另外只提供Map和Reduce这两种计算因子使得用户在实现迭代式计算比如机器学习算法时成本高且效率低。 另一方面在数据仓库的按天生产中由于某些原始日志是半结构化或者非结构化数据因此对其进行清洗和转换操作时需要结合SQL查询以及复杂的过程式逻辑处理这部分工作之前是由Hive SQL结合Python脚本来完成。这种方式存在效率问题当数据量比较大的时候流程的运行时间较长这些ETL流程通常处于比较上游的位置会直接影响到一系列下游的完成时间以及各种重要数据报表的生成。 基于以上原因美团在2014年的时候引入了Spark。为了充分利用现有Hadoop集群的资源我们采用了Spark on Yarn模式所有的Spark app以及MapReduce作业会通过Yarn统一调度执行。Spark在美团数据平台架构中的位置如图所示 经过近两年的推广和发展从最开始只有少数团队尝试用Spark解决数据处理、机器学习等问题到现在已经覆盖了美团各大业务线的各种应用场景。从上游的ETL生产到下游的SQL查询分析以及机器学习等Spark正在逐步替代MapReduce作业成为美团大数据处理的主流计算引擎。目前美团Hadoop集群用户每天提交的Spark作业数和MapReduce作业数比例为41对于一些上游的Hive ETL流程迁移到Spark之后在相同的资源使用情况下作业执行速度提升了十倍极大地提升了业务方的生产效率。 下面我们将介绍Spark在美团的实践包括我们基于Spark所做的平台化工作以及Spark在生产环境下的应用案例。其中包含Zeppelin结合的交互式开发平台也有使用Spark任务完成的ETL数据转换工具数据挖掘组基于Spark开发了特征平台和数据挖掘平台另外还有基于Spark的交互式用户行为分析系统以及在SEM投放服务中的应用以下是详细介绍。 Spark交互式开发平台 在推广如何使用Spark的过程中我们总结了用户开发应用的主要需求 1. 数据调研在正式开发程序之前首先需要认识待处理的业务数据包括数据格式类型若以表结构存储则对应到字段类型、存储方式、有无脏数据甚至分析根据业务逻辑实现是否可能存在数据倾斜等等。这个需求十分基础且重要只有对数据有充分的掌控才能写出高效的Spark代码 2. 代码调试业务的编码实现很难保证一蹴而就可能需要不断地调试如果每次少量的修改测试代码都需要经过编译、打包、提交线上会对用户的开发效率影响是非常大的 3. 联合开发对于一整个业务的实现一般会有多方的协作这时候需要能有一个方便的代码和执行结果共享的途径用于分享各自的想法和试验结论。 基于这些需求我们调研了现有的开源系统最终选择了Apache的孵化项目Zeppelin将其作为基于Spark的交互式开发平台。Zeppelin整合了SparkMarkdownShellAngular等引擎集成了数据分析和可视化等功能。 我们在原生的Zeppelin上增加了用户登陆认证、用户行为日志审计、权限管理以及执行Spark作业资源隔离打造了一个美团的Spark的交互式开发平台不同的用户可以在该平台上调研数据、调试程序、共享代码和结论。 集成在Zeppelin的Spark提供了三种解释器Spark、Pyspark、SQL分别适用于编写Scala、Python、SQL代码。对于上述的数据调研需求无论是程序设计之初还是编码实现过程中当需要检索数据信息时通过Zeppelin提供的SQL接口可以很便利的获取到分析结果另外Zeppelin中Scala和Python解释器自身的交互式特性满足了用户对Spark和Pyspark分步调试的需求同时由于Zeppelin可以直接连接线上集群因此可以满足用户对线上数据的读写处理请求最后Zeppelin使用Web Socket通信用户只需要简单地发送要分享内容所在的http链接所有接受者就可以同步感知代码修改运行结果等实现多个开发者协同工作。 Spark作业ETL模板 除了提供平台化的工具以外我们也会从其他方面来提高用户的开发效率比如将类似的需求进行封装提供一个统一的ETL模板让用户可以很方便的使用Spark实现业务需求。 美团目前的数据生产主体是通过ETL将原始的日志通过清洗、转换等步骤后加载到Hive表中。而很多线上业务需要将Hive表里面的数据以一定的规则组成键值对导入到Tair中用于上层应用快速访问。其中大部分的需求逻辑相同即把Hive表中几个指定字段的值按一定的规则拼接成key值另外几个字段的值以json字符串的形式作为value值最后将得到的 对写入Tair。 , 由于Hive表中的数据量一般较大使用单机程序读取数据和写入Tair效率比较低因此部分业务方决定使用Spark来实现这套逻辑。最初由业务方的工程师各自用Spark程序实现从Hive读数据写入到Tair中以下简称hive2Tair流程这种情况下存在如下问题 每个业务方都要自己实现一套逻辑类似的流程产生大量重复的开发工作 由于Spark是分布式的计算引擎因此代码实现和参数设置不当很容易对Tair集群造成巨大压力影响Tair的正常服务。 基于以上原因我们开发了Spark版的hive2Tair流程并将其封装成一个标准的ETL模板其格式和内容如下所示 source用于指定Hive表源数据target指定目标Tair的库和表这两个参数可以用于调度系统解析该ETL的上下游依赖关系从而很方便地加入到现有的ETL生产体系中。 有了这个模板用户只需要填写一些基本的信息包括Hive表来源组成key的字段列表组成value的字段列表目标Tair集群即可生成一个hive2Tair的ETL流程。整个流程生成过程不需要任何Spark基础也不需要做任何的代码开发极大地降低了用户的使用门槛避免了重复开发提高了开发效率。该流程执行时会自动生成一个Spark作业以相对保守的参数运行默认开启动态资源分配每个Executor核数为2内存2GB最大Executor数设置为100。如果对于性能有很高的要求并且申请的Tair集群比较大那么可以使用一些调优参数来提升写入的性能。目前我们仅对用户暴露了设置Executor数量以及每个Executor内存的接口并且设置了一个相对安全的最大值规定避免由于参数设置不合理给Hadoop集群以及Tair集群造成异常压力。 基于Spark的用户特征平台 在没有特征平台之前各个数据挖掘人员按照各自项目的需求提取用户特征数据主要是通过美团的ETL调度平台按月/天来完成数据的提取。 但从用户特征来看其实会有很多的重复工作不同的项目需要的用户特征其实有很多是一样的为了减少冗余的提取工作也为了节省计算资源建立特征平台的需求随之诞生特征平台只需要聚合各个开发人员已经提取的特征数据并提供给其他人使用。特征平台主要使用Spark的批处理功能来完成数据的提取和聚合。 开发人员提取特征主要还是通过ETL来完成有些数据使用Spark来处理比如用户搜索关键词的统计。 开发人员提供的特征数据需要按照平台提供的配置文件格式添加到特征库比如在图团购的配置文件中团购业务中有一个用户24小时时段支付的次数特征输入就是一个生成好的特征表开发人员通过测试验证无误之后即完成了数据上线另外对于有些特征只需要从现有的表中提取部分特征数据开发人员也只需要简单的配置即可完成。 在图中我们可以看到特征聚合分两层第一层是各个业务数据内部聚合比如团购的数据配置文件中会有很多的团购特征、购买、浏览等分散在不同的表中每个业务都会有独立的Spark任务来完成聚合构成一个用户团购特征表特征聚合是一个典型的join任务对比MapReduce性能提升了10倍左右。第二层是把各个业务表数据再进行一次聚合生成最终的用户特征数据表。 特征库中的特征是可视化的我们在聚合特征时就会统计特征覆盖的人数特征的最大最小数值等然后同步到RDB这样管理人员和开发者都能通过可视化来直观地了解特征。 另外我们还提供特征监测和告警使用最近7天的特征统计数据对比各个特征昨天和今天的覆盖人数是增多了还是减少了比如性别为女这个特征的覆盖人数如果发现今天的覆盖人数比昨天低了1%比如昨天6亿用户女性2亿那么人数降低了12亿2百万突然减少2万女性用户说明数据出现了极大的异常何况网站的用户数每天都是增长的。这些异常都会通过邮件发送到平台和特征提取的相关人。 Spark数据挖掘平台 数据挖掘平台是完全依赖于用户特征库的通过特征库提供用户特征数据挖掘平台对特征进行转换并统一格式输出就此开发人员可以快速完成模型的开发和迭代之前需要两周开发一个模型现在短则需要几个小时多则几天就能完成。特征的转换包括特征名称的编码也包括特征值的平滑和归一化平台也提供特征离散化和特征选择的功能这些都是使用Spark离线完成。 开发人员拿到训练样本之后可以使用Spark mllib或者Python sklearn等完成模型训练得到最优化模型之后将模型保存为平台定义好的模型存储格式并提供相关配置参数通过平台即可完成模型上线模型可以按天或者按周进行调度。当然如果模型需要重新训练或者其它调整那么开发者还可以把模型下线。不只如此平台还提供了一个模型准确率告警的功能每次模型在预测完成之后会计算用户提供的样本中预测的准确率并比较开发者提供的准确率告警阈值如果低于阈值则发邮件通知开发者是否需要对模型重新训练。 在开发挖掘平台的模型预测功时能我们走了点弯路平台的模型预测功能开始是兼容Spark接口的也就是使用Spark保存和加载模型文件并预测使用过的人知道Spark mllib的很多API都是私有的开发人员无法直接使用所以我们这些接口进行封装然后再提供给开发者使用但也只解决了Spark开发人员的问题平台还需要兼容其他平台的模型输出和加载以及预测的功能这让我们面临必需维护一个模型多个接口的问题开发和维护成本都较高最后还是放弃了兼容Spark接口的实现方式我们自己定义了模型的保存格式以及模型加载和模型预测的功能。 以上内容介绍了美团基于Spark所做的平台化工作这些平台和工具是面向全公司所有业务线服务的旨在避免各团队做无意义的重复性工作以及提高公司整体的数据生产效率。目前看来效果是比较好的这些平台和工具在公司内部得到了广泛的认可和应用当然也有不少的建议推动我们持续地优化。 随着Spark的发展和推广从上游的ETL到下游的日常数据统计分析、推荐和搜索系统越来越多的业务线开始尝试使用Spark进行各种复杂的数据处理和分析工作。下面将以Spark在交互式用户行为分析系统以及SEM投放服务为例介绍Spark在美团实际业务生产环境下的应用。 Spark在交互式用户行为分析系统中的实践 美团的交互式用户行为分析系统用于提供对海量的流量数据进行交互式分析的功能系统的主要用户为公司内部的PM和运营人员。普通的BI类报表系统只能够提供对聚合后的指标进行查询比如PV、UV等相关指标。但是PM以及运营人员除了查看一些聚合指标以外还需要根据自己的需求去分析某一类用户的流量数据进而了解各种用户群体在App上的行为轨迹。根据这些数据PM可以优化产品设计运营人员可以为自己的运营工作提供数据支持用户核心的几个诉求包括 1. 自助查询不同的PM或运营人员可能随时需要执行各种各样的分析功能因此系统需要支持用户自助使用。 2. 响应速度大部分分析功能都必须在几分钟内完成。 3. 可视化可以通过可视化的方式查看分析结果。 要解决上面的几个问题技术人员需要解决以下两个核心问题 1. 海量数据的处理用户的流量数据全部存储在Hive中数据量非常庞大每天的数据量都在数十亿的规模。 2. 快速计算结果系统需要能够随时接收用户提交的分析任务并在几分钟之内计算出他们想要的结果。 要解决上面两个问题目前可供选择的技术主要有两种MapReduce和Spark。在初期架构中选择了使用MapReduce这种较为成熟的技术但是通过测试发现基于MapReduce开发的复杂分析任务需要数小时才能完成这会造成极差的用户体验用户无法接受。 因此我们尝试使用Spark这种内存式的快速大数据计算引擎作为系统架构中的核心部分主要使用了Spark Core以及Spark SQL两个组件来实现各种复杂的业务逻辑。实践中发现虽然Spark的性能非常优秀但是在目前的发展阶段中还是或多或少会有一些性能以及OOM方面的问题。因此在项目的开发过程中对大量Spark作业进行了各种各样的性能调优包括算子调优、参数调优、shuffle调优以及数据倾斜调优等最终实现了所有Spark作业的执行时间都在数分钟左右。并且在实践中解决了一些shuffle以及数据倾斜导致的OOM问题保证了系统的稳定性。 结合上述分析最终的系统架构与工作流程如下所示 1. 用户在系统界面中选择某个分析功能对应的菜单并进入对应的任务创建界面然后选择筛选条件和任务参数并提交任务。 2. 由于系统需要满足不同类别的用户行为分析功能目前系统中已经提供了十个以上分析功能因此需要为每一种分析功能都开发一个Spark作业。 3. 采用J2EE技术开发了Web服务作为后台系统在接收到用户提交的任务之后根据任务类型选择其对应的Spark作业启动一条子线程来执行Spark-submit命令以提交Spark作业。 4. Spark作业运行在Yarn集群上并针对Hive中的海量数据进行计算最终将计算结果写入数据库中。 5. 用户通过系统界面查看任务分析结果J2EE系统负责将数据库中的计算结果返回给界面进行展现。 该系统上线后效果良好90%的Spark作业运行时间都在5分钟以内剩下10%的Spark作业运行时间在30分钟左右该速度足以快速响应用户的分析需求。通过反馈来看用户体验非常良好。目前每个月该系统都要执行数百个用户行为分析任务有效并且快速地支持了PM和运营人员的各种分析需求。 Spark在SEM投放服务中的应用 流量技术组负责着美团站外广告的投放技术目前在SEM、SEO、DSP等多种业务中大量使用了Spark平台包括离线挖掘、模型训练、流数据处理等。美团SEM搜索引擎营销投放着上亿的关键词一个关键词从被挖掘策略发现开始就踏上了精彩的SEM之旅。它经过预估模型的筛选投放到各大搜索引擎可能因为市场竞争频繁调价也可能因为效果不佳被迫下线。而这样的旅行在美团每分钟都在发生。如此大规模的随机“迁徙”能够顺利进行Spark功不可没。 Spark不止用于美团SEM的关键词挖掘、预估模型训练、投放效果统计等大家能想到的场景还罕见地用于关键词的投放服务这也是本段介绍的重点。一个快速稳定的投放系统是精准营销的基础。 美团早期的SEM投放服务采用的是单机版架构随着关键词数量的极速增长旧有服务存在的问题逐渐暴露。受限于各大搜索引擎API的配额请求频次、账户结构等规则投放服务只负责处理API请求是远远不够的还需要处理大量业务逻辑。单机程序在小数据量的情况下还能通过多进程勉强应对但对于如此大规模的投放需求就很难做到“兼顾全局”了。 新版SEM投放服务在15年Q2上线内部开发代号为Medusa。在Spark平台上搭建的Medusa全面发挥了Spark大数据处理的优势提供了高性能高可用的分布式SEM投放服务具有以下几个特性 1. 低门槛Medusa整体架构的设计思路是提供数据库一样的服务。在接口层让RD可以像操作本地数据库一样通过SQL来“增删改查”线上关键词表并且只需要关心自己的策略标签不需要关注关键词的物理存储位置。Medusa利用Spark SQL作为服务的接口提高了服务的易用性也规范了数据存储可同时对其他服务提供数据支持。基于Spark开发分布式投放系统还可以让RD从系统层细节中解放出来全部代码只有400行。 2. 高性能、可伸缩为了达到投放的“时间”、“空间”最优化Medusa利用Spark预计算出每一个关键词在远程账户中的最佳存储位置每一次API请求的最佳时间内容。在配额和账号容量有限的情况下轻松掌控着亿级的在线关键词投放。通过控制Executor数量实现了投放性能的可扩展并在实战中做到了全渠道4小时全量回滚。 3. 高可用有的同学或许会有疑问API请求适合放到Spark中做吗因为函数式编程要求函数是没有副作用的纯函数输入是确定的输出就是确定的。这确实是一个问题Medusa的思路是把请求API封装成独立的模块让模块尽量做到“纯函数”的无副作用特性并参考面向轨道编程的思路将全部请求log重新返回给Spark继续处理最终落到Hive以此保证投放的成功率。为了更精准的控制配额消耗Medusa没有引入单次请求重试机制并制定了服务降级方案以极低的数据丢失率完整地记录了每一个关键词的旅行。 结论和展望 本文我们介绍了美团引入Spark的起源基于Spark所做的一些平台化工作以及Spark在美团具体应用场景下的实践。总体而言Spark由于其灵活的编程接口、高效的内存计算能够适用于大部分数据处理场景。在推广和使用Spark的过程中我们踩过不少坑也遇到过很多问题但填坑和解决问题的过程让我们对Spark有了更深入的理解我们也期待着Spark在更多的应用场景中发挥重要的作用。