「非同期むベントモデル」ずは䜕か、なぜ「ファッション」になっおいるのか

テヌマのあるむンタヌネットでは、 「Node.js」ずいう蚀葉が流行しおいたす。 この短い蚘事では、このすべおがどこから来たのか「指で」、このアヌキテクチャがアプリケヌションコヌド PHP + MySQLの通垞のWebサむトで「同期」および「ブロッキング」I / Oを䜿甚する通垞のアヌキテクチャずどのように異なるかを理解しようずしたす 「リク゚ストごずのスレッドたたはプロセスによる」スキヌム埓来のApache Webサヌバヌ に埓っお動䜜するアプリケヌションサヌバヌで実行したす 。



蚘事の読みやすさに぀いお



この蚘事は、ここに登堎しおから、蚘事の最埌で蚀及した読者からのフィヌドバックのおかげで、倚くの倉曎抂念的な倉曎を含むず远加が行われたした。 䜕かを理解するのが難しいず感じたら、コメントでそれを説明しおください。そしお、私たちはそれをより理解しやすい蚀語で蚘事に曞きたす。



パフォヌマンスに぀いお



twitter 、 VKontakte 、 facebookなどの最新の負荷の高いサむトは、PHP + Apache + NoSQLたたはRuby on Rails + Unicorn + NoSQLの圢匏のバンドルで動䜜し、たったく遅くなりたせん。 たず、SQLではなくNoSQLを䜿甚したす。 次に、倚くの同䞀の実皌働サヌバヌにリク゚ストを分散 「バランス」 したすこれを「氎平スケヌリング」ず呌びたす。 第䞉に、可胜なすべおをキャッシュしたす。ペヌゞ党䜓、ペヌゞの断片、 Ajaxリク゚スト甚のJson圢匏のデヌタなどです。キャッシュされたデヌタは「静的」であり、 NginXなどのサヌバヌから盎ちに送信されたす。アプリケヌション。



個人的には、Apache + PHPからNode.jsに曞き換えた堎合にサむトが高速になるかどうかはわかりたせん。 テヌマむンタヌネットでは、「非同期むベントモデル」よりもシステムフロヌが遅いず考える人ず、反察の芳点を守る人の䞡方に䌚うこずができたす。



次のプロゞェクトを䜕に曞くかを考えお、そのタスクから先に進み、プロゞェクトのタスクによく重なるアヌキテクチャを遞択する必芁がありたす。



たずえば、プログラムが倚数の同時接続をサポヌトし、垞にそれらぞの曞き蟌みず読み取りを行う堎合、この堎合は必ず「非同期むベントモデル」Node.jsなどを怜蚎する必芁がありたす。 Node.jsは、サブシステムをWebSocketプロトコルに切り替えたい堎合に最適です。



「非同期むベントモデル」がうたくいくシステムの䟋



ブロッキングおよびノンブロッキング入力/出力ずは䜕ですか



むンタヌネットナヌザヌがサむトに接続し、アバタヌの画像をアップロヌドするネットワヌク゜ケット 「゜ケット」-文字通り「接続ポむント」の䟋を䜿甚しお、入力/出力のタむプを凊理したす。 この蚘事では、アプリケヌションコヌドのすべおの入力/出力が「同期」および「ブロック」である「非同期むベントモデル」ず「䜿い慣れた」アヌキテクチャを比范したす。 「習慣」-以前は、誰もあらゆる皮類の「ロック」に悩たされおいなかったため、誰もがそのように曞き、誰もが十分でした。 「同期」および「ブロック」I / Oずは䜕ですか これは、ほずんどのサむトが蚘述されおいる最も単玔で最も䞀般的な入力/出力です。



゜ケットの堎合、これは次のようになりたす。

同時に、プログラムのコヌド内で「ブロッキング」が発生したす。この間、スレッドはアむドル状態になりたすが、䜕か有甚なこずができたす。 この問題を解決するために、「同期」および「非ブロッキング」I / Oが発明されたした。

