gpfdist可读外部表协议介绍

本文深入探讨了Greenplum Database (GPDB) 的可读外部表功能,特别是gpfdist服务器与GPDB之间的通信机制。介绍了gpfdist使用的HTTP头部字段及两种不同的协议版本(Protocol0和Protocol1),并解释了它们在处理外部数据时的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接

  • 作为Greenplum所有ETL操作基本原理,我们有必要稍微多介绍一些gpfdist的细节,以便于理解为什么它比其他工具速度更快,以及将来我们应如何对其进行改进。
  • 本文将聚焦在gpfdist server和Greenplum 可读外部表之间的通信细节上,介绍数据流以及gpfdist外部表协议。
  • Gpfdist使用HTTP协议和Greenplum segment通信。Gpfdist作为HTTP Server,负责将静态文件内容分发到GPDB,或从GPDB接收内容。每个Segment作为一个HTTP client,通过get或post从gpfdist获取数据。

HTTP Header 介绍

  • Gpfdist 协议使用特殊的HTTP Header传递GPDB和Gpfdist之间必要信息。下表列出了gpfdist 可读外部表用到的所有特殊HTTP Hader。
HeaderMessage typeRequireddescription
X-GP-XIDRequestYtransaction id
X-GP-CIDRequestYcommand id
X-GP-SNRequestYscan counter
X-GP-SEGMENT-IDRequestNsegment id
X-GP-SEGMENT-COUNTRequestNSegment count
X-GP-LINE-DELIM-LENGTHRequestNlength of line ending
X-GP-PROTORequest/ResponseYprotocol version, 0 or 1
X-GP-MASTER_HOSTRequestNGPDB master host address
X-GP-MASTER_PORTRequestNGPDB master port
X-GP-CSVOPTRequestYCSV option format
X-GP_SEG_PG_CONFRequestNconfig path of segment
X-GP_SEG_DATADIRRequestNdata directory of segment
X-GP-DATABASERequestNcurrent database name
X-GP-USERRequestNcurrent login user
X-GP-SEG-PORTRequestNSegment port
X-GP-SESSION-IDRequestNgp_session_id
X-GPFDIST-VERSIONResponseYgpfdist server version
  • 上述表中Message type一列表示对应的Header字段应该出现在什么位置。
    • Request 表示出现在从Greenplum到gpfdist的HTTP请求头中
    • Response表示出现在gpfdist的响应头中
  • 并非所有字段都是必须的,具体参见required
  • 接下来将介绍最重要的几个字段:

X-GP-SN

  • Greenplum外部表目前只支持顺序扫描,因此一些self-join的查询会对一个外部文件进行两次扫描。X-GP-SN用来记录当前扫描计数。Gpfdist将会使用该参数(连同command id和transaction id)来决定两个连接是否属于同一个session。

X-GP-PROTO

  • 可读外部表有两种不同的协议,Protocol 0 和 Protocol 1 目前都是可用的。我们稍后会介绍他们的区别。该参数是gpfdist识别一个请求是否来自GPDB还是其他工具的重要依据。Gpfdist会拒绝没有X-GP-PROTO的连接。

X-GP-CSVOPT

  • GPfdist 支持text和csv格式。
    • Text很方便处理。每解析一行就发送数据给GPDB就可以了。
    • 对于CSV格式,gpfdist需要知道更多关于转义(escape)或引号符(quote character)的信息。其格式为m.x.q.n.h.。各小写字母的含义如下:
LetterMeaningExample
mCsv or not1 or 0
xDecimal number of escape byte9 (TAB), 124 (|), etc
qDecimal number of quote byte34(“)
nEOL type0-(EOL_UNKNOWN), 1-(EOL_LF), 2-(EOL_CR), 3-(EOL_CRLF)
hWith header or not1 or 0
  • 示例m1x9q34n0h0

可读外部表如何工作

  • 当用户在可读外部表上执行一个select查询时,GPDB的每个segment各自发送已填好Header字段的HTTP GET请求到gpfdist,获取和此次查询相关的数据。
  • 当gpfdist收到来自GPDB segment的请求后,按照每个请求中的<transaction id,command id,scan count> 参数,分组到各个session。所有属于同一个session的请求都是服务于同一个查询的,且由不同的segment并行发送而来。gpfdist会根据URL路径,读取本地文件的数据,直到已经读取足够多的数据到缓存之后才会发送。默认缓存大小是32KB,可通过-m参数修改。如果gpfdist正在读的文件是一个管道,且管道输入很慢,它会持续等待,且不会响应其他请求。这是gpfdist当前版本的一个局限,在后续版本中将会得到改进。

