离线计算平台系列之一

简介: # 离线计算平台简介 在蚂蚁金服风控体系里面,有一个重要的环节就是离线仿真,在规则,模型上线之前,在离线的环境里面进行仿真验证,来对规则和模型进行效能的评估,避免人为因素造成不准确性从而造成的资损。起初为了达到这个目的,离线计算平台就这样孕育而生了,慢慢地整个离线平台覆盖了更多风控的业务,也慢慢变成目前Odps-Spark最大的用户,拥有的集群数目也是最大的。离线计算平台主要以Spark为基

离线计算平台简介

在蚂蚁金服风控体系里面,有一个重要的环节就是离线仿真,在规则,模型上线之前,在离线的环境里面进行仿真验证,来对规则和模型进行效能的评估,避免人为因素造成不准确性从而造成的资损。起初为了达到这个目的,离线计算平台就这样孕育而生了,慢慢地整个离线平台覆盖了更多风控的业务,也慢慢变成目前Odps-Spark最大的用户,拥有的集群数目也是最大的。离线计算平台主要以Spark为基础,在其上建立起来的一套平台. 后面我们团队会给大家带来一系列,关于离线平台的架构以及我们做过相应业务以及经验,希望和大家一起来探讨。
下面由我来给大家分享下,我们整个团队建立起离线计算平台里面的SparkContext管理以及几个Spark优化手段。

SparkContext 管理

在我们的离线业务场景里面,我们需要持续地接受用户提交实验任务进行分析以及运算,所以对于Spark的要求第一点就是需要Long-Live的SparkContext, 可以持续接受任务提交,而不是类似d2那样提交一次性的任务。所以我们以目前Odps-Spark Client模式为基础,建立了一套自己的SparkContext 管理系统,提供了动态新增,删除SparkContext功能,可以持续地提交任务,调度相应任务的功能。

Spark1

由于SparkContext需要一个独立的JVM进程服务,我们目前是利用RMI来完成启动SparkContext的工作。 在应用服务器上面,当它被通知自己需要启动SparkContext的时候,就会在进行相应的Spark Jar准备,然后进行打包,并且启动相应的RMI进程来当做SparkContext. 在任务执行的流程中,前端系统会向离线系统提交任务,离线系统就有一套自己的任务调度系统,根据目前管理的SparkContext里面选择一个相对比较空闲的,进行任务提交,否则就进行等待。当任务提交到RMI Server之后,就会对任务进行相应的组装以及转化成Spark可以执行的任务,进行执行并且同Spark Cluster进行交互。最终Spark任务结果会同步地返回给RMI Server, 然后再通过RMI Server异步的通知到应用服务器,并且进行任务的进一步处理。

经验分享:控制好每个SparkContext的并发度,充分利用SparkContext的能力(目前我们一个SparkContext上面并发3个任务,后续会引入动态任务大小的评估,从而实现真正的动态任务提交以及资源分配),统一管理每个SparkContext下面的并发线程,而且不是每个任务都去创建线程池,特别注意从RMI Server返回给离线系统数据,不能带有Scala相关的东西,离线系统无法解析。优雅地停掉SparkContext, 防止资源的泄露。


Spark程序调优手段