画像デヌタの最埌の郚分が読み取られるたでこれらのステップがサむクルで実行される堎合、最埌に再び、党䜓像を完党に取埗したす。 唯䞀の違いは、このサむクルでは、゜ケットからのデヌタの読み取りに加えお、「ロック」の䞋でアむドル状態にならないように、他の䟿利なこずを実行できるこずです。 たずえば、別の゜ケットからデヌタを読み取るこずもできたす。 このような「非ブロッキング」I / Oサむクルは、蚘事の䞭倮近くに再び珟れたす。



「非同期」I / Oもありたす。 この蚘事では考慮したせんが、䞀般的には、コヌドから「コヌルバック」関数を切断したす。これは、画像デヌタの別の郚分がこの゜ケットに来るたびにオペレヌティングシステムによっお呌び出されたす。 そしお、この゜ケットを䞀般的に聞いお、他のこずをするこずをすでに忘れおいたす。 「非同期」I / Oは、「同期」ず同様に、「ブロック」ず「非ブロック」に分けられたす。 しかし、この蚘事では、「ブロッキング」ず「ノンブロッキング」ずいう蚀葉の䞋で、正確に「同期」入出力を意味したす。



しかし、この蚘事では、アプリケヌションがシステムスレッドを䜿甚しおオペレヌティングシステム䞊で盎接実行される「銎染みのある」アヌキテクチャのみを怜蚎し、「グリヌンスレッド」を備えた䜕らかの「仮想マシン」では怜蚎したせん。 「グリヌンスレッド」を備えた「仮想マシン」内では、「同期」ず思われるI / Oを「非同期」に倉えるなど、さたざたな奇跡を実行できたす。これに぀いおは、「代替方法」セクションで詳しく説明したす。



背景



新しいアプリケヌションアヌキテクチャでの実隓の雪厩は、埓来のアヌキテクチャが開発の倜明けにむンタヌネットのニヌズを解決したずいう事実によっお匕き起こされたした。もちろん、すべおが賑やかである「2りェブ」りェブの進化するニヌズを満たすように蚭蚈されおいたせんでした。



長幎にわたっおテストされた䞀連のPHP + MySQL + Apacheは、 Internet 1.0でうたく機胜したした。 サヌバヌは、ナヌザヌ芁求ごずに新しいスレッドたたはプロセス、 オペレヌティングシステムの芳点からはほが同じ を開始したした。 このストリヌムはそこからPHPに行き、デヌタベヌスに行き、そこで䜕かを遞択し、 HTTPを介しおナヌザヌに送信した応答で戻り、その埌、それ自䜓を砎壊したした。



しかし、「リアルタむム」アプリケヌションの堎合、芋逃され始めたした。 「ナヌザヌずの10,000の接続を同時にサポヌトする」ずいうタスクがあるずしたす。 このために10,000個のスレッドを䜜成できたす。 圌らはお互いにどうやっお仲良くなりたすか それらは、システム「スケゞュヌラ」によっお互いに共存したす。そのタスクは、各スレッドにプロセッサ時間のシェアを䞎え、同時に誰も奪わないこずです。 圌はそのように振る舞いたす。 1぀のスレッドが少し動䜜するず、スケゞュヌラヌが開始し、このスレッドを䞀時的に停止し、「サむトを準備しお」次のスレッドキュヌで既に埅機しおいるを開始したす。



この「サむトの準備」は「コンテキストスむッチング」ず呌ばれ、䞀時停止したストリヌムの「コンテキスト」の保存、および次に起動されるストリヌムのコンテキストの埩元が含たれたす。 「コンテキスト」には、オペレヌティングシステム自䜓のプロセッサレゞスタおよびプロセスデヌタid'shniki、アクセス暩、リ゜ヌスずロック、割り圓おられたメモリなどが含たれたす。



スケゞュヌラの起動頻床は、オペレヌティングシステムが決定したす。 たずえば、Linuxでは、デフォルトで、スケゞュヌラヌは100分の1秒のどこかで開始したす。 スケゞュヌラは、プロセスが手動でたずえば、スリヌプ機胜によっお「ブロック」されたずき、たたは「同期」および「ブロック」぀たり、最も単玔で最も䞀般的なI / Oを芋越しお呌び出されたすたずえば、デヌタベヌスがPHPストリヌムのナヌザヌ芁求を埅機しおいるずきデヌタは圌に毎月の販売レポヌトを提䟛したす。



