[Day 24] 资料产品在部署阶段的五个大坑

上线之後才是开始。

第一坑 开发和部署环境不一致

如果一开始开发和部署没有「乔好」环境的话,那上线的过程可是会吃一番苦头。例如搞不清楚环境有哪些套件,只好正式环境乱装一堆。如果每个开发工程师都用不同的套件,那正式环境会变得异常复杂。如果正式环境是分散式系统的话,状况又会变得更复杂,需要确保每台节点都有相同的套件。现在大多人用的解法都会使用 Docker Image 来将程序和套件一起打包,这样一来方便管理上线的版本,二来也是可以让开发与部属环境保持一至。

第二坑 出现不如预期的结果

不管是原始资料、加工资料、模型什麽的,上线之後永远会产生意外的状况。不是资料格式不对、笔数不对、转换方式错误、或是意外的预测结果,总之「有可能发生的问题就会发生」。这些意外往往是来自於资料产品层层叠叠的影响,只要一层出错,後面就很有可能接连产生错误。

举例来说,之前我们都是透过 AWS Kinesis 来接收使用者手机传送过来的资料,後续所有 ETL、使用者报表、模型都是依据这个资料来做处理。有一天 Kinesis 在半夜断了两小时,少了这两小时资料,计算每日使用者数的报表自然就发生异常、另外一张根据每日使用者人数计算存活率的报表自然也不正确、少了那两小时的资料,针对使用者观看影片的训练的推荐模型自然也会受到影响。

第三坑 非预期结果的後续影响持久

这些异常的後续效果会比想像中还来得久以及来的难处理。例如延续上面的例子,尽管後来 Kineis 修复後资料成功进来,但是像是「过去七天使用者人数」的报表、或是「过去三十日观看热门影片」都会有一天的资料是「不正确」的,直到那个有问题的资料不会再被查询之後影响才会消失。

第四坑 稍微复杂的二阶段部署

由於坏资料的影响会留存很久,所以我们必须尽量避免坏资料进入生产环境。这时候就很推荐使用「两阶段转换」。将处理完的结果,先放到别的地方,等资料验证没有问题後,再进入正式的 DB。

然而二阶段转换并不是说单纯把资料放到 Staging 环境而已,以下就来说明开发 Data Pipeline 通常的做法,以及环境的区分。

从测试到正式环境

ETL 的正确性涵盖了两部分:

  1. 原始资料的正确
  2. 商务逻辑的正确

所以一般来说,比较严谨的开发流程会是这样子:

  • 测试资料 => 测试资料处理程序 => 测试 DB(先确认资料处理程序正确)
  • 测试资料 => 正式资料处理程序 => 测试 DB
  • 正式资料 => 正式资料处理程序 => 测试 DB (确认资料处理程序能应付正式资料)
  • 正式资料 => 正式资料处理程序 => 正式 DB

加入二阶段转换後最终会像这样:
正式资料 => 正式资料处理程序 => 暂存区 => 确认资料品质 => 正式DB

其他变形应用

当然除了放到暂存区之外,也可以直接在程序里确认程序品质,放在同一个处理程序中:

  • 正式资料 => 「正式资料处理程序 => 暂存区(in memory) => 确认资料品质」 => 正式DB

当然当资料量大,或是需要累积多一点资料一起验证时,还是会先落地在检查。

  • 正式资料 => 正式资料处理程序 => 暂存区(in db 或其他persistance storage) => 确认资料品质 => 正式DB

第五坑 安全性管理

由於资料产品包含许多隐私或是机敏内容,所以在安全性上一定要特别注意,这边列几个比较常被忽略的地方:

  • 使用者介面
    像 Airflow Web Server ,这是是使用者观察 job 执行的和操作的入口。虽然不能直接删除 Job,但是仍然可以可以看到 DAG 的 Code。那如果您用的是 Jenkins ,或其他可以直接在 UI 上删除 Job 的套件,在权限控管上更要小心。

  • Job Runner
    Job Runner 通常是用来实际执行 ETL 程序的环境。Job Runner 由於要直接执行各式 ETL,通常会拥有比较多的权限,像是:存取 s3 bucket、存取 Database、Athena,甚至操作其他 AWS 元件等等。所以通常不会直接开放给使用者连线,而是仅开放从公司或特定内部连线存取。

我们可以从两方面来控制:

  • 连线管理
    网路连线需要一边管理使用者可以从哪连线,另一边管理服务可以跟谁连线。一般来说会采取这样的方式:
    使用者 > UI > Job Runner > Database。
    使用者 > UI > Metadata DB

  • 资源权限管理
    在 AWS 上很方便的就是可以透过给予机器 instance_profile 的方式来给予权限,让 service 可以不用碰到权限管理的问题。但是另外一方面,如果我们都将 Airflow 的 UI / Job Runner 都部署在 k8s 上,要从机器来管理权限恐怕又不是那麽容易。比较理想当然是拆成 node pool,但是现实上…

帐密(Secret)管理

一个好的程序,就不该把帐号密码写在里面。如果要用到 db connection,可以从环境变数拿,或是像 Airflow 这样从 secret manager 拿。用统一的 secret manager 拿的好处很多。除了安全之外,当连线资讯要更改时(例如有些公司规定三个月要变更密码一次),也可以很轻松的替换。

https://ithelp.ithome.com.tw/upload/images/20210925/201411401sfj9cpDEK.png


<<:  第十九天:用 Gradle 做 Build Scan

>>:  离职倒数7天:让人感觉自在,不是要说什麽动听的话,而是要把持住不要讲出讨人厌的话

人脸辨识的流程--人脸识别

人脸辨识系统有三个步骤,人脸侦测、特徵撷取、人脸识别。 人脸识别(Face recognition)...

【Day 03】从零开始的 Line Chatbot-建立专案

今天要来正式建立 Chatbot 的 Python 专案! 登入资料 进入 Line Develop...

Day11 配对品质评估 Evaluator

由於 Open-Match 在架构上,允许使用同一张 ticket,对不同的配对池进行搜寻与配对,这...

【资料结构】读档相关 12/18更

二维阵列的一维读入法 #include <math.h> #include <st...

[Day 08] 原形设计的样板参考

由於不是设计师,对於UI/UX相关的东西懂得可能就跟完全没接触过的人一样, 所以在想做一个自己的Ap...