Aio
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • 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
7,034
On Slideshare
7,012
From Embeds
22
Number of Embeds
5

Actions

Shares
Downloads
25
Comments
0
Likes
1

Embeds 22

http://www.slideshare.net 12
http://bora.klab.org 7
http://bora 1
http://twitter.com 1
https://twitter.com 1

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. おしまい