如何模拟EMRFS处理S3返回503 Slow Down的情况

在 EMRFS (EMR 5.25) 的配置文件 /usr/share/aws/emr/emrfs/conf/emrfs-default.xml 里看到 fs.s3.sleepTimeSeconds 这个参数。按照配置文件里的注释,这个参数控制 S3 调用失败重试的间隔,默认是10秒。
由于 EMRFS 闭源,想测试一下,验证这个参数是否有效。

因为需要很大的请求量才能触发 503 Slow Down, 需要另辟蹊径来测试。步骤如下:

1. 启动 EMR 5.25.

2. 登录主节点,修改 core-site.xml,将 s3 endpoint 指向本机。

  <property>
    <name>fs.s3n.endpoint</name>
    <value>http://127.0.0.1:8888</value>
  </property>

3. 修改 EMRFS 的参数,调整重试次数和重试间隔。/usr/share/aws/emr/emrfs/conf/emrfs-site.xml

<configuration>
  <property>
    <name>fs.s3.maxRetries</name>
    <value>10</value>
    <description>The number of times to retry an AWS SDK method on failure</description>
  </property>
  <property>
    <name>fs.s3.sleepTimeSeconds</name>
    <value>10</value>
    <description>The length of time in seconds to wait between AWS SDK method failure retries</description>
  </property>
</configuration>

4. 在本地启动 netcat, 做一个假的 S3 server, 手动应答请求。

$ nc -l 8888
(看到客户端发来的 head 请求,就粘贴以下内容,按两下回车)
HTTP/1.1 503 Slow Down
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0

5. 用 hdfs 命令调用 EMRFS.

$ hdfs dfs -ls s3://feichashao/

nc 中,应该能看到 HEAD 请求,回复(4)提到的 503 返回。然后会看到客户端重试,继续回复 503.

6. 经过测试,发现 fs.s3.maxRetries 指定的次数是生效的,而 fs.s3.sleepTimeSeconds 并没有生效。不到1秒就收到重试请求了。 可能是默认 S3 SDK 会使用指数等待法来重试。