tonglin0325的个人主页

Amazon S3限流机制

当使用S3作为Amazon EMR的存储的时候,当写入的流量比较大的时候,有时会遇到性能瓶颈,报错如下

1
2
Caused by: com.amazonaws.services.s3.model.AmazonS3Exception: Please reduce your request rate.

在如下的AWS文章中介绍,S3的性能不是按照bucket定义的,而是按照bucket的prefix,对于每个prefix,3500的PUT/COPY/POST/DELETE能力和5000的GET/HEAD能力,如果超过这个限制的话,就会被限流

关于prefix定义,参考文档:aws s3原理和常用命令

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

在咨询了AWS的工程师后,说上面的文档不是很准确,更具体的回答是:

1.对于一个刚创建的bucket,默认每个bucket有3500写+5000读的能力

2.当S3 bucket的流量增加后,S3会对应进行bucket的split partition,根据的规则是按照prefix逐位向后分割

意思是对于S3://bucket_name/[a-z,0-9][a-z,0-9]…./object的s3存储结构,prefix的第1个字符有a-z+0-9(26+10=36)种可能性,如果这36个字符出现的可能性是一样的话,则当整个bucket的流量很大的时候,bucket就会扩容到36个partition,从而获得36*(3500/5000)的能力

这也就是为什么当遇到S3性能问题的能力,AWS的工程师经常会建议使用增加随机前缀,或者分区倒排的方案,其他AWS文章也有提到:Amazon EMR实战心得浅谈

增加随机前缀(最建议,但不适用于数仓):对于S3://bucket_name/xxx/2022/10/01/object_name的路径,如果bucket的并发超过了3500/5000的限制后,则S3会进行扩容partition,这时S3://bucket_name/xxx/2022/10/01/和S3://bucket_name/xxx/2022/10/02/分split成2个partition,到了第二天02分区又会split成02和03分区,但是S3扩容是需要一定时间的,所以每天流量峰值的时候有可能会出现限流。

如果增加了随机前缀,路径则会变成S3://bucket_name/[a-z,0-9][a-z,0-9]…./xxx/2022/10/01/object_name,这来一是流量被打散成36份,不会在每天的prefix上形成单独的热点;二来在遇到每年/每月/每日路径更新的时候,也不会进行S3扩容,因为扩容只会发生在第一个字符[a-z,0-9]

分区倒排:对于S3://bucket_name/xxx/2022/10/01/object_name的路径,分区倒排之后,路径变成S3://bucket_name/xxx/01/10/2022/object_name,即变成日/月/年,如果S3://bucket_name/xxx/路径下的并发超过3500/5000,第一个月过后,整个bucket会split成30或者31份(每天扩容一次),到了第二个月的时候,流量就会继续循环打到这30或者31个partition上,从而不会每天进行扩容

上面介绍的S3自动split的原理,如果是手动split的话,就没有以上限制,就是给AWS对接的工程师提support case让他们后台调整,人工指定从第几个字符开始split,类似于预分区

 

其他优化方法,参考:从 Amazon EMR 和 AWS Glue 访问 Amazon S3 中数据的性能优化最佳实践