对于风控来说,查看用户历史数据来进行判断风险的行为是一种常见的手段,所以动不动就30天的交易记录,90的某相累计数据。。。 做离线的小伙伴已经哭晕在厕所,在做Spark离线的期间,我们也产出了自己的东西,这里我就介绍三种比较有意义的内容,后续欢迎大家来交流。

  • 动态加载Jar
    由于安全性的问题,目前Odps-Spark并没有实现动态加载Jar的功能,那如果真有这部分需求的时候,我们应该怎么做呢?例如有些规则脚本在我们实验的时候进行了更新,离线也需要同步更新,可是这里SparkContext已经创建出来,没有办法再新增Jar了。目前我们的解决方案是,在执行任务的时候,把这些Jar打好包,并且创建出一个ClassLoader来加载这些可变的Jar, 然后在实验的时候,把Classloader 通过broadcast机制分发到各个worker上面,然后再需要利用这些Jar的闭包里面,通过这个classloader进行加载并且执行。这里需要注意的问题是: 多线程的问题, 因为broadcast value每台worker只有一份,如果一个台worker上面有多个cpu去访问broadcast value的时候,如果没有控制好多线程的问题,就会出现一些奇葩问题,而且这种问题不好排查,因为已经在worker上面,不好去打日志进行验证。所以在处理Broadcast value的时候,尽量做到线程安全。
  • 减少shuffle key的数目
    在Spark开发中,基本上都会用到join, cogroup等操作,这类操作就会产生shuffle操作, Spark程序的性能很大程度就是取决于shuffle的性能上面,除了调优修改shuffle的参数(spark.shuffle.memoryFraction, spark.shuffle.manager, spark.shuffle.file.buffer等), 也可以利用其它手段来完成

    1. map side join, 特别是在两个RDD, 一个数据量小, 一个数据量大的情况,我们可以把数据量小的那个做成broadcast, 从而把这次shuffle操作转变成一次map操作,大大地减少shuffle中的性能消耗。
    2. 利用Bloom Filter过滤掉多余的key, 这也是我们在实践发现的,当两个RDD进行cogroup的时候,其实会有很多无用的key, 例如用userId进行关联的时候,会很多无用的userId进行干扰,但是他们也参与整个shuffle的流程中,这时候我们可以把key数目相对比较少的那个RDD的key收集来(可能会有多次collect操作,因为每次collect操作有大小限制),然后把这些做成Bloom Filter去过滤另外一个RDD里面的key, 从而达到减少shuffle中间的数据量的效果。
  • 数据倾斜的解决
    当你在logview上面发现你的2400分区的数据,2399都跑完,另外一个分区怎么跑都跑不完,并且执行时间已经远远超越同伴啦。那么恭喜你,很有可能是数据倾斜发生了。目前介绍下我们的做法

    • 首先是去采集哪些key会出现数据倾斜,这里可以使用groupbykey,然后进行count, 如果这样都会挂掉,那么进行sample抽样来解决,随机抽样10%的数据来进行判断。
    • 找到这样的key之后, 在RDD A里面过滤掉热点对应的key, 形成nonHot的RDD A, 然后针对有HotKey的RDD, 里面的每一个key打上 n 以内的随机数作为后缀。

        hasHotEvent.map(x =>   
      if (hotKeySet.value.contains(x.1)) {  
      (x.1 + "@" + Random.nextInt(hashPartitionSize), x.2)  
       else   
      x  
        
      })
    • 在RDD B里面首先同样先过滤掉热点的key, 形成nonHot的RDD B, 然后针对HotKey的RDD, 里面每一个key按顺序附加 0 - n 的后缀,每条hotKey的数据就会膨胀成n条数据

    1. hotValues = res.filter(x => hotKeySet.value.contains(x.1)).flatMap(x =>
      for (i <- 0.until(hashPartitionSize)) yield {

      (x.1 + "@" + i, x.2)  

      }

      })
    • 最后notHotKey的RDD 进行join, hotkey的RDD进行join, 最后再进行union操作就可以等到最后的结果。

经验总结:主要思路就是把少数的key,打散成n份去进行join,这样就不会集中大量的数据在一个worker中,并且把它高挂。如果针对RDD里面很多的key都是hot key的情况,就无需过滤hot key, 直接给一个RDD打上随机数,另外一个RDD扩容n份进行join.


To Be Continued

还有很多细节以及经验想跟大家分享,奈何实力有限,后续的分享会持续到来,大家会看到变态数据点优化,velocity数据结构优化,会针对新版的内存计算平台进行相应的改造以及相关的技术落地。 以上都是来自 蚂蚁金服-大安全-成都安全技术平台的小伙伴们。顺便打个小广告,我们在大量招人,希望回成都的同学,以及想做离线这块的同学(当然我们也很多实时的业务),可以联系@锋扬,@云震。