䞀般的なケヌスでは 、システムスレッド間の「コンテキストスむッチング」はそれほど高䟡ではなく、マむクロ秒のオヌダヌであるず考えられおいたす。



スレッドがRAMのさたざたな領域をアクティブに読み取るおよびRAMのさたざたな領域に曞き蟌む堎合、スレッドの数が増えるず、プロセッサの「セカンドレベルキャッシュ」L2が倱われたす。これはメガバむト単䜍です。 この堎合、 システムバス䞊のデヌタのRAMからプロセッサぞの配信、およびシステムバス䞊のデヌタのプロセッサからRAMぞの蚘録を毎回埅機する必芁がありたす。 このようなRAMぞのアクセスは、プロセッサキャッシュぞのアクセスよりも桁違いに遅くなりたす。このキャッシュはこのために考案されたした。 これらの堎合、「コンテキスト切り替え」時間は最倧50マむクロ秒になりたす。



むンタヌネット䞊では、倚数の同時ストリヌムにおける絶え間ない「コンテキストスむッチング」により、システム党䜓の速床が倧幅に䜎䞋する堎合がありたす。 ただし、この仮説の明確で詳现な数倀的蚌拠は芋぀かりたせんでした。



たた、マルチスレッドモデルがアプリケヌションのメモリ消費に䞎える圱響を怜蚎しおみたしょう。 「スタック」は、各システムスレッドに関連付けられおいたす。 スレッドが匕数付きの特定の関数を呌び出すず、この関数の匕数は「スタック」に眮かれ、コヌド内の珟圚のアドレスは「戻りアドレス」ず呌ばれたす呌び出された関数の実行が終了するずここに戻るため。 この関数がそれ自䜓の内郚で別の関数を呌び出すず、察応するデヌタが再び「スタック」に曞き蟌たれ、すでにそこに曞き蟌たれおいるデヌタに加えお、も぀れのように芋えたす。



システムスレッドを䜜成するずき、「スタック」はオペレヌティングシステムによっおRAM内で党䜓ずしおすぐに割り圓おられるのではなく、䜿甚時に「ピヌス」によっお割り圓おられたす。 これは「仮想メモリ」ず呌ばれたす 。 ぀たり、各スレッドはすぐに「スタック」の䞋の「仮想メモリ」の倧きな郚分に割り圓おられたすが、実際には、この「仮想メモリ」はすべお「メモリペヌゞ」ず呌ばれる「郚分」に分割され、すでにこれらの「メモリペヌゞ」は「実際の」 »RAMは、必芁な堎合にのみ䜿甚したす。 スレッドが「実際の」RAMにただ割り圓おられおいない「メモリペヌゞ」に觊れるずたずえば、プロセッサに䜕かを曞き蟌むようにプロセッサに指瀺しようずするず、プロセッサの「メモリ管理ブロック」がこのアクションを怜出し、オペレヌティングシステムで「 䟋倖 」を匕き起こしたす「 ペヌゞフォヌルト 」。「実際の」RAMにこの「メモリペヌゞ」を割り圓おるこずで応答したす。



Linuxでは、デフォルトのスタックサむズは8メガバむトで、「メモリペヌゞ」のサむズは4キロバむトです 1぀たたは2぀の「メモリペヌゞ」がすぐに「スタック」に割り圓おられたす。 同時に起動される10,000のスレッドに関しお、玄80メガバむトの「実際の」RAMの芁件がありたす。 それは少しのように思われ、心配する理由はないようです。 ただし、この堎合に必芁なメモリのサむズはOnになりたす。これは、負荷がさらに増加するず、 「スケヌラビリティ」に問題があるこずを瀺唆しおいたす。明日、サむトがすでに100,000の同時ナヌザヌに察応し、100を維持する必芁がある堎合000同時接続 そしお明埌日-1,000,000 そしお明埌日の埌-それはただ䞍明です...



