Tech Blog 〜ぞうの日記

HadoopやLinux関連の技術的な内容の紹介です

HDFSが高速に?mmapによるzero-copyでの読み込み

本日公開されたHDFSの高速化に関連するJIRAの2つ目です。

通常、アプリケーションはread()などのシステムコール経由でファイルを読み出します。
このHDFS-4953mmap()システムコールを使用することで、読み取り時にかかるオーバーヘッドを減らそうというものです。

参考までに、通常アプリケーションがファイルを読み出す場合、以下のようなフローでカーネルからの読み込み処理が行われます。

アプリからの読み込み要求
   v
fread()など (stdlib)
   v
read()システムコール(glibc)
   v
(以下カーネル空間)
   v
sys_read()
   v
vfs_read()
   v
  ….
参考資料:ページキャッシュのメモ P.12

アプリケーションからの読み出し要求によりシステムコールが呼ばれるのは上記の通りですが、問題となるのは、

  • read()が頻繁に呼びだされる場合、コンテキストスイッチが多く発生してコストがかかる※コストの計測には strace や valgrind、perfなどが利用できます
  • デバイスから読み込んだカーネル空間のデータを、copy_to_user() などによってユーザー空間にコピーする必要がある

mmap()を使用することで、ファイルをメモリにマッピングすることができるようになります。以前の@IT面白い比較があったので、興味があればご覧になって下さい。

ということで、mmap()により読み取りをゼロコピーにする、というのがこの修正案のようです。

注意しなければならないのは、mmap()システムコール自体のコストはそれなりにかかるので、1)ファイルオープン、2)数バイト読み込み、3) クローズ、というようなアクセスパターンであれば、mmap()よりもread()の方が良いかもしれません。

ただしHDFSのブロックサイズは64MB なので、mmap()の効果は期待できますね。

元記事:http://linux.wwing.net/WordPress/?p=320