flink读取不到文件_日处理数据量超10亿:友信金服基于Flink构建实时用户画像系统的实践...

005aedb0d1d9ffc0cb3c0bed136d7ba1.png

简介: 友信金服公司推行全域的数据体系战略,通过打通和整合集团各个业务线数据,利用大数据、人工智能等技术构建统一的数据资产,如 ID-Mapping、用户标签等。友信金服用户画像项目正是以此为背景成立,旨在实现“数据驱动业务与运营”的集团战略。目前该系统支持日处理数据量超 10 亿,接入上百种合规数据源。

作者 | 杨毅,穆超峰,贺小兵,胡夕导读:当今生活节奏日益加快,企业面对不断增加的海量信息,其信息筛选和处理效率低下的困扰与日俱增。由于用户营销不够细化,企业 App 中许多不合时宜或不合偏好的消息推送很大程度上影响了用户体验,甚至引发了用户流失。在此背景下,友信金服公司推行全域的数据体系战略,通过打通和整合集团各个业务线数据,利用大数据、人工智能等技术构建统一的数据资产,如 ID-Mapping、用户标签等。友信金服用户画像项目正是以此为背景成立,旨在实现“数据驱动业务与运营”的集团战略。目前该系统支持日处理数据量超 10 亿,接入上百种合规数据源。
一、技术选型
传统基于 Hadoop 生态的离线数据存储计算方案已在业界大规模应用,但受制于离线计算的高时延性,越来越多的数据应用场景已从离线转为实时。这里引用一张表格对目前主流的实时计算框架做个对比。

51a15f73fe78be41eae5afdcc350e3d9.png


Apache Storm 的容错机制需要对每条数据进行应答(ACK),因此其吞吐量备受影响,在数据大吞吐量的场景下会有问题,因此不适用此项目的需求。
Apache Spark 总体生态更为完善,且在机器学习的集成和应用性暂时领先,但 Spark 底层还是采用微批(Micro Batching)处理的形式。
Apache Flink 在流式计算上有明显优势:首先其流式计算属于真正意义上的单条处理,即每一条数据都会触发计算。在这一点上明显与 Spark 的微批流式处理方式不同。其次,Flink 的容错机制较为轻量,对吞吐量影响较小,使得 Flink 可以达到很高的吞吐量。最后 Flink 还拥有易用性高,部署简单等优势。相比之下我们最终决定采用基于 Flink 的架构方案。
二、用户画像业务架构
用户画像系统目前为集团线上业务提供用户实时标签数据服务。为此我们的服务需要打通多种数据源,对海量的数字信息进行实时不间断的数据清洗、聚类、分析,从而将它们抽象成标签,并最终为应用方提供高质量的标签服务。在此背景下,我们设计用户画像系统的整体架构如下图所示:

d9ba7f4adfcc64ba37bb589668d8cef2.png


整体架构分为五层:

  1. 接入层:接入原始数据并对其进行处理,如 Kafka、Hive、文件等。
  2. 计算层:选用 Flink 作为实时计算框架,对实时数据进行清洗,关联等操作。
  3. 存储层:对清洗完成的数据进行数据存储,我们对此进行了实时用户画像的模型分层与构建,将不同应用场景的数据分别存储在如 Phoenix,HBase,HDFS,Kafka 等。
  4. 服务层:对外提供统一的数据查询服务,支持从底层明细数据到聚合层数据的多维计算服务。
  5. 应用层:以统一查询服务对各个业务线数据场景进行支撑。目前业务主要包含用户兴趣分、用户质量分、用户的事实信息等数据。

三、用户画像数据处理流程
在整体架构设计方案设计完成之后,我们针对数据也设计了详尽的处理方案。在数据处理阶段,鉴于 Kafka 高吞吐量、高稳定性的特点,我们的用户画像系统统一采用 Kafka 作为分布式发布订阅消息系统。数据清洗阶段利用 Flink 来实现用户唯一性识别、行为数据的清洗等,去除冗余数据。这一过程支持交互计算和多种复杂算法,并支持数据实时 / 离线计算。目前我们数据处理流程迭代了两版,具体方案如下:
1.0 版数据处理流程
数据接入、计算、存储三层处理流程
整体数据来源包含两种:

  1. 历史数据:从外部数据源接入的海量历史业务数据。接入后经过 ETL 处理,进入用户画像底层数据表。
  2. 实时数据:从外部数据源接入的实时业务数据,如用户行为埋点数据,风控数据等。