シングルスレッドのアプリケヌションサヌバヌにはこの欠点はなく、同時接続数の増加に䌎う新しいメモリは必芁ありたせんこれはO1ず呌ばれたす。 Apache Web ServerずNginXのメモリ䜿甚量を比范するこのグラフを芋おください 



画像



最新のWebサヌバヌ最新のApacheを含むは、完党に「芁求時のフロヌ」のアヌキテクチャではなく、より最適化されたアヌキテクチャ䞊に構築されおいたす。到着したすべおの芁求を凊理する事前準備スレッドの 「プヌル」がありたす。 これは、10頭の銬ず100人のラむダヌが乗るアトラクションず比范できたす。列が圢成され、最初の10人のラむダヌが「あちこち」に乗るたで、次の10人のラむダヌが䞊んで埅機したす。 この堎合、アトラクションはアプリケヌションサヌバヌであり、銬はプヌルからのスレッドであり、ラむダヌはサむトのナヌザヌです。



このようなシステムフロヌの「プヌル」を䜿甚する堎合、同時に、ナヌザヌ数、「プヌル内にあるスレッドの数」、぀たり10,000だけではなく、サヌビスを提䟛できたす。



このセクションで説明する困難は、非垞に倚数の同時接続を凊理するためのマルチスレッドアヌキテクチャの適合性の問題を垞に念頭に眮いおおり、たずめおThe C10K problemず呌ばれおいたした。



非同期むベントモデル



このクラスのアプリケヌションには、新しいアヌキテクチャが必芁でした。 そしお、この状況では、念のため、「非同期むベントモデル」が登堎したした。 これは、 「むベントサむクル」ずテンプレヌト「リアクタヌ」に基づいおいたす 「反応する」ずいう蚀葉から-応答する。



「むベントルヌプ」ずは、「むベントの゜ヌス」蚘述子をポヌリングしお、その䞭にある皮の「むベント」が出珟するかどうかを調べる無限ルヌプです。 ポヌリングは、 「同期」 I / Oラむブラリを䜿甚しお行われたすが、これは同時に「非ブロッキング」になりたす O_NONBLOCKフラグがシステムI / O関数に枡されたす。



぀たり、「むベントサむクル」の次のラりンドで、システムはすべおの蚘述子を順番に通過し、それらから「むベント」の読み取りを詊みたす。読み取り機胜によっおシステムに返されたす。 蚘述子に新しいむベントがない堎合、「ブロック」しお「むベント」が衚瀺されるのを埅機したせんが、すぐに「新しいむベントはありたせん」ずいう回答を返したす。



「むベント」ずは、 ネットワヌク゜ケット䞊の次のデヌタ郚分の到着「゜ケット」-文字通り「接続の堎所」、たたはハヌドディスクからのデヌタの新しい郚分の読み取り䞀般に、任意の入出力のこずです。 たずえば、ホスティングに写真をアップロヌドするず、デヌタが断片的になり、そのたびに「画像デヌタの新しい郚分が受信されたした」ずいうむベントがトリガヌされたす。



この堎合、「むベントの゜ヌス」は、ネットワヌク経由でサむトに接続したTCP゜ケットの「蚘述子」 デヌタストリヌムぞのポむンタヌになりたす。



既に述べたように、新しいアヌキテクチャの2番目のコンポヌネントは、リアクタヌテンプレヌトです。 そしお、ロシア人にずっお、これは原子力発電所の原子炉ではありたせん。 このテンプレヌトの本質は、サヌバヌコヌドが1぀の倧きな郚分で曞き蟌たれ、連続しお実行されるのではなく、小さなブロックに曞き蟌たれ、各ブロックが関連付けられたむベントの発生時に呌び出される「反応する」こずです。 したがっお、コヌドは倚くのブロックのセットであり、そのタスクはいく぀かのむベントに「応答する」こずです。



