NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

Saleforce 基于 Kotlin 构建数据管道的探索和实践  

  • 2021-08-26
  • 本文字数:2948 字

    阅读完需:约 10 分钟

Saleforce基于Kotlin构建数据管道的探索和实践   

直到最近,我们都和许多公司一样在基于 Java 或 Scala 的那几种技术(包括 Apache Spark、Storm 和 Kafka)中选一种来构建我们的数据管道。但 Java 是一种非常冗长的语言,因此用 Java 编写这些管道时需要大量样板代码。例如,bean 类这么简单的东西也需要编写多个常规的 getter 和 setter 以及多个构造器和/或构建器。一般来说,哈希和相等方法必须用一种很平常但啰嗦的方式覆盖掉。此外,所有函数参数都需要检查是否为“null”,为此需要多个污染代码的分支运算符。分析哪些函数参数可以或不可以为“null”是非常耗时的(而且很麻烦!)。

 

处理那些用 Java 编写的管道出来的数据时,往往需要基于管道数据的类型或值来做分支,但 Java“switch”运算符的限制让人们不得不大量使用庞大的“if-then-elseif-...”构造。最后,大多数数据管道使用不可变数据/集合,但 Java 几乎没有对分离可变和不可变构造的内置支持,于是人们只能编写额外的样板代码。

 

为了解决 Java 在数据管道方面的这些缺点,我们选择了 Kotlin 作为后端开发的替代方案。

为什么是 Kotlin?


我们选择 Kotlin 主要基于如下考虑:

 

  • Kotlin 中对数据 bean 类的丰富支持让我们无需再编写显式的 getter 和 setter。

  • 可选参数和简化的构造器语法让我们无需再编写多个构造器和构建器。

  • “数据类”结构让我们不必再使用简单的样板代码显式覆盖哈希/相等函数。

  • 内置的类型系统空指针安全保证不会跳过任何必要的空指针检查,并且我们会收到关于不必要检查的警告,从而大大减少样板代码。我们切换到 Kotlin 后,几乎没再见过可怕的运行时 NPE 异常。

  • 用于分离可变数据和不可变数据的强大机制允许我们对并行数据处理进行更简单的推理。

  • 通用的“when”运算符允许我们根据数据类型和值编写灵活简洁的分支表达式。

  • 与 Java 的无缝集成让我们能继续使用所有 Java API,无需额外的心智负担。在 Java 中使用 Kotlin 接口也几乎不存在摩擦,并且我们在 Kotlin 中实现的 API 还被其他使用 Java 的团队用上了。

 

下面是 Kotlin 代码的一个简单示例,它展示了上面列举的一些要点:

enum class RequestType {CREATE, DELETE}data class RuleChange(val organizationId: String, val userIds: List<String>, val request: RequestType)
复制代码


Java 中的等效实现如下所示:

enum RequestType {CREATE, DELETE}public final class RuleChange {    final private String orgraniztionId;    final private List<String> userIds;    final private RuleChange ruleChange;    RuleChange(String organizationId, List<String> userIds, RuleChange ruleChange) {        this.orgraniztionId = organizationId;        this.userIds = userIds;        this.ruleChange = ruleChange;    }    final public String getOrgraniztionId() {        return orgraniztionId;    }    final public List<String> getUserIds() {        return Collections.unmodifiableList(userIds);    }    final public RuleChange getRuleChange() {        return ruleChange;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        RuleChange that = (RuleChange) o;        return Objects.equals(getOrgraniztionId(), that.getOrgraniztionId()) && Objects.equals(getUserIds(), that.getUserIds()) && Objects.equals(getRuleChange(), that.getRuleChange());    }    @Override    public int hashCode() {        return Objects.hash(getOrgraniztionId(), getUserIds(), getRuleChange());    }}
复制代码


这两段代码做的是几乎完全一样的事情。Kotlin 还有一些好东西我们没放在示例里面,它们需要额外的样板代码才能在 Java 中实现,但是这个示例已经足够说明问题了——Kotlin 代码更加简洁,并且为开发人员提供了很多免费赠品。

Kotlin 中的一个清晰的代码示例


Kotlin 简洁易懂的代码的一个很好的例子是我们的规则更改处理器 Kafka 流作业,它对输入数据进行空安全验证,使用扩展函数反序列化数据,然后使用详尽的模式匹配对数据执行操作。



这里你可以清楚地看到 Kotlin 为我们提供的几个好处:

 

  1. 空值安全性:再也没有难看的的 if/else 空检查了。我们使用了 Kotlin 的内置空值安全性检查,它可以防止 NPE 并让代码更具可读性。

  2. 扩展函数:Kotlin 提供了向现有类添加新函数的能力,添加时无需继承该类。第 4 行的 it.deserialize()是不是看起来比使用一些辅助类来反序列化数据更易读?

  3. 对属性的一流支持:我们不需要编写 get/set 方法,因为 Kotlin 为属性提供了一流的支持,如第 5 行和第 6 行所示。

  4. 使用 when 构造的详尽模式匹配:从第 8 行开始,Kotlin 的 when 表达式对枚举值和 case 类进行详尽的模式匹配。使用 Java 的 switch 构造时我们必须编写 no-op default case,现在再也用不着了。

Kotlin 用于 Salesforce 的活动平台


活动平台(Activity Platform)是我们的一个大数据事件处理引擎,每天摄取和分析 100 多万次客户交互,以自动捕获数据、生成见解推荐



如上图所示,我们广泛采用了 Kotlin 代替 Java 进行跨活动平台的后端开发工作。下面是具体的流程:


  • 我们以流媒体方式处理活动数据,并使用 AI 和机器学习生成智能见解,为 Salesforce 中的多种产品提供支持。

  • 为了处理这些数据并生成见解,我们会运行一些大数据系统(如 Kafka-Streams、Spark 和 Storm)并公开一个 HTTPS GraphQL API 供其他团队消费数据。

  • 我们用 Kotlin 编写所有业务逻辑库。

  • Kafka Streams 作业是用 Kotlin 编写的。我们使用 Kafka Streams 作业进行简单的映射、过滤和写入操作。

  • Apache Storm 拓扑是用 Kotlin 编写的。Storm 拓扑对我们的数据执行通用数据保护条例(GDPR)操作。

  • Spark 作业是用 Scala 编写的,但它们会消费用 Kotlin 编写的库。我们使用这些 Spark 作业运行复杂的 SparkML 模型。

  • GraphQL API 也是用 Kotlin 编写的,同时由一个 Jetty 服务器提供支持。

 

所以基本上来说,我们在所有可以使用 Java 或其他 JVM 语言的地方都改用了 Kotlin。

迁移到 Kotlin 后为我们带来的好处


当其他团队使用我们的库时,Kotlin 的数据类和不变性确保了一致性(防止意外数据损坏)。它的函数式语法和不变性为我们编写数据管道所需的处理流提供了一种优雅的方式。Kotlin 可以在一个文件中拥有多个类,并能够使用顶级函数,这让我们的代码组织起来更轻松了,大大减少了我们需要导航的文件数量。这篇博文中还没具体介绍 Kotlin 中我们喜欢的很多内容,例如扩展函数、类型别名、字符串模板、使用协程和 async-await 的并发代码执行等。

 

使用 Kotlin 构建数据管道可以获得很多好处,尤其是提升开发人员的生产力。让来自不同编程背景(如 Java、Scala、Python)的工程师上手 Kotlin 都是非常轻松的事情,而且他们都喜欢 Kotlin 提供的编程结构。这就是为什么它是 2020 年最受欢迎的编程语言之一。我们将继续扩大其采用范围,同时用它来构建新的管道、并将旧管道也逐渐切换到 Kotlin 上。当 Kotlin 对 Spark 的更稳定支持可用时,我们也有兴趣使用 Kotlin 来构建 Spark 作业。对于所有对构建数据管道感兴趣的读者,我们都建议大家尝试使用 Kotlin,看看它相对于其他编程语言有哪些优势。

 

原文链接:


https://engineering.salesforce.com/building-data-pipelines-using-kotlin-2d70edc0297c

2021-08-26 17:006298

评论

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

拒绝编译等待 - 动态研发模式 ARK

字节跳动终端技术

ios 字节跳动 移动开发

iOS开发面试和底层学习视频整理合集

iOSer

ios iOS面试 ios开发 iOS视频学习 iOS涨薪

许式伟:Go+ v1.x 的设计与实现丨Go+ 公开课 • 第一期

七牛云

Go 语言 goplus

单机训练6000万类视觉分类模型,飞桨大规模分类库PLSC做到了

百度开发者中心

飞桨 视觉分类 plsc

明道云商业化成果巡礼|2021年11月

明道云

【体验有礼】Serverless 极速搭建 Hexo 博客

阿里巴巴中间件

阿里云 Serverless 云原生 Hexo 中间件

【强势推出】专家带你玩,秒懂数据库!官方证书、万元奖品带回家!

华为云数据库小助手

GaussDB GaussDB(for openGauss) 华为云数据库

无处不在的 Kubernetes,难用的问题解决了吗?

阿里巴巴中间件

阿里云 Kubernetes 容器 云原生 中间件

参会指南 | 2021MongoDB南京技术沙龙

MongoDB中文社区

mongodb

林昊:开发者如何提升写代码的硬实力丨Go+ 1.0 发布会干货分享

七牛云

Go 语言

程序员的硬核浪漫 — 女友专属语聊房(内附源码)

ZEGO即构

音视频 语聊房 demo源码 即构科技

干货分享:细说双 11 直播背后的压测保障技术

阿里巴巴中间件

阿里云 云原生 中间件 全链路 PTS

网易云信发布虚拟形象实时互动融合 SDK ,元宇宙大幕即将开启

网易云信

人工智能 数字化 元宇宙

HarmonyOS 3.0.0开发者预览版全新发布

HarmonyOS开发者

HarmonyOS ArKUI 3.0 ArkCompiler 3.0

基于Guava API实现异步通知和事件回调

Tom弹架构

Java 架构 设计模式

构建 Snowpack + React + Typescript + Electron的Desktop App

DisonTangor

typescript Electron React webpack

视野 | OpenSearch,云厂商的新选择?

RadonDB

数据库 搜索引擎; Elastic Search

恒源云(GPUSHARE)_基于梯度的NLP对抗攻击方法

恒源云

人工智能 深度学习

原因揭秘!为什么选择 Pulsar 而非 Kafka

Apache Pulsar

kafka 开源 架构 分布式 Apache Pulsar

Microsoft SQL Server 迁移利器,Babelfish for Aurora PostgreSQL 上线!

亚马逊云科技 (Amazon Web Services)

数据库 开源 源代码

如何在浏览器 console 控制台中播放视频?

CRMEB

🏆【Alibaba中间件技术系列】「RocketMQ技术专题」小白专区之领略一下RocketMQ基础之最!

洛神灬殇

RocketMQ 消息队列 Alibaba技术 11月日更

许式伟:Go+ Together丨Go+ 1.0 发布会干货分享

七牛云

Go 语言

【高并发】通过源码深度分析线程池中Worker线程的执行流程

冰河

Java 并发编程 多线程 高并发 异步编程

Go+ Together!Go+ 1.0 发布会暨 Go+ 开发者基金会启动仪式圆满结束!

七牛云

Go 语言

黄东旭:写给后端程序员看的认知心理学丨Go+ 1.0 发布会干货分享

七牛云

Go 语言

vue3 学习笔记 (一)——mixin 混入

码仔

Vue3 mixin

多变的智能降噪

睿象云

运维 告警 智能运维 告警管理

阿里IM技术分享(六):闲鱼亿级IM消息系统的离线推送到达率优化

JackJiang

架构设计 即时通讯 IM

为AI另辟蹊径的“小”数据

澳鹏Appen

人工智能 大数据 小数据 数据标注 训练数据

17 K8S之容器资源需求与资源限制

穿过生命散发芬芳

k8s 11月日更

Saleforce基于Kotlin构建数据管道的探索和实践   _大数据_Saleforce工程博客_InfoQ精选文章