Go中的复杂管线(第一部分)-简介

54 阅读2分钟

就在最近,我有机会在一个工具上工作,负责通过电线处理数千兆字节的数据,最终的目标是下载这些数据,处理这些数值,最后分批将它们插入持久性存储中。

大图片

简而言之,这个解决方案将由3个进程组成。

  1. 数据生产者过程:读取输入数据,并将其发送到一个目的地进行进一步处理。
  2. 数据消费者过程:接收原始数据,使用预期的格式解析这些值,并将其发送到不同的过程。
  3. 持久性存储过程:接收解析后的数据并分批存储。

这是用管道解决的经典问题。那个经典的帖子和这个新的系列最大的区别是,当与多个goroutines一起工作时,如何取消到位。这意味着定义有关任何失败时的预期行为的规则,所有这些都是使用两个伟大的Go包处理的。 contexterrgroup.

对于我们的例子,我们将使用IMDB的数据集的一部分文件。这些文件是以UTF-8字符集格式的gzipped、tab分隔的数值(TSV)。要使用的具体文件将是 name.basics.tsv.gz它定义了以下字段。

|-------------------|-----------|---------------------------------------------------|
|       Field       | Data Type |                   Description                     |
|-------------------|-----------|---------------------------------------------------|
| nconst            | string    | alphanumeric unique identifier of the name/person |
| primaryName       | string    | name by which the person is most often credited   |
| birthYear         | string    | in YYYY format                                    |
| deathYear         | string    | in YYYY format if applicable, else '\N'           |
| primaryProfession | []string  | the top-3 professions of the person               |
| knownForTitles    | []string  | titles the person is known for                    |
|-------------------|-----------|---------------------------------------------------|

数据生产者过程。输入数据格式

由于这个输入文件的位置(http资源)和文件数据格式(gzip),我们的数据生产者进程将使用以下方式请求该文件 net/http请求文件,用 compress/gzip并将它们作为原始[]byte 发送给数据消费者进程

数据消费者过程。输入数据格式

这些原始[]byte 值将被读成TSV记录,使用 encoding/csv并从那里将它们转换为新的结构类型Name ,以便我们管道的下一步能够理解。

持久性存储过程。输入数据格式

以下将被用作包含最终被持久化在数据库中的值的类型。

type Name struct {
	NConst             string
	PrimaryName        string
	BirthYear          string
	DeathYear          string
	PrimaryProfessions []string
	KnownForTitles     []string
}

我们将使用PostgreSQL作为关系型数据库,特别是 github.com/jackc/pgx将被导入用于分批存储这些值。

下一步是什么?

下一篇博文将介绍PostgreSQL Batcher的实现,随着我们在这个系列中的进展,我们将不断地把所有的部分连接在一起,最终完成我们的最终工具。