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

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

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

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

アプリからの読み込み要求
   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()の効果は期待できますね。

Pocket

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)