この新しいアヌキテクチャは、Node.jsの登堎埌に䞻流になりたした。 Node.jsはC ++で蚘述されおおり、そのむベントルヌプはlibev Cラむブラリに基づいおいたす。 ただし、ここでJavascriptは遞択された蚀語ではありたせん。ラむブラリの蚀語に「非ブロッキング」I / Oがある堎合、同様の「フレヌムワヌク」を蚘述するこずもできたす。PythonにはTwisted 、 Tornado 、PearlにはPerl Object Environment 、RubyにはEventMachine すでに5歳です。 これらの「フレヌムワヌク」では、Node.jsに䌌た独自のサヌバヌを䜜成できたす。 たずえば、Javajava.nioベヌスではNettyずMINAが、RubyEventMachineベヌス-Goliath Fibersも利甚が蚘述されおいたす。



長所ず短所



「非同期むベントモデル」は、倚くの倚くのナヌザヌがプロセッサをロヌドしないアクションを同時に実行する堎合に適しおいたす。 たずえば、「 珟圚時刻 」モヌドのセンサヌから枩床を取埗し、ビデオカメラから画像を取埗し、接続された枩床蚈から取埗した枩床をサヌバヌに転送し、チャットに新しいメッセヌゞを曞き蟌み、チャットから新しいメッセヌゞを受信したす。



プロセッサをロヌドしないアクションの芁件は、この無限ルヌプ党䜓が1぀のスレッドで実行されるこずを思い出すず、このルヌプに重い蚈算を抌し蟌んだ堎合たずえば、埮分方皋匏の解法を開始した堎合、他のすべおのナヌザヌは、この蚈算が完了するたで順番に埅機したす。



したがっお、Node.jsのようなサヌバヌは、プロセッサをロヌドしないタスクに適しおいるか、重いバック゚ンドのフロント゚ンドずしおのみ適しおいたす。 たた、「遅い」リク゚スト狭い通信チャネル、遅いリタヌン/デヌタの送信、内郚のどこかでの長い応答時間などを凊理するためのサヌバヌずしおも適しおいたす。 Node.jsのようなサヌバヌに「入出力」仲介の堎所を䞎えたす。 たずえば、「クラむアント」ず「サヌバヌ」の間の仲介芖芚的衚珟党䜓が䜜成され、むンタヌネットナヌザヌのブラりザヌで盎接レンダリングされ、必芁なすべおのデヌタがリポゞトリのサヌバヌに保存され、Node.jsが仲介のタスクを実行し、芁求に応じお「クラむアント」に必芁なデヌタを提䟛したす、「クラむアント」から来たずきに新しいデヌタをリポゞトリに曞き蟌む。



「非同期むベントモデル」によるサヌバヌが同じシステムスレッドで実行されおいるずいう事実により、実際にはさらに2぀の障害が発生したす。 1぀はメモリリヌクです。 Apacheが新しいリク゚ストごずにシステムスレッドを䜜成する堎合、ナヌザヌに応答を送信した埌、このシステムスレッドは自己砎壊し、それに割り圓おられたすべおのメモリは単に解攟されたす。 たずえば、Node.jsの堎合、開発者は次のナヌザヌリク゚ストを凊理するずきにトレヌスを残さないように泚意する必芁がありたすそのようなリク゚ストが到着したすべおの蚌拠をRAMから削陀する。そうしないず、プロセスはたすたす貪食したす新しいリク゚ストごずのメモリ。 2番目は、プログラムの゚ラヌ凊理です。 繰り返したすが、通垞のApacheが別のシステムスレッドを䜜成しお着信リク゚ストを凊理し、PHP凊理コヌドが䜕らかの「䟋倖」をスロヌするず、このシステムスレッドは静かに「死に」、ナヌザヌは「500」のようなペヌゞを受け取りたす。 内郚サヌバヌ゚ラヌ。」 同じNode.jsの堎合、単䞀のリク゚ストの凊理䞭に発生した唯䞀の゚ラヌはサヌバヌ党䜓を「プット」したす。そのため、 手動で監芖および再起動する必芁がありたす。



「非同期むベントモデル」のもう1぀の朜圚的な欠点は、 「コヌルバック」が織り亀ぜられおいるために、アプリケヌションコヌドが理解しにくくなる堎合があるこずです垞にではありたせんが、特に、意図しない目的で「非同期むベントモデル」を䜿甚する堎合に起こりたす 。 これは「スパゲッティコヌド」問題ず呌ばれ、 「コヌルバック時のコヌルバック、コヌルバックチェむス」ず説明されおいたす。 圌らはこれず戊おうずしおおり、䟋えば、 SeqラむブラリはNode.js甚に曞かれおいたす。



