写点什么

Yelp 的实时流技术之五:数据管道之 Salesforce Connector

  • 2016-11-23
  • 本文字数:3000 字

    阅读完需:约 10 分钟

本文翻译自 Data Pipeline: Salesforce Connector ,原作者为Ian F.,已获得原网站授权。

这是关于 Yelp 的实时流数据基础设施系列文章的第五篇。这个系列会深度讲解我们如何用“确保只有一次”的方式把 MySQL 数据库中的改动实时地以流的方式传输出去,我们如何自动跟踪表模式变化、如何处理和转换流,以及最终如何把这些数据存储到 Redshift 或 Salesforce 之类的数据仓库中去。

阅读本系列的第一篇:
中文:一天几十亿条消息:Yelp 的实时数据管道
英文: Billions of Messages a Day - Yelp’s Real-time Data Pipeline

阅读本系列的第二篇:
中文: Yelp 的实时流技术之二:将 MySQL 表数据变更实时流到 Kafka 中
英文: Streaming MySQL tables in real-time to Kafka

阅读本系列的第三篇:
中文: Yelp 的实时流技术之三:不止是模式存储服务的 Schematizer
英文: More Than Just a Schema Store

阅读本系列的第四篇:
中文: Yelp 的实时流技术之四:流处理器 PaaStorm
英文: PaaStorm: A Streaming Processor

Yelp 用客户关系管理(customer relationship management,CRM)平台 Salesforce 来为超过 2000 人的销售团队提供支持。Salesforce 提供了许多现成的功能,让我们的销售团队可以轻松地定制他们的业务流程。

我们的销售团队主要做什么呢?他们卖广告包!他们卖给谁呢?Yelp 上的商家!那我们如何从 Yelp 的数据库中获取这些商家信息并提供给 Salesforce 呢?读过下文你就明白了。

以前的方法

我们现有的单向同步基础架构名为“Bulk Workers”,是早在 2010 年设计的了,目的是要显著地改进端到端发送数据的时间。这套设计方案成功地把同步时间从 3 星期缩短为 24 小时,这很棒!这套方案细节是怎样的呢?

这些“Bulk Workers”实际上就是一些 Gearman 定时任务,它们会检索业务表中的每一行数据,再按 Salesforce 的模式对这些数据进行转换。转换后的数据会用一个 Salesforce 客户端发送给 Salesforce,客户端是基于 Beatbox 开发的,主要的改进是增加了对 Salesforce 批量 API 的支持。

旧的集成方法

上面的方法一直工作得很好……直到它再也顶不住的时候。

在接下来的 5 年里,这套架构见证了数据的急速增长,从最初的 30 万亿行,到 2015 年超过了 100 万亿行。数据更新的操作影响尤其大。后来,同步时间开始越拖越长。我们就知道我们需要优化一下系统,来更好地支持更新操作了。

进入正题:数据管道

于是我们开始收集需求。我们认为新的解决方案需要下面这些:

  • 实时处理
  • 保证“至少一次提交”
  • 自带监控和告警等功能
  • 由配置驱动模式之间的转换
  • 可以很容易地增加新字段和转换

差不多是在相同的时间点,我们已经在做依靠分布式发布 / 订阅消息系统 Kafka 新数据管道了。这个数据管道可以直接满足我们的前三个需求。那我们剩下的工作就是构建一个转换框架来满足后面的两个需求,并且作为到Salesforce.com 的连接器。

Salesforce 数据管道集成方法

转换器(Transformer)

我们采用了一个名为 PaaStorm 的、在 Yelp Hackathon 上产生的并且已经应用到生产环境的项目作为我们的 Kafka-to-Kafka 处理器,叫这个名字是因为它与 Storm 很相似,并且是用 Yelp PaaSTA 部署的。在保留了 Storm 的范式的前提下,我们构建了一个通用的转换器,可以生成许多实例,处理各个 Topic 中的要发往 Salesforce 的原始数据。在处理源 Topic 时,每个实例都会从一个 YAML 文件中得到转换步骤,然后再做拷贝、移动和(或)值映射操作。这很重要,因为 Salesforce 的模式存在的时间远远长于我们的新架构,是很难改动的。这个也意味着没有什么比较自动的方法去做字段映射。如果有一个由配置驱动的映射关系,那就让我们可以快速对转换做解析而不必真正地部署代码。这对项目的灵活性至关重要。