可读外部表GUC

gp_external_max_segs

  • 用于控制每个查询中,允许连接到单个gpfdist上的最大segment数量。即对于同一个查询session,最多允许gp_external_max_segs个segment连接到单个gpfdist server。默认值是64. Gpfdist在开始发送数据之前不需要等待所有segment都连接上来。每个segment一次只会创建一个到gpfdist的连接。第一个到gpfdist的连接会在gpfdist中创建一个session,之后属于同一个查询的连接都会加入这个session。只要session非空,gpfdist就会轮询地(round robin)通过这些连接向segment发送数据。

readable_external_table_timeout

  • 该值控制GPDB在取消链接之前的等待时间。如果一个基于gpfdist的查询执行了很长时间,将会回错误intermittent network connectivity issues。用户可自己设置readable_external_table_timeout 的值。

可读外部表工作流

  • 可读外部表的工作流是很简单的。GPDB发送HTTP请求到gpfdist,gpfdist返回HTTP响应和请求的数据。
  • 有两个版本的协议可用于读外部表,通过X-GP-PROTO区分。我们接下来将会解释二者的区别。下面是可读外部表在单个segment和gpfdist之间的工作流。

Protocol 0

  • Protocol 0很简单:使用HTTP头部字段来传递所有元数据。GPDB Segments 发送 GET请求,gpfdist向segment响应原始数据(raw data)
  • Protocol 0最大的缺陷在于当gpfdist内部发生错误时,没有途径告知GPDB。如果gpfdist被用户杀掉,或原始文件损坏,gpfdist无法将此类消息告知GPDB。它唯一能做的就是立即关闭socket以结束HTTP连接。然后,这和普通的读成功时表现一致,因此GPDB无法识别读成功还是失败。

Protocol 1

  • Protocol 1的目的就是解决Protocol 0最致命的缺陷。它为每个数据块(称之为package)定义了一个新的数据格式,封装后再发送给GPDB。Gpfdist和GPDB不会直接发送原始数据。所有数据通过特殊格式封装,然后通过一个个package发送。Package 由消息构成。有3中类型的package和4种类型的消息。每种消息有3个字段:message type,content length,content
Field namefield length
Message type1
Content length4
Content dataValue of Content length
  • 以下是对4种消息类型的描述:
Message TypeFull namecontent
Ffilenamefile name that related data belong to
Ooffsetapprox office(译注:疑为笔误,应该是offset) in file of current data
Ddatathe real data
EerrorError message of gpfdist
Lline numberapprox line number in file
  • 由于gpfdist从文件夹中查找文件时支持通配符,F消息(filename)总是显示数据所在的正确文件名。 Offset(O)和line number(L)是对数据在文件中位置的一个估值,在向用户展示错误信息的时候很有意义,比如当Greenplum解析数据内容时发现格式错误。可以通过该信息知道文件中发生错误的大概位置。
  • Package 可对数据或消息进行封装。
    • 对于数据package,消息序列是F,O,L,D。
    • 如果没有更多消息可发送,gpfdist将发送空的package并携带长度为0的D消息,用于关闭连接。
    • 如果有错误,gpfdist发送包含错误详细信息的E消息
Package typeMessage content
DataFOLD
Endzero-length D
ErrorE

- 下图为Protocol 1的连接的典型示例
这里写图片描述l

  • 如果对HTTP协议熟悉,你会注意到上述消息和HTTP Chunked-mode很类似,但实际上二者是完全不同的,尽管其目的类似。
    • Chunked-mode 非常适合传输流式数据
    • Gpfdist的Protoco1响应,借鉴了HTTP并添加了其专有的特殊目的元数据。

概述

  • 本文介绍了gpfdist可读外部表的两种协议。可通过wireshark工具理解这些协议,该工具能捕获TCP报文并以图形化方式展示通信过程。建议和gpfdist相同的的主机上运行wireshark,以观察来自GPDB segment的请求和响应。
  • 新写一个基于上述协议、能够发送数据到GPDB的简单版本gpfdist并不难。事实上目前已有一些gpfdist的实现,比如Gemfire GPDB Connector 或者 一个C#版本的工具(https://github.com/pf-qiu/gpfdist.net)

参考

https://gpdb.docs.pivotal.io/43160/ref_guide/config_params/guc-list.html
https://github.com/greenplum-db/gpdb/tree/master/src/bin/gpfdist

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值