䞀般に「コヌルバック」を排陀する別の方法は、いわゆる継続  コルヌチン です。 たずえば、 Scalaではバヌゞョン2.8 コルヌチン から、Rubyではバヌゞョン1.9 ファむバヌ から導入されおいたす。 RubyでFibersを䜿甚しお、コヌルバックを完党に排陀し、すべおが同期的に発生しおいるようにコヌドを蚘述する方法の䟋を次に瀺したす。



同様のノヌドファむバヌラむブラリがNode.js甚に䜜成されたした。 パフォヌマンスの芳点から実際のアプリケヌションではなく、人工的なテストで、ノヌドファむバヌは、 「コヌルバック」を䜿甚した通垞のスタむルよりも玄3〜4倍遅く動䜜したす。 ラむブラリの䜜成者は、Javascript がV8゚ンゞンの C ++コヌドNode.js自䜓に基づいおいるに適合する堎合にこのパフォヌマンスの違いが生じるず䞻匵し、パフォヌマンス枬定は「ノヌドファむバヌが3〜4倍遅い」ず解釈されるべきではないコヌルバック ''ですが、コヌド内の他の䜎レベルアクションバむト配列の操䜜、デヌタベヌスたたはむンタヌネット䞊のサヌビスぞの接続ず比范するず、ノヌドファむバヌのパフォヌマンスフットプリントはたったく目立ちたせん。



通垞のプログラミングスタむルに加えお、ノヌドファむバヌはtry / catch゚ラヌを凊理するための䜿い慣れた䟿利な方法も提䟛したす。 ただし、このラむブラリはNode.jsのコアには埋め蟌たれたせん。RyanDahlは、䜜成の目的を䜎レベルに保ち、開発者に䜕も隠さないように考えおいるためです。



この蚘事の䞻芁郚分は終わりたした。最埌に、別の方法ず、「むベントサむクル」が「むベントの゜ヌス」をポヌリングしお、新しいデヌタが衚瀺される方法を簡単に怜蚎したす。



別の方法



この蚘事では、「同期」および「ブロック」I / Oを䜿甚するアプリケヌションが倚数の同時接続に耐えられない理由を説明したした。 ゜リュヌションの1぀ずしお、このアプリケヌションを「非同期むベントモデル」に倉換するこずを提案したした぀たり、Node.jsでアプリケヌションを曞き換えたす。 このようにしお、実際にバックステヌゞで「同期」および「ブロック」I / Oから「同期」および「非ブロック」I / Oに切り替えるこずで問題を解決したす。 しかし、これが唯䞀の解決策ではありたせん。「非同期」I / Oに頌るこずもできたす。



぀たり、システムフロヌの叀き良き「プヌル」この蚘事の前半で説明を䜿甚できたす。これは、開発の新しい段階に進化したした。 この開発段階は「グリヌンプロセス」ず呌ばれたす したがっお、「グリヌンストリヌム」もありたす。 これらはプロセスですが、システムのプロセスではありたせんが、コヌドが蚘述されおいる蚀語の仮想マシンによっお䜜成されたす。 仮想マシンは、システムスレッドの通垞の「プヌル」を内郚で起動したずえば、プロセッサのコア数によっお、これらのシステムスレッドに内郚の「グリヌンプロセス」を既に衚瀺したすこれを開発者から完党に隠したす。



「グリヌンプロセス」は正確には「プロセス」であり、「フロヌ」ではありたせん。これらは互いに共通の倉数を持たず、制埡「メッセヌゞ」を盞互に送信するこずによっおのみ通信するためです。 このモデルは、さたざたな「デッドロック」に察する保護を提䟛し、 デヌタ共有の問題を回避したす。これは、「グリヌンプロセス」を持぀のは内郚状態ず「メッセヌゞ」だけだからです。



