在 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>
<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>
<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
(看到客户端发来的 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 会使用指数等待法来重试。