目录
相关文章
|
JavaScript 对象存储
JS - 阿里云 OSS 文件下载通用办法(支持跨域)
JS - 阿里云 OSS 文件下载通用办法(支持跨域)
5095 0
JS - 阿里云 OSS 文件下载通用办法(支持跨域)
|
4月前
|
XML 人工智能 JSON
别再让 AI 自动总结 Skill 了!
本文作者姜饼,详解如何将重复流程拆解为真正可复用的Skill。指出AI自动总结易生成冗长Prompt,而非结构化Skill;强调Skill应是含入口(SKILL.md)、资料(references/)和脚本(scripts/)的工作目录,并明确各部分职责。附5步拆解法与自查清单,助你告别“伪Skill”。
451 0
|
5月前
|
JSON 缓存 监控
【剪映小助手】辅助工具接口
CapCut Mate辅助工具接口提供链接提取、贴纸搜索与数据转换三大核心功能,涵盖get_url、search_sticker及多种格式转换API,支持高效素材处理与自动化集成,专为视频创作者优化工作流。(239字)
|
机器学习/深度学习 计算机视觉
RT-DETR改进策略【模型轻量化】| GhostNetV2:利用远距离注意力增强廉价操作
RT-DETR改进策略【模型轻量化】| GhostNetV2:利用远距离注意力增强廉价操作
629 63
RT-DETR改进策略【模型轻量化】| GhostNetV2:利用远距离注意力增强廉价操作
|
前端开发 网络架构 智能硬件
每日一个计算机小知识:Host
每日分享一个计算机小知识:Host(主机)指网络中拥有独立IP、可参与通信的设备,如电脑、手机、服务器等。IP如同设备的“门牌号”,是定位Host的关键。开发中常说的Host多指部署服务的服务器,具备高配置与固定公网IP,便于他人访问接口或网站。
|
安全 Linux 开发者
⭐⭐⭐⭐⭐Linux C/C++ 进程崩溃诊断以及有效数据收集:解锁代码问题快速定位与修复的方法
⭐⭐⭐⭐⭐Linux C/C++ 进程崩溃诊断以及有效数据收集:解锁代码问题快速定位与修复的方法
1411 1
|
人工智能 自然语言处理 测试技术
Goedel-Prover:专为自动化数学问题的形式证明生成而设计的 LLM,快速解决形式化数学问题
Goedel-Prover 是一款由普林斯顿大学和清华大学等机构联合推出的开源模型,专注于自动化数学问题的形式证明生成。它通过将自然语言数学问题翻译成形式语言(如 Lean 4),显著提升了数学问题的证明效率。
950 4
Goedel-Prover:专为自动化数学问题的形式证明生成而设计的 LLM,快速解决形式化数学问题
|
人工智能 IDE 测试技术
如何用好 AI 编码工具,让通义灵码帮你做更多工作
如何用好 AI 编码工具,让通义灵码帮你做更多工作
1064 2
|
前端开发 JavaScript 安全
前端JS实现密码校验键盘横竖、26字母、相同字母、相同数字、密码包含用户名、数字 字母不能连续 不能相同三个、不能横向 竖向 连续三个 包含字符、不能有中文符号
该 JavaScript 代码实现了一个严格的密码校验功能,确保密码满足多种安全要求,包括长度、字符类型、不包含中文及特殊字符、不与用户名相似等。通过多个辅助函数,如 `validateFormat` 检查密码格式,`isHasChinaCharFun` 检测中文符号,`getCharAll` 生成键盘组合,以及 `checkPasswordFun` 综合验证密码的有效性和安全性。此工具对于提高用户账户的安全性非常有用。
1070 0
|
存储 数据安全/隐私保护
贴片卡与插拔卡的优缺点
在讨论贴片卡(通常指的是嵌入在设备内部的存储卡,如SIM卡、eMMC等)与插拔卡(如SD卡、microSD卡等,用户可以轻松插入和拔出的存储卡)的优缺点时,我们可以从多个方面进行比较:

热门文章

最新文章