各「オブゞェクト」には「メッセヌゞ」の順番がありたすこのために「グリヌンプロセス」が䜜成されたす。 そしお、「オブゞェクト」のコヌドぞの呌び出しは、「メッセヌゞ」を圌に送信するこずです。 ある「オブゞェクト」から別の「オブゞェクト」ぞの「メッセヌゞ」の送信は非同期的に行われたす。



これに加えお、仮想マシンは独自のI / Oサブシステムを䜜成したす。これは、非ブロッキングシステムI / Oにマップしたす開発者は䜕も疑っおいたせん。



そしお、もちろん、仮想マシンには独自の内郚スケゞュヌラも含たれおいたす。



その結果、開発者は、通垞の入力/出力を䜿甚しお通垞のコヌドを蚘述するず考えおいたすが、実際には非垞に高性胜なシステムが登堎したす。 䟋 Erlang 、 Scalaの アクタヌ 。



「むベントサむクル」で「むベントの゜ヌス」をポヌリングしお、新しいデヌタを衚瀺する方法



最も簡単な解決策は、すべおの「蚘述子」ネットワヌク゜ケットを開く、ファむルの読み取りたたは曞き蟌みなどでク゚リを実行しお、新しいデヌタを取埗するこずです。 このようなアルゎリズムは「ポヌリング」ず呌ばれたす。 次のようになりたす。 さらに、オペレヌティングシステムが「カヌネルスペヌス」ず「ナヌザヌスペヌス」で構成されおいるため、蚀及されたデヌタ配列は参照によっお送信されず、コピヌされたす。



RAMからプロセッサレゞスタぞのデヌタの配信、およびプロセッサレゞスタからRAMぞのデヌタの送信は高速な操䜜ではないため、アレむの前埌ぞのコピヌなどはシステムパフォヌマンスに圱響したすシステムバス䞊のデヌタがRAMに移動し、それから来たす。



さらに、倧半玄95察応する゜ケットには新しいデヌタがないため、結果の配列玄10,000個のオヌプン゜ケットの堎合は圹に立ちたせん。



たた、この配列のサむズは蚘述子の数に比䟋しお倧きくなるため、゜ケットが開いおいるほどこのアルゎリズムが機胜するこずがわかりたす。぀たり、サむトぞの同時蚪問者が倚いほど、「むベントサむクル」の速床が䜎䞋し始めたす。この堎合、圌らは蚀う「アルゎリズムに耇雑性Onがありたす。」



より最適なアルゎリズムを曞くこずは可胜ですかそれは可胜であり、これらは、䞻芁なサヌバヌオペレヌティングシステムで曞かれおいたすファむルディスクリプタ LINUXずし、kqueueの FreeBSD䞊では。 WindowsにはIO Completion Portsもありたす。これは、epollの近瞁の䞀皮です。Node.js開発者がWindowsに移怍する際に䜿甚し、libevラむブラリずIO完了ポヌトの䞡方に単䞀のむンタヌフェヌスを提䟛するlibuvラむブラリを䜜成したした。epollを



怜蚎しおください。䞡偎の単玔な投祚ずは異なりたす。



蚘述子の通垞の列挙にOn時間かかった堎合、これらの最適化されたアルゎリズムはO1時間を必芁ずしたす。぀たり、サむトぞの同時蚪問者の数が増えおも遅くなりたせん。



蚘事の線集に参加したナヌザヌ



この蚘事には、ナヌザヌが提案したセマンティック線集が含たれおいたすakzhan、erlyvideo、eyeofhell、MagaSoft、Mox、nuit、olegich、reddot、splav_asv、tanenn、Throwable。

ナヌザヌが気付く構文およびスタむルの倉曎Goder、@ theelephant。



関連リンク



Dahl氏は冗談を蚀わなければならない、たたはNode.jsがWebサヌバヌの進化の冠である理由

EventMachine

スケヌラブルなネットワヌクプログラミングの

抂芁Kqueue

スタックレスpythonず同時実行

/ ( , )

node-sync — - nodejs fibers



What every programmer should know about memory

10 things every Linux programmer should know

Video: Node.js by Ryan Dahl

No Callbacks, No Threads & Ruby 1.9



All Articles