每个转换器都会向一个新的 Kafka Topic 中发布序列化后的 Salesforce 对象,供上传器消费并发往 Salesforce。

上传器(Uploader)

让上传器自己做为一个实例就可以让我们清楚地知道我们有多少个服务要与 Salesforce.com 通信。上传器会消费各个转换器转换后的消息,将它们批量发送到 Salesforce。因为发往 Salesforce 的请求是发向互联网的,所以这是我们的管道中最慢的部分之一。因而能不有效地进行批量处理就对性能影响非常大。使用合适的 API 也非常重要。因为 Salesforce 提供了好多种不同的 API,所以有时候选择用哪个也不容易。为了让我们可以很容易地不必做更多的工作就在 API 之间切换,我们写了个通用的客户端,用它包装了现有的 SOAP、REST 和批量 API 等 Python 客户端。我们也写了一个 ORM(Object-Relational Mapping)客户端,并为每张我们要写的目标表定义了模型。这让我们可以在发送到 Salesforce.com 之前就对数据进行验证,并且在写数据的时候确认该用哪个 Salesforce External ID

评估

我们用来评估的第一张表就是我们的广告商表。选它是因为它是我们 Yelp 整体业务中规模比较小的表之一,但对于我们的销售团队的运作又是非常重要的。在之前要把数据变更操作从 Yelp 同步到 Salesforce 需要 16 小时。在切换到新架构之后,可以看到同步时间变成了平均约 10 秒钟,偶尔会有一些波峰,但也就只是变为几分钟而已!这就足以表明出现在 Salesforce 上的数据是非常可靠的,销售团队在查看数据时,再也不必不断地来要更新的数据了。

每秒钟平均同步延迟

挑战

听起来很容易?事实上并非如此。在设计和构建我们的连接器的过程中,我们要解决好几个问题:

我们注意到在处理失败的更新操作中有很大部分都是在 Salesforce 一侧超时了,或者是由于没能成功的为某行数据获取锁而被拒绝了。这两种问题的根本原因都在于我们在 Salesforce 的程序中使用了大量的触发器和回滚操作。差不多每张表上都有非常复杂的逻辑,而每一条写操作都要把这些逻辑全处理一遍,以保证不同数据之间的一致性,或者为了将某些业务流程自动化。这些功能本来都是很好的,但碰上问题时你就不那么想了。所以我们工作的重点就是要减少做写操作时的处理量。把这样的处理尽可能地挪到异步处理的过程中,就可以减少我们锁定单条记录的时间,也就减少了每条写操作的处理时间。

另一个要解决的问题是依赖关系。我们本来的数据源(MySQL)有限制依赖,而 Kafka 并没有。虽然写到每个 Kafka Topic 中的消息都是保证有序的,但是我们并不能保证这些 Topic 中的数据会以某个确定的速度被处理。在各张表都彼此依赖的情况下这个问题就很严重,因为一张表中的数据可能会比另一张表的数据更先被读取和更新,导致数据在一定时间内处于不一致的状态。一个常见的例子就是广告商的数据记录会比用户的数据稍早到一会。因为广告商的数据中包含一个指向 User 表的外键字段,写入就会失败。因此我们就要跟踪哪些数据是因为不符合依赖约束而写入失败的,然后再由上传器在确定依赖关系满足了之后再重试。把上传的操作按依赖顺序序列化并处理重试,这可以覆盖我们绝大多数的用例,尽管这意味着我们因此没办法达到一个很高的并行度。

还有一个问题,就是我们的数据没有全放在一个单一的数据库里面,所以对我们来说可用的就是单条的数据记录。为了解决这样的问题我们开发了新功能,读两个 Topic 中的数据并把它们关联起来,然后再把关联后的数据重新发布出去。

