读数据工程之道:设计和构建健壮的数据系统23批量获取的考虑因素
1. 批量获取的考虑因素
1.1. 批量获取,通常是获取数据的一种便捷方式
- 1.1.1. 通过从源系统中抽取一个数据子集,根据时间间隔或累积数据的大小来获取数据
1.2. 基于时间间隔的批量获取在传统ETL的数据仓库中很普遍
- 1.2.1. 每天在非工作时间(也可以按其他频率)处理一次数据,目的是提供每日的业务报表
1.3. 当数据从基于流的系统转移到对象存储时,基于数据量大小的批量获取是很常见的
- 1.3.1. 需要把数据分成离散的块,以便后续在数据湖中进行处理
1.4. 常用的批量获取数据模式
-
1.4.1. 快照或差异数据提取
-
1.4.1.1. 数据工程师必须选择是捕获源系统的全速快照还是捕获差异(有时称为增量)更新
-
1.4.1.2. 使用全速快照,工程师在每次读取更新时都会抓取源系统的整个当前状态
> 1.4.1.2.1. 全速快照读取由于其简单性仍然非常普遍
- 1.4.1.3. 使用差异更新模式,工程师可以只提取自上次从源系统读取后的更新和变化
> 1.4.1.3.1. 差异更新是最小化网络流量和节省目标存储空间的理想选择
-
1.4.2. 基于文件的导出和获取
-
1.4.2.1. 数据经常以文件为介质在数据库和其他系统之间移动
-
1.4.2.2. 数据以可交换的格式序列化为文件,然后这些文件被提供给获取系统
-
1.4.2.3. 基于文件的导出是一种基于推送的获取模式
> 1.4.2.3.1. 数据导出和准备工作是在源系统一侧完成的
- 1.4.2.4. 出于安全原因,允许直接访问后端系统往往是不可取的
> 1.4.2.4.1. 通过基于文件的获取,导出过程在数据源端运行,让源系统工程师完全控制哪些数据被导出以及数据如何被预处理
-
1.4.2.5. 常见的文件交换方法是对象存储、安全文件传输协议(Secure File Transfer Protocol,SFTP)、电子数据交换(Electronic Data Interchange,EDI)或安全拷贝(Secure Copy,SCP)
-
1.4.3. ETL与ELT
-
1.4.3.1. 提取意味着从一个源系统中获取数据
-
1.4.3.2. 提取通常是拉取数据,但它也可以是基于推送的
-
1.4.3.3. 一旦数据被提取出来,就可以在其被加载到目标存储之前对其进行转换(ETL),或者简单地将数据加载到存储中,以便将来进行转换
-
1.4.4. 插入、更新和批大小
-
1.4.4.1. 当用户试图执行许多小批量的操作而不是数量较少的大操作时,批处理系统往往表现不佳
-
1.4.5. 数据迁移
-
1.4.5.1. 将数据迁移到一个新的数据库或环境中通常不是一件简单的事,数据需要被以批量的方式迁移
-
1.4.5.2. 大多数数据系统在批量移动数据时性能表现得比以单行或单个事件移动数据更好
-
1.4.5.3. 文件或对象存储通常是转移数据的一个很好的中间介质
-
1.4.5.4. 数据库迁移的最大挑战之一不是数据本身的移动,而是数据管道连接从旧系统到新系统的移动
2. 消息和流获取的考虑因素
2.1. 模式演进
-
2.1.1. 模式演进在处理事件数据时是很常见的
-
2.1.2. 模式演进可能会对你的数据管道和目标存储产生意想不到的影响
-
2.1.3. 如果你的事件处理框架有一个模式注册表,使用它来对你的模式变化进行版本管理
-
2.1.4. 一个死信队列可以帮助你检查那些没有被正确处理的事件的问题
-
2.1.5. 最简单粗暴的方式(也是最有效的)是定期与上游利益相关者就潜在的模式变化进行沟通,并与引入这些变化的团队一起主动解决模式变化,而不是只在接收端对发生破坏性变化的数据作出反应
2.2. 迟到数据
-
2.2.1. 事件可能会迟到
-
2.2.2. 为了处理迟到的数据,你需要设置一个截止时间,即迟到的数据将不再被处理
2.3. 顺序和重复发送
-
2.3.1. 流平台通常是由分布式系统构建的,这会导致一些复杂的问题
-
2.3.2. 消息可能不按预想的顺序传输,而且相同的消息可能被传输多次
2.4. 重放
-
2.4.1. 重放允许消息的使用者从历史数据中请求一系列的消息,允许你将事件倒退到一个过去的特定时间点
-
2.4.2. 重放是许多流式获取平台的关键功能,当你需要重新获取和处理特定时间范围的数据时,它非常有用
-
2.4.3. RabbitMQ通常会在所有订阅者消费完消息后将其删除
-
2.4.4. Kafka、Kinesis和Pub/Sub都支持事件保留和重放
2.5. 生存时间
-
2.5.1. 最大消息保留时间,也被称为生存时间
-
2.5.1.1. 生存时间是你希望事件在被确认和获取之前保存多长时间的设置
-
2.5.2. 任何在生存时间过期后没有被获取的未确认事件都会自动消失
-
2.5.2.1. 有助于减少事件获取管道中的背压和非必要的事件量
-
2.5.3. 要找到生存时间对我们数据管道影响的正确平衡点
-
2.5.3.1. 一个极短的生存时间(几毫秒或几秒)可能会导致大多数消息在处理前就消失
-
2.5.3.2. 一个很长的生存时间(几周或几个月)会造成许多未处理消息的积压,从而导致很长的等待时间
-
2.5.4. Google Cloud Pub/Sub支持最长7天的保留期
-
2.5.5. Amazon Kinesis Data Stream的保留期可以到365天
-
2.5.6. Kafka可以被配置为无限期保留,仅受限于可用的磁盘空间
-
2.5.6.1. Kafka还支持将旧消息写入云对象存储的选项,解锁几乎无限的存储空间和保留期
2.6. 消息大小
- 2.6.1. 必须确保你的流框架能够处理你预期内最大的消息
2.7. 错误处理和死信队列
-
2.7.1. 因为消息大小超标,或者已经过了生存时间,所以事件可能被发送到一个不存在的主题或消息队列
-
2.7.2. 不能被获取的事件需要被重新路由并存储在一个单独的位置,称为死信队列
-
2.7.3. 死信队列将有问题的事件和消费者可以正确获取的事件分开
-
2.7.4. 数据工程师可以使用死信队列来诊断为什么会发生获取错误,并解决数据管道问题
-
2.7.4.1. 在找到错误的根本原因并解决后,就可以重新处理队列中的消息了
2.8. 消费者的推送和拉取
-
2.8.1. Kafka和Kinesis只支持拉取式订阅
-
2.8.2. Pub/Sub和RabbitMQ还支持推送式订阅,允许这些服务将消息写到监听器上
-
2.8.3. 拉取式订阅是大多数数据工程应用程序的默认选择
-
2.8.4. 如果你添加一个额外的层来处理这个问题,纯拉取式的消息获取系统仍然可以推送
2.9. 位置
-
2.9.1. 为了增强冗余度,我们会集成来自不同位置的数据流并在靠近数据生成的位置消费数据
-
2.9.2. 你的获取点越靠近数据生成的位置,你的带宽和延迟就越好
-
2.9.3. 需要平衡位置与在区域之间移动数据以在组合数据集上运行分析的成本