Original URL:https://aws.amazon.com/blogs/big-data/analyze-your-amazon-s3-spend-using-aws-glue-and-amazon-redshift/
AWS 成本和使用情况报告 (CUR) 会追踪您的 AWS 使用情况,并提供与之相关联的预计费用。您可以配置此报告为以小时或日为间隔显示数据;在账单收费期最后结束前,它至少每天会更新一次。成本和使用情况报告会自动发送到由您指定的 Amazon S3 存储桶,可以在那里直接下载。您还可以将该报告整合到 Amazon Redshift,也可以通过 Amazon Athena 进行查询,或者把它上传到 Amazon QuickSight。如需更多信息,见本文将介绍采用 AWS Glue 数据目录和 Amazon Redshift,整合 AWS CUR、S3 清单报告和 S3 服务器访问日志,从而对 S3 使用情况和支出进行分析的解决方案。
在开始前,满足以下先决条件:
Amazon S3 清单是 S3 提供帮助对您的存储进行管理的工具之一。您可以用它对您的业务、合规和监管需求对象的复制与加密状态进行审计和报告。Amazon S3 清单每天或每周会为特定 S3 存储桶提供列出您的对象及其对应元数据列表, 以CSV、ORC,或Parquet 格式输出。
服务器访问日志详细记录了您向存储桶发起的请求。服务器访问日志对于众多应用程序来说都相当有用,如在安全方面和访问审计时。它还有助于理解您的客户群与您的 S3 账单。
AWS Glue 是一项完全托管的提取、转换和加载 (ETL) 服务,可简化并使对您的数据进行分类、清理、丰富,以及在各种数据存储之间进行可靠移动变得更具成本效益。AWS Glue 由一个被称为“数据目录”的中央元数据存储库、一个使用表格填充“数据目录”的爬网程序、一个自动生成 Python 或 Scala 代码的 ETL 引擎,以及一个可处理依赖关系解析、作业监控和重试的灵活计划程序组成。AWS Glue 采用无服务器技术,无需对基础设施进行设置或管理。本文使用 AWS Glue 对 S3 清单数据和服务器访问日志进行目录编列,让您可以通过 Amazon Redshift Spectrum 进行查询。
Amazon Redshift 是一项完全托管的云中 PB 级数据仓库服务。您可以使用Amazon Redshift 对存储在 S3 上结构化数据进行高效查询与检索,而不用将数据加载到 Amazon Redshift 原生表当中。您可以在 AWS Glue 数据目录中定义文件的结构,从而创建 Amazon Redshift 外表。
本文将 Parquet 做为清单报告输出文件格式,并且每天将文件传输到 S3 存储桶。您可以在高级设置下方选择传输的频率与输出文件格式,如下方截图所示:

如需关于配置您的 S3 清单的更多信息,见如何配置 Amazon S3 清单?
下图显示的是此解决方案的数据流:

以下步骤对上述数据流图表进行了总结:
清单报告被传输至 S3 存储桶。以下截图显示的是 S3 清单报告的 S3 存储桶结构:

此存储桶中有一个数据文件夹。此文件夹含有您想要分析的 Parquet 格式数据。以下截图显示的是该文件夹的内容。

这些都是日常文件,每天都有一个。
您可以使用 AWS Glue 爬网程序来发现您的 S3 存储桶中的此数据集,并且在数据目录中创建Schema 。在创建这些表以后,您可以直接从 Amazon Redshift 对其进行查询。
要配置您的爬网程序以便从您的 S3 存储桶读取 S3 清单文件,执行以下步骤:
AmazonS3FullAccess 和 AWSGlueConsoleFullAccess。本文使用数据库 s3spendanalysis。
以下截图显示的是已完成的爬网程序配置。

运行此爬网程序,以添加表到您的 Glue 数据目录。在成功完成对爬网程序的设置以后,转至您的 AWS Glue 控制台的表部分,以验证表的详细信息和表的元数据。以下截图显示的是在成功设置 AWS Glue 爬网程序以后的表的详细信息和表的元数据:

在可以对 S3 清单报告进行查询前,您需要在 Amazon Redshift 中创建外部schema(并随后创建外部表)。Amazon Redshift 外部schema会引用外部数据目录中的外部数据库。由于使用 AWS Glue 数据目录作为您的外部目录,在 Amazon Redshift 内创建外部schema以后,您可以在 Amazon Redshift 内看到您的数据目录中的全部外部表。要创建外部schema,输入以下代码:
create external schema spectrum_schema from data catalog
database 's3spendanalysis'
iam_role 'arn:aws:iam::<AWS_IAM_ROLE>';在 Amazon Redshift 控制面板的查询编辑器的下方,您可以看到数据表。您还可以查询 svv_external_schemas 数据表,以验证您的外部schema创建成功。见以下截图。

您现在可以从 Amazon Redshift 直接查询 S3 清单报告,而无需首先将数据移动到 Amazon Redshift。以下截图显示的是如何使用 Amazon Redshift 控制台的“查询编辑器”执行此操作:

下图显示的是此解决方案的数据流。

以下步骤对上述数据流图表进行了总结:
S3 服务器访问日志会被传输到 S3 存储桶。如需关于设置服务器访问日志记录的更多信息,见 Amazon S3 服务器访问日志记录。
以下截图显示的是存放服务器访问日志的 S3 存储桶结构。
服务器访问日志文件由一系列以换行符分隔的日志记录组成。每条日志记录表示一次请求,并且由以空格分隔的字段组成。以下代码为日志记录的示例:
b8ad5f5cfd3c09418536b47b157851fb7bea4a00486471093a7d765e35a4f8ef s3spendanalysisblog [23/Sep/2018:22:10:52 +0000] 72.21.196.65 arn:aws:iam::<AWS Account #>:user/shayons D5633DAD1063C5CA REST.GET.LIFECYCLE - "GET /s3spendanalysisblog?lifecycle= HTTP/1.1" 404 NoSuchLifecycleConfiguration 332 - 105 - "-" "S3Console/0.4, aws-internal/3 aws-sdk-java/1.11.408 Linux/4.9.119-0.1.ac.277.71.329.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.181-b13 java/1.8.0_181"您可以将 S3 服务器访问日志定义为外部表。由于您已经有外部schema,因此要使用以下代码创建外部表。本文使用 RegEx SerDe 创建表,以允许您正确地解析 S3 服务器访问日志中的全部字段。见以下代码:
CREATE EXTERNAL TABLE spectrum_schema.s3accesslogs(
BucketOwner varchar(256),
Bucket varchar(256),
RequestDateTime varchar(256),
RemoteIP varchar(256),
Requester varchar(256),
RequestID varchar(256),
Operation varchar(256),
Key varchar(256),
RequestURI_operation varchar(256),
RequestURI_key varchar(256),
RequestURI_httpProtoversion varchar(256),
HTTPstatus varchar(256),
ErrorCode varchar(256),
BytesSent varchar(256),
ObjectSize varchar(256),
TotalTime varchar(256),
TurnAroundTime varchar(256),
Referrer varchar(256),
UserAgent varchar(256),
VersionId varchar(256))
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'input.regex' = '([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) \"([^ ]*) ([^ ]*) ([^ ]*)\" (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\") ([^ ]*)'
)
STORED AS TEXTFILE
LOCATION
's3://s3spendanalysisblog/accesslogs/';您可以验证 Amazon Redshift 中的外部表数据。以下截图显示的是如何使用 Amazon Redshift 控制台的“查询编辑器”执行此操作:

您现在已准备好分析数据。
在本文中,您的 S3 存储桶内每天都会有一个 CUR 文件。以月为单位对文件进行整理。见以下截图。

每天的文件由 CUR 数据的以下文件组成:
使用 Amazon Redshift 是执行此分析的众多方式之一。Amazon Redshift 是一个快速、完全托管的云数据仓库,可简化并使通过标准的 SQL 和您的现有商业智能 (BI) 工具对您的全部数据进行分析变得更具成本效益。Amazon Redshift 为您提供针对使用熟悉的基于 SQL 客户端的结构化数据和使用标准 ODBC 和 JDBC 连接的 BI 工具的快速查询功能。查询分布且并行于多个物理资源。
您现在可以使用 Amazon Redshift SQL 查询编辑器运行 SQL 查询。本文还会使用 psql 客户端工具(PostgreSQL 的基于终端的前端)查询集群中的数据。
要查询数据,执行以下步骤:
create schema if not exists redshift_schema;您应该在 schema 中创建您的表,而不是对公众开放以控制用户访问数据库对象。
create table redshift_schema.AWSBilling201910 (
identity_LineItemId VARCHAR(256),
identity_TimeInterval VARCHAR(100),
bill_InvoiceId VARCHAR(100),
bill_BillingEntity VARCHAR(10),
bill_BillType VARCHAR(100),
bill_PayerAccountId VARCHAR(100),
bill_BillingPeriodStartDate TIMESTAMPTZ,
bill_BillingPeriodEndDate TIMESTAMPTZ,
lineItem_UsageAccountId VARCHAR(100),
lineItem_LineItemType VARCHAR(100),
lineItem_UsageStartDate TIMESTAMPTZ,
lineItem_UsageEndDate TIMESTAMPTZ,
lineItem_ProductCode VARCHAR(100),
lineItem_UsageType VARCHAR(100),
lineItem_Operation VARCHAR(100),
lineItem_AvailabilityZone VARCHAR(100),
lineItem_ResourceId VARCHAR(256),
lineItem_UsageAmount DECIMAL(11,2),
lineItem_NormalizationFactor VARCHAR(10),
lineItem_NormalizedUsageAmount DECIMAL(11,2),
lineItem_CurrencyCode VARCHAR(10),
lineItem_UnblendedRate DECIMAL(11,2),
lineItem_UnblendedCost DECIMAL(11,2),
lineItem_BlendedRate DECIMAL(11,2),
lineItem_BlendedCost DECIMAL(11,2),
lineItem_LineItemDescription VARCHAR(100),
lineItem_TaxType VARCHAR(100),
lineItem_LegalEntity VARCHAR(100),
product_ProductName VARCHAR(100),
product_alarmType VARCHAR(100),
product_automaticLabel VARCHAR(100),
product_availability VARCHAR(100),
product_availabilityZone VARCHAR(100),
product_clockSpeed VARCHAR(100),
product_currentGeneration VARCHAR(100),
product_databaseEngine VARCHAR(100),
product_dedicatedEbsThroughput VARCHAR(100),
product_deploymentOption VARCHAR(100),
product_durability VARCHAR(100),
product_ecu VARCHAR(100),
product_edition VARCHAR(100),
product_engineCode VARCHAR(100),
product_enhancedNetworkingSupported VARCHAR(100),
product_eventType VARCHAR(100),
product_feeCode VARCHAR(100),
product_feeDescription VARCHAR(100),
product_fromLocation VARCHAR(100),
product_fromLocationType VARCHAR(100),
product_gpu VARCHAR(100),
product_gpuMemory VARCHAR(100),
product_group VARCHAR(100),
product_groupDescription VARCHAR(100),
product_instanceFamily VARCHAR(100),
product_instanceType VARCHAR(100),
product_instanceTypeFamily VARCHAR(100),
product_io VARCHAR(100),
product_labelingTaskType VARCHAR(100),
product_licenseModel VARCHAR(100),
product_location VARCHAR(100),
product_locationType VARCHAR(100),
product_maxThroughputvolume VARCHAR(100),
product_maxVolumeSize VARCHAR(100),
product_memory VARCHAR(100),
product_messageDeliveryFrequency VARCHAR(100),
product_messageDeliveryOrder VARCHAR(100),
product_minVolumeSize VARCHAR(100),
product_networkPerformance VARCHAR(100),
product_normalizationSizeFactor VARCHAR(100),
product_operation VARCHAR(100),
product_physicalCpu VARCHAR(100),
product_physicalGpu VARCHAR(100),
product_physicalProcessor VARCHAR(100),
product_processorArchitecture VARCHAR(100),
product_processorFeatures VARCHAR(100),
product_productFamily VARCHAR(100),
product_protocol VARCHAR(100),
product_queueType VARCHAR(100),
product_region VARCHAR(100),
product_servicecode VARCHAR(100),
product_servicename VARCHAR(100),
product_sku VARCHAR(100),
product_storage VARCHAR(100),
product_storageClass VARCHAR(100),
product_storageMedia VARCHAR(100),
product_subscriptionType VARCHAR(100),
product_toLocation VARCHAR(100),
product_toLocationType VARCHAR(100),
product_transferType VARCHAR(100),
product_usageFamily VARCHAR(100),
product_usagetype VARCHAR(100),
product_vcpu VARCHAR(100),
product_version VARCHAR(100),
product_volumeType VARCHAR(100),
product_workforceType VARCHAR(100),
pricing_RateId VARCHAR(100),
pricing_publicOnDemandCost DECIMAL(11,2),
pricing_publicOnDemandRate DECIMAL(11,2),
pricing_term VARCHAR(100),
pricing_unit VARCHAR(100),
reservation_AmortizedUpfrontCostForUsage DECIMAL(11,2),
reservation_AmortizedUpfrontFeeForBillingPeriod DECIMAL(11,2),
reservation_EffectiveCost DECIMAL(11,2),
reservation_EndTime TIMESTAMPTZ,
reservation_ModificationStatus VARCHAR(100),
reservation_NormalizedUnitsPerReservation BIGINT,
reservation_RecurringFeeForUsage DECIMAL(11,2),
reservation_StartTime TIMESTAMPTZ,
reservation_SubscriptionId VARCHAR(100),
reservation_TotalReservedNormalizedUnits BIGINT,
reservation_TotalReservedUnits BIGINT,
reservation_UnitsPerReservation BIGINT,
reservation_UnusedAmortizedUpfrontFeeForBillingPeriod DECIMAL(11,2),
reservation_UnusedNormalizedUnitQuantity BIGINT,
reservation_UnusedQuantity BIGINT,
reservation_UnusedRecurringFee DECIMAL(11,2),
reservation_UpfrontValue BIGINT
);3使用提供的 CUR 清单文件将最近一个月的数据加载到 Amazon Redshift 当中。见以下代码:
copy AWSBilling201910 from 's3://ss-cur//myCURReport/20191001-20191101/fd76beee-0709-42d5-bcb2-bb45f8ba1aae/myCURReport-RedshiftManifest.json'
credentials 'arn:aws:iam::<AWS_IAM_ROLE>'
GZIP CSV IGNOREHEADER 1 TIMEFORMAT 'auto' manifest;where lineItem_ProductCode = 'AmazonS3'
and lineItem_ResourceId = 's3spendanalysisblog' limit 10;以下截图显示的是已被正确加载到 Amazon Redshift 表的数据:
您可以通过控制哪些用户拥有哪些数据库对象的访问权限,在 Amazon Redshift 中管理数据库安全性。要确保您的对象正确无误,创建两个组:FINANCE 和 ADMIN,两个用户在 FINANCE 中,一个用户在 ADMIN。请执行以下步骤:
create group admin;要查看所有用户组,查询 PG_GROUP 系统目录表(您应该可以在此处看到 finance 和 admin):
select * from pg_group:
in group finance;
create user finance2 password 'finance2Pass'
in group finance;
create user admin1 password 'admin1Pass'
in group admin;验证已成功创建用户。要查看用户列表,查询 PG_USER 目录表:
redshift_schema 中的表 AWSBilling201910,向 FINANCE 组授予 SELECT 权限,向 ADMIN 组授予 ALL 权限。见以下代码:grant select on table redshift_schema.AWSBilling201910 to group finance; grant all on table redshift_schema.AWSBilling201910 to group admin;您可以验证是否已正确执行数据库安全措施。用户 finance1 尝试对 redshift_schema 中的表 AWSBilling201910 进行重命名,但却收到 permission denied 错误消息(由于访问受限)。以下截图显示的是此种情况,以及后续的错误消息:
根据存储桶对 S3 费用进行拆分。以下查询会识别每个独立 S3 存储桶的数据存储和传输成本:
SELECT
"lineitem_productcode",
"lineitem_usagetype",
"lineitem_resourceid",
b."storage_class",
SUM(CASE
WHEN "lineitem_usagetype" like '%Byte%' THEN "lineitem_usageamount"/1024
ELSE "lineitem_usageamount"
END) as "Usage",
CASE
WHEN "lineitem_usagetype" like '%Byte%' THEN 'TBs'
ELSE 'Requests'
END as "Usage Units",
sum("lineitem_blendedcost") as cost
from awsbilling201902 a
join spectrum_schema.data b
on a.lineItem_ResourceId = b.bucket
where "product_productname" = 'Amazon Simple Storage Service'
group by
"lineitem_productcode",
"lineitem_usagetype",
"lineitem_resourceid",
b."storage_class"
order by
sum("lineitem_blendedcost") desc;以下截图显示的是执行上述查询的结果:
根据存储类型拆分成本(如,Glacier 和标准存储)。
以下查询会识别不同 S3 存储类(使用量、非混合成本、混合成本)的 S3 数据传输成本(区域内和区域间):
SELECT
lineitem_productcode
,product_fromlocation
,product_tolocation,
b.storage_class
,sum(lineitem_usageamount) usageamount
,sum(lineitem_unblendedcost) unblendedcost
,sum(lineitem_blendedcost) blendedcost
FROM
awsbilling201902 a
join spectrum_schema.data b
ON
a.lineItem_ResourceId = b.bucket
WHERE
a.lineitem_productcode = 'AmazonS3'
AND a.product_productfamily = 'Data Transfer'
GROUP BY
1,2,3,4
ORDER BY
usageamount desc;以下截图显示的是执行上述查询的结果:
以下查询会识别 S3 费用、API 请求和存储费用:
SELECT
lineitem_productcode
,product_productfamily
,b.storage_class
,sum(lineitem_usageamount) usageamount
,sum(lineitem_unblendedcost) unblendedcost
,sum(lineitem_blendedcost) blendedcost
FROM
awsbilling201902 a
join spectrum_schema.data b
ON
a.lineItem_ResourceId = b.bucket
WHERE
a.lineitem_productcode = 'AmazonS3'
and a.product_productfamily <> 'Data Transfer'
GROUP BY
1,2,3
ORDER BY
usageamount desc;以下截图显示的是执行上述查询的结果:
不同操作类型的 S3 访问日志费用。以下查询会识别每项独立 HTTP 操作的数据存储和传输成本:
SELECT
"lineitem_productcode",
"lineitem_usagetype",
"lineitem_resourceid",
b."operation",
b."httpstatus",
b."bytessent",
SUM(CASE
WHEN "lineitem_usagetype" like '%Byte%'
THEN "lineitem_usageamount" / 1024
ELSE "lineitem_usageamount"
END) as "Usage",
CASE
WHEN "lineitem_usagetype" like '%Byte%'
THEN 'TBs'
ELSE 'Requests'
END as "Usage Units",
sum("lineitem_blendedcost") as cost
from awsbilling201902 a
join spectrum_schema.s3accesslogs b
on a.lineItem_ResourceId = b.bucket
where "product_productname" = 'Amazon Simple Storage Service'
group by
1, 2, 3, 4, 5, 6
order by
sum("lineitem_blendedcost") desc;以下截图显示的是执行上述查询的结果:
以下查询会识别不同 S3 操作和 HTTP 状态(使用量、非混合成本、混合成本)的 S3 数据传输成本(区域内和区域间):
SELECT
lineitem_productcode
,product_fromlocation
,product_tolocation
,b.operation
,b.httpstatus
,sum(lineitem_usageamount) usageamount
,sum(lineitem_unblendedcost) unblendedcost
,sum(lineitem_blendedcost) blendedcost
FROM
awsbilling201902 a
JOIN spectrum_schema.s3accesslogs b
ON
a.lineItem_ResourceId = b.bucket
WHERE
a.lineitem_productcode = 'AmazonS3'
AND a.product_productfamily = 'Data Transfer'
GROUP BY
1,2,3,4,5
ORDER BY
usageamount desc;以下截图显示的是执行上述查询的结果:
以下查询会识别 S3 费用、API 请求和存储费用:
SELECT
lineitem_productcode
,product_productfamily
,b.operation
,b.httpstatus
,sum(lineitem_usageamount) usageamount
,sum(lineitem_unblendedcost) unblendedcost
,sum(lineitem_blendedcost) blendedcost
FROM
awsbilling201902 a
JOIN spectrum_schema.s3accesslogs b
ON
a.lineItem_ResourceId = b.bucket
WHERE
a.lineitem_productcode = 'AmazonS3'
and a.product_productfamily <> 'Data Transfer'
GROUP BY
1,2,3,4
ORDER BY
usageamount desc;以下截图显示的是执行上述查询的结果:
下图显示的是此解决方案的完整数据流。
AWS Glue 提供一种简单便利而且安全高效的云原生方式,可以自动发现存储在您的 S3 存储桶中的数据。本文展示了如何通过 AWS Glue 和 Amazon Redshift,整合 AWS CUR、S3 清单报告和 S3 服务器访问日志,从而对 S3 使用情况和支出进行分析。您还将学到通过用户和组在 Amazon Redshift 中管理数据库安全性的最佳做法。使用此框架,您只需要在 AWS 管理控制台上点击几次,花费数分钟就能开始分析您的 S3 存储桶支出!
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3150314/ ,如需转载,请注明出处,否则将追究法律责任。