结论

使用基于 Kafka 的数据管道来为销售团队获取数据,我们已经在这方面取得了很大改进。接下来我们准备构建自己的基础架构,这样就可以实现其他的转换操作、简单的聚合、以及在写 Salesforce 的高可靠保障等等功能。

2016-11-23 16:522569
用户头像

发布了 152 篇内容, 共 79.8 次阅读, 收获喜欢 64 次。

关注

评论

发布
暂无评论
发现更多内容

localStorage和sessionStorage本地存储

我是哪吒

html html5 面试 大前端 html/css

产业互联网业务与团队的思考

Geek_vidmje

软件教练说:性能优化与性能设计,“相亲相爱”的一对

华为云开发者联盟

架构 性能优化 设计 程序 软件教练

阿里一线架构师甩出“源码阅读指南”,从源码到实战,一键搞定

比伯

Java 编程 程序员 架构 计算机

Java学习笔记整理:Spring+tomcat+Kafka+多线程面试笔记

Java架构之路

Java 程序员 架构 面试 编程语言

成长篇-结构思考力笔记(完整版)

小诚信驿站

程序员 刘晓成 小诚信驿站 成长笔记 28天写作

团队建设,凝聚人心打胜战

一笑

管理 团队建设 28天写作

区块链真正的价值即将“引爆”行业应用

CECBC

区块链金融

NeoKylin-Server-5.0离线部署etcd+flannel集群,实现docker容器跨主机网络通信

星河寒水

Docker etcd flannel 麒麟操作系统 离线部署

融资融券两融系统搭建开发

v16629866266

数字货币将如何改变日常生活

CECBC

数字货币

蚂蚁金服二面被血虐,鬼知道面试的我经历了什么?

Java架构之路

Java 程序员 架构 面试 编程语言

谁,是产品的利益相关方?

不离

极客大学认识产品经理 极客大学产品经理训练营 跟着二爷学产品

Mybatis【16】-- Mybatis多对一关联查询

秦怀杂货店

数据库 mybatis

Soul 源码阅读 06|Nacos 同步数据分析

哼干嘛

【Node.js】事件触发器 - 基础篇

德育处主任

Node 28天写作

架构解读丨Volcano作业资源预留设计原理

华为云开发者联盟

批处理 Volcano 资源预留 作业资源预留

架构师训练营第 2 期 第 7 周 作业一

老腊肉

架构师训练营第2期

面试官问:ZooKeeper是强一致的吗?怎么实现的?

Java 编程 程序员 面试 分布式

30+程序员竞争力从哪里来?

我心依然

程序员 竞争力

真狠!涵盖了Netty+Spark+Hadoop+分布式五部分!讲的清清楚楚!

996小迁

redis hadoop 架构 面试 Netty

苹果设备电池及充电周期

张老蔫

28天写作

两种端到端通用目标检测方法

华为云开发者联盟

训练 目标检测 端到端 DETR DeFCN

jdk8 String和StringBuilder对象创建所在位置

ilovealt

Java string StringBuilder

BAT面试Spring全家桶:Spring+SpringBoot+SpringCloud+SpringMVC

Java架构之路

Java 程序员 架构 面试 编程语言

浅说 SQLite 的许可证模式

Justin

开源 版权保护 28天写作

区块链人才能力评价测试机构亮相

CECBC

区块链人才

奇葩java迭代器笔试题,做对算你厉害

田维常

迭代器模式

Elasticsearch 是分布式文件存储么 ?

escray

elastic 七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试

老外程序员的Java性能优化方式是什么?JVM调优策略+工具+技巧

Java架构追梦

Java 学习 架构 面试 jvm调优

14天1000+大集群滚动升级,银行柜台竟然毫无感觉

华为云开发者联盟

大数据 金融 FusionInsight 华为云 集群

Yelp的实时流技术之五:数据管道之Salesforce Connector_大数据_Ian F_InfoQ精选文章