s3://协议

s3://协议

Amazon简单存储服务(Amazon S3)提供了安全、持久、高可扩展的对象存储。有关Amazon S3的信息请见Amazon S3

s3协议被用在一个URL中,它指定一个Amazon S3桶的位置以及用来读写该桶中文件的前缀。用户可以定义只读外部表使用S3桶中现有的数据文件作为表数据,或者创建可写外部表将来自于INSERT操作的数据存储到S3桶中的文件。Greenplum数据库使用协议URL中指定的S3 URL以及前缀来为一个只读表选择一个或更多文件,还可以在为INSERT操作上传S3文件到可写表中时定义文件位置和文件名格式。

s3协议也支持Dell EMC Elastic Cloud Storage(ECS),这是一种与Amazon S3兼容的服务。

配置和使用S3外部表

按照下面这些基本步骤来配置S3协议和使用S3外部表,更多的信息请使用相应的链接。另见s3协议的限制来更好地理解S3外部表的能力和限制:
  1. 配置每一个数据库支持s3协议:
    1. 在每一个将通过s3协议访问S3桶的数据库中,为s3协议库创建读写函数:
      CREATE OR REPLACE FUNCTION write_to_s3() RETURNS integer AS
         '$libdir/gps3ext.so', 's3_export' LANGUAGE C STABLE;
      CREATE OR REPLACE FUNCTION read_from_s3() RETURNS integer AS
         '$libdir/gps3ext.so', 's3_import' LANGUAGE C STABLE;
    2. 在每一个将要访问S3桶的数据库中,声明s3协议并且指定前一步中创建的读写函数:
      CREATE PROTOCOL s3 (writefunc = write_to_s3, readfunc = read_from_s3);
      注意:协议名称s3必须和创建用来访问S3资源的外部表中指定的协议一样。

      相应的函数会被Greenplum数据库的每一个Segment实例调用。所有的Segment主机必须能够访问该S3桶。

  2. 在每一个Greenplum数据库的Segment上,创建并且安装s3协议的配置文件:
    1. 使用gpcheckcloud工具创建一个s3协议配置文件的模板:
      gpcheckcloud -t > ./mytest_s3.config
    2. 编辑该模板文件以指定连接S3位置所需的accessidsecret。有关其他协议参数的配置请见s3协议的配置文件
    3. 为Greenplum数据库的所有Segment把该文件复制到所有主机上的相同位置。默认的文件位置是gpseg_data_dir/gpseg_prefixN/s3/s3.confgpseg_data_dir是Greenplum数据库的Segment的数据目录路径,gpseg_prefix是Segment前缀,而N是Segment的ID。当用户初始化一个Greenplum数据库系统时,Segment的数据目录、前缀和ID就已经被设置好了。

      如果用户复制该文件到一个不同的位置或者文件名,那么用户必须用s3协议URL的config参数指定该位置。见关于s3协议的配置参数

    4. 使用gpcheckcloud工具验证到该S3桶的连接性:
      gpcheckcloud -c "s3://<s3-endpoint>/<s3-bucket> config=./mytest_s3.config"
      为用户的系统的配置文件指定正确的路径,还有用户想要检查的S3端点名和桶。gpcheckcloud会尝试连接到该S3端点并且列出S3桶中的任何文件(如果可用)。一次成功的连接将以这样的消息结束:
      Your configuration works well.
      使用gpcheckcloud工具中所述,用户可以有选择地使用gpcheckcloud来验证对该S3桶进行上传和下载。
  3. 在完成前几个创建和配置S3协议的步骤后,用户可以在CREATE EXTERNAL TABLE命令中指定一个S3协议URL来定义S3外部表。对于只读的S3表,该URL定义组成该S3表的现有数据文件的位置和前缀。例如:
    CREATE READABLE EXTERNAL TABLE S3TBL (date text, time text, amt int)
       LOCATION('s3://s3-us-west-2.amazonaws.com/s3test.example.com/dataset1/normal/
          config=/home/gpadmin/aws_s3/s3.conf')
       FORMAT 'csv';
    对于可写的S3表,协议URL定义S3位置,Greenplum数据库会把该表的数据文件存储在其中,该URL还定义了一个表INSERT操作创建文件时使用的前缀。例如:
    CREATE WRITABLE EXTERNAL TABLE S3WRIT (LIKE S3TBL)
       LOCATION('s3://s3-us-west-2.amazonaws.com/s3test.example.com/dataset1/normal/
          config=/home/gpadmin/aws_s3/s3.conf')
       FORMAT 'csv';

    更多信息请见关于S3协议URL

关于S3协议URL

对于s3协议,用户需要在CREATE EXTERNAL TABLE命令的LOCATION子句中指定文件的位置以及一个可选的配置文件位置。下面是语法:

's3://S3_endpoint[:port]/bucket_name/[S3_prefix] [region=S3_region] [config=config_file_location]'

s3协议要求指定S3端点和S3桶名。Greenplum数据库的每一个Segment实例必须能够访问该S3位置。可选的S3_prefix值被用来选择只读S3表的文件,或者被用作向S3可写表上传数据时的文件名前缀。

注意: Greenplum数据库的s3协议的URL必须包括S3的端点主机名。

要在LOCATION子句中指定一个ECS端点(一种Amazon S3的兼容服务),用户必须把s3配置文件参数version设置为2。version参数控制region参数是否被用在LOCATION子句中。当version参数为2时,用户还可以指定一个Amazon S3位置。有关version参数的信息,请见s3协议的配置文件

注意: 尽管S3_prefix是这种语法中一个可选的部分,用户应该总是为可写和只读S3表包括一个S3前缀,它被用来分隔作为CREATE EXTERNAL TABLE语法一部分的数据集。

对于可写的S3表,s3协议的URL指定Greenplum数据库为该表上传数据文件的端点和桶名。对于上传文件的S3用户ID,该S3桶的权限必须是Upload/Delete。对于每一个由于向表中插入数据形成的新的上传文件,都会使用这个S3文件前缀。见关于S3数据文件

对于只读的S3表,S3文件前缀是可选的。如果用户指定了一个S3_prefix,那么s3协议会选择所有以该前缀开始的文件作为该外部表的数据文件。s3协议不使用斜线字符(/)作为定界符,因此跟在前缀后面的一个斜线字符会被当做该前缀本身的一部分。

例如,考虑下面的5个文件,其中的每一个都有名为s3-us-west-2.amazonaws.comS3_endpoint以及bucket_name test1

s3://s3-us-west-2.amazonaws.com/test1/abc
s3://s3-us-west-2.amazonaws.com/test1/abc/
s3://s3-us-west-2.amazonaws.com/test1/abc/xx
s3://s3-us-west-2.amazonaws.com/test1/abcdef
s3://s3-us-west-2.amazonaws.com/test1/abcdefff
  • 如果提供的S3 URL是s3://s3-us-west-2.amazonaws.com/test1/abc,那么abc前缀会选择全部的5个文件。
  • 如果提供的S3 URL是s3://s3-us-west-2.amazonaws.com/test1/abc/,那么abc/前缀选择文件s3://s3-us-west-2.amazonaws.com/test1/abc/s3://s3-us-west-2.amazonaws.com/test1/abc/xx
  • 如果提供的S3 URL是s3://s3-us-west-2.amazonaws.com/test1/abcd,那么abcd前缀选择文件s3://s3-us-west-2.amazonaws.com/test1/abcdef以及s3://s3-us-west-2.amazonaws.com/test1/abcdefff

S3_prefix中不支持通配符字符。不过,S3前缀本来的功能就好像其后有一个通配符一样。

被S3 URL(S3_endpoint/bucket_name/S3_prefix)选中的所有文件都会被用作外部表的来源,因此它们必须有同样的格式。每个文件还必须包含有完整的数据行。一个数据行不能跨文件存在。对于访问这些S3文件的S3用户ID,文件的权限必须是Open/DownloadView

有关Amazon S3端点的信息请见http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region。有关S3桶和文件夹的信息请见Amazon S3的文档https://aws.amazon.com/documentation/s3/。有关S3文件前缀的信息请见Amazon S3的文档Listing Keys Hierarchically Using a Prefix and Delimiter

config参数指定所需的s3协议配置文件的位置,该文件包含AWS连接证书和通信参数。见关于S3协议的配置参数

关于S3数据文件

对于可写S3表上的每个INSERT操作,Greenplum数据库的每个Segment会使用文件名格式 <prefix><segment_id><random>.<extension>[.gz]上传一个单一文件到配置好的S3桶。文件名格式中:
  • <prefix>是在S3 URL中指定的前缀。
  • <segment_id>是Greenplum数据库的Segment的ID。
  • <random>是一个用来确保文件名唯一的随机数。
  • <extension>描述文件类型(.txt或者.csv,取决于用户在CREATE WRITABLE EXTERNAL TABLEFORMAT子句中提供的值)。gpcheckcloud工具创建的文件总是使用扩展名.data
  • 如果为S3可写表启用了压缩(默认启用),会在文件名后追加.gz

对于可写的S3表,用户可以配置Segment上传文件用的缓冲区尺寸以及线程数量。见s3协议的配置文件

对于只读的S3表,所有通过S3的文件位置(S3_endpoint/bucket_name/S3_prefix)指定的文件都被用作该外部表的来源并且都必须具有相同的格式。每个文件还必须包含有完整的数据行。如果这些文件含有一个可选的头部行,头部行中的列名不能包含新行字符(\n)以及回车(\r)。另外,列定界符也不能是新行字符(\n)以及回车(\r)。

s3协议可以识别gzip格式并且解压这类文件。只支持gzip压缩格式。

对于访问这些S3文件的S3用户ID,文件的权限必须是Open/DownloadView。可写的S3表要求该S3用户ID具有Upload/Delete权限。

对于只读的S3表,每一个Segment一次可以从S3位置使用几个线程下载一个文件。为了利用Greenplum数据库的Segment所执行的并行处理,S3位置中的文件应该在尺寸上相似并且文件的数量应该允许多个Segment从S3位置下载数据。例如,如果Greenplum数据库系统由16个Segment组成并且有充足的网络带宽,在S3位置中创建16个文件允许每个Segment从该S3位置下载一个文件。相反,如果如果该位置只包含1个或者2个文件,就只有1个或者2个Segment能下载数据。

s3协议的AWS服务端加密支持

Greenplum数据库支持用可读和可写外部表(用s3协议创建)访问的AWS S3文件进行服务端加密,服务端加密使用Amazon的S3-managed密钥(SSE-S3)。SSE-S3在用户的对象数据被写入到磁盘时对它们加密,并且在用户访问它们时透明地解密。

注意: s3协议只对Amazon Web Services的S3文件支持SSE-S3。在访问S3兼容服务上的文件时不支持SSE-S3。

用户的S3 accessidsecret权限掌管着用户对所有S3桶对象的访问,不管该数据是否被加密。但是,为了访问加密数据,用户必须配置用户的客户端使用S3-managed密钥。

有关AWS服务端加密的额外信息,请参考AWS文档中的 使用服务端加密保护数据

配置S3服务端加密

s3协议的服务端加密默认被禁用。要在使用Greenplum数据库的s3协议写入的AWS S3对象上利用服务端加密,用户必须在用户的s3配置文件中把配置参数server_side_encryption设置为值sse-s3

server_side_encryption = sse-s3

当用户把一个包括了server_side_encryption = sse-s3设置的配置文件提供给使用s3CREATE WRITABLE EXTERNAL TABLE调用时,Greenplum数据库会在该外部表上进行INSERT操作时应用加密头部。然后S3会在写LOCATION子句中提供的URI所标识的对象时进行加密。

在通过用s3协议创建的可读外部表访问加密文件时,S3会透明地解密数据。不需要做额外的配置。

对于更细粒度的加密配置,用户可以考虑创建Amazon Web Services S3的桶策略,按照AWS文档的Protecting Data Using Server-Side Encryption with Amazon S3-Managed Encryption Keys (SSE-S3)部分标识用户想要加密的对象以及在那些对象上的写动作。

关于S3协议的配置参数

可选的config参数指定所需的s3协议配置文件的位置。该文件包含Amazon Web Services (AWS) 的连接证书和通信参数。有关该文件的信息请见s3协议的配置文件

在Greenplum数据库的所有Segment主机上都要求这个配置文件。其默认位置是Greenplum数据库每一个Segment实例的数据目录下的一个位置。
gpseg_data_dir/gpseg_prefixN/s3/s3.conf

gpseg_data_dir是该Greenplum数据库Segment的数据目录路径,gpseg_prefix是该Segment的前缀,而N是该Segment的ID。Segment的数据目录、前缀还有ID都是在初始化一个Greenplum数据库系统时被设置好的。

如果在Segment主机上有多个Segment实例,用户可以通过在每个Segment主机上创建一个位置来简化配置。然后用户可以在s3协议的LOCATION子句中的config参数中指定该位置的绝对路径。这个例子指定了一个位于gpadmin主目录中的位置。

LOCATION ('s3://s3-us-west-2.amazonaws.com/test/my_data config=/home/gpadmin/s3.conf')

该主机上的所有Segment实例都会使用文件/home/gpadmin/s3.conf

S3协议的配置文件

在使用s3协议时,Greenplum数据库的所有Segment都要求一个s3协议配置文件。默认位置是:
gpseg_data_dir/gpseg-prefixN/s3/s3.conf

gpseg_data_dir是该Greenplum数据库Segment的数据目录路径,gpseg_prefix是该Segment的前缀,而N是该Segment的ID。Segment的数据目录、前缀还有ID都是在初始化一个Greenplum数据库系统时被设置好的。

如果在Segment主机上有多个Segment实例,用户可以通过在每个Segment主机上创建一个位置来简化配置。然后用户可以在s3协议的LOCATION子句中的config参数中指定该位置的绝对路径。不过,注意只读和可写S3外部表使用相同的参数进行连接。如果用户想为只读和可写S3表配置不同的协议参数,那么用户必须使用两个不同的s3协议配置文件并且在创建每个表时在CREATE EXTERNAL TABLE语句中指定正确的文件。

这个例子指定一个单一文件位置,它位于gpadmin主目录的s3目录中:

config=/home/gpadmin/s3/s3.conf

主机上的所有Segment实例都使用文件 /home/gpadmin/s3/s3.conf

s3协议配置文件是一个文本文件,它由一个[default]小节和参数构成。这里是一个配置文件的例子:
[default]
secret = "secret"
accessid = "user access id"
threadnum = 3
chunksize = 67108864

可以使用Greenplum数据库的gpcheckcloud工具来测试S3配置文件。见使用gpcheckcloud工具

s3配置文件参数

accessid
必需。访问S3桶的AWS S3 ID。
secret
必需。访问S3桶的AWS S3 ID的密码。
autocompress
对于可写的S3外部表,这个参数指定是否在上传到S3之前(使用gzip)压缩文件。如果没有指定这个参数,文件会默认被压缩。
chunksize
每个Segment线程用来读写S3服务器的缓冲区尺寸。默认是64MB。最小是8MB而最大是128MB。

在插入数据到可写S3表时,Greenplum数据库的每个Segment把数据写入到其缓冲区(使用最多threadnum个线程)中直到缓冲区被填满,之后它会把该缓冲区写入到S3桶中的一个文件里。根据需要这一处理会在每个Segment上反复执行直到插入操作完成。

因为Amazon S3允许最多10,000个部分的多部分上传,最小8MB的chunksize值就支持在Greenplum数据库的每个Segment上最大80GB的插入量。最大128MB的chunksize值支持每个Segment最大1.28TB的插入量。对于可写的S3表,用户必须确保chunksize的设置能支持表预期的大小。更多有关上传到S3的信息请见S3文档中的Multipart Upload Overview

encryption
使用被安全套接字层(SSL)保护的连接。默认值是true。值truetonyes以及y(大小写无关)都被当作是true。任何其他值都被当成是false

如果在CREATE EXTERNAL TABLE命令的LOCATION子句中的URL没有指定端口,配置文件的encryption参数会影响s3协议使用的端口(HTTP是端口80,HTTPS是端口443)。如果指定了端口,不管encryption设置是什么都会使用那个端口。

low_speed_limit
上传/下载速度下限,以字节每秒为单位。默认速度是10240(10K)。如果上传或者下载速度低于该限制超过low_speed_time所指定的时间,那么该连接会被中止并且重试。在3次重试后,s3协议会返回一个错误。指定值为0表示没有下限。
low_speed_time
当连接速度低于low_speed_limit时,这个参数指定在中止对S3桶上传或者下载之前应等待的总时间(以秒为单位)。默认值是60秒。指定值为0表示没有时间限制。
server_side_encryption
为桶配置的S3服务端加密方法。Greenplum数据库只支持使用Amazon S3-managed密钥的服务端加密,由配置参数值sse-s3表示。默认情况下服务端加密被禁用(值为none)。
threadnum
对S3桶上传或者下载数据时,一个Segment能够创建的并发线程的最大数量。默认值是4。最小值是1且最大值是8。
verifycert
控制在HTTPS上建立客户端和S3数据源之间加密通信时s3协议如何处理认证。其值可以是true或者false。默认值是true
  • verifycert=false - 忽略认证错误并且允许HTTPS之上的加密通信。
  • verifycert=true - 要求合法的认证(一个正确的证书)用于HTTPS之上的加密通信。
在测试和开发环境中设置这个值为false有助于允许无需更改证书的通信。
警告: 设置这个值为false会在建立客户端和S3数据存储之间的通信时忽略证书,这会暴露出安全性风险。
version
指定在CREATE EXTERNAL TABLE命令的LOCATION子句中指定的信息的版本。值可以是1或者2。默认值是1
如果值是1,则LOCATION子句支持Amazon S3 URL并且不含region参数。如果值是2,则LOCATION支持S3兼容服务并且必须包括region参数。region参数指定S3数据源的地区。对于下面这个S3 URL s3://s3-us-west-2.amazonaws.com/s3test.example.com/dataset1/normal/,其AWS S3地区是us-west-2
如果version是1或者没有指定,下面的LOCATIONCREATE EXTERNAL TABLE命令的子句)例子指定了一个Amazon S3端点。
LOCATION ('s3://s3-us-west-2.amazonaws.com/s3test.example.com/dataset1/normal/
      config=/home/gpadmin/aws_s3/s3.conf')
如果version是2,下面的带region参数的LOCATIONCREATE EXTERNAL TABLE命令的子句)例子指定了一个AWS S3兼容服务。
LOCATION ('s3://test.company.com/s3test.company/test1/normal/ region=local-test
      config=/home/gpadmin/aws_s3/s3.conf') 
如果version是2,该LOCATION子句还能指定一个Amazon S3端点。这个例子指定了一个使用region参数的Amazon S3端点。
LOCATION ('s3://s3-us-west-2.amazonaws.com/s3test.example.com/dataset1/normal/ region=us-west-2
      config=/home/gpadmin/aws_s3/s3.conf') 
注意: 在上传或者下载S3文件时,Greenplum数据库在每个Segment主机上可能要求最多threadnum * chunksize的内存。在配置Greenplum数据库的总内存时,请考虑这种s3协议的内存需求,并且在必要时增加gp_vmem_protect_limit的值。

S3协议的限制

samp class="ph codeph">s3协议有一些限制:
  • 只支持S3路径风格的URL。
    s3://S3_endpoint/bucketname/[S3_prefix]
  • 只支持S3端点。该协议不支持S3桶的虚拟主机(绑定一个域名给一个S3桶)。
  • 支持版本2和版本4的AWS签名的签名处理。

    有关每种签名处理支持的S3端点的信息,请见http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region

  • CREATE EXTERNAL TABLE命令的LOCATION子句中只支持一个单一URL和可选的配置文件。
  • 如果在CREATE EXTERNAL TABLE命令中没有指定NEWLINE参数, 新行字符在特定前缀的所有数据文件中都必须一样。如果在同一个前缀的某些数据文件中有不一样的新行字符,在这些文件上的读操作可能会失败。
  • 对于可写的S3外部表,只支持INSERT操作。不支持UPDATEDELETE以及TRUNCATE操作。
  • 因为Amazon S3允许做多10,000个部分的多部分上传,最大128MB的chunksize值在Greenplum数据库的每个Segment上支持对可写S3表最大1.28TB的插入量。用户必须确保chunksize的设置能支持表预期的大小。更多有关上传到S3的信息请见S3文档中的Multipart Upload Overview
  • 为了利用Greenplum数据库的Segment所执行的并行处理,S3位置中的文件应该在尺寸上相似并且文件的数量应该允许多个Segment从S3位置下载数据。例如,如果Greenplum数据库系统由16个Segment组成并且有充足的网络带宽,在S3位置中创建16个文件允许每个Segment从该S3位置下载一个文件。相反,如果如果该位置只包含1个或者2个文件,就只有1个或者2个Segment能下载数据。

使用gpcheckcloud工具

Greenplum数据库的工具gpcheckcloud帮助用户创建一个s3协议配置文件并且测试一个配置文件。用户可以用指定选项来测试用一个配置文件访问S3桶的能力,并且可以选择对该桶中的文件上传或者下载数据。

如果不用任何选项运行该工具,它会发送一个模板配置文件到STDOUT。用户可以捕捉该输出并且创建一个连接到Amazon S3的s3配置文件。

该工具被安装在Greenplum数据库的$GPHOME/bin目录中。

语法
gpcheckcloud {-c | -d} "s3://S3_endpoint/bucketname/[S3_prefix] [config=path_to_config_file]"

gpcheckcloud -u <file_to_upload> "s3://S3_endpoint/bucketname/[S3_prefix] [config=path_to_config_file]"
gpcheckcloud -t

gpcheckcloud -h
选项
-c
s3协议URL中指定的配置连接到指定的S3位置并且返回其中的文件信息。
如果连接失败,该工具显示关于失败的信息,例如非法的证书、前缀或者服务器地址(DNS错误)或服务器不可用。
-d
s3协议URL中指定的配置从指定的S3位置下载数据并且把输出发送到STDOUT
如果文件被gzip压缩过,解压后的数据会被发送到STDOUT
-u
使用指定的配置文件(如果有)上传一个文件到s3协议URL中指定的S3桶中。使用这个选项可以测试压缩和配置中的chunksizeautocompress设置。
-t
发送一个模板配置文件到STDOUT。用户可以捕捉该输出并且创建一个连接到Amazon S3的s3配置文件。
-h
显示gpcheckcloud帮助。

例子

这个例子运行不带选项的工具在当前目录下创建一个模板s3配置文件mytest_s3.config
gpcheckcloud -t > ./mytest_s3.config
这个例子尝试使用s3配置文件s3.mytestconf上传一个本地文件test-data.csv到一个S3桶位置:
gpcheckcloud -u ./test-data.csv "s3://s3-us-west-2.amazonaws.com/test1/abc config=s3.mytestconf"

一次成功的上传会导致在S3桶中出现一个或者更多个以文件名格式 abc<segment_id><random>.data[.gz]命名的文件。见关于S3数据文件

这个例子尝试使用s3配置文件s3.mytestconf连接到一个S3桶位置。
gpcheckcloud -c "s3://s3-us-west-2.amazonaws.com/test1/abc config=s3.mytestconf"
从该S3桶位置下载所有文件并且发送输出到STDOUT
gpcheckcloud -d "s3://s3-us-west-2.amazonaws.com/test1/abc config=s3.mytestconf"