Aio

  • 4,861 views
Uploaded on

 

More in: Technology , Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
4,861
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
25
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. 非同期 I/O 概説 Introduction to Asynchronous I/O AIO, I/O Multiplexing…
  • 2. 今日の目的
    • 非同期 I/O とは何かを知る
    • 非同期 I/O を使うと何がうれしいのかを知る
    • 非同期 I/O を実現する手段(複数)を知る
  • 3. アジェンダ
    • 非同期 I/O を使う理由
    • 非同期 I/O とは?
    • AIO の実装を紹介
    • AIO の使い方
    • 落穂ひろい
  • 4. アジェンダ
    • 非同期 I/O を使う理由
    • 非同期 I/O とは?
    • AIO の実装を紹介
    • AIO の使い方
    • 落穂ひろい
  • 5. ネットワークサーバのお仕事を考えてみる
    • Web サーバとか
    • I/O (ネットワーク I/O 、ディスク I/O )に着目
      • リクエストを受ける(ネットワーク read )
      • ディスクからコンテンツを読む(ディスク read )
      • レスポンスを返す(ネットワーク write )
  • 6. 一般的な I/O の特性
    • read(2)/write(2)
      • いつでもデータが読める / 書けるとは限らない
      • 準備ができるまで戻らない=待たされる
    • 「 I/O ブロッキング」
  • 7. ネットワークサーバ ×I/O
    • ネットワークサーバ
      • ネットワーク I/O 、ディスク I/O を伴う
    • I/O ブロッキング
      • I/O で待たされる
    • 単一の処理(リクエスト / レスポンス)を完了するまでに時間がかかる(待たされるので)
    • 単位時間の処理能力が下がる
      • 並行度( concurrent )が下がる
  • 8. The C10K problem
    • The C10K problem
      • http://www.kegel.com/c10k.html
      • http://www.hyuki.com/yukiwiki/wiki.cgi?TheC10kProblem
    • “ 「 C10K 問題」(クライアント 1 万台問題)とは、ハードウエアの性能上は問題がなくても、あまりにクライアントの数が多くなるとサーバがパンクする問題のこと”
    • 同時処理数を上げるための、 I/O 戦略について説明しているドキュメント
  • 9. C10K - I/O 戦略
    • 1スレッド:1クライアントで、ブロッキング I/O
      • × 各スレッドでスタックを消費する
        • NPTL の場合 8MB/thread
    • 1スレッド:多クライアントで、ノンブロッキング I/O (I/O 多重化 )
      • select, poll, epoll, kqueue, /dev/poll
    • 1スレッド:多クライアントで、 AIO
      • POSIX AIO, libaio
    非同期 I/O
  • 10. アジェンダ
    • 非同期 I/O を使う理由
    • 非同期 I/O とは?
    • AIO の実装を紹介
    • AIO の使い方
    • 落穂ひろい
  • 11. I/O モデルの整理 Synchronous Asynchronous Blocking Non-blocking read/write read/write (O_NONBLOCK) I/O multiplexing I/O 多重化 (select, poll) AIO 非同期 I/O (POSIX AIO, libaio) ~ Boost application performance using asynchronous I/O http://www-128.ibm.com/developerworks/linux/library/l-async/
  • 12. I/O 多重化とは
    • I/O 可能になった fd の集合を通知するしくみ
      • 通知後に、 read(2),write(2) を行う
    • 実装
      • select(2)
        • I/O 可否の検査のためにすべての fd を走査する必要があるので、 fd が多いと効率が悪い
        • FD_SETSIZE (Linux だと 1024) までしか fd を監視できない
      • poll(2)
        • FD_SETSIZE の上限がない select(2)
      • epoll(2) Linux, kqueue(2) FreeBSD, /dev/poll Solaris
        • I/O 可能な fd だけ返却される
        • OS のよって実装がばらばら-> libevent
  • 13. AIO とは
    • 非同期に I/O を行うしくみ
      • 通知時にはすでに read や write が完了している
      • read の場合はバッファにデータが入っている
    • 実装
      • POSIX AIO
        • http://opengroup.org/onlinepubs/009695399/basedefs/aio.h.html
        • Linux, FreeBSD , Mac OS X , Solaris, HP-UX, AIX
      • libaio
        • http:// lse.sourceforge.net/io/aio.html
        • Linux 独自の実装
  • 14. I/O 多重化 vs AIO
    • select(2) はブロックする ※タイムアウトは指定可能
    • 通知後に read(2) が必要=コンテキストスイッチ
  • 15. I/O 多重化 vs AIO
    • ブロックしない=ほかの処理を行える
    • シグナルかコールバックが非同期に呼ばれる
    • 通知時には既にバッファに入ってる
  • 16. アジェンダ
    • 非同期 I/O を使う理由
    • 非同期 I/O とは?
    • AIO の実装を紹介
    • AIO の使い方
    • 落穂ひろい
  • 17. AIO の実装 – Linux 2.6
    • POSIX AIO – POSIX 準拠
      • aio_read / aio_write, aio_error, aio_return, …
      • 通知方法は、スレッド( SIGEV_THREAD )とシグナル( SIGEV_SIGNAL )の両方に対応している
      • 実はシステムコールじゃなくてライブラリ関数( librt )
        • 裏でいくつかスレッドを作ってがんばってるっぽい
    • libaio – Linux 独自
      • io_queue_init, io_prep_pread / io_prep_pwrite, io_set_callback, io_submit, …
      • http://lse.sourceforge.net/io/aio.html
      • システムコール
      • POSIX AIO より性能は上
  • 18. AIO の実装 – FreeBSD 6.2
    • POSIX AIO – POSIX 準拠
      • aio_read / aio_write, aio_error, aio_return, …
      • システムコール
      • 通知方法は SIGEV_KEVENT のみ
        • SIGEV_KEVENT: kqueue(2) と kevent(2) で通知
        • SIGEV_THREAD 、 SIGEV_SIGNAL は使えない><
  • 19. アジェンダ
    • 非同期 I/O を使う理由
    • 非同期 I/O とは?
    • AIO の実装を紹介
    • AIO の使い方
    • 落穂ひろい
  • 20. POSIX AIO – スレッド通知 iocb->aio_fildes = … iocb->aio_buf = … iocb->aio_nbytes = … iocb->aio_offset = … iocb->aio_sigevent.sigev_notify = SIGEV_THREAD ; iocb->aio_sigevent.sigev_notify_function = rd_done ; iocb->aio_sigevent.sigev_value.sival_ptr = iocb ; aio_read (iocb); /* void rd_done (sigval_t sigval) */ iocb = (struct aiocb *)sigval.sival_ptr; while ((rc = aio_error (iocb)) == EINPROGRESS); rc = aio_return (iocb); char *buf = (void *)iocb->aio_buf; struct aiocb の初期化 aiocb を取り出す データが詰まってる buf 返り値を得る エラー状態を確認 スレッドを起床して通知 コールバック関数 自分自身を格納 非同期処理をリクエスト
  • 21. POSIX AIO – スレッド通知/注意点
    • スレッドセーフ ではない 関数の一覧
      • http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html#tag_02_09_01
  • 22. POSIX AIO – シグナル通知 iocb->aio_fildes = … iocb->aio_buf = … iocb->aio_nbytes = … iocb->aio_offset = … iocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL ; iocb->aio_sigevent.sigev_signo = SIGIO_READ ; iocb->aio_sigevent.sigev_value.sival_ptr = iocb ; aio_read (iocb); /* void rd_done (int signo, siginfo_t *info, void *context) */ iocb = (struct aiocb *)info->si_value.sival_ptr; while ((rc = aio_error (iocb)) == EINPROGRESS); rc = aio_return (iocb); char *buf = (void *)iocb->aio_buf; struct aiocb の初期化 aiocb を取り出す ☚ データが詰まってる buf 返り値を得る エラー状態を確認 シグナルで通知 ☚ 発生シグナルを指定 ☚ 自分自身を格納 非同期処理をリクエスト sigemptyset(&sigact_r.sa_mask); sigact_r.sa_flags = SA_SIGINFO; sigact_r.sa_sigaction = rd_done ; sigaction( SIGIO_READ , &sigact_r, NULL); シグナルハンドラ
  • 23. POSIX AIO – シグナル通知/注意点
    • シグナルセーフ である 関数の一覧
      • http://www.linux.or.jp/JM/html/LDP_man-pages/man7/signal.7.html#lbAH
  • 24. libaio io_queue_init (AIO_MAXIO, &myctx); struct iocb *ioq[n]; for (i=0; i<=n; i++) { io_prep_pread (iocb, srcfd, iosize, offset); io_set_callback (iocb, rd_done); ioq[i] = iocb; } io_submit (myctx, n, ioq); io_queue_run (myctx); io_queue_wait(myctx, NULL); /* void rd_done(io_context_t ctx, struct iocb *iocb , long res,…) */ int iosize = iocb->u.c.nbytes; char *buf = iocb->u.c.buf; off_t offset = iocb->u.c.offset; 非同期イベント処理-> CB データが詰まってる buf コンテキストの初期化 iocb のセットアップ (read) コールバック関数のセット 非同期処理をリクエスト 非同期処理の完了を待つ
  • 25. サンプルコードのありか
    • http://klab.klab.org/trac/general/wiki/aio-copy
  • 26. アジェンダ
    • 非同期 I/O を使う理由
    • 非同期 I/O とは?
    • AIO の実装を紹介
    • AIO の使い方
    • 落穂ひろい
  • 27. sival_ptr と sigval_ptr
    • sigval union - /usr/include/sys/signal.h
    • sival_ptr
      • POSIX, Linux
    • si g val_ptr
      • FreeBSD, Mac OS X
    /* borrow from lighttpd-1.5.0 */ #if (defined(__FreeBSD__) || defined(__DragonFly__)) #define sival_ptr sigval_ptr #endif
  • 28. AIO を使っているプロダクト
    • lighttpd-1.5.0 (PRE RELEASE)
      • Linux : libaio (io_submit + io_getevents)
      • POSIX : AIO (SIGEV_THREAD)
      • FreeBSD : ×
    • nginx-0.6.4 ( んぎんくす )
      • Linux : × (たぶん…)
      • FreeBSD : AIO (SIGEV_KEVENT)
    io_queue_* を使っていない。 が、実は io_queue_* は io_setup や io_getevents のラッパーにすぎない
  • 29. POSIX AIO で扱えるファイルディスクリプタ
    • regular file
    • 名前付きパイプ
    • ソケット
    • なんでもおk
  • 30. libaio で扱えるファイルディスクリプタ
    • regular file
    • ソケットはダメ
    • 名前付きパイプもダメ
  • 31. では、 lighttpd はどこで libaio を使っているのか?
    • tmpfs(/dev/shm/) にファイルを作る
    • tmpfs 上のファイルを mmap(2) する
    • 非同期に、
      • ファイルからデータを read して、
      • mmap(2) した領域に write する
    • tmpfs 上のファイルを sendfile(2) でソケットに送る
    read(2)+write(2) よりも mmap(2)+sendfile(2) のほうが早い。 なぜなら、カーネル内でコピーが行われるから。
  • 32. レベルトリガとエッジトリガ
    • epoll(2)
      • デフォルト : レベルトリガ
      • EPOLLET : エッジトリガ
  • 33. レベルトリガとエッジトリガ
    • レベルトリガ
      • 越えている間はイベントが起こり続ける
    • エッジトリガ
      • 超えた / 下回ったときだけイベントが起こる
    ★ ★ ★ ★ ★ ★ ★ ★
  • 34. レベルトリガとエッジトリガ
    • レベルトリガ
      • 越えている間はイベントが起こり続ける
    • エッジトリガ
      • 超えた / 下回ったときだけイベントが起こる
    ★ ★ ★ ★ ★ ★ ★ ★
  • 35. Syslets, Threadlets
    • Syslets, Threadlets (≧2.6.24)
      • http://lwn.net/Articles/219954/
      • http://www.cuspy.org/blog/2007/07/25/
    “ Syslets” はカーネル内で小さなプログラムを動作させるための手段であり、システムコールを非同期かつユーザー空間から出ずに実行する方法です。 “ Threadlets” はユーザー空間で非同期のコードを実行するメカニズムと同類です。 どちらのケースでも、コードの問い合わせがブロックしない限り同期的に実行されますが、もし何かを待たなければならない場合カーネルはスレッドを生成し ( スペアのスレッドが再利用される場合もある ) 、ユーザー空間でそのスレッドを実行します。 このパッチの最初の動機はメンテナンスに大変な手間が掛かる AIO のアプローチを使わずに、完全な非同期 I/O を実装を可能にすることでした。 以来、 syslets と threadlets はシステムコールの非同期実行を可能にしただけでなく、より多くのアプリケーションの対応が可能となりました。
  • 36. 参考文献
    • The C10K problem
      • http://www.kegel.com/c10k.html
      • http://www.hyuki.com/yukiwiki/wiki.cgi?TheC10kProblem
    • Boost application performance using asynchronous I/O / IBM developerWorks
      • http://www-128.ibm.com/developerworks/linux/library/l-async/
    • Kernel Asynchronous I/O (AIO) Support for Linux
      • http:// lse.sourceforge.net/io/aio.html
  • 37. おしまい