zeppelin在云音乐的实践

1,051 阅读10分钟

在这里插入图片描述

汪磊(网易云音乐数据平台组)

音乐自2013发布以来,已经走过6个多年头,累计用户量突破8亿,每天光用户的行为日志就已经突破了千亿,我们经历了杭研猛犸平台从无到有
的整个发展阶段,在早期猛犸还非常不成熟的情况下,Zeppelin可以说是伴随这我们音乐数据分析师、数据开发团队发展壮大的一个重要工具, 云音乐是如何使用Zeppelin., 我们对Zeppelin做了哪些工作?

zeppelin是什么

Zeppelin是一个基于Web的可以做交互式数据查询、数据分析、数据可视化且可多人协作的NoteBook工具,支持NoteBook的权限控制、动态表单、以及调度执行

目前是Apache的顶级开源项目 github.com/apache/zepp…

Zeppelin使用场景

Zeppelin的主要用户有三类

  • 数据开发:使用Spark、Hive、SQL做一些数据清洗、数据集成的工作

  • 数据分析:使用SQL、PySpark、R做一些数据分析探索工作

  • 产品运营:查看报表

ZeppelinServer架构

Zepplelin本身采用了一个非常好的可插拔的架

主应用ZeppelinServer,然后分别有三个可扩展模块,NoteBook存储、解释器、以及可视化模块,每个模块都是可扩展的,这里我着重讲一下解释器

  • 解释器
    解释器是Zepplein的语言后端。例如,在 Zeppelin 中使用 scala 代码,您需要一个 scala 解释器、使用Python需要Python的解释器,每个解释器都属于一个解释器组。相同解释器组中的解释器可以互相引用。例如Spark、SparkSQL、Pyspark、SparkR都属于同一个解释器组,同一个实例中他们之间可以相互引用,RDD也可以共享,在用户发起执行请求时Zeppelin Server会通过代码中的repl找到相应的解释器,调用解释器的interpreter方法执行,zeppelin server会通过WebSocket实时的把进度反馈到web前端,详细的介绍可以参考:How Apache Zeppelin runs a paragraph,文章有些老,最好还是自己去看源代码;

  • 解释器有两种启动形式,本地或者远程,本地解释器通过classLoader动态加载到JVM直接调用,远程解释器会在本地重启一个进程,启动一个Thrift Server通过Thrift远程调用,以Spark插件为例

Spark插件本身就是一个常驻的Spark任务,在Spark的Driver端启动一个Thirft Server,然后通过Thirft和Zeppelin Server进行通信,接受执行SQL、Scala、Python等任务、反馈执行进度等;这种架构的问题很明显,当用户很多,解释器的数量很多时,单机很块就会成为性能瓶颈,这块最新的版本已经可以把Thirft Server包装到Docker环境中,和K8S集群对接解决这个问题,这块的代码是我们杭研的同学提供的解决方案,还是比较给力的;Interpreter更多的介绍可以参考What is Apache Zeppelin Interpreter

Zeppelin在云音乐的使用

云音乐从16年开始大规模使用Zeppelin作为我们主力的分析查询工具,截止当前以及有NoteBook3000+,每天Adhoc执行次数300+次左右,调度任务数200+;用户数:60+,主要是我们的数据开发和分析师同学,在三年多的时间里我们对Zeppelin也做过很多的修改,下面给大家介绍一些可见的比较典型的部分:

  • 表格展示下载:Zeppelin的前端承担着很多数据组装的工作,为了保证前端的展示性能,Zeppelin会限制展示的数据量,这就会造成一个问题,超过这个限制的数据用户都无法下载,因为zeppelin的整个文件下载功能,包含文件的组装、生成都是在前端实现的,为了解决这问题,我们做了一个服务端版本的下载功能,当结果的量超过前端展示的限制时,我们会把数据结果存储到HDFS上然后通过Http服务的方式提供下载,在反馈数据结果时,同时会把下载链接反馈到前端,下载的数据量不受前端展示的限制

  • 结果数据自动缓存:分析师提出在Adhoc查询的时候经常会出现因为考虑的不够周全、或者少写条件导致了很多的重复查询,为了解决这个问题我们做了一个自动cache的功能,当SQL有Shuffle操作时我们会把SQL的结果自动保存到hive的一个临时表中,并且把临时表反馈给用户。这样用户在少写条件或者做一些探索式的查询时可以使用临时表做迭代查询,减少一些重复查询,当然临时表我们也会每天清理

  • 单机瓶颈、任务运维改造
    Zeppelin的解释的隔离默认提供了三种方式:

  • Globally:全局只使用一个Interpreter实例
  • PerNote:每个Note一个Interpreter实例
  • PerUser:每个用户一个Interpreter实例

简单解释下:以Spark插件为例,Globally表示所有的人的任务都由一个Spark任务执行,PerNote表每个Note一个Spark任务,PerUser表示一个用户一个Spark任务,初期为了防止定时任务和AdHoc任务相互干扰,影响体验,我们对这块做了一些修改,对于定时任务我采用一个Note一个任务,Adhoc任务采用每个Note一个任务;但是随着用户慢慢的增多,定时任务越来越多,单机的瓶颈渐渐展现,Zeppelin本身的稳定性以及Spark任务的稳定性都经常出现问题;为了解决这个问题,保证定时任务的稳定性;我们决定将zeppelin整合到我们音乐搭建不久数据平台体系当中,用我们的一些基础服务替换zeppelin原有一些模块,废话少说直接看图:

简答介绍下我们数据平台的各个组件:

  • Pandora: 是我们音乐自研的用来补充猛犸功能的数据工具平台,目前有数据邮件、数据传输、zepplein、spark等

  • 其中zeppelin是我们今天要讲的主角

  • 执行服务:数据平台的公共服务负责任务执行,执行类型组件可插拔热部署,目前支持spark、zp、数据传输、tf、ps等等很多不同类型的任务,Pandora上所有的任务执行都是走的执行服务

  • 调度服务、报警服务、元数据中心,这家大家看名字应该都能明白,这些都是公共基础服务,共同支持Pandora上相应的功能模块。

我们整体的思路是将定时任务和AdHoc任务分开,AdHoc查询任务还是走zepplin本身服务执行,定时任务因为不需要中间进度的反馈,而且应该都是写任务,只读的调度任务也没有什么调度的必要,所以首先我们我们参考了Zeppelin本身Spark插件的实现,开发了一个ZP插件集成在我们执行服务上,它的作用是接收Note的内容,将Note直接包装成一个Spark任务提交,执行结束以后再把结果反馈回来;然后做了一些组件打通的工作,最终流程是:用户在Zeppelin配置调度任务或者修改调度任务时Zeppelin会同步任务到Pandora上,此时Pandora上在相同的账户下会出现一个zeppelin类型的任务,所有调度任务都会在Pandora上通过执行服务执行,同时借助Pandora完善的运维能力,这些调度任务也拥有了完善的监控、报警、回跑、重跑的能力

任务回跑

结果反馈

这样就算Zeppelin本身服务挂了,也不会影响调度任务的正常执行,因为Pandora、调度、执行这些服务都是高可用、分布式、可扩展的,所以也不会有单机瓶颈;做完这些改造Zeppelin只需要承担Adhoc查询就好了,当然随着用户量增长单机瓶颈还是可能出现,但是问题的严重性好了很多,Adhoc任务失败也不是什么特别大的问题,当然我们也有后续的计划彻底解决这个问题,如
a. 继续改造zp,使用我们的执行服务完成adhoc查询操作
b. 使用现有docker方案

  • 数据传输集成
    云音乐有一套自研的基于Spark的异构数据源之间数据传输方案,对目前网易的存储中间件:如DDB、HBase、Redis、NOS等都做过定制化的改造。目前这套方案已经贡献给了杭研,不出以外的话,大家在10月份就能在猛犸上看到它的身影;在这个数据传输之上我们还开发了一个SQL的版本集成在了Zeppelin当中,实现了数据传输、不同数据源之间的联邦查询等功能

  • 写入数据库到Oracle

  • 写入数据源到NOS

  • 不同数据源的联邦查询

这块的可以讲的东西很多,我们也做了很多看不见的工作,如小文件自动merge,简单的broadcast操作;精力有限就不在这里做太多介绍,后面有机会再单独开一篇来讲。

未来规划

1.音乐自己的规划:继续改造zeppelin和我们平台服务做更多的整合工作,目前分析师需要Pandora、zeppelin两套系统中操作非常不方便,zepplein本身的服务的端的代码写的也不是很好特别是在多线程处理方面,
还需要一些时间打磨,后面我们会考虑直接将zeppelin的功能集成到我们的Pandora当中,只维护一套系统

2. zeppelin社区规划:

  • 分布式:解决单机性能问题 https://issues.apache.org/jira/browse/ZEPPELIN-4104

  • 容器化:Interpreter的Docker容器化支持,解决单机性能问题https://issues.apache.org/jira/browse/ZEPPELIN-3471
    其它应该还有,工作太忙没有太多时间关注了