上线之後才是开始。
如果一开始开发和部署没有「乔好」环境的话,那上线的过程可是会吃一番苦头。例如搞不清楚环境有哪些套件,只好正式环境乱装一堆。如果每个开发工程师都用不同的套件,那正式环境会变得异常复杂。如果正式环境是分散式系统的话,状况又会变得更复杂,需要确保每台节点都有相同的套件。现在大多人用的解法都会使用 Docker Image 来将程序和套件一起打包,这样一来方便管理上线的版本,二来也是可以让开发与部属环境保持一至。
不管是原始资料、加工资料、模型什麽的,上线之後永远会产生意外的状况。不是资料格式不对、笔数不对、转换方式错误、或是意外的预测结果,总之「有可能发生的问题就会发生」。这些意外往往是来自於资料产品层层叠叠的影响,只要一层出错,後面就很有可能接连产生错误。
举例来说,之前我们都是透过 AWS Kinesis 来接收使用者手机传送过来的资料,後续所有 ETL、使用者报表、模型都是依据这个资料来做处理。有一天 Kinesis 在半夜断了两小时,少了这两小时资料,计算每日使用者数的报表自然就发生异常、另外一张根据每日使用者人数计算存活率的报表自然也不正确、少了那两小时的资料,针对使用者观看影片的训练的推荐模型自然也会受到影响。
这些异常的後续效果会比想像中还来得久以及来的难处理。例如延续上面的例子,尽管後来 Kineis 修复後资料成功进来,但是像是「过去七天使用者人数」的报表、或是「过去三十日观看热门影片」都会有一天的资料是「不正确」的,直到那个有问题的资料不会再被查询之後影响才会消失。
由於坏资料的影响会留存很久,所以我们必须尽量避免坏资料进入生产环境。这时候就很推荐使用「两阶段转换」。将处理完的结果,先放到别的地方,等资料验证没有问题後,再进入正式的 DB。
然而二阶段转换并不是说单纯把资料放到 Staging 环境而已,以下就来说明开发 Data Pipeline 通常的做法,以及环境的区分。
ETL 的正确性涵盖了两部分:
所以一般来说,比较严谨的开发流程会是这样子:
加入二阶段转换後最终会像这样:
正式资料 => 正式资料处理程序 => 暂存区 => 确认资料品质 => 正式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,但是现实上…
一个好的程序,就不该把帐号密码写在里面。如果要用到 db connection,可以从环境变数拿,或是像 Airflow 这样从 secret manager 拿。用统一的 secret manager 拿的好处很多。除了安全之外,当连线资讯要更改时(例如有些公司规定三个月要变更密码一次),也可以很轻松的替换。
<<: 第十九天:用 Gradle 做 Build Scan
>>: 离职倒数7天:让人感觉自在,不是要说什麽动听的话,而是要把持住不要讲出讨人厌的话
人脸辨识系统有三个步骤,人脸侦测、特徵撷取、人脸识别。 人脸识别(Face recognition)...
今天要来正式建立 Chatbot 的 Python 专案! 登入资料 进入 Line Develop...
由於 Open-Match 在架构上,允许使用同一张 ticket,对不同的配对池进行搜寻与配对,这...
二维阵列的一维读入法 #include <math.h> #include <st...
由於不是设计师,对於UI/UX相关的东西懂得可能就跟完全没接触过的人一样, 所以在想做一个自己的Ap...