根据不同业务的指标需求我们直接从集团数据仓库抽取数据并落入 Kafka,或者直接从业务端以 CDC(Capture Data Change)的方式写入 Kafka。在计算层,数据被导入到 Flink 中,通过 DataStream 生成 ID-Mapping、用户标签碎片等数据,然后将生成数据存入 JanusGraph(JanusGraph 是以 HBase 作为后端存储的图数据库介质)与 Kafka,并由 Flink 消费落入 Kafka 的用户标签碎片数据,进行聚合生成最新的用户标签碎片(用户标签碎片是由用户画像系统获取来自多种渠道的碎片化数据块处理后生成的)。

42563ed5a581cf4b227fcceb204da820.png


数据服务层处理流程
服务层将存储层存储的用户标签碎片数据,通过 JanusGraph Spark On Yarn 模式,执行 TinkerPop OLAP 计算生成全量用户 Yids 列表文件。Yid 是用户画像系统中定义的集团级用户 ID 标识。结合 Yids 列表文件,在 Flink 中批量读取 HBase 聚合成完整用户画像数据,生成 HDFS 文件,再通过 Flink 批量操作新生成的数据生成用户评分预测标签,将用户评分预测标签落入 Phoenix,之后数据便可通过统一数据服务接口进行获取。下图完整地展示了这一流程。

f3bbd67852ea139d276f857740c67ee2.png


ID-Mapping 数据结构
为了实现用户标签的整合,用户 ID 之间的强打通,我们将用户 ID 标识看成图的顶点、ID pair 关系看作图的边,比如已经识别浏览器 Cookie 的用户使用手机号登陆了公司网站就形成了对应关系。这样所有用户 ID 标识就构成了一张大图,其中每个小的连通子图 / 连通分支就是一个用户的全部标识 ID 信息。
ID-Mapping 数据由图结构模型构建,图节点包含 UserKey、Device、IdCard、Phone 等类型,分别表示用户的业务 ID、设备 ID、身份证以及电话等信息。节点之间边的生成规则是通过解析数据流中包含的节点信息,以一定的优先级顺序进行节点之间的连接,从而生成节点之间的边。比如,识别了用户手机系统的 Android_ID,之后用户使用邮箱登陆了公司 App,在系统中找到了业务线 UID 就形成了和关系的 ID pair,然后系统根据节点类型进行优先级排序,生成 Android_ID、mail、UID 的关系图。数据图结构模型如下图所示:

7d51d6f666ec47f02dc0d7001204ea9c.png


Gephi
1.0 版本数据处理流程性能瓶颈
1.0 版本数据处理流程在系统初期较好地满足了我们的日常需求,但随着数据量的增长,该方案遇到了一些性能瓶颈:

  1. 首先,这版的数据处理使用了自研的 Java 程序来实现。随着数据量上涨,自研 JAVA 程序由于数据量暴增导致 JVM 内存大小不可控,同时它的维护成本很高,因此我们决定在新版本中将处理逻辑全部迁移至 Flink 中。
  2. 其次,在生成用户标签过程中,ID-Mapping 出现很多大的连通子图(如下图所示)。这通常是因为用户的行为数据比较随机离散,导致部分节点间连接混乱。这不仅增加了数据的维护难度,也导致部分数据被“污染”。另外这类异常大的子图会严重降低 JanusGraph 与 HBase 的查询性能。

43063e3a9160df675860643a5e339d81.png


Gephi

  1. 最后,该版方案中数据经 Protocol Buffer(PB)序列化之后存入 HBase,这会导致合并 / 更新用户画像标签碎片的次数过多,使得一个标签需要读取多次 JanusGraph 与 HBase,这无疑会加重 HBase 读取压力。此外,由于数据经过了 PB 序列化,使得其原始存储格式不可读,增加了排查问题的难度。

