从 Amazon EMR 和 Amazon Glue 访问 Amazon S3 中数据的性能优化最佳实践

0
0
{"value":"客户越来越多地构建数据湖,以在云中大规模存储数据。当您想要在数据湖中处理和分析数据时,通常会使用分布式计算引擎、云原生数据库和数据仓库。[Amazon EMR](http://aws.amazon.com/emr) 和 [Amazon Glue](https://aws.amazon.com/glue) 是可用于此类使用场景的两项关键服务。[Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 是一个托管的大数据框架,支持多种不同的应用程序,包括 [Apache Spark](https://spark.apache.org/)、[Apache Hive](https://hive.apache.org/)、[Presto](https://prestodb.io/)、[Trino](https://trino.io/) 和 [Apache HBase](https://hbase.apache.org/)。Amazon Glue Spark 作业在 Apache Spark 之上运行,并行分配数据处理工作负载用于执行提取、转换和加载(ETL, Extract, Transform, and Load)作业,从而大规模地扩充、去规范化、遮蔽和标记数据。\n\n对于数据湖存储,客户通常会使用 [Amazon Simple Storage Service](http://aws.amazon.com/s3)([Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail)),因为它安全、可扩展、持久且具备高可用性。[Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 专为满足 11 个 9 的持久性而设计,为全球数百万个应用程序存储超过 200 万亿个对象,使其成为数据湖的理想存储目标。[Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 平均每秒执行超过 1 亿次操作,因此在将 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 用作数据湖时,应用程序可以轻松实现高请求速率。\n\n这篇文章介绍了使用 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 Amazon Glue 分析 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 中数据时,实现所需性能扩展的最佳实践。我们重点强调了在 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 [AWS Glue](https://aws.amazon.com/cn/glue/?trk=cndc-detail) Spark 作业上针对 Apache Spark 进行优化。\n\n### **面向大型 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 Amazon Glue 作业优化 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 性能**\n\n[Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 是一个非常大的分布式系统,在应用程序对 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 读写数据时,您可以将请求性能扩展到每秒数千个事务。[Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 性能不是按存储桶定义的,而是按存储桶中的[前缀](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#keyprefix)。在一个存储桶中,对于每个前缀,应用程序每秒可以处理至少 3500 个 PUT/COPY/POST/DELETE 请求或 5500 个 GET/HEAD 请求。此外,存储桶中的前缀数量没有限制,因此您可以利用并行处理,横向扩展读取或写入性能。例如,如果您在 S3 存储桶中创建 10 个前缀来并行执行读取操作,则可以将读取性能扩展到每秒 55000 个读取请求。同样,您也可以利用多个前缀写入数据来扩展写入性能。\n\n您可以利用 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 中的弹性伸缩功能来扩展性能,为运行在 PB 级数据上的查询扫描数百万个对象。[Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 会自动扩展以响应持续的新请求速率,从而动态优化性能。在 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 针对新的请求速率进行内部优化的时候,您会暂时收到 HTTP 503 请求响应,直至优化完成:\n\n```\\nAmazonS3Exception: Please reduce your request rate.(Service: Amazon S3; Status Code: 503; Error Code: SlowDown)(AmazonS3Exception:请降低请求速率。(服务:Amazon S3;状态代码:503;错误代码:速度缓慢))\\n```\n\n此类情况需要应用程序稍等片刻再重试,但在 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 针对新请求速率完成内部性能优化后,所有请求通常无需重试即可得到处理。当分布式计算引擎(如 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 Amazon Glue)中的多个工作线程临时生成大量的请求,需要访问相同前缀下的数据时,就会出现这种情况。\n\n使用 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 Amazon Glue 处理 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 中的数据时,您可以采用某些最佳实践来管理请求流量,避免 HTTP 速度缓慢错误。我们来看看其中的一些策略。\n\n### **管理 HTTP 速度缓慢响应的最佳实践**\n\n在使用 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 [AWS Glue](https://aws.amazon.com/cn/glue/?trk=cndc-detail) 访问 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 数据时,您可以使用以下方法来利用 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 中的横向扩展功能,提高请求的成功率:\n\n- 修改 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求的重试策略\n- 调整处理的 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 对象的数量\n- 调整并发 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求的数量\n\n我们建议您根据自己的使用场景选择并应用最适合的选项,以优化 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 上的数据处理。在以下各节中,我们将介绍每种方法的最佳实践。\n\n### **修改 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求的重试策略**\n\n这是避免 HTTP 503 速度缓慢响应并提高请求成功率的最简单方法。要访问 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 数据,[Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 Amazon Glue 均使用 [EMR 文件系统](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-fs.html)(EMRFS, EMR File System),该文件系统在收到 503 速度缓慢响应时,会以抖动方式重试 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求。要提高 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求的成功率,您可以通过配置某些属性来调整重试策略。在 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 中,您可以在 ```emrfs-site```配置中配置参数。在 Amazon Glue 中,您可在作业参数中配置参数。您可通过以下方式调整重试策略:\n\n- **提高 EMRFS 原定设置重试次数限制** – 默认情况下,EMRFS 使用指数回退策略来重试向 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 发出的请求。原定设置 EMRFS 重试限制为 15 次。不过,当您在创建新机群时、在运行中的集群上时或对于应用程序运行时,可以提高此限制。要提高重试次数限制,可以更改 ```fs.s3.maxRetries```参数的值。请注意,如果为此参数设置较高的值,则可能会出现较长的作业持续时间。我们建议使用不同的值进行试验,例如以 ```20```作为起点,确认每个值的作业持续时间开销,然后根据您的要求调整此参数。\n- **为 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 使用 AIMD 重试策略** – 对于 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 6.4.0 及更高版本,EMRFS 支持基于和式增加/积式减少(AIMD, Additive-Increase/Multiplicative-Decrease)模型的替代重试策略。此策略在调整来自大型集群的请求速率时非常有用。此模式不会单独处理每个请求,而是跟踪最近的成功请求速率和受限制请求速率。根据最近的成功请求速率来确定请求的限制速率。这减少了受限制请求的数量,从而减少了每个请求所需的尝试次数。要启用 AIMD 重试策略,可以将 ```fs.s3.aimd.enabled```属性设置为 ```true```。您可以使用[高级 AIMD 重试设置](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-emrfs-retry.html#emr-spark-emrfs-retry-advanced-properties)进一步优化 AIMD 重试策略。\n\n### **调整处理的 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 对象的数量**\n\n另一种方法是调整已处理的 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 对象的数量,以便减少同时发出的请求数。当您减少作业中要处理的对象数量时,就会减少使用的 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求数,从而降低每个作业所需的请求速率或每秒事务数(TPS, Transactions Per Second)。请注意以下注意事项:\n\n- **通过将多个较小的文件聚合为较少数量的较大数据块来预处理数据** – 例如,使用 [s3-dist-cp](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/UsingEMR_s3distcp.html) 或 [Amazon Glue 压缩蓝图](https://github.com/awslabs/aws-glue-blueprint-libs/tree/master/samples/compaction),将大量小文件(通常小于 64 MB)合并为数量更少的优化大小文件(例如 128–512 MB)。这种方法减少了所需的请求数量,同时提高了 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 中读取和处理数据的总吞吐量。您可能需要进行实验,以获得适合您工作负载的最优大小,因为创建极大的文件会降低作业的并行度。\n- **使用分区修剪功能扫描特定分区下的数据** – 在与 Apache Hive 和 Hive MetaStore 兼容的应用程序(如 Apache Spark 或 Presto)中,一个表可以有多个分区文件夹。分区修剪是一种仅在表的特定分区文件夹中扫描所需数据的技术。此技术在需要从整个表中读取特定部分时非常有用。要利用谓词下推,您可以在 Spark SQL 的 WHERE 子句中使用分区列,或者在 DataFrame 中使用筛选表达式。在 Amazon Glue 中,您还可以在[创建 DynamicFrames 时使用分区下推谓词](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-partitions.html)。\n- **对于 Amazon Glue,启用作业书签** – 您可以使用 [Amazon Glue 作业书签](https://docs.aws.amazon.com/glue/latest/dg/monitor-continuations.html)来重复处理连续摄入的数据。它仅从上一次作业运行中选取未处理的数据,从而减少了 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 读取或检索的对象数量。\n- **对于 Amazon Glue,启用边界执行** – [Amazon Glue 边界执行](https://docs.aws.amazon.com/glue/latest/dg/bounded-execution.html)是一种仅选取未处理数据的技术,其上限为要处理的数据集大小或文件数。这是另一种减少向 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 发出的请求数量的方法。\n\n### **调整并发 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求的数量**\n\n要调整 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求的数量以减少各个前缀的并发读取数,您可以配置 Spark 参数。默认情况下,在创建 Spark DataFrame 时,Spark 会填充 10000 个任务以列出前缀。您可能会遇到速度缓慢响应,尤其是在读取具有高度嵌套的前缀结构的表时。在这种情况下,最好配置 Spark,通过减小参数 ```spark.sql.sources.parallelPartitionDiscovery.parallelism```(原定设置值为 ```10000```)来限制最大列表并行度的数量。\n\n要减少每个前缀的并发写入请求数,可以使用以下技巧:\n\n- **在写入之前减少 Spark RDD 分区的数量** – 您可在 DataFrames 中使用 ```df.repartition(n)```或```df.coalesce(n)```做到这一点。对于 Spark SQL,您还可以使用 ```REPARTITION```或 ```COALESCE```等[查询提示](https://spark.apache.org/docs/3.1.1/sql-ref-syntax-qry-select-hints.html)。您可以在 [Spark UI 上看到任务数量(= RDD 分区数)](https://spark.apache.org/docs/3.1.1/web-ui.html)。\n- **对于 Amazon Glue,分组输入数据** – 如果数据集由小文件组成,我们建议对[输入数据进行分组](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html),因为这样可以减少 RDD 分区的数量并减少写入文件的 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求数量。\n- **使用 EMRFS S3 优化的提交程序** – 默认情况下,[Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 5.19.0 及更高版本以及 Amazon Glue 3.0 中使用 [EMRFS S3 优化的提交程序](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-s3-optimized-committer.html)。在 Amazon Glue 2.0 中,您可以在作业参数 ```--enable-s3-parquet-optimized-committer```中配置此项。提交程序使用 [Amazon S3 分段上传](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html)而不是重命名文件,并且这样通常可显著减少 HEAD/LIST 请求数。\n\n以下介绍在 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 Amazon Glue 中调整 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求速率的其他技巧。这些选项的纯效果是减少 Spark 作业的并行度,从而减少出现 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 速度缓慢响应的可能性,尽管这可能导致较长的作业持续时间。我们建议针对使用场景测试和调整这些值。\n\n- **减少并发作业的数量** – 从最繁重的读/写作业开始。如果您为 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 配置了跨账户访问,请记住,其他账户也可能向该前缀提交作业。\n- **减少并发 Spark 任务的数量** – 您有以下几种选择:\n- 对于 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail),请设置 Spark 执行程序的数量(例如,```\\nspark-submit```选项 ```--num-executors```和 Spark 参数 ```spark.executor.instance```)。\n- 对于 Amazon Glue,请在 ```NumberOfWorkers```参数中设置工作线程的数量。\n- 对于 Amazon Glue,请将 ```WorkerType```参数更改为较小的值(例如,从 G.2X 更改为 G.1X)。\n- 配置 Spark 参数:\n- 减少 ```spark.default.parallelism```的数量。\n- 减少 ```spark.sql.shuffle.partitions```的数量。\n- 增加 ```spark.task.cpus```的数量(原定设置为 ```1```),为每个 Spark 任务分配更多 CPU 核心数。\n\n### **结论**\n\n在这篇文章中,我们针对从 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 Amazon Glue 访问 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 中的数据,介绍了优化访问性能的最佳实践。借助这些最佳实践,您可以利用 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 横向扩展轻松运行 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 和 Amazon Glue 作业,并以高度分布的方式大规模处理数据。\n\n如需更多指导,请联系 [Amazon Premium Support](https://aws.amazon.com/premiumsupport/)。\n\n### **附录 A:配置 CloudWatch 请求指标**\n\n要监控 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求,您可以在 [Amazon CloudWatch](http://aws.amazon.com/cloudwatch) 中为存储桶[启用请求指标](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/configure-metrics.html)。然后,为前缀[定义一个筛选条件](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/configure-metrics-filter.html)。有关要监控的有用指标列表,请参阅[使用 Amazon CloudWatch 监控指标](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html#s3-request-cloudwatch-metrics)。启用指标后,使用指标中的数据来确定上述哪个选项最适合您的使用场景。\n\n### **附录 B:配置 Spark 参数**\n\n在 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 中配置 Spark 参数有几个选项:\n\n- **spark-submit command** – 您可以通过 ```--conf```选项传递 Spark 参数。\n- **作业脚本** – 您可以在作业脚本代码的 ```SparkConf```对象中设置 Spark 参数。\n- **[Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 配置** – 您可以使用 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 配置,通过 API 配置 Spark 参数。有关更多信息,请参阅[配置 Spark](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-configure.html)。\n\n要在 Amazon Glue 中配置 Spark 参数,您可以使用键 ```--conf```及类似于 ```spark.hadoop.fs.s3.maxRetries=50```的值来配置 Amazon Glue 作业参数。\n\n要设置多个配置,您可以使用键 ```--conf```及类似于 ```spark.hadoop.fs.s3.maxRetries=50 --conf spark.task.cpus=2```的值来配置作业参数。\n\n### **本篇作者**\n\n![image.png](https://dev-media.amazoncloud.cn/da9b99e8fe244422b79e6c9b6bdbe79e_image.png)\n\n**Noritaka Sekiyama**\n\nNoritaka Sekiyama 是 Amazon Glue 团队的首席大数据架构师。他热衷于发布 Amazon Glue 连接器自定义蓝图和其他软件构件,帮助客户构建数据湖。在业余时间,他喜欢和孩子们一起观察寄居蟹。\n\n![image.png](https://dev-media.amazoncloud.cn/e2d31fb7e2e8488e9f1eea27e3194005_image.png)\n\n**Aditya Kalyanakrishnan**\n\nAditya Kalyanakrishnan 是 Amazon 的 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 团队的高级产品经理。他乐于从客户那儿了解如何使用 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 并帮助他们扩展性能。Adi 住在西雅图,业余时间喜欢徒步旅行,以及偶尔酿啤酒。","render":"<p>客户越来越多地构建数据湖,以在云中大规模存储数据。当您想要在数据湖中处理和分析数据时,通常会使用分布式计算引擎、云原生数据库和数据仓库。<a href=\\"http://aws.amazon.com/emr\\" target=\\"_blank\\">Amazon EMR</a> 和 <a href=\\"https://aws.amazon.com/glue\\" target=\\"_blank\\">Amazon Glue</a> 是可用于此类使用场景的两项关键服务。[Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 是一个托管的大数据框架,支持多种不同的应用程序,包括 <a href=\\"https://spark.apache.org/\\" target=\\"_blank\\">Apache Spark</a>、<a href=\\"https://hive.apache.org/\\" target=\\"_blank\\">Apache Hive</a>、<a href=\\"https://prestodb.io/\\" target=\\"_blank\\">Presto</a>、<a href=\\"https://trino.io/\\" target=\\"_blank\\">Trino</a> 和 <a href=\\"https://hbase.apache.org/\\" target=\\"_blank\\">Apache HBase</a>。Amazon Glue Spark 作业在 Apache Spark 之上运行,并行分配数据处理工作负载用于执行提取、转换和加载(ETL, Extract, Transform, and Load)作业,从而大规模地扩充、去规范化、遮蔽和标记数据。</p>\\n<p>对于数据湖存储,客户通常会使用 <a href=\\"http://aws.amazon.com/s3\\" target=\\"_blank\\">Amazon Simple Storage Service</a>([Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail)),因为它安全、可扩展、持久且具备高可用性。[Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 专为满足 11 个 9 的持久性而设计,为全球数百万个应用程序存储超过 200 万亿个对象,使其成为数据湖的理想存储目标。[Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 平均每秒执行超过 1 亿次操作,因此在将 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 用作数据湖时,应用程序可以轻松实现高请求速率。</p>\\n<p>这篇文章介绍了使用 Amazon EMR 和 Amazon Glue 分析 Amazon S3 中数据时,实现所需性能扩展的最佳实践。我们重点强调了在 Amazon EMR 和 AWS Glue Spark 作业上针对 Apache Spark 进行优化。</p>\n<h3><a id=\\"_Amazon_EMR__Amazon_Glue__Amazon_S3__6\\"></a><strong>面向大型 Amazon EMR 和 Amazon Glue 作业优化 Amazon S3 性能</strong></h3>\\n<p>Amazon S3 是一个非常大的分布式系统,在应用程序对 Amazon S3 读写数据时,您可以将请求性能扩展到每秒数千个事务。Amazon S3 性能不是按存储桶定义的,而是按存储桶中的<a href=\\"https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#keyprefix\\" target=\\"_blank\\">前缀</a>。在一个存储桶中,对于每个前缀,应用程序每秒可以处理至少 3500 个 PUT/COPY/POST/DELETE 请求或 5500 个 GET/HEAD 请求。此外,存储桶中的前缀数量没有限制,因此您可以利用并行处理,横向扩展读取或写入性能。例如,如果您在 S3 存储桶中创建 10 个前缀来并行执行读取操作,则可以将读取性能扩展到每秒 55000 个读取请求。同样,您也可以利用多个前缀写入数据来扩展写入性能。</p>\\n<p>您可以利用 Amazon S3 中的弹性伸缩功能来扩展性能,为运行在 PB 级数据上的查询扫描数百万个对象。Amazon S3 会自动扩展以响应持续的新请求速率,从而动态优化性能。在 Amazon S3 针对新的请求速率进行内部优化的时候,您会暂时收到 HTTP 503 请求响应,直至优化完成:</p>\n<pre><code class=\\"lang-\\">AmazonS3Exception: Please reduce your request rate.(Service: Amazon S3; Status Code: 503; Error Code: SlowDown)(AmazonS3Exception:请降低请求速率。(服务:Amazon S3;状态代码:503;错误代码:速度缓慢))\\n</code></pre>\\n<p>此类情况需要应用程序稍等片刻再重试,但在 Amazon S3 针对新请求速率完成内部性能优化后,所有请求通常无需重试即可得到处理。当分布式计算引擎(如 Amazon EMR 和 Amazon Glue)中的多个工作线程临时生成大量的请求,需要访问相同前缀下的数据时,就会出现这种情况。</p>\n<p>使用 Amazon EMR 和 Amazon Glue 处理 Amazon S3 中的数据时,您可以采用某些最佳实践来管理请求流量,避免 HTTP 速度缓慢错误。我们来看看其中的一些策略。</p>\n<h3><a id=\\"_HTTP__20\\"></a><strong>管理 HTTP 速度缓慢响应的最佳实践</strong></h3>\\n<p>在使用 Amazon EMR 和 AWS Glue 访问 Amazon S3 数据时,您可以使用以下方法来利用 Amazon S3 中的横向扩展功能,提高请求的成功率:</p>\n<ul>\\n<li>修改 Amazon S3 请求的重试策略</li>\n<li>调整处理的 Amazon S3 对象的数量</li>\n<li>调整并发 Amazon S3 请求的数量</li>\n</ul>\\n<p>我们建议您根据自己的使用场景选择并应用最适合的选项,以优化 Amazon S3 上的数据处理。在以下各节中,我们将介绍每种方法的最佳实践。</p>\n<h3><a id=\\"_Amazon_S3__30\\"></a><strong>修改 Amazon S3 请求的重试策略</strong></h3>\\n<p>这是避免 HTTP 503 速度缓慢响应并提高请求成功率的最简单方法。要访问 Amazon S3 数据,Amazon EMR 和 Amazon Glue 均使用 <a href=\\"https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-fs.html\\" target=\\"_blank\\">EMR 文件系统</a>(EMRFS, EMR File System),该文件系统在收到 503 速度缓慢响应时,会以抖动方式重试 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求。要提高 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求的成功率,您可以通过配置某些属性来调整重试策略。在 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 中,您可以在 <code>emrfs-site</code>配置中配置参数。在 Amazon Glue 中,您可在作业参数中配置参数。您可通过以下方式调整重试策略:</p>\\n<ul>\\n<li><strong>提高 EMRFS 原定设置重试次数限制</strong> – 默认情况下,EMRFS 使用指数回退策略来重试向 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 发出的请求。原定设置 EMRFS 重试限制为 15 次。不过,当您在创建新机群时、在运行中的集群上时或对于应用程序运行时,可以提高此限制。要提高重试次数限制,可以更改 <code>fs.s3.maxRetries</code>参数的值。请注意,如果为此参数设置较高的值,则可能会出现较长的作业持续时间。我们建议使用不同的值进行试验,例如以 <code>20</code>作为起点,确认每个值的作业持续时间开销,然后根据您的要求调整此参数。</li>\\n<li><strong>为 Amazon EMR 使用 AIMD 重试策略</strong> – 对于 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 6.4.0 及更高版本,EMRFS 支持基于和式增加/积式减少(AIMD, Additive-Increase/Multiplicative-Decrease)模型的替代重试策略。此策略在调整来自大型集群的请求速率时非常有用。此模式不会单独处理每个请求,而是跟踪最近的成功请求速率和受限制请求速率。根据最近的成功请求速率来确定请求的限制速率。这减少了受限制请求的数量,从而减少了每个请求所需的尝试次数。要启用 AIMD 重试策略,可以将 <code>fs.s3.aimd.enabled</code>属性设置为 <code>true</code>。您可以使用<a href=\\"https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-emrfs-retry.html#emr-spark-emrfs-retry-advanced-properties\\" target=\\"_blank\\">高级 AIMD 重试设置</a>进一步优化 AIMD 重试策略。</li>\\n</ul>\n<h3><a id=\\"_Amazon_S3__37\\"></a><strong>调整处理的 Amazon S3 对象的数量</strong></h3>\\n<p>另一种方法是调整已处理的 Amazon S3 对象的数量,以便减少同时发出的请求数。当您减少作业中要处理的对象数量时,就会减少使用的 Amazon S3 请求数,从而降低每个作业所需的请求速率或每秒事务数(TPS, Transactions Per Second)。请注意以下注意事项:</p>\n<ul>\\n<li><strong>通过将多个较小的文件聚合为较少数量的较大数据块来预处理数据</strong> – 例如,使用 <a href=\\"https://docs.aws.amazon.com/emr/latest/ReleaseGuide/UsingEMR_s3distcp.html\\" target=\\"_blank\\">s3-dist-cp</a> 或 <a href=\\"https://github.com/awslabs/aws-glue-blueprint-libs/tree/master/samples/compaction\\" target=\\"_blank\\">Amazon Glue 压缩蓝图</a>,将大量小文件(通常小于 64 MB)合并为数量更少的优化大小文件(例如 128–512 MB)。这种方法减少了所需的请求数量,同时提高了 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 中读取和处理数据的总吞吐量。您可能需要进行实验,以获得适合您工作负载的最优大小,因为创建极大的文件会降低作业的并行度。</li>\\n<li><strong>使用分区修剪功能扫描特定分区下的数据</strong> – 在与 Apache Hive 和 Hive MetaStore 兼容的应用程序(如 Apache Spark 或 Presto)中,一个表可以有多个分区文件夹。分区修剪是一种仅在表的特定分区文件夹中扫描所需数据的技术。此技术在需要从整个表中读取特定部分时非常有用。要利用谓词下推,您可以在 Spark SQL 的 WHERE 子句中使用分区列,或者在 DataFrame 中使用筛选表达式。在 Amazon Glue 中,您还可以在<a href=\\"https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-partitions.html\\" target=\\"_blank\\">创建 DynamicFrames 时使用分区下推谓词</a>。</li>\\n<li><strong>对于 Amazon Glue,启用作业书签</strong> – 您可以使用 <a href=\\"https://docs.aws.amazon.com/glue/latest/dg/monitor-continuations.html\\" target=\\"_blank\\">Amazon Glue 作业书签</a>来重复处理连续摄入的数据。它仅从上一次作业运行中选取未处理的数据,从而减少了 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 读取或检索的对象数量。</li>\\n<li><strong>对于 Amazon Glue,启用边界执行</strong> – <a href=\\"https://docs.aws.amazon.com/glue/latest/dg/bounded-execution.html\\" target=\\"_blank\\">Amazon Glue 边界执行</a>是一种仅选取未处理数据的技术,其上限为要处理的数据集大小或文件数。这是另一种减少向 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 发出的请求数量的方法。</li>\\n</ul>\n<h3><a id=\\"_Amazon_S3__46\\"></a><strong>调整并发 Amazon S3 请求的数量</strong></h3>\\n<p>要调整 Amazon S3 请求的数量以减少各个前缀的并发读取数,您可以配置 Spark 参数。默认情况下,在创建 Spark DataFrame 时,Spark 会填充 10000 个任务以列出前缀。您可能会遇到速度缓慢响应,尤其是在读取具有高度嵌套的前缀结构的表时。在这种情况下,最好配置 Spark,通过减小参数 <code>spark.sql.sources.parallelPartitionDiscovery.parallelism</code>(原定设置值为 <code>10000</code>)来限制最大列表并行度的数量。</p>\\n<p>要减少每个前缀的并发写入请求数,可以使用以下技巧:</p>\n<ul>\\n<li><strong>在写入之前减少 Spark RDD 分区的数量</strong> – 您可在 DataFrames 中使用 <code>df.repartition(n)</code>或<code>df.coalesce(n)</code>做到这一点。对于 Spark SQL,您还可以使用 <code>REPARTITION</code>或 <code>COALESCE</code>等<a href=\\"https://spark.apache.org/docs/3.1.1/sql-ref-syntax-qry-select-hints.html\\" target=\\"_blank\\">查询提示</a>。您可以在 <a href=\\"https://spark.apache.org/docs/3.1.1/web-ui.html\\" target=\\"_blank\\">Spark UI 上看到任务数量(= RDD 分区数)</a>。</li>\\n<li><strong>对于 Amazon Glue,分组输入数据</strong> – 如果数据集由小文件组成,我们建议对<a href=\\"https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html\\" target=\\"_blank\\">输入数据进行分组</a>,因为这样可以减少 RDD 分区的数量并减少写入文件的 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 请求数量。</li>\\n<li><strong>使用 EMRFS S3 优化的提交程序</strong> – 默认情况下,[Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 5.19.0 及更高版本以及 Amazon Glue 3.0 中使用 <a href=\\"https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-s3-optimized-committer.html\\" target=\\"_blank\\">EMRFS S3 优化的提交程序</a>。在 Amazon Glue 2.0 中,您可以在作业参数 <code>--enable-s3-parquet-optimized-committer</code>中配置此项。提交程序使用 <a href=\\"https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html\\" target=\\"_blank\\">Amazon S3 分段上传</a>而不是重命名文件,并且这样通常可显著减少 HEAD/LIST 请求数。</li>\\n</ul>\n<p>以下介绍在 Amazon EMR 和 Amazon Glue 中调整 Amazon S3 请求速率的其他技巧。这些选项的纯效果是减少 Spark 作业的并行度,从而减少出现 Amazon S3 速度缓慢响应的可能性,尽管这可能导致较长的作业持续时间。我们建议针对使用场景测试和调整这些值。</p>\n<ul>\\n<li><strong>减少并发作业的数量</strong> – 从最繁重的读/写作业开始。如果您为 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 配置了跨账户访问,请记住,其他账户也可能向该前缀提交作业。</li>\\n<li><strong>减少并发 Spark 任务的数量</strong> – 您有以下几种选择:</li>\\n<li>对于 Amazon EMR,请设置 Spark 执行程序的数量(例如,<code> spark-submit</code>选项 <code>--num-executors</code>和 Spark 参数 <code>spark.executor.instance</code>)。</li>\\n<li>对于 Amazon Glue,请在 <code>NumberOfWorkers</code>参数中设置工作线程的数量。</li>\\n<li>对于 Amazon Glue,请将 <code>WorkerType</code>参数更改为较小的值(例如,从 G.2X 更改为 G.1X)。</li>\\n<li>配置 Spark 参数:</li>\n<li>减少 <code>spark.default.parallelism</code>的数量。</li>\\n<li>减少 <code>spark.sql.shuffle.partitions</code>的数量。</li>\\n<li>增加 <code>spark.task.cpus</code>的数量(原定设置为 <code>1</code>),为每个 Spark 任务分配更多 CPU 核心数。</li>\\n</ul>\n<h3><a id=\\"_69\\"></a><strong>结论</strong></h3>\\n<p>在这篇文章中,我们针对从 Amazon EMR 和 Amazon Glue 访问 Amazon S3 中的数据,介绍了优化访问性能的最佳实践。借助这些最佳实践,您可以利用 Amazon S3 横向扩展轻松运行 Amazon EMR 和 Amazon Glue 作业,并以高度分布的方式大规模处理数据。</p>\n<p>如需更多指导,请联系 <a href=\\"https://aws.amazon.com/premiumsupport/\\" target=\\"_blank\\">Amazon Premium Support</a>。</p>\\n<h3><a id=\\"_A_CloudWatch__75\\"></a><strong>附录 A:配置 CloudWatch 请求指标</strong></h3>\\n<p>要监控 Amazon S3 请求,您可以在 <a href=\\"http://aws.amazon.com/cloudwatch\\" target=\\"_blank\\">Amazon CloudWatch</a> 中为存储桶<a href=\\"https://docs.aws.amazon.com/AmazonS3/latest/user-guide/configure-metrics.html\\" target=\\"_blank\\">启用请求指标</a>。然后,为前缀<a href=\\"https://docs.aws.amazon.com/AmazonS3/latest/user-guide/configure-metrics-filter.html\\" target=\\"_blank\\">定义一个筛选条件</a>。有关要监控的有用指标列表,请参阅<a href=\\"https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html#s3-request-cloudwatch-metrics\\" target=\\"_blank\\">使用 Amazon CloudWatch 监控指标</a>。启用指标后,使用指标中的数据来确定上述哪个选项最适合您的使用场景。</p>\\n<h3><a id=\\"_B_Spark__79\\"></a><strong>附录 B:配置 Spark 参数</strong></h3>\\n<p>在 Amazon EMR 中配置 Spark 参数有几个选项:</p>\n<ul>\\n<li><strong>spark-submit command</strong> – 您可以通过 <code>--conf</code>选项传递 Spark 参数。</li>\\n<li><strong>作业脚本</strong> – 您可以在作业脚本代码的 <code>SparkConf</code>对象中设置 Spark 参数。</li>\\n<li><strong>Amazon EMR 配置</strong> – 您可以使用 [Amazon EMR](https://aws.amazon.com/cn/emr/?trk=cndc-detail) 配置,通过 API 配置 Spark 参数。有关更多信息,请参阅<a href=\\"https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-configure.html\\" target=\\"_blank\\">配置 Spark</a>。</li>\\n</ul>\n<p>要在 Amazon Glue 中配置 Spark 参数,您可以使用键 <code>--conf</code>及类似于 <code>spark.hadoop.fs.s3.maxRetries=50</code>的值来配置 Amazon Glue 作业参数。</p>\\n<p>要设置多个配置,您可以使用键 <code>--conf</code>及类似于 <code>spark.hadoop.fs.s3.maxRetries=50 --conf spark.task.cpus=2</code>的值来配置作业参数。</p>\\n<h3><a id=\\"_91\\"></a><strong>本篇作者</strong></h3>\\n<p><img src=\\"https://dev-media.amazoncloud.cn/da9b99e8fe244422b79e6c9b6bdbe79e_image.png\\" alt=\\"image.png\\" /></p>\n<p><strong>Noritaka Sekiyama</strong></p>\\n<p>Noritaka Sekiyama 是 Amazon Glue 团队的首席大数据架构师。他热衷于发布 Amazon Glue 连接器自定义蓝图和其他软件构件,帮助客户构建数据湖。在业余时间,他喜欢和孩子们一起观察寄居蟹。</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/e2d31fb7e2e8488e9f1eea27e3194005_image.png\\" alt=\\"image.png\\" /></p>\n<p><strong>Aditya Kalyanakrishnan</strong></p>\\n<p>Aditya Kalyanakrishnan 是 Amazon 的 Amazon S3 团队的高级产品经理。他乐于从客户那儿了解如何使用 Amazon S3 并帮助他们扩展性能。Adi 住在西雅图,业余时间喜欢徒步旅行,以及偶尔酿啤酒。</p>\n"}
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