- gpfdist 支持可读外部表和可写外部表。本文将介绍可写外部表如何工作。
介绍
可写外部表的目的是将GPDB中的数据并发地从segment上导出到远程服务器上的text或CSV格式文件中,可支持压缩选项。所有的segments直接导出自己的数据到gpfdist外部服务器,而不需要首先经过master。
可写外部表和可读外部表有类似的HTTP结构。GPDB segment作为http client,将数据post到http server(gpfdist)。不过可写外部表的通信协议和可读外部表并不相同。它并不会在一个HTTP连接中完成任何处理,而是通过一个HTTP请求序列(最少数量是3)。可写外部表仅支持协议版本0,就是说数据以原始格式传输,元数据通过header字段发送。附加的控制信息通过inital和teardown连接发送。
HTTP Header
可写外部表用到的所有header字段解释如下:
Header | Message type | Required | description |
---|---|---|---|
X-GP-XID | Request | Y | transaction id |
X-GP-CID | Request | Y | command id |
X-GP-SN | Request | Y | scan counter |
X-GP-SEGMENT-ID | Request | N | segment id |
X-GP-SEGMENT-COUNT | Request | N | Segment count |
X-GP-LINE-DELIM-LENGTH | Request | N | length of line ending |
X-GP-PROTO | Request/Response | Y | protocol version, only 0 for writable external table |
X-GP-SEQ | Request | Y | Sequence number of data request |
X-GPFDIST-VERSION | Response | N | Gpfdist version |
X-GP-DONE | Request | N | Indicates the full write operation is done on this segment |
X-GP-DATABASE | Request | N | current database name |
大多数字段含义和可读外部表中一致。这里只解释可写外部表中最重要的几个字段。
X-GP-SEQ
- 如前面所述,GPDB的每个segment会发送至少3个http请求来完成一次完整的上传操作。包括一个初始化请求,若干个数据请求和一个teardown请求。GPDB的每个segment使用X-GP-SEQ 统计当前到gpfdist的连接数。每个segment自己拥有独立的序列号。
(译注:每个任务都从1开始,还是每个segment累积??)
X-GP-DONE
- 该字段用于指示整个上传操作是否结束。它可以替代teardown请求。Gpfdist在关闭session之前需要等待每个segment的(所有)teardown消息。
HTTP请求类型
有3种类型的HTTP请求:初始化请求,数据请求和teardown请求。Gpfdist使用http 1.0协议,因此每个HTTP连接只能处理一个请求。在可写外部表上的每个查询将会包含一个初始化请求,一个或多个数据请求以及一个teardown请求。具体如下:
初始化请求
- 每个segment通过inital请求开始上传数据。inital请求post一个空的数据包(Content-Length是0),且 X-GP-SEQ 字段被设置为1. Gpfdist 记录这个session,并回复一个空的响应。inital请求初始化segment的数据传输流程。
- 以下是一个示例:
POST /lineite_wtite HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
X-GP-XID: 1502765779-0000000095
X-GP-CID: 0
X-GP-SN: 0
X-GP-SEGMENT-ID: 0
X-GP-SEGMENT-COUNT: 3
X-GP-LINE-DELIM-LENGTH: -1
X-GP-PROTO: 0
X-GP-SEQ: 1
Content-Type: text/xml
Content-Length: 0
HTTP/1.0 200 ok
Content-type: text/plain
Expires: 0
X-GPFDIST-VERSION: 5.0.0
X-GP-PROTO: 0
Cache-Control: no-cache
Connection: close
数据请求
- 数据请求是一个POST请求,URL和initial请求相同。如果数据内容长度大于
writable_external_table_bufsize
(单个包POST请求包的最大大小)将会有多个数据请求。数据请求包含一个"Expect: 100-continue"
的header。如果gpfdist server已经准备好接受该数据请求,它将回复"HTTP/1.1 100 Continue"
的响应。在收到gpfdist的"continue"
响应之后,GPDB segment将会开始POST数据。 - 以下是一个数据请求示例:
POST /lineite_wtite HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
X-GP-XID: 1502765779-0000000095
X-GP-CID: 0
X-GP-SN: 0
X-GP-SEGMENT-ID: 0
X-GP-SEGMENT-COUNT: 3
X-GP-LINE-DELIM-LENGTH: -1
X-GP-PROTO: 0
X-GP-SEQ: 606
Content-Type: text/xml
Content-Length: 65507
Expect: 100-continue
HTTP/1.1 100 Continue
33|605187|55200|2|32.00|34948.80|0.02|0.05|A|F|1993-12-09|1994-01-04|1993-12-28|COLLECT COD |MAIL |gular theodolites
33|1374686|99700|3|5.00|8803.10|0.05|0.03|A|F|1993-12-09|1993-12-25|1993-12-23|TAKE BACK RETURN |AIR |. stealthily bold exc
33|339175|39176|4|41.00|49780.56|0.09|0.00|R|F|1993-11-09|1994-01-24|1993-11-11|TAKE BACK RETURN |MAIL |unusual packages doubt caref
...
Teardown 请求
- Teardown请求是所有数据请求之后的最终请求,其HTTP data为空,header中包含”GP-DONE”字段且值为1。当gpfdist收到teardown请求后,它会回复一个空的响应报文,并清理连接资源。
- 以下是teardown请求示例:
POST /lineite_wtite HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
X-GP-XID: 1502765779-0000000095
X-GP-CID: 0
X-GP-SN: 0
X-GP-SEGMENT-ID: 0
X-GP-SEGMENT-COUNT: 3
X-GP-LINE-DELIM-LENGTH: -1
X-GP-PROTO: 0
X-GP-SEQ: 608
Content-Type: text/xml
X-GP-DONE: 1
Content-Length: 0
HTTP/1.0 200 ok
Content-type: text/plain
Expires: 0
X-GPFDIST-VERSION: 5.0.0
X-GP-PROTO: 0
Cache-Control: no-cache
Connection: close
可写外部表工作原理
- 和可写读部表类似,gpfdist server会依据
transaction id
,command id
,scan count
参数,对来自segments的请求进行按sessions进行分组。Gpfdist会将相同session的数据写到同一个文件。 - 可写外部协议使用
Protocol 0
在Greenplum segment和gpfdist之间交换控制信息和数据。segment通过initial request
发起写流程,其后是一系列数据请求。Segment只写属于他们自己的数据,写完后发送teardown
表示已经没有更多的数据。 下图演示了一个Segment上三种类型的请求序列
当所有segments完成数据传输,gpfdist将会关闭session并完成对目标文件的写入操作。
可写外部表GUC
- 有一些控制可写外部表行为的GUC参数如下:
Writable_external_table_bufsize
- 该值用于控制每个数据请求中可以发送多少数据。这个值是最大buffer大小。如网络良好的情况下,增大该值可以改善数据传输效率。
概述
- 到目前为止,我们介绍了可读、可写外部表。这将有助于诊断外部表传输失败问题,或设计你的新服务器。此外,还有很多可改善gpfdist协议的方面。比如,我们可以对传输的数据进行压缩,或使用最新的HTTP 2.0协议。