もっと詳しい方のフォロー募集です

アプリケーションがマルチスレッドになってもネットワーク処理が分散されなければマルチコアを活かせない典型的な例です。id:viverの古橋さんがs100kpsとしてあげていた件にも近いかも。

memcachedで現象を確認します。最近のmemcachedはマルチスレッドで動くようになっているので、まずはそれを確認します。

$ memcached-tool localhost stats|grep threads
threads           4

スレッドが4つで起動しています。

負荷がそれなりにある状態(8000req/sec程度)で、コマンドラインでtopを開き、「1」キーを押して、CPUごとの使用率を表示します。(例はFedora8 kernel-2.6.23)

Tasks:  77 total,   1 running,  76 sleeping,   0 stopped,   0 zombie
Cpu0  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu1  :  3.0%us,  5.7%sy,  0.0%ni, 75.3%id,  0.0%wa,  7.7%hi,  8.3%si,  0.0%st
Cpu2  :  0.0%us,  0.3%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu3  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                            
3692 nobody    20   0 10.9g  10g  716 S   10 44.0  10253:09 memcached

*メモリの行は削除しています。

CPUは4つ認識されていますが、CPU1しか使用されていないのがわかると思います。おそらく、CPU1のアイドルがなくなった時点で他のCPUに空きがあってもそれ以上の処理ができなくなります。なぜCPU1しか使われないかは「/proc/interrupts」をみるとなんとなくわかります。NICはBroadcom BCM5722です。

$ cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3 
  0:      10569          0      10460          0   IO-APIC-edge      timer
 16:        301        301        302     303161   IO-APIC-fasteoi   aerdrv, aerdrv, aerdrv, ioc0, eth0
 17:          8 3570118309          7          7   IO-APIC-fasteoi   eth1

memcachedの通信は主にeth1で行われるのですが、このeth1に関する割り込み処理がCPU1でしか行われていません。ソフトウェア割り込みはハードウェア割り込みが行われたCPUでしか行われないのもこの傾向を強めます。

マルチコアCPUの性能を活かすために考えられることは、ネットワークの割り込み処理を複数のCPUに分散することだと思うのですが、最新のNICにはRX/TX Multiple Queue(正式名称がわからない。Receive Side ScalingとかScalable I/O?)機能が備わっています。もともとRX/TX Multiple Queueは10GbpsのNICなどに備わっていた機能で、複数の割り込みチャンネルを持つことでネットワーク処理の分散を実現しています。最近のIntelやBroadcomの1GbpsのNICにも同じ機能があります。

以下はBroadcomのBCM5709を搭載しているマシンのinterrupts。(CentOS 5.3)

           CPU0       CPU1       CPU2 ..  CPUy      CPUz
  0:  342688765          0          0         0          0    IO-APIC-edge  timer
114:         55         34      19613     39212         11       PCI-MSI-X  eth0
122:         23          0        145       193          0       PCI-MSI-X  eth0
130:        243          0         75       138          0       PCI-MSI-X  eth0
138:         24         12      10423     35836          6       PCI-MSI-X  eth0
146:       2141          0        110       556          0       PCI-MSI-X  eth0
154:         21          4      12802     17806          7       PCI-MSI-X  eth0
162:        561          0        216        72          0       PCI-MSI-X  eth0
186:         72         76      97076    137548     197952       PCI-MSI-X  eth1
194:         24      45478     100337    140189     554148       PCI-MSI-X  eth1
202:         24     527452      94677     87876     305476       PCI-MSI-X  eth1
210:         23     220400     175792     56390     205521       PCI-MSI-X  eth1
218:         24      37023      30778      6169      11788       PCI-MSI-X  eth1
226:         21     349792      48599     91969          0       PCI-MSI-X  eth1
234:         23     206063       5911     43536          4       PCI-MSI-X  eth1

*加工済み

こんな感じで、割り込み処理用のチャンネルが複数個存在して、CPU間で分散ができています。

まとめると、マルチコアCPU、SSDの普及によってハードウェアの性能があがり、epoll/kqueue/event portsによって大量のコネクションをさばけるようになると、こういった複数のCPUに分散できない処理がボトルネックになってくるので、最新のハードウェアとか対応しているカーネルを利用しようということです。

このブログ記事について

このページは、Masahiro Naganoが2010年1月29日 17:02に書いたブログ記事です。

ひとつ前のブログ記事は「来年度(2010年度)のRFPで主流となりそうなサーバ」です。

次のブログ記事は「nginxの組み込みperlで非同期に遅延させてレスポンス」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 4.27-ja