S3A 连接器为审计 S3 请求提供了一个扩展点。审计可以在每个 FS 操作的入口点进行,也可以在 AWS S3 SDK 中进行,即在执行请求之前。
完整架构在 审计架构 中进行了介绍;本文档介绍了其用法。
由于使用 ThreadLocal
字段导致内存泄漏,此审计功能在创建和删除 S3A 文件系统实例时会泄漏内存。这会在不重复使用文件系统实例或尝试删除属于特定用户的全部实例的长生命周期进程中造成问题。请参阅 HADOOP-18091 S3A 审计通过 ThreadLocal 引用泄漏内存。
为了避免这些内存泄漏,在 hadoop 3.3.2 版本中默认禁用了审计。
由于这些内存泄漏现已修复,因此已重新启用审计。
要禁用它,请将 fs.s3a.audit.enabled
设置为 false
。
因此:可以插入审计服务以提供(尽力而为)审计以及暗示允许/拒绝安全性。
这不是控制对 S3 资源的访问的一种手段。这是尽力而为地尝试支持 FileSystem 操作 API 调用的日志记录,特别是将 S3 多个对象请求与单个 FS API 调用关联起来,理想情况下甚至可以识别生成负载的进程/作业。
默认情况下禁用审计。启用审计时,日志审计将通过对 S3 发出的请求中的自定义 HTTP Referrer 标头对 S3 日志进行注释。可以使用其他审计器类。
选项 | 含义 | 默认值 |
---|---|---|
fs.s3a.audit.enabled |
是否启用审计? | true |
fs.s3a.audit.service.classname |
审计器类名 | org.apache.hadoop.fs.s3a.audit.impl.LoggingAuditor |
fs.s3a.audit.request.handlers |
要包含在处理程序链中的 AWS SDK RequestHandler2 的额外子类的列表 | "" |
fs.s3a.audit.referrer.enabled |
日志审计在 HTTP Referrer 标头中发布审计信息 | true |
fs.s3a.audit.referrer.filter |
要过滤的审计字段列表 | "" |
fs.s3a.audit.reject.out.of.span.operations |
审计器拒绝“跨度之外”的操作 | false |
在此 Hadoop 版本中,审计已禁用。
这可以针对全局或特定存储桶显式设置
<property> <name>fs.s3a.audit.enabled</name> <value>false</value> </property>
即使在全局启用审计时,也可以禁用特定存储桶的审计。
<property> <name>fs.s3a.bucket.landsat-pds.audit.enabled</name> <value>false</value> <description>Do not audit landsat bucket operations</description> </property>
“日志审计器”是默认审计器。它提供两种形式的日志记录
通过在选项 fs.s3a.audit.service.classname
中提供其类名来启用日志审计器。
<property> <name>fs.s3a.audit.enabled</name> <value>true</value> </property> <property> <name>fs.s3a.audit.service.classname</name> <value>org.apache.hadoop.fs.s3a.audit.impl.LoggingAuditor</value> </property>
要在本地客户端日志中打印审计事件,请将关联的 Log4J 日志设置为在调试中记录
# Auditing log4j.logger.org.apache.hadoop.fs.s3a.audit.impl.LoggingAuditor=DEBUG
可以将 AWS S3 存储桶配置为将对存储桶的所有 HTTP 请求的日志存储到另一个 S3 存储桶中,S3 服务器访问日志记录在日志审计器中,每个 AWS S3 请求的 HTTP referer
字段都构建到一个 URL 中,该 URL 提供上下文和跨度信息。由于此字段保存在 S3 日志中,因此如果启用了 S3 存储桶日志记录,则日志将能够将 S3 客户端的访问与正在进行的实际操作相关联。
注意:此日志记录被描述为“尽力而为”。无法保证日志何时到达。
可以将日志审计器配置为在通过 S3AFileSystem
实例(创建了审计器的实例)与 S3 交互的线程没有任何跨度处于激活状态时,对 S3 发出请求时引发异常。
这主要是为了开发,因为它可用于保证通过公共 API 调用输入跨度。
<property> <name>fs.s3a.audit.reject.out.of.span.operations</name> <value>true</value> </property>
此拒绝过程对某些 AWS S3 请求类禁用,这些类在 AWS SDK 中创建,作为更大操作的一部分,并且无法附加跨度。
始终允许的 AWS 请求 | 原因 |
---|---|
GetBucketLocationRequest |
在 AWS SDK 中用于确定 S3 终端节点 |
CopyPartRequest |
在 AWS SDK 中用于复制操作 |
CompleteMultipartUploadRequest |
在 AWS SDK 中用于完成复制操作 |
发起复制/多部分上传的请求始终会接受审计,因此审计过程确实涵盖了重命名和多部分 IO。但是,AWS S3 日志不会在关联的复制/完成调用的引荐人标头中包含完整的跟踪信息。
HTTP 引用标头由日志记录审核员附加。如果 S3 存储桶配置为将请求记录到另一个存储桶,则这些日志条目将包含审核信息作为引用。
可以解析此信息(查阅 AWS 文档以获取正则表达式)并提取 HTTP 引用标头。
https://audit.example.org/hadoop/1/op_rename/3c0d9b7e-2a63-43d9-a220-3c574d768ef3-3/ ?op=op_rename &p1=s3a://alice-london/path1 &pr=alice &p2=s3a://alice-london/path2 &ps=235865a0-d399-4696-9978-64568db1b51c &ks=5 &id=3c0d9b7e-2a63-43d9-a220-3c574d768ef3-3 &t0=12 &fs=af5943a9-b6f6-4eec-9c58-008982fc492a &t1=12 &ts=1617116985923
以下是请求中可能找到的字段。如果任何字段值为 null
,则省略该字段。
名称 | 含义 | 示例 |
---|---|---|
cm |
命令 | S3GuardTool$BucketInfo |
fs |
文件系统 ID | af5943a9-b6f6-4eec-9c58-008982fc492a |
id |
跨度 ID | 3c0d9b7e-2a63-43d9-a220-3c574d768ef3-3 |
ji |
作业 ID(S3A 提交者) | (由查询引擎生成) |
op |
文件系统 API 调用 | op_rename |
p1 |
操作的路径 1 | s3a://alice-london/path1 |
p2 |
操作的路径 2 | s3a://alice-london/path2 |
pr |
主体 | alice |
ps |
唯一的进程 UUID | 235865a0-d399-4696-9978-64568db1b51c |
rg |
GET 请求范围 | 100-200 |
ta |
任务尝试 ID(S3A 提交者) | |
t0 |
线程 0:创建线程跨度 | 100 |
t1 |
线程 1:执行此操作的线程 | 200 |
ts |
时间戳(UTC 纪元毫秒) | 1617116985923 |
ks |
作为给定请求一部分要删除的文件(数量)的关键大小(适用于删除和重命名操作) | 5 |
备注
Long.toString(Thread.currentThread().getId())
当 t0
和 t1
不同时,这意味着该范围已移交给另一个线程,以代表原始操作进行工作。这可以与客户端上的日志条目关联,以将工作隔离到特定线程。
标头长度存在大小限制;对长路径的操作可能会超过该限制。在这种情况下,审计日志不完整。
这就是将 span ID 始终作为 URL 的一部分传递的原因,而不仅仅是 HTTP 查询参数:即使标头被截断,span ID 也会始终存在。
当 S3A 客户端向 S3 存储桶发出请求时,审计员会将 span 信息添加到标头中,然后将其存储在日志中
如果 S3 存储桶归客户端所属的同一组织所有,则此 span 信息是组织内部的。
如果 S3 存储桶归不同的实体所有/管理,则该实体收集的任何 S3 存储桶日志中都可以看到 span 信息。这包括主体名称和通过 Tools
或服务启动器 API 启动应用程序时执行的命令。
可以通过过滤特定标头或完全明确禁用引荐标头生成来禁用共享此信息。
注意:即使通过或主体过滤禁用 HTTP Referrer,AWS S3 日志也会包含发出请求的用户或 IAM 角色的 ARN。
可以从引荐标头中过滤特定字段,因此不会包含在 S3A 日志中。
<property> <name>fs.s3a.audit.referrer.filter</name> <value>pr, cm</value> <description>Strip out principal and command from referrer headers</description> </property>
可以通过将选项 fs.s3a.audit.referrer.enabled
设置为 false
(全局或针对特定存储桶)来配置日志审计器,使其不添加引荐标头
<property> <name>fs.s3a.audit.referrer.enabled</name> <value>false</value> <description>Disable referrer for all buckets</description> </property> <property> <name>fs.s3a.bucket.landsat-pds.audit.referrer.enabled</name> <value>false</value> <description>Do not add the referrer header to landsat operations</description> </property>
必须为 S3 存储桶设置 服务器访问日志记录。
这将告知 AWS S3 收集所有 HTTP 请求的访问日志,并将它们存储在同一区域中的另一个存储桶中。日志会以文件形式到达,其中包含几秒钟的日志数据,存储在配置的路径下。
logs/$BUCKET/log-
的前缀来隔离不同存储桶的日志。例如,来自 dev data london
的路径日志数据可以是 s3://london-log-bucket/logs/dev-data-lon/log-
在 S3 请求发出和日志出现之间大约有一个小时的延迟;如果在设置期间事情似乎不起作用,请不要担心。启用日志,通过“hadoop fs”命令行使用存储桶,等待一小时,然后去日志存储桶中查找条目。日志文件名包括这些日志开始的时间
由于日志存储在 S3 存储桶中,因此它们也会产生费用。通过在一段时间后删除日志来降低成本,和/或设置一个工作流来加载和合并日志条目到压缩格式和更大的文件中。
设置一个规则来自动删除旧日志文件非常简单。
london-log-bucket
。logs/
以删除所有存储桶的所有日志。重要提示:你不得有任何前导“/”,例如 /logs/
- 将没有匹配项,规则将不起作用。密切关注存储桶以确保删除操作正常运行;前缀中很容易出错,并且由于日志会无限创建,因此成本会不断增加。
AWS S3 文档涵盖了日志格式,并包含一个用于处理日志格式的 Hive 外部表声明。
hadoop-aws
测试套件中用于提取标头的 Java 模式正则表达式定义为
(?<owner>[^ ]*) (?<bucket>[^ ]*) (?<timestamp>\[(.*?)\]) (?<remoteip>[^ ]*) (?<requester>[^ ]*) (?<requestid>[^ ]*) (?<operation>[^ ]*) (?<key>[^ ]*) (?<requesturi>(-|"[^"]*")) (?<http>(-|[0-9]*)) (?<awserrorcode>[^ ]*) (?<bytessent>[^ ]*) (?<objectsize>[^ ]*) (?<totaltime>[^ ]*) (?<turnaroundtime>[^ ]*) (?<referrer>(-|"[^"]*")) (?<useragent>(-|"[^"]*")) (?<version>[^ ]*) (?<hostid>[^ ]*) (?<sigv>[^ ]*) (?<cypher>[^ ]*) (?<auth>[^ ]*) (?<endpoint>[^ ]*) (?<tls>[^ ]*)*$
类 org.apache.hadoop.fs.s3a.audit.S3LogParser
提供了此模式以及每个组的常量。它被声明为 Public/Unstable
。
org.apache.hadoop.fs.s3a.audit
日志上下文包含实现审计的不同组件的日志。
可以通过将该日志设置为调试来启用使用 LoggingAuditService
审计的请求的日志记录。
# Log before a request is made to S3 log4j.logger.org.apache.hadoop.fs.s3a.audit.impl.LoggingAuditor=DEBUG
这会为每个请求添加一行日志,并提供对 S3A 客户端和 AWS S3 之间通信的一些见解。
对于审计系统的低级别调试(例如,当进入和退出跨度时),将日志设置为 TRACE
# log request creation, span lifecycle and other low-level details log4j.logger.org.apache.hadoop.fs.s3a.audit=TRACE
这会产生很多噪音,不建议在正常操作中使用。
通过 S3A 提交者提交的工作将具有与针对该线程中所有 S3A 文件系统执行的 S3 操作关联的作业(查询)ID。
要使此操作有用,任务中执行的工作必须与在提交者上调用 jobSetup()
或 taskSetup()
的同一线程中。