传统企业很多在转型做大数据,在技术层面上从互联网公司学到不少,改革也可谓大刀阔斧,就几年时间,很多传统企业的数据仓库全部从小型机转到了X86,现在做数据处理和分析如果不提hadoop甚至有点落伍了。
应该来说,现在搞一套大数据平台其实已经不是难事,但如果企业希望能基于新的大数据平台快速的进行创新,事情就并不像想象的那么简单,你会发现,换了平台以后,虽然数据增加了,创新的可能性增加了,但很多数据工作效率却比以前降低了,从采集、开发、分析、挖掘、运维不一而足,我们在看得见的成本上的确降低了,但看不见的成本却在大幅提升。
从平台的角度讲,由于技术组件的多样化,开源化,技术的复杂性大幅提升,企业能得到的标准化服务能力肯定是下降了,为了保障服务的连续性,企业必然要花更多的其它成本去做补偿,比如不少技术组件甚至业界也没多少人用过,企业只能硬着头皮自己去抗,难度可想而知。
从工具的角度看,当前各种技术组件的配套设施并不完备,我们不再拥有像PL/DEV这种完美的ORACLE第三方客户端软件,得自己重新开发一套客户端工具来跑脚本,比如针对HIVE的运行工具,但这些客户端工具的开发也是摸着石头过河,体验显然也是没法跟以前相比的。
互联网公司对于新产品的竞争力有个公式:竞争力=(新产品体验-老产品体验)-替换成本,因此,要推广一个体验还不如老工具的东西对于大数据平台运营人员来讲也是非常艰难,当然不仅是开发工具,还包括监控工具、优化工具等等。
从管理的角度看,更是要建立一套适应新的大数据平台运营的组织、机制和流程,比如建立小快灵的团队来适应大数据的创新,新的平台工具需要新的培训,比如hive脚本跑不动得自己有能力去解析yarn的日志,看看是否有数据倾斜的问题……。
无论如何,我们都将与BI时代的稳定再见,面对的将是一个全新的环境,这是当前任何一支大数据团队都会面临的问题,在如此不确定的环境中,一支大数据团队如何才能变得更高效是摆在每个大数据管理者面前的课题。
这个时候,我们首先要拥有对新事物勇敢提出问题的能力,而能否创造开放透明的环境是最重要的一个,这也是笔者最近的感悟,因此特别来说一说。
这里先举三个案例。
团队组织了一次工作研讨会,特意邀请了刚入职的新员工谈谈工作中的问题和建议,哪知道原来引以为豪的数据开发管理平台被一顿臭骂,从资源占用模式,开发界面,调试方式……但为什么老员工就能泰然自若,不愿意升级问题呢?也许是习惯了吧。
不少新人在日报中抱怨,一个脚本HIVE跑了很多个小时没跑出来,因此只能凌晨起来乘着人少跑,运维说一些不规范的脚本也帮助查杀了,性能也就这样了。
接到客户投诉,说一个标签质量有问题,核查发现原来标签开发人员为了万无一失,将正确的标签命名为sex_new,老的标签sex还留着,说是担心梳理不出对老应用的影响,就想了这个两全其美的方法。
这些看似不经意的问题,其实对于大数据的效率影响很大,一旦习惯了就会积重难返,大家都懂的,但关键是这些其实并不是团队不能解决的问题,但为什么会习惯于迁就呢?
笔者分析下来,大致有以下的原因;
1、认知格局问题:员工之间,员工与管理者之间信息非常不对称,拥有的视野和资源不同,对于事物的轻重缓急认知不同,比如管理者认为租户性能是全局问题,不及时解决后果很严重,而员工认为自己忍忍就算了,员工经常听到领导的教诲说要站得高一点就是这个理,对冲基金公司桥水将所有公司的资料开放给员工是提升员工格局的一种手段。有时候,不知道这个问题是大问题是最大的问题。
2、趋利避害问题:员工的工作边界有限,对于可提可不提的问题,从降低风险的角度讲一般会选择回避,毕竟提出问题是需要付出代价的,你得分析清楚原因吧,得找到利益相关方讨论清楚吧,一般还得求助上级协调解决,每一样工作都让你脱离原有的工作舒适区,这个违背人性,多一事不如少一事。
从更自私的角度来讲,比如碰到的是工具不好用的全局问题,我慢你也慢,那就不会由于这个问题导致自己的成果比别人差,那就无所谓了,其实很多KPI做到了极端就这样了,问题能否解决、饼能不能做大无关紧要,只要你不比我过得好。
3、沟通环境问题:要打造开放透明的沟通环境非常不易,互联网公司相对比较扁平化,也还在不停的琢磨如何提升企业的透明程度,比如Google,大多企业层级式的汇报体系的确抑制了问题的暴露,从大了讲涉及到企业的文化,从小了讲涉及团建能力,很多问题其实早就有人提了,要么没人理,要么草草应付。
4、小白兔问题:如果说趋利避害还带有一点选择性作为的话,小白兔就是不作为了,不作为不是不做事,如果你的工作都是领导安排的,比如说一下动一下,就要考虑自己是不是已经成为小白兔了。
有人说我的工作性质就是稳定啊,只需要执行就成,没有需要主动推进的事情,姑且不说这种被动心态,其实任何事情有深有浅之分,没有简单的事,只有简单的人,比如按部就班的处理工单算做事,想着如何提高工单效率也是做事,把处理工单的方法编撰成手册是做事,最后实现了一套自动化工单处理系统更是做事,其实没有人为你过设定边界,前者相对后者就是小白兔,而小白兔对于大数据这种创新团队影响更大。
大家会笑国王的新装,但自己不小心就会成为主角,管理者则被过顶传球了,这对于团队的伤害很大,大数据这类新事物特别需要问题的暴露和反馈,从而推进各类问题的快速解决,刻意练习提到重复单调的10000小时努力不会让你成为专家,这个道理同样适用于团队,卓越的团队无法靠无脑的扩张和机械的重复打造。
互联网公司值得我们学习的,不仅仅是技术,透明化、扁平化绝对是重要的一条,Google在《重新定义团队》提了很多了,对冲基金公司桥水创始人瑞·达利欧在《原则》一书中提到了“极度求真和极度透明”,李开复在微软亚洲研究院提倡的“白板文化”激荡和迸发了多少创意,也许只有经历过才能知道开放透明的价值。
毫无疑问,大数据将带来平台,工具,管理的巨大变革,有太多的问题需要解决,而能否勇敢、坦诚的提出问题是适应新变化的前提,同样起点的团队,会由于开放透明程度的不同形成巨大差距,大数据不能容忍鸵鸟政策,比如前面的三个问题通过团队的群策群力,我们给出了以下举措:
措施1:将开发管理平台的体验改善提升到团队工作的高级别,落实相关开发资源,在年底前逐步解决,同时反思项目化的建设模式是否符合新时期的要求。
措施2:新申请租户资源或者调整各个租户资源配额,削峰填谷;将开发人员按业务拆分成多个团队租户;明确开发规范,在年底前将开发规则内嵌在开发管理平台。
措施3:标签上线增加审核,比如区分变更还是新增,规范命名,对于存量标签相似名称进行核查,下线造成歧义的雷同标签。
现在有个热词叫做涌现,凯文.凯利在他的《失控》这本书中专门讲过蚁群,一只蚂蚁可能什么都做不了,但是一群蚂蚁通过一种协同的机制,可以做出很多精巧的事情。人的大脑是由神经元构成的,但是单个的神经元独立的看只是一个部件,但是通过不断的刺激,让神经元之间产生联系之后,我们就可以创造人类文明。这些就是涌现。我们熟悉的市场是涌现,区块链技术也是涌现。
这个道理似乎也能应用于团队,如果每个成员都能做到知无不言,团队将涌现出一种高效解决问题的能力,这也是我们梦寐以求的吧。
当然,笔者这里只是提出了问题,但却无法告诉解决问题的办法,比如打造开放、透明的团队环境的具体方法,因为自己也不知道,只知道照搬别人是很难的,因为每个企业有自己独特的环境,头脑风暴在一些企业很好使,但在很多地方完全不行,为了加大沟通让新人写日报能成,但对于其他人就不一定适用,因为不一定能对这个事达成共识,强扭的瓜也不会甜,“白板文化”说说容易,但真功夫不是看看李开复的书就能学会的,还是要自己实践和体会。
但在这个特殊的时期,理解“开放、透明的环境对于大数据团队是如此重要”这句话是非常有益的,因为认识到这个问题的重要性才有行动的可能。
你看赫拉利又出了本新书《今日简史》,他只是提出了21个问题,啥回答都没有,但也引发了大家的思考,最近正好读托马斯.弗里德曼的《世界是平的》一书,也发现了类似的话,分享于你。
一位朋友曾向诺贝尔物理学奖获得者伊西多.拉比询问他的成才之道。拉比回答说,小时候每天放学后母亲都会问他当天的学习情况。她对儿子一天所学的内容并不感兴趣,但她总是会问:“今天你是否提出了一个好问题?”,拉比说:“提出好问题让我成为了科学家。”
自 2016 年以来,Uber 已在平台上增加了几项新业务,包括 Uber Eats、Uber Freight 和 Jump Bikes。现在,Uber 平台每天发生 1500 万次交易,每月有超过 7500 万活跃用户。在过去的八年中,Uber 已经从一家小型创业公司发展成为一个在全球拥有 18,000 名员工的巨头公司。
随着业务的增长,数据系统和工程架构的复杂性也日益增加。我们的分析引擎中存在数万个表,包括 Hive、Presto 和 Vertica。因为数据太过分散,我们必须对可用的信息有全面的了解,特别是当我们继续添加新业务数据和员工时。2015 年,Uber 开始使用一些手动维护的静态 HTML 文件对这些数据表进行编目。
随着公司的发展,我们需要更新的表的数量和相关元数据的数量也在增长。为了确保我们的数据分析能够跟上公司发展的步伐,我们需要一种更简单、更快捷的方式来更新这些信息。在这种规模和增长速度的背景下,拥有一个可用于发现数据集及其相关元数据的强大系统已经到了刻不容缓的地步。
图1
为了可以更容易发现和探索数据集,我们开发了 Databook。Databook 可用于管理和展示 Uber 数据集的元数据,让 Uber 的员工能够在 Uber 探索、发现和有效利用这些数据。Databook 可以保证数据的上下文(数据的意义、质量等)对于成千上万试图分析它们的人来说是有意义的。简单地说,Databook 元数据让 Uber 的工程师、数据科学家和运营团队从原先的查看原始数据转变为现在的掌握可操作信息。
有了 Databook,我们从手动更新转变为利用高级自动化元数据存储来收集各种经常刷新的元数据。Databook 具备以下几项特性:
可扩展性:易于添加新的元数据、存储和实体。
可访问性:服务可以以编程的方式访问所有元数据。
可伸缩性:支持高吞吐量读取。
其他:跨数据中心读写。
Databook 提供了各种源自 Hive、Vertica、MySQL、Postgres、Cassandra 和其他几种内部存储系统的元数据,包括:表的模式、表 / 列说明、样本数据、统计信息、Lineage、表的新鲜度、SLA 和所有者、个人数据分类。
所有的元数据都可以通过一个集中式 UI 和 RESTful API 来访问。Databook UI 为用户访问元数据提供了一种便利的方式,而 Restful API 则为 Uber 的其他服务和用例提供支持。
虽然现在已经有像 LinkedIn WhereHows 这样的开源解决方案,但在开发 Databook 的过程中,Uber 不支持 Play Framework 和 Gradle。WhereHows 缺乏对跨数据中心读写的支持,而这对于我们来说却至关重要。因此,我们开始构建自己的内部解决方案,并使用 Java 开发,充分利用 Java 的内置功能和成熟的生态系统。
接下来,我们将分享我们是如何创建 Databook 的,以及在这一过程中遇到了哪些挑战。
Databook 架构
Databook 的架构可以分为三个部分:如何收集元数据、如何存储元数据以及如何显示元数据。下图描绘了 Databook 的整体架构:
图2
Databook 将多个源作为输入,存储相关元数据,并通过 RESTful API 输出这些信息。其中 Databook UI 也使用了这些 API。
在设计 Databook 之初,我们必须做出一个重大的决定:存储收集到的元数据还是按需获取?我们的服务需要支持高吞吐量和低延迟读取,如果我们将操作委托给元数据源,所有源都要支持高吞吐量和低延迟读取,这将带来更大的复杂性和更高的风险。例如,用于获取表模式的 Vertica 查询通常需要几秒钟,所以不适合用于可视化。同样,我们的 Hive Metastore 管理着所有的 Hive 元数据,要让它支持高吞吐量读取是有风险的。Databook 可以支持多种不同的元数据源,因此我们决定将元数据保存在 Databook 中。此外,虽然大多数用例需要新的元数据,但它们不需要实时查看元数据变更,所以我们可以进行定时爬取。
我们还将请求服务层与数据收集层分开,每个层都运行在一个单独的进程中,如下图所示:
图3
这种方式将两个层隔离开,从而减少了附带影响。例如,数据收集爬虫作业可能会使用较多的系统资源,从而影响请求服务层 API 的 SLA。此外,与 Databook 的请求服务层相比,数据收集层对中断不太敏感,如果数据收集层关闭,仍然可以提供过时的元数据,从而最大限度地减少对用户的影响。
基于事件的收集与调度收集
我们的下一个挑战是决定改如何最有效地从几个不同的数据源收集元数据。我们考虑了多种方案,包括:创建分布式的容错框架,并利用事件流来近乎实时地检测和调试问题。
我们先是创建了爬虫,定时收集来自各种数据源和微服务的信息,这些数据源和微服务会生成数据集的元数据信息,例如由开源工具 Queryparser 生成的数据表的使用统计信息。(有趣的是,Queryparser 是由 Uber 的数据知识平台团队开发的)。
我们需要以可伸缩的方式频繁收集元数据信息,同时不能阻塞其他爬虫任务。为此,我们将爬虫部署在不同的计算机上,并且需要协调这些分布式的爬虫。我们使用了 Quartz 的分布式模式(由 MySQL 支持)。然而,有两个问题阻碍了这个方案的实现:首先,在多台机器上以集群模式运行 Quartz 需要定期同步 Quartz 时钟,从而增加了外部依赖。其次,在调度程序启动后,持续出现 MySQL 连接不稳定的情况。最后,我们决定不使用 Quartz 的集群模式。
不过,我们仍然继续使用 Quartz 来实现内存调度,以便更轻松、更高效地将任务发布到任务队列中。我们使用了 Uber 开源的任务执行框架 Cherami 来处理任务队列。这个开源工具可以用来解耦分布式系统中的消费者应用程序,让它们能够以异步方式跨多个消费者群组进行通信。有了 Cherami,我们就可以爬虫打包成 Docker 容器,并部署到不同的主机和多个数据中心中。借助 Cherami,我们可以从多个不同来源收集各种元数据,而不会阻塞任何任务,同时将 CPU 和内存消耗保持在理想水平。
虽然我们的爬虫可以爬取大多数元数据类型,但是有时候需要近乎实时地捕获一些元数据,于是我们决定过渡到使用基于事件的架构(Kafka)。有了这个,我们就能够立即检测并调试数据中断。我们的系统还可以捕获到关键的元数据变更,例如数据集 lineage 和新鲜度,如下图所示:
图4
这种架构让我们的系统能够以编程方式触发其他微服务,并近乎实时地向数据用户发起通信。我们仍然使用爬虫执行其他一些任务,比如收集(或刷新)样本数据、限制目标资源请求,以及一些没有必要收集的元数据(有些事件发生时会自动触发其他系统,如数据集使用统计)。
除了近乎实时地轮询和收集元数据之外,Databook UI 还收集来自数据集消费者和生产者的语义信息,例如对表和列的描述。
我们是如何存储元数据的
在 Uber,为了能够进行失效备援,我们的大多数管道都运行在多个集群上。因此,同一张表的某些类型元数据的值(例如延迟和使用统计)可能因集群的不同而不同,它们是特定于集群的。相反,来自用户的元数据则与群集无关:同一张表的描述和所有权信息对于所有群集来说都是一样的。为了正确链接这两种类型的元数据,例如将列描述与所有集群数据表的列关联起来,可以采用两种方法:写入期间链接或读取期间链接。
写入期间链接
在关联特定于群集的元数据和群集无关的元数据时,最直接的策略是在写入期间将元数据链接在一起。例如,当用户将列描述添加到给定的表列时,我们将信息保存到所有集群的表中,如下图所示:
图5
这个方法可确保持久数据处于干净状态。例如,在上图中,如果“列 1”不存在,它将会拒绝请求。不过这样就存在一个问题:在写入期间将与群集无关的元数据链接到特定于群集的元数据,所有特定于群集的元数据必须存在,并且只有一次机会。例如,当图 4 中的描述被触发时,只有集群 1 有“列 1”,因此对集群 2 的写入会失败。稍后,群集 2 中同一个表的模式会被更新,但已经没有链接元数据的机会了,除非我们进行定时重试,否则这个描述将永远不可用,从而让系统变得更复杂。下图描述了这种场景:
图6
读取期间链接
另一种方法是在读取期间链接群集无关和特定于群集的元数据。这个方法解决了写入期间链接会丢失元数据的问题,因为只要特定于群集的元数据存在,这两种类型的元数据就可以在读取期间进行链接。模式更新后,“列 1”就会出现,并在用户读取时被合并,如下图所示:
图 7
存储选择
MySQL 最初用于为 Databook 的后端提供支持,因为用它开发速度快,还可以通过 Uber 的基础设施门户进行自动配置。不过,当涉及多数据中心时,共享 MySQL 集群的效果并不理想,原因有三:
单个主节点:首先,Uber 只支持单个主节点,导致其他数据中心的写入较慢(每次写入增加了约 70 毫秒)。
手动切换主节点:其次,当时还不支持自动切换主节点。因此,如果主节点宕机,需要几小时才能切换到新的主节点。
数据量:我们弃用 MySQL 的另一个原因是 Uber 的大量数据。我们打算保留所有的历史变更记录,并希望我们的系统能够支持未来的扩展,而无需在集群维护上花费太多时间。
鉴于这些原因,我们使用 Cassandra 取代了 MySQL,因为它提供了强大的 XDC 复制支持,可以在几乎不增加延迟的情况下从多个数据中心写入数据。而且 Cassandra 是线性可扩展的,可以适应 Uber 不断增长的数据量。
我们是如何提供数据的
Databook 提供了两种访问元数据的方法:RESTful API 和 UI 控制台。Databook 的 RESTful API 由 Dropwizard 提供支持,Dropwizard 是一个用于开发高性能 RESTful Web 服务的 Java 框架,可部署在多台计算机上,并通过 Uber 的内部请求转发服务进行负载均衡。
在 Uber,大部分服务通过编程的方式访问 Databook 的数据。例如,我们的查询解析 / 重写服务就依赖于 Databook 的表模式信息。API 可以支持高吞吐量读取,并且支持水平扩展,每秒的峰值查询大约为 1,500。UI 控制台使用 React.js、Redux 以及 D3.js 开发,整个公司的工程师、数据科学家、数据分析师和运营团队都在用它诊断数据质量问题以及识别和探索相关数据集。
搜索
搜索是 Databook UI 的一项重要功能,用户因此能够轻松访问和浏览表的元数据。我们使用 Elasticsearch 作为全索引搜索引擎,Elasticsearch 会从 Cassandra 同步数据。用户可以使用 Databook 进行跨维度搜索,例如名称、所有者、列和嵌套列,如下图所示,从而实现更及时、更准确的数据分析: