在火山引擎创建EMR或者将Proton应用到自建Hadoop集群后,可以根据使用场景的不同进行针对性性能优化。
Proton在写大文件时,会基于对象存储MPU机制进行异步分片上传,在客户端每写满一个分片之前,默认会优先写到本地磁盘,一个分片写满之后,会异步上传到对象存储,并清除磁盘上的分片数据。所以文件写入速度可能会受限于本地磁盘写入带宽和上传网络带宽,默认情况下,前者远高于后者。因此写入流程可以充分利用多块本地磁盘来提升数据写入性能,可以通过修改core-site.xml
中的fs.tos.multipart.staging-dir
进行多盘配置,比如:
<property> <name>fs.tos.multipart.staging-dir</name> <value>/data01/stagingdir,/data02/stagingdir,/data03/stagingdir</value> </property>
说明
EMR场景下已经默认根据EMR节点的磁盘挂载情况进行了配置,无需再额外配置。手动配置该参数时,需要注意写数据的任务有这些配置目录的读写权限。
同时,基于MPU上传大文件时,由于MPU有10000分片个数的限制,所以需要设置合适的分片值。以写一个100G的对象为例,分片的最小值为10.24MB,这种情况下建议将对应的参数fs.tos.multipart.size
设置为2^n
, 即16MB。
<property> <name>fs.tos.multipart.size</name> <value>16777216</value> <description>默认值为8MB</description> </property>
同时也可以增大并发上传分片的线程数,来加速文件的写操作。
<property> <name>fs.tos.multipart.thread-pool-size</name> <value>64</value> <description>默认值为所在ECS节点核数的2倍,不建议超过超过ECS节点核数的4倍</description> </property>
与写大文件类似,客户端会写一批数据到本地之后,再上传到对象存储。高并发写小文件场景下,客户端可以直接将数据写入内存中,然后上传到对象存储,没有必要写到本地磁盘。因此可以提升小文件的上传速度。可以通过设置fs.tos.multipart.staging-buffer-size
参数的值,作为将数据写入哪种存储介质的阈值,当写入的数据量小于该值时,会写入内存,否则会写入本地磁盘。生产实践中,增大该值时,建议同时调整JVM堆的参数,避免内存不足导致频繁GC影响性能以及OOM问题。
<property> <name>fs.tos.multipart.staging-buffer-size</name> <value>4096</value> <description>默认值为4k,单位为byte</description> <property>
同时,在上传数据到对象存储时,可以选择MPU多分片上传或者直接PUT两种上传模式。对于小文件场景,直接PUT的方式有利于提升写入性能,可以通过设置fs.tos.multipart.threshold
参数配置阈值,如果写入的对象大小大于该值时,会采用MPU分片异步上传的方式,小于该值时,使用直接PUT的方式。
<property> <name>fs.tos.multipart.threshold</name> <value>10485760</value> <description>默认值为10M,不建议将该指设置的特别大,同时如果启用Job Committer场景下,会直接使用MPU</description> </property>
当我们需要对一个大目录执行Rename/MV操作时,客户端首先会批量的list该目录下的子文件/子目录,然后再并行对子文件/子目录并行执行Rename操作,可以通过增大并发数fs.tos.task.thread-pool-size
来提升Rename子目录/子文件的速度。
<property> <name>fs.tos.task.thread-pool-size</name> <value>64</value> <description>默认值为所在ECS节点核数的2倍</description> </property>
Proton默认通过Copy + Delete来执行对一个文件的Rename操作,火山引擎TOS原生支持Rename语义,所以直接使用TOS的Rename语义可以极大的提升Rename的性能。使用Rename语义需要执行以下两个操作:
core-site.xml
的fs.tos.rename.enabled
参数<property> <name>fs.tos.rename.enabled</name> <value>true</value> <description>默认false,开启后直接使用Rename语义代替Copy+Delete操作</description> </property>
说明