在 2014 年早些时候,Simple 还是一家创业中期的公司,只有一名数据分析师,在回答与用户行为或业务性能相关的问题时还必须查询产品数据库。那时,公司里的每个人都想做出明智的决定,从工程师到产品战略到业务开发到客户关系都是如此,为此 Simple 构建了一个数据仓库和一个支持它的团队。
现在,随着公司的发展壮大 Simple 有了近 300 名员工,同时拥有一个 11 个人(包括 1 个数据总监、5 个工程师和 5 个分析师)的数据团队,他们管理着 Simple 存储在 Amazon Redshift 上的丰富的业务数据。拥有强健的、近乎实时的分析能力并不容易,Simple 在这条路上积累了非常宝贵的经验教训。本文来自于 Jeff Klukas 在 Simple 官方博客上的分享,介绍了 Simple 目前数据基础设施实现的细节,使用场景,以及 Simple 做出相关决策的原因。
如何构建数据团队
Simple 的分析师和工程师对公司的其他人而言是一种资源,因为他们提供数据让其他人做出明智的决定。下面是一些协作示例:
- 与产品团队一起分析事件跟踪数据,帮助他们理解用户是如何与 APP 交互的,团队应该如何安排潜在特性的优先级。
- 与风险部门合作识别不规则的使用模式并精确定位新兴的欺诈形式。
- 构建仪表盘帮助客户关系部门预测人员需求,优化他们的计划,同时对紧急事件做出有效地应对。
- 为行政领导团队和董事会提供度量,指导他们做出公司的战略远景决策。
在 Simple 公司让所有人都能访问数据是非常重要的。任何部门的人都能够通过 GitHub 提交数据分析和基础设施请求给数据团队,数据团队每周都会定期举行分析会对这些问题进行分类标记。
在 Simple 的发展历程中,数据一直都具有最高的优先级,而随着公司的发展,数据请求越来越多以至于无法全部实现,为此 Simple 开始对整个系统进行大修以便于支持持续增长的业务需求。另外,Simple 公司还发现随着公司的发展数据请求变得越来越具体,部分分析师需要将一半多的时间花费到与特定团队的合作上,Simple 认为将来这种工作很有可能会更加专业。
在 Simple 数据分析师和数据工程师是一个团队,他们在办公室里坐在一起,共享同一个管理组织结构。虽然从理论上来说构建基础设施提供数据仓库的工程师与根据数据回答业务问题的分析师责任是不同的,但是 Simple 发现分析师和工程师的工作有很多重叠,他们能够从这种紧密的反馈环中受益。当数据请求需要 Redshift 中并不存在的数据时,分析师非常清楚应该找谁,工程师通常也能够在几天之内准备好新的数据源。另外,分析师和工程师也会合作,工程师会使用编程的专业知识分析问题,分析师也会构建 Web 应用处理特定的分析工作流。
数据基础设施
Simple 大部分数据基础设施的作用是从产品服务抓取数据并填充到 Amazon Redshift 中作为数据仓库。数据仓库存储了来自于 PostgreSQL 数据库、消息队列和公共 HTTP 端点(Endpoint)的数据。
之所以选择 Redshift 作为数据仓库是出于集成和可伸缩性方面的考虑:
- Simple 所有的后端基础设施都在使用 Amazon Web Services(AWS),因而 Redshift 更容易部署并与已有的环境集成。
- Redshift 是一个大规模可伸缩的数据仓库,相对而言又比较便宜。虽然 Simple 现在存储在 Redshift 中的数据不足 1TB,但是在接下来的几年中其数据量将会呈指数增长。
- Redshift 的接口是 SQL,Simple 的分析师以及公司中的其他人都对此非常熟悉。
(点击放大图像)
Redshift 加载(Loader)服务
Simple 的计算后端遵循面向服务的架构,技术运营团队针对微服务的部署和维护开发了非常出色的业务工具。鉴于这方面的经验和支持,Simple 最大程度地采用了同样的模式来构建数据管线(Pipeline)。
仓库加载服务从消息队列(每一条消息代表仓库中的一行数据)读取数据,然后将消息以表为单位批量插入到S3 中,最后运行COPY 命令将数据从S3 导入到Redshift。这样如果上游服务想要将数据发送到Redshift 上,只需要简单地将消息按照仓库特定的JSON 模式发送到RabbitMQ Exchange 或者Kafka Topic 上即可。
因为传入数据的模式有时会发生变化,所以Simple 对加载服务所产生的所有S3 批量任务的档案进行了维护。虽然Simple 没有自动化的系统来通知传入消息模式中的变化,但是档案让他们能够事后对模式的变化做出反应,进而在Redshift 中添加相关的列,然后重播档案从而回填新列。
HTTP 分析服务
Simple 构建的第一个上游服务是 HTTP 服务,它有对外公开的端点,市场营销网站、Web 应用和移动客户端都会访问这个服务。对于每一个传入的请求,该服务都会将 JSON 有效载荷(Payload)转换成加载服务所期望的格式并把结果发布到加载服务的 RabbitMQ Exchange 上。
消息队列监听服务
Simple 的后端服务通常使用 RabbitMQ 将消息从一个组件传递到另一个组件。这些交换(数据工程师偶尔会在后端服务里添加新的事件以处理特定的分析提取任务)是在一个小的监听服务里面处理的。消息队列监听服务与 HTTP 服务类似,它也接受 JSON 有效载荷,执行一些轻量级的转换将数据转换成适合于加载服务的格式,最后重新发布到加载服务的 Exchange 上。
Simple 的后端现在已经开始使用 Kafka 和 Amazon SQS 了,因此将来可能会构建针对它们的监听器,或者使用 heka 实现更加通用的消息分流服务。
PostgreSQL 数据库查询服务
Simple 的大部分后端服务都使用 PostgreSQL 存储数据,通常还会在仓库里面对产品数据库表做镜像。目前的处理方法是: 创建数据库查询服务的实例,周期性地查询被配置的表中的新行,将这些行发布到 RabbitMQ 上让加载服务进行处理。通过直接查询数据库表,Simple 实现了对已有数据的完整回填(这一点无法通过监听消息队列实现)。
虽然从概念上看使用 SQL 查询从数据库中抽取行非常简单,但是实际上这需要有效地配置。为了增量地拉取更新,必须跟踪每一个表最后一次抽取数据的时间戳,如果表包含记录插入时间的列那么这很容易;但是有时候需要向后端服务添加 updated_at 列,或者添加全新的历史表以识别新行并知道何时删除了行。
Simple 的技术运营团队现在正在将后端数据库迁移到 PostgreSQL 9.4 上,这样就能使用该版本新的逻辑复制(Logical Decoding)特性监控数据库的变化了。目前 Simple 所采用的方法非常类似于 bottledwater ,后者通过 PostgreSQL 插件将更新发布到 Kafka 上而 Simple 则是将这些更新发送到加载服务上。
Redshift 性能监控服务
在构建好数据仓库之后,各个业务部门就可以使用相关数据进行决策了,随之而来的责任就是必须要确保基础设施的平稳运行,为此 Simple 构建了监控预警系统。在构建的过程中 Simple 再次借鉴并利用了后端工程和技术运营团队在为捕获 Redshift 度量设计解决方案时所积累的经验及基础设施。
Simple 的大部分后端服务运行在 JVM 上,它们使用 Dropwizard 框架,通过 Dropwizard 优秀的度量工具包将数据发送到 Graphite ,然后通过 Grafana 仪表盘实现可视化。为了与该基础设施对接,Simple 构建了一个专门的服务来收集度量数据,该服务周期性地(通常是每分钟一次)查询 Redshift 表并请求 AWS 的 CloudWatch 服务以获取数据。
(点击放大图像)
通过收集这些度量数据Simple 能够监控系统的性能状况,找到数据管线的瓶颈。另外Simple 还建立了一些预警机制,能够通过网页或者Slack 消息对暗示管道问题的症状进行预警。
计划任务(当一切都失败的时候,导入CSV)
每一个组织最终都会有一些重要的信息藏在尴尬、 偏僻的地方,既不是传统的数据存储也不需要特殊处理,因为它们存在于基础设施之外。为了将这种数据拉入数据仓库,有时需要依靠简单的、访问一个API 或者复制一个文件的计划任务。
为了满足这种需求Simple 基于 Celery 构建了一个基础的任务调度服务,该服务处理的数据源包括:
- 通过 SFTP 从 ExactTarget 和 Simple email 服务提供商那里获取的包含 email 交互数据的 CSV 文件
- 通过 Google Sheets API 获取的客户关系团队的人员计划
- 通过 Nanigans HTTP API 获取的每日广告花费概要
- 通过 GitHub Enterprise HTTP API 从 GitHub Issues 中获取的备注和元数据
该服务还被用来在 Redshift 上执行夜间维护活动,包括清空表或者重新创建各种分析特定的表。
转换数据进行分析
抽取——转换——加载(ETL)流程从字面上看只有简单的三步,但实际上很少会这么简单,通常情况下更会是(ET*L)+ 正则表达式,数据在多个系统间传递,中间经过了大量的转换。
Simple 存储在 Redshift 中的数据通常会与原始数据源中的数据在结构上保持一致,这样做的好处是管道实现起来比较简单,也为原始数据的处理留有余地,缺点是结果数据对分析非常不友好。
Simple 使用 Redshift 作为自己的转换引擎,通过在夜间执行很多 SQL 为特定的分析任务创建优化的“具体的视图”(Redshift 并不支持真正的视图,Simple 是通过定期地销毁、创建静态表来模拟视图效果的)。这些 SQL 通常是一个包含了 CREATE TABLE AS 语句的纯 SQL 文件,计划任务服务会定期执行它们创建具体的视图。之所以这样做是因为 Simple 发现如果能充分地利用 Redshift 分布式的数据结构,那么它就能非常出色地完成转换工作。为了更有效地实现连接(join),Simple 还根据具体的场景在表上增加了具有针对性的分布和排序键,对于大部分表而言,分布键和排序键都会是 user id,但是有时还会增加 timestamp 列作为二级排序键。在这个过程中,Simple 还总结了一些最佳实践:避免在转换中使用通用的表表达式(WITH 语句),因为查询优化器倾向于在内存中构建这些语句的中间结果,而这通常会导致不必要的跨片(cross-slice)结果。
前端让数据仓库可用性更高
Simple 的数据分析师大量使用 Navicat 等 SQL 客户端以及 R 或者 Python 脚本来直接查询 Redshift,其他人也会直接访问 Redshift,但是并不是每一个人都精通 SQL(或者 Simple 自身的模式),为了让每一个人都能自助地享受数据,为数据仓库构建一个前端就变地越来越重要了。
(点击放大图像)
Simple 通过仪表盘为重点业务子集提供洞察力,所构建的仪表盘都托管在 Periscope Data 上,对其他人而言 Periscope Data 就是数据仓库。
对于一些特别的、涉及更多数据输入/输出的工作流,Simple 也提供了工具。包括使用 Python 构建的能够根据接收的文件或者参数产生某些转换输出的命令行工具,以及一个为 R 模型提供了 Web 交互界面的 Shiny app ,虽然这些工具解决的都是劳动密集型问题,应用范围有限,但是相对于手工查询它们在各自领域大大节省了手工查询的时间。
(点击放大图像)
Periscope Data 仪表盘
Periscope Data 的前端页面上首先显示了 Simple 年度主要目标的进度。因为 Simple 是通过净推荐分数(Net Promoter Score,NPS)来衡量成功的,所以 NPS 数据显示在 Periscope Data 主仪表盘的中心,这样每一个 Simple 员工都能够知道自己为客户提供的服务是否足够好,服务质量是否正在提高。
另外,Periscope Data 上还显示了一些其他的仪表盘用于查看具体团队的运营状况。例如,记录客户关系团队与客户聊天队列的仪表盘,该仪表盘能够让客户关系团队知道还有多少聊天未处理?最老的聊天是哪一个?聊天的平均反应时间有多长?仪表盘上数字的提升代表着客户关系团队能够更有效地回答客户的问题,也表示 Simple 的产品正在变得更容易使用。
(点击放大图像)
Simple 洞察内部运营状况的另外一种方式是可视化 GitHub Enterprise 实例上的讨论。Simple 将 GitHub 视为中心的交流工具,所有的团队都使用它来跟踪问题。Simple 的 GitHub 活动仪表盘能够根据组织和仓库过滤信息,因此每个团队都可以使用它来跟踪问题的处理情况,问题被挂起了多长时间,应该如何安排问题的优先级等。
(点击放大图像)
Simple 认为仪表盘非常适合自己的数据工作流。当分析师拿到一个数据请求的时候,在 Periscope Data 上创建一个仪表盘通常比分发一个 CSV、电子表格或者静态图表更加容易。
下一步工作
Simple 对自己数据团队第一年的工作非常满意,接下来 Simple 将会简化基础设施,进一步扩展系统的能力,从而更有效地满足已有需求。
在接下来的几个月,Simple 将为服务实现更健壮的错误处理机制,尽可能地实现自动化维护,寻找开源的计划任务服务从而处理更复杂的工作流,构建自己的 ShiftManager ,整理 Redshift 管理最佳实践并通过 Python 命令行界面实现一套工具。随着公司的增长,Simple 认为对所有工作进行整理也是非常重要的,因为通过知识的积累和分享能够让所有员工更好地理解数据仓库中有哪些数据,自己能够利用这些数据做什么。
关于作者
Jeff Klukas 是 Simple 的数据工程师,毕业于威斯康星大学麦迪逊分校。在就职于 Simple 之前,Jeff 在 Epic 工作过两年,之后于 2014 年 8 月加入 Simple 的数据分析团队,和团队中的其他成员一起帮助产品和业务团队构建系统和模型实现数据驱动的决策。
感谢杜小芳对本文的策划和审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群(已满),InfoQ 读者交流群(#2))。
评论