鉴于这些问题,我们提出了 2.0 版本的解决方案。在 2.0 版本中,我们通过利用 HBase 列式存储、修改图数据结构等优化方案尝试解决以上三个问题。
2.0 版数据处理流程
版本流程优化点
如下图所示,2.0 版本数据处理流程大部分承袭了 1.0 版本。新版本数据处理流程在以下几个方面做了优化:

b617ba7b58b78958e9c85dff5703264d.png


2.0 版本数据处理流程

  1. 历史数据的离线补录方式由 JAVA 服务变更为使用 Flink 实现。
  2. 优化用户画像图数据结构模型,主要是对边的连接方式进行了修改。之前我们会判断节点的类型并根据预设的优先级顺序将多个节点进行连接,新方案则采用以 UserKey 为中心的连接方式。做此修改后,之前的大的连通子图(图 6)优化为下面的小的连通子图(图 8),同时解决了数据污染问题,保证了数据准确性。另外,1.0 版本中一条数据需要平均读取十多次 HBase 的情况也得到极大缓解。采用新方案之后平均一条数据只需读取三次 HBase,从而降低 HBase 六七倍的读取压力(此处优化是数据计算层优化)。

68ccde31a40ce242a3917643585e78d7.png


Gephi

  1. 旧版本是用 Protocol Buffer 作为用户画像数据的存储对象,生成用户画像数据后作为一个列整体存入 HBase。新版本使用 Map 存储用户画像标签数据,Map 的每对 KV 都是单独的标签,KV 在存入 HBase 后也是单独的列。新版本存储模式利用 HBase 做列的扩展与合并,直接生成完整用户画像数据,去掉 Flink 合并 / 更新用户画像标签过程,优化数据加工流程。使用此方案后,存入 HBase 的标签数据具备了即席查询功能。数据具备即席查询是指在 HBase 中可用特定条件直接查看指定标签数据详情的功能,它是数据治理可以实现校验数据质量、数据生命周期、数据安全等功能的基础条件。
  2. 在数据服务层,我们利用 Flink 批量读取 HBase 的 Hive 外部表生成用户质量分等数据,之后将其存入 Phoenix。相比于旧方案中 Spark 全量读 HBase 导致其读压力过大,从而会出现集群节点宕机的问题,新方案能够有效地降低 HBase 的读取压力。经过我们线上验证,新方案对 HBase 的读负载下降了数十倍(此处优化与 2 优化不同,属于服务层优化)。

四、问题
目前,线上部署的用户画像系统中的数据绝大部分是来自于 Kafka 的实时数据。随着数据量越来越多,系统的压力也越来越大,以至于出现了 Flink 背压与 Checkpoint 超时等问题,导致 Flink 提交 Kafka 位移失败,从而影响了数据一致性。这些线上出现的问题让我们开始关注 Flink 的可靠性、稳定性以及性能。针对这些问题,我们进行了详细的分析并结合自身的业务特点,探索并实践出了一些相应的解决方案。
CheckPointing 流程分析与性能优化方案
CheckPointing 流程分析
下图展示了 Flink 中 checkpointing 执行流程图:

9d6470a3e69c471c5f70572a9342d5af.png


Flink 中 checkpointing 执行流程

  1. Coordinator 向所有 Source 节点发出 Barrier。
  2. Task 从输入中收到所有 Barrier 后,将自己的状态写入持久化存储中,并向自己的下游继续传递 Barrier。
  3. 当 Task 完成状态持久化之后将存储后的状态地址通知到 Coordinator。
  4. 当 Coordinator 汇总所有 Task 的状态,并将这些数据的存放路径写入持久化存储中,完成 CheckPointing。

性能优化方案
通过以上流程分析,我们通过三种方式来提高 Checkpointing 性能。这些方案分别是:

  1. 选择合适的 Checkpoint 存储方式
  2. 合理增加算子(Task)并行度
  3. 缩短算子链(Operator Chains)长度

选择合适的 Checkpoint 存储方式
CheckPoint 存储方式有 MemoryStateBackend、FsStateBackend 和 RocksDBStateBackend。由官方文档可知,不同 StateBackend 之间的性能以及安全性是有很大差异的。通常情况下,MemoryStateBackend 适合应用于测试环境,线上环境则最好选择 RocksDBStateBackend。
这有两个原因:首先,RocksDBStateBackend 是外部存储,其他两种 Checkpoint 存储方式都是 JVM 堆存储。受限于 JVM 堆内存的大小,Checkpoint 状态大小以及安全性可能会受到一定的制约;其次,RocksDBStateBackend 支持增量检查点。增量检查点机制(Incremental Checkpoints)仅仅记录对先前完成的检查点的更改,而不是生成完整的状态。与完整检查点相比,增量检查点可以显著缩短 checkpointing 时间,但代价是需要更长的恢复时间。
合理增加算子(Task)并行度
Checkpointing 需要对每个 Task 进行数据状态采集。单个 Task 状态数据越多则 Checkpointing 越慢。所以我们可以通过增加 Task 并行度,减少单个 Task 状态数据的数量来达到缩短 CheckPointing 时间的效果。
缩短算子链(Operator Chains)长度
Flink 算子链(Operator Chains)越长,Task 也会越多,相应的状态数据也就更多,Checkpointing 也会越慢。通过缩短算子链长度,可以减少 Task 数量,从而减少系统中的状态数据总量,间接的达到优化 Checkpointing 的目的。下面展示了 Flink 算子链的合并规则:

  1. 上下游的并行度一致
  2. 下游节点的入度为 1
  3. 上下游节点都在同一个 Slot Group 中
  4. 下游节点的 Chain 策略为 ALWAYS
  5. 上游节点的 Chain 策略为 ALWAYS 或 HEAD
  6. 两个节点间数据分区方式是 Forward
  7. 用户没有禁用 Chain

基于以上这些规则,我们在代码层面上合并了相关度较大的一些 Task,使得平均的操作算子链长度至少缩短了 60%~70%。
Flink 背压产生过程分析及解决方案
背压产生过程分析
在 Flink 运行过程中,每一个操作算子都会消费一个中间 / 过渡状态的流,并对它们进行转换,然后生产一个新的流。这种机制可以类比为:Flink 使用阻塞队列作为有界的缓冲区。跟 Java 里阻塞队列一样,一旦队列达到容量上限,处理速度较慢的消费者会阻塞生产者向队列发送新的消息或事件。下图展示了 Flink 中两个操作算子之间的数据传输以及如何感知到背压的:

aa25619f169ff6848dded1a970c53fba.png


首先,Source 中的事件进入 Flink 并被操作算子 1 处理且被序列化到 Buffer 中,然后操作算子 2 从这个 Buffer 中读出该事件。当操作算子 2 处理能力不足的时候,操作算子 1 中的数据便无法放入 Buffer,从而形成背压。背压出现的原因可能有以下两点:

  1. 下游算子处理能力不足;
  2. 数据发生了倾斜。

背压解决方案
实践中我们通过以下方式解决背压问题。首先,缩短算子链会合理的合并算子,节省出资源。其次缩短算子链也会减少 Task(线程)之间的切换、消息的序列化 / 反序列化以及数据在缓冲区的交换次数,进而提高系统的整体吞吐量。最后,根据数据特性将不需要或者暂不需要的数据进行过滤,然后根据业务需求将数据分别处理,比如有些数据源需要实时的处理,有些数据是可以延迟的,最后通过使用 keyBy 关键字,控制 Flink 时间窗口大小,在上游算子处理逻辑中尽量合并更多数据来达到降低下游算子的处理压力。
优化结果
经过以上优化,在每天亿级数据量下,用户画像可以做到实时信息实时处理并无持续背压,Checkpointing 平均时长稳定在 1 秒以内。
五、未来工作的思考和展望
端到端的实时流处理
目前用户画像部分数据都是从 Hive 数据仓库拿到的,数据仓库本身是 T+1 模式,数据延时性较大,所以为了提高数据实时性,端到端的实时流处理很有必要。
端到端是指一端采集原始数据,另一端以报表 / 标签 / 接口的方式对这些对数进行呈现与应用,连接两端的是中间实时流。在后续的工作中,我们计划将现有的非实时数据源全部切换到实时数据源,统一经过 Kafka 和 Flink 处理后再导入到 Phoenix/JanusGraph/HBase。强制所有数据源数据进入 Kafka 的一个好处在于它能够提高整体流程的稳定性与可用性:首先 Kafka 作为下游系统的缓冲,可以避免下游系统的异常影响实时流的计算,起到“削峰填谷”的作用;其次,Flink 自 1.4 版本开始正式支持与 Kafka 的端到端精确一次处理语义,在一致性方面上更有保证。

7a0531b9c938d8dfa5da15e62ba3aaf3.png

作者介绍:
杨毅:友信金服计算平台部 JAVA 工程师
穆超峰:友信金服计算平台部数据开发高级工程师
贺小兵:友信金服计算平台部数据开发工程师
胡夕:友信金服计算平台部技术总监

存储 消息中间件 分布式计算 搜索推荐 Java Kafka 分布式数据库 数据处理 流计算 Hbase

a6753e8a78ca64e8623a7c9f294d68ef.png

版权声明:本文中所有内容均属于阿里云开发者社区所有,任何媒体、网站或个人未经阿里云开发者社区协议授权不得转载、链接、转贴或以其他方式复制发布/发表。申请授权请邮件developerteam@list.alibaba-inc.com,已获得阿里云开发者社区协议授权的媒体、网站,在转载使用时必须注明"稿件来源:阿里云开发者社区,原文作者姓名",违者本社区将依法追究责任。 如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

apache pulsar_Apache Pulsar:分布式Pub-Sub消息系统

apache pulsarApache Pulsar是一个开源的分布式pub-sub消息传递系统,最初是由Yahoo创建的,并且是Apache Software Foundation的一部分 。 Pulsar是用于服务器到服务器消息传递的多租户高性能解决方案。 脉冲星的主要功能包括[4]: 对Pulsar…

python deque索引超出范围_Python基础语法

学习Python的四个要素有数据,函数,条件循环和模块一、数据数据是Python编程过程中的原材料,通过导入数据,对数据进行操作,实现预先设想的功能。数据共有5种类型,分别是字符串、数字、容器、布尔值和空值。字…

Path环境变量的理解以及设置MinGW环境变量

配置path环境变量 在使用MinGW的时候,不小心把path变量的东西全部删掉了,结果只能自己重新设置path变量,首先要知道如何设置path变量。 Path路径:用来指定可执行文件的搜索路径,也就是后缀名为.exe文件,方…

python爬取网站的图片

python爬取网站的图片 本次爬取图片所需要用到的库:Requests库,BeautifulSoup库,正则表达式,os库。 思路:先爬一张图片,再爬一个网站的图片 先爬一张图片: 首先要得到这张图片的地址&#x…

用户登陆_华为路由器AAA用户密码登陆你了解吗?

AAA Authentication(认证)、Authorization(授权)、Accounting()它提供了认证、授权、计费三种安全功能,可以验证用户帐户是否合法,授权用户可以访问的服务,并记录用户使用网络资源的…

word域变成正常文本_【Word小技巧】不学会后悔哦~

工作中使用Word早已成了习惯,因此,今天小编将为大家分享几个实用的的Word小技巧。重叠字快速录入文字录入是word最基本操作,过程中我们难免要输入重叠字,例如:热热闹闹,卿卿我我等……你知道如何快速录入吗…

sql server 2008 年累计数_Windows Server 2008 和 SQL Server 2008将终止支持 迁移至Azure 微软提供3年免费技术支持...

点击上方蓝色字关注我们~迁移至 Azure 并利用免费扩展安全更新。了解有关支持终止建议的更多信息,请使用浏览器访问:https://www.microsoft.com/zh-cn/sql-server/sql-server-2008.对您意味着什么1 2017年基于风险的安全报告; 思科 2017 年度网络安全报告…

旧版Requests库

requests库基本使用Requests解析库方法response对象response对象的属性**r.encoding**属性与**r.apparent_encoding**属性的区别requests库的异常举例Requests解析库 方法 最常用的两个方法: request.get() request.post() 作用:都是从服务器获取网页信息 区别&…

夸克浏览器怎么安装脚本_iOS 第一浏览器发布安卓版,除了真香我还能说什么...

如果不算 Safari 的话,iOS 平台公认最好的浏览器是 Alook。无推送无新闻无广告、日常售价 12 元、工具类排行第三、7.8 万个评分足以证明其优秀。以至于很多双持或对 Alook 有所了解的用户都希望 Alook 能推出安卓端。现在安卓端真的来了。(安卓端免费)假如这个时候…

Windows 10 笔记本如何使用外接显示器

文章目录如何连接外接显示屏如何设置显示模式如何设置不同显示屏各自的分辨率如何设置主显示器通过显卡来设置显示器如何连接外接显示屏 VGA 线或者 HDMI 线连接好电脑和显示器,以 HDMI 线为例简单讲下吧。 显示器可能会有多个 HDMI 接口,假设你插入 H…

蓝牙信号强度检测app_基于蓝牙技术的智能插座方案

有这样一句话“科技时代,生活轻快”。随着社会现代化程度越来越高,科技的应用为人们的生活带来便捷,大大提高了工作效率。纵观市场上“智能家居”产品很多,功能各异,各有千秋,但是针对家电控制的智能插座还…

图片清晰度,分辨率,像素总结

像素 像素是一个个小方块,是构成位图的基本单位。将图片放大即可看出来,如图: 分辨率 显示分辨率是指像素的总数量,如上图的22001400,也就是宽有2200个像素,高有1400个像素。 图像分辨率是指每英寸所包含…

apache isis_使用Apache Isis快速进行SEMAT应用程序开发

apache isisTL; DR这是关于一个帖子会谈SEMAT宠物项目我创建使用Apache伊希斯和部署到OpenShift在线这里http://semat.ofbizian.com Apache Isis 作为主要在后端系统上工作的Java开发人员,我讨厌创建用户界面和处理Java脚本。 幸运的是,有一些Java项目&…

MacBook外接显示器及相关设置详解(分屏/多屏)

文章目录一、连接显示器和电脑二、打开显示器设置界面三、调整显示器图标位置四、设置主显示器五、移动 Dock六、镜像模式七、合盖模式八、扩展模式九、设置外接显示器竖屏显示十、外接显示器后,如何调出更多分辨率十一、关于程序坞显示的问题一、连接显示器和电脑 …

ibm liberty_使用Eclipse和Open Liberty的Java EE 8上的Java 9

ibm liberty几周前,我写了一篇文章,题目是哪个IDE和服务器支持Java EE 8和Java9 ,着眼于Java 9和Java EE 8之间的当前状态。您可以期望事情发展很快,现在我们有了一些alpha和支持Java 9和Java EE 8的开发版本。这些是– Payara 5…

关键词分词工具_快图制作工具 | 如何制作词云图?

点击蓝字关注我们如何制作词云图?首先,我们需要对“词云”有个简单的概念。“词云”这个概念最先由美国西北大学新闻学副教授、新媒体专业主任里奇戈登(Rich Gordon)提出。“词云”(别名:文字云,外文名:wordle)即由词汇…

openhub_OpenHub框架–下一个有趣的功能

openhub这是有关OpenHub框架系列的第三篇文章-第一篇介绍OpenHub框架 ,第二篇介绍异步消息传递模型 。 该系列的最后一篇文章将更详细地介绍其他一些有趣的功能,并说明为什么OpenHub可以成为您的集成项目的理想选择的原因。 节流 节流是一种功能&#…

售票系统的组件图和部署图_识读配电箱系统图

配电箱确实有很多字母,要熟悉这些字母的基本含义,才能更准确地知道配电箱系统图的意思。网上查了一些资料,发现配电箱中的字母实在是太多了,先简单说几个需要基本认识的字母:GCK、GCS、MNS是低压抽出式开关柜&#xff…

packt_Packt和Java Code Geeks提供的$ 5 Java编程书籍!

packt你好,极客! 今天,我们为您带来一些激动人心的消息! Java Code Geeks和Packt联手为您提供广泛的书籍库每周折扣。 对于开发人员来说,Java仍然是最强大的选择之一,它是定义企业和移动设备的语言。 本…

MacBook 如何一次性关闭所有程序的通知消息

特别反感应用程序经常弹出通知消息,挨个去关闭应用程序的通知消息又特别麻烦,可以打开『勿扰模式』,这就可以屏蔽掉所有的通知消息了。