ablog

不器用で落着きのない技術者のメモ

HDFS の I/O サイズ

emr-5.17.0 で /etc/hadoop/conf/core-site.xml を確認すると以下の通り*1

  <property>
    <name>io.file.buffer.size</name>
    <value>65536</value>
  </property>

Note that HDFS Readers do not read whole blocks of data at a time, and instead stream the data via a buffered read (64k-128k typically). That the block size is X MB does not translate into a memory requirement unless you are explicitly storing the entire block in memory when streaming the read.

Solved: Hadoop read IO size - Cloudera Community
  @Override
  public FSDataInputStream open(Path f, final int bufferSize)
      throws IOException {
    statistics.incrementReadOps(1);
    Path absF = fixRelativePart(f);
    return new FileSystemLinkResolver<FSDataInputStream>() {
      @Override
      public FSDataInputStream doCall(final Path p)
          throws IOException, UnresolvedLinkException {
        final DFSInputStream dfsis =
          dfs.open(getPathName(p), bufferSize, verifyChecksum);
        return dfs.createWrappedInputStream(dfsis);
      }
      @Override
      public FSDataInputStream next(final FileSystem fs, final Path p)
          throws IOException {
        return fs.open(p, bufferSize);
      }
    }.resolve(this, absF);
  }
https://github.com/cloudera/hadoop-common/blob/cdh5.4.5-release/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java#L294-L303

これは, 各 Mapper は独立にシーケンシャル I/O をバッファサイズ単位(注4)で発行しているため, ディスクドライブに対しては完全なシーケンシャルアクセスにはならず, Mapper 数(同時 I/O ストリーム数) の増加により, シーケンシャリティは低下するためだと考えられる. つまり, 前述の性能律速は, 複数ストリーム I/O によるディスクシークの増加から起因される問題であると考えられる.
一般的に, 前述のような複数ストリーム I/O による性能律速の問題に対しては, I/O バッファサイズの増加, または, I/O のスケジューリングにより解決が図られる. 以下に, それぞれの解決策を Hadoop において検証した結果を示す.図 5 に I/O バッファサイズを変化させた時の I/O 転送レートを示す. I/O バッファサイズの増加に伴い, I/O 転送レートが低下の傾向にあることがわかる. また, 32MB の時は, 大きな性能低下が確認された. これは, 各 Mapper の逐次的な I/O処理モデル(注5) が起因していると考えられる. つまり, 小さい単位で I/O を発行した場合は, I/O 発行の間隔が短いことからOS の先読み機構が効率的に機能し, ディスクドライブに対するシーケンシャリティの増加に加えて, I/O 処理が CPU 処理にオーバーラップして実行される可能性が高いが, 大きい単位で I/O を発行した場合は, ディスクドライブに対するシーケンシャリティは増加するものの, I/O 発行の間隔が長いため OSの先読み機構が効率的に機能せず, I/O 処理と CPU 処理が逐次的に処理されるため, 小さい単位で I/O を発行した場合と比べて性能が低下してしまうと考えられる. このことから, 現状の Hadoop の I/O 処理モデルでは, I/O バッファサイズの増加のアプローチは当該問題に対する解決策とはならないと考えられる.

(注4):デフォルトは 4KB.
(注5):Hadoop の各 Mapper は I/O 処理と CPU 処理を同時には実行せず,逐次的に実行することで処理を進めるデータ処理アーキテクチャとなっている.
(注6):Hadoop は, 通常 HDFS のブロックを Spilt とし, Split ごとに Mapperを割り当てて処理を進める.

並列データインテンシブ処理基盤のI/O性能評価に関する実験的考察

*1:マスターノードとコアノードで確認した