MS_C10kProblem - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
- æ»ãïŒãã®ä»ãéçºã®è²ã ïŒ
ãC10K åé¡ãïŒã¯ã©ã€ã¢ã³ã 1 äžå°åé¡ïŒãšã¯ãããŒããŠã§ã¢ã®æ§èœäžã¯åé¡ããªããŠãã
ããŸãã«ãã¯ã©ã€ã¢ã³ãã®æ°ãå€ããªããšå¹çãæªåããµãŒãããã³ã¯ããåé¡ã®ããšã
- ã¹ã¬ãããªã©ã®ãªãœãŒã¹ã倧éã«æ¶è²»ããŠããŸãã
- æè¿ã¯ããC10M åé¡ãïŒã¯ã©ã€ã¢ã³ã 1,000 äžå°åé¡ïŒãªã©ãåºãŠæ¥ãŠããã
è£è¶³ïŒãªãã¹ã¬ãããæ¶è²»ãããšç Žç¶»ããã®ãïŒ: åé¡ã®æ¬è³ªã
æ°åã§æŒãããŠãããšã以éã®è°è«ãçè§£ããããããã¹ã¬ãã 1 æ¬ãããã®ã³ã¹ãã ã»ã¹ã¿ãã¯é å âŠ ãæ¢å® 1MBãïŒWindows / .NETïŒâ ã»ã«ãŒãã« ãªããžã§ã¯ã âŠ æ° KB ã»ã³ã³ããã¹ã ã¹ã€ãã âŠ æ° ÎŒsïŒåãæ¿ãã®ãã³ïŒ ã1 æ¥ç¶ = 1 ã¹ã¬ããã ãšã 10,000 æ¥ç¶ à 1MB = ã10GB ã®ã¹ã¿ãã¯ã â ã¡ã¢ãªãè¶³ããŠãããã¹ã±ãžã¥ãŒã©ãåããªãã â ã³ã³ããã¹ã ã¹ã€ããã ãã§ CPU ãé£ã朰ã âã1 æ¥ç¶ = 1 ã¹ã¬ãããæç«ããŠããæä»£ã ã»åææ¥ç¶ãæ°çŸçšåºŠ ã»æ¥ç¶ã¯ãçåœãïŒãªã¯ãšã¹ã â ã¬ã¹ãã³ã¹ â åæïŒ ãæç«ããªããªã£ãçç±ã ã»Keep-AliveããWebSocketãSSEãïŒ æ¥ç¶ãé·æéå± åº§ã â ã»Ajax / SPA ã«ãã现ããéä¿¡ã®å¢å ã»IoTãã¢ãã€ã«ã®åžžææ¥ç¶ãC10Mããžã®èšåãç確ã§ã
çŸåšã¯ã«ãŒãã«ãè¿åããææ³ïŒDPDKãio_uringãeBPFãXDPïŒãŸã§
è°è«ãé²ãã§ããããã ããæ¥åã·ã¹ãã ã§å¿ èŠã«ãªãããšã¯çšã§ããã
- nginxïŒãšã³ãžã³ãšãã¯ã¹ïŒ
- Node.jsïŒããŒããžã§ã€ãšã¹ïŒ
ãµãŒããµã€ã JavaScript ã® Node.js ã¯ãã³ããããã³ã° I/O ãšããã¢ãã«ã«ããã
ã€ãã³ãã«ãŒããæ¢ããŠããŸããããªããããã³ã°ãåé¿ããC10K åé¡ã«å¯Ÿå¿ããã
- Unix ç³» OS åãã®éåæ I/O ç°å¢(epoll/kqueue/event port)ã䜿çšãã
ãlibevãã©ã€ãã©ãªã䜿çšããŠããã - Windows åãã®éåæ I/O ç°å¢(IOCP : Input/output completion port)ã䜿çšãã
ãlibuvããéçºããã - çŸåšãlibeio / libev ã«ä»£ãã£ãŠ libuv ããNode.js ã®ã³ã¢ãšããŠçœ®ãæããã€ã€ããã
è£è¶³ïŒãã®èšè¿°ã¯æ£ç¢ºãçŸåšã¯çœ®ãæããå®äºããŠããïŒ: ã眮ãæãã
ã€ã€ããããšæžãããŠãããã
libuv ãžã®çµ±äžã¯ 2012 幎é ã«å®äºããŠããïŒNode.js 0.9 以éïŒããlibuv ãæœè±¡åããŠãããã®ãâ ã¢ããªã®ã³ãŒãïŒNode.jsïŒ â libuv ã OS å·®ãåžåãã Linux â epoll macOS â kqueue Solaris â event ports Windows â ãIOCPãããã§éèŠãªã®ã¯ãWindows ã ãæ¹åŒãéãç¹ã§ããã
ãepoll / kqueueïŒUnix ç³»ïŒãââ ãæºåå®äºéç¥ãå ãèªããç¶æ ã«ãªã£ãããšã ãæããŠããã â éç¥ãåããŠããããèªåã§ read ããã â Readiness-based ãIOCPïŒWindowsïŒãââ ãå®äºéç¥ãå â ãèªã¿çµãã£ããããŒã¿ã¯ããããšæããŠããã â OS ããã«ãŒãã«åŽã§èªã¿èŸŒã¿ãŸã§æžãŸããã â Completion-basedãã®éã㯠.NET ã§ãéèŠã§ããã
ã».NET ã®éåæ I/O ã¯ãWindows ã§ã¯ãIOCP ã䜿ãã â ThreadPool ã®ãI/O å®äºããŒã ã¹ã¬ãããããã ã»Linux ã§ã¯ epoll ããŒã¹ïŒ.NET Core 以éïŒ ã»ãã©ã¡ãã§ã async/await ã®ã³ãŒãã¯åããâ â libuv ãšåãããã©ã³ã¿ã€ã ãå·®ãåžåããŠãããªããLinux ã§ãè¿å¹Ž
io_uringïŒå®äºéç¥åïŒãç»å ŽããŠããã
IOCP ã«è¿ãæ¹åŒãžåæãã€ã€ããã
UI ãµãã·ã¹ãã ã®ã¡ãã»ãŒãžã«ãŒããšåãæå³ã§å©çšãããçšèªã ãã
Web ãµãŒããŒã«é¢ããã³ã³ããã¹ãã§ã¯ãC10k ã«å¯Ÿå¿ããã¢ãŒããã¯ãã£çšèªãšããŠäœ¿çšãããã
-
æ¹åŒ
ã·ã³ã°ã«ã¹ã¬ããã§ã«ãŒãåŠçãåãã- ãã¥ãŒã«æºãŸã£ãã€ãã³ããåŠçããŠããæ¹åŒã
- ãªã¯ãšã¹ããïŒã€ã®ã¹ã¬ããã§åãåãããšãã§ããã
-
ç¹åŸŽ
- ã¹ã¬ãããªã©ã®ãªãœãŒã¹æ¶è²»ãå°ãªããŠæžãã
-
åé¡
- ã€ãã³ãã«ãŒãã¯ãææãããããã³ããªãšã³ããã£ãã»ãã«ãã¿ã¹ã¯ OS ã®ããã«ã
ã©ããã§ããããã³ã°ãçºçãããšãã€ãã³ãã«ãŒãå šäœãã¹ãããããŠããŸãã - ãã®ãã€ãã³ãã«ãŒããã®åé¡ã解決ããã®ãããã³ããããã³ã° I/Oããããã
- ã€ãã³ãã«ãŒãã¯ãææãããããã³ããªãšã³ããã£ãã»ãã«ãã¿ã¹ã¯ OS ã®ããã«ã
è£è¶³ïŒãã³ããªãšã³ããã£ãã»ãã«ãã¿ã¹ã¯ ãšã®å¯Ÿæ¯ãç§éžïŒ: ãã®
ããšãã¯æ¬è³ªãçªããŠããã®ã§ãæç€ºçã«æŽçããŠããããå調çïŒãã³ããªãšã³ããã£ãïŒãã«ãã¿ã¹ã¯ã ã»åã¿ã¹ã¯ããèªçºçã«å¶åŸ¡ãè¿ãã ã»1 ã€ãè¿ããªããšãå šäœãæ¢ãŸãã â Windows 3.1 ã®æä»£ã®åé¡ ãã€ãã³ãã«ãŒãã ã»åã³ãŒã«ããã¯ããèªçºçã«å¶åŸ¡ãè¿ãã ã»1 ã€ãè¿ããªããšãå šäœãæ¢ãŸããâ åãæ§é â Node.js ã§éãåæåŠçãæžããšãå šãªã¯ãšã¹ããåŸ ãããã// Node.js ã§çµ¶å¯Ÿã«ãã£ãŠã¯ãããªãäŸ const data = fs.readFileSync('huge.csv'); // â åæ I/O // â ãã®éããä»ã®å šãªã¯ãšã¹ããæ¢ãŸããâ for (let i = 0; i < 1e10; i++) { /* CPU ãåã */ } // â ãããåæ§ãCPU ããŠã³ããªåŠçã¯ã€ãã³ãã«ãŒããå¡ãã察çïŒNode.jsïŒã ã»åæ API ã䜿ããªãïŒreadFileSync çïŒ ã»CPU ããŠã³ããªåŠçã¯ãWorker Threads / å¥ããã»ã¹ããžéãã.NET ã®å Žåã¯ãããéãã
ã.NETïŒASP.NET CoreïŒã ã»ã€ãã³ãã«ãŒã 1 æ¬ã§ã¯ãªããã¹ã¬ãã ããŒã«ãã§åŠçãã ã»1 ã€ã®èŠæ±ã CPU ãåããŠããä»ã®ã¹ã¬ãããåã â ãå šäœãæ¢ãŸãããšã¯ãªããâ ã»ãã ããã¹ã¬ãã ããŒã«ãæ¯æžãããšé ããªãïŒåŸè¿°ïŒ â ã.NET 㯠Node.js ããå£ãã«ãããã æ¯æžã®ããããåããã«ããããšãèšãã
-
ç°¡åã«ãããããã³ã°ã鲿¢ããããšã§ã€ãã³ãã«ãŒãã®åæ¢ã鲿¢ããã
-
ä»çµã¿ãšããŠã¯ããã£ããã
- ã¯ãŒã«ãŒã¹ã¬ããããŒã«ãš I/O åŠçãããŸãå調ããŠåãã
- ã¹ã¬ãããç¯çŽããŠåäœããŠããã¯ã©ã€ã¢ã³ãã«åŠçå®äºåŸã®ã³ãŒã«ããã¯ãè¿ãã
ãšãããéåžžã«åªããæ¹æ³ã§ãããããã
-
.NET ã®ãasync/awaitãã¯ãâãã®ãã€ãã³ãã«ãŒãã
ãã³ããããã³ã° I/O ã§åäœããã
è£è¶³ïŒ
async/awaitãšã®é¢ä¿ ââ ãããæ¬ããŒãžã®æ žå¿ïŒ: ãâãã®ã
ã€ãã³ãã«ãŒãããã³ããããã³ã° I/O ã§åäœããããšããææã¯
æ¹åãšããŠæ£ããããéèŠãªéããããã®ã§æç¢ºã«ããŠããããå ±éããæ¬è³ªãâ ãI/O ãåŸ ã£ãŠããéãã¹ã¬ãããå æããªãã â åŸ ã¡æéäžã«ã¹ã¬ãããä»ã®ä»äºã«åãã â ãå°ãªãã¹ã¬ããã§å€æ°ã®æ¥ç¶ãæãããïŒ C10K ãžã®åç ãéãã Node.js ⊠ãã·ã³ã°ã« ã¹ã¬ãããã®ã€ãã³ãã«ãŒã .NET ⊠ãã¹ã¬ãã ããŒã«ãïŒ I/O å®äºããŒã â è€æ°ã¹ã¬ããã§äžŠè¡ã«åŠçãã// async/await ããåŸ ããªããä»çµã¿ public async Task<IActionResult> Get(int id) { var order = await _db.Orders.FindAsync(id); // â ããã§ã¹ã¬ããããè¿ããâ // DB ãå¿çãããŸã§ã®éããã®ã¹ã¬ããã¯å¥ã®èŠæ±ãåŠçã§ãã return Ok(order); // â å®äºåŸã«åéïŒå¥ã¹ã¬ããããïŒ }
async/awaitã䜿ã£ãŠãéããªããªãç¹ã¯èª€è§£ãå€ãããasync/await ãæ¹åãããã®ã ã»ãã¹ã«ãŒããããïŒåæã«æããèŠæ±æ°ïŒâ ã»ã¹ã¬ããæ°ã»ã¡ã¢ãªæ¶è²» ãæ¹åããªããã®ã ã»ãåã ã®èŠæ±ã®ã¬ã€ãã³ã·ãïŒãããå ãã«å¢ããïŒ ã»CPU ããŠã³ããªåŠçã®é床åæãšéåæãæ··ãããšææªã«ãªãââãããå®åã§æãéèŠã§ããã
// â 絶察ã«ãã£ãŠã¯ãããªãïŒSync over AsyncïŒâ var order = _service.GetOrderAsync(id).Result; // ããããã㯠/ ã¹ã¬ããæ¯æž _service.DoSomethingAsync().Wait(); // â async voidïŒäŸå€ãææã§ããªããã€ãã³ã ãã³ãã©ä»¥å€ã§äœ¿ããªãïŒ public async void DoWork() { } // â æåŸãŸã§éåæã§éãïŒasync all the wayïŒ var order = await _service.GetOrderAsync(id);ãã¹ã¬ãã ããŒã«æ¯æžïŒThread Pool StarvationïŒãâ ã».Result / .Wait() ã§ã¹ã¬ãããå¡ã ã»â ããŒã«ã®ã¹ã¬ãããè¶³ããªããªã ã»â .NET ã¯ã1 ç§ã« 1ïœ2 æ¬ããå¢ãããªãã ã»â å¿çæéããçªç¶ãéæ®µç¶ã«æªåããã ã»â è² è·ãäžãããšå埩ããïŒåå ãåããã«ããïŒ ãæ€ç¥ã ã»dotnet-counters ã§ ThreadPool Queue Length ãèŠã ã»ThreadPool.GetAvailableThreads
-
C10k problem - Wikipedia
https://en.wikipedia.org/wiki/C10k_problem -
Web2.0ã®å ã«ããC10Kåé¡ ïŒ ïŒ IT
https://atmarkit.itmedia.co.jp/news/analysis/200701/09/c10k.html -
TheC10kProblem
ãC10K åé¡ãïŒã¯ã©ã€ã¢ã³ã 1 äžå°åé¡ïŒãšã¯ãããŒããŠã§ã¢ã®æ§èœäžã¯åé¡ããªããŠãã
ããŸãã«ãã¯ã©ã€ã¢ã³ãã®æ°ãå€ããªããšãµãŒãããã³ã¯ããåé¡ã®ããš
https://www.hyuki.com/yukiwiki/wiki.cgi?TheC10kProblem
-
ã€ãã³ãã«ãŒã - Wikipedia
https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%83%AB%E3%83%BC%E3%83%97 -
ã€ãã³ãã«ãŒããªãã§ã®ãã€ããã©ãŒãã³ã¹
C10Kåé¡ãžã®Goã®åç | ããã°ã©ãã³ã° | POSTD
https://postd.cc/performance-without-the-event-loop/
- ãã³ããããã³ã°I/OãšéåæI/Oã®éããçè§£ãã â PAYFORWARD
http://blog.takanabe.tokyo/2015/03/26/240/
è£è¶³ïŒçšèªã®æŽç ââ åèãªã³ã¯ã®äž»é¡ïŒ: ããã³ããããã³ã° I/Oããš
ãéåæ I/Oãã¯å³å¯ã«ã¯å¥ãªã®ã§ãæŽçããŠããã
çšèª æå³ ããããã³ã° I/O å®äºãããŸã§åŒã³åºããè¿ããªã ãã³ããããã³ã° I/O ããè¿ãããããŸã æºåã§ããŠããªãããšè¿ã â èªåã§ããŒãªã³ã°ãã I/O å€éå è€æ°ã® fd ããŸãšããŠç£èŠïŒselect / poll / epoll / kqueueïŒ éåæ I/OïŒAIOïŒ å®äºãããéç¥ãããïŒIOCPãio_uringïŒâ ãNode.js ãããã³ããããã³ã° I/OããšåŒã°ããçç±ã æ£ç¢ºã«ã¯ãI/O å€éå + ã€ãã³ãéç¥ãã§ãã â Unix ç³»ã§ã¯ epollïŒæºåå®äºéç¥ïŒ â Windows ã§ã¯ IOCPïŒå®äºéç¥ïŒ çã®éåæ I/OïŒ ã.NET ã® async/awaitã Windows ã§ã¯ãIOCPïŒ çã®éåæ I/Oãâ Linux ã§ã¯ epoll ããŒã¹ â å©çšè ããèŠã广ïŒã¹ã¬ãããå¡ããªãïŒã¯åãã ãã ä»çµã¿ã®å±€ãéã
nginxãšNode.js
-
Node.js ã5åã§å€§éæã«çè§£ãã - Qiita
https://qiita.com/hshimo/items/1ecb7ed1b567aacbe559 -
Node.jsã«ã€ããŠèª¿ã¹ãŠã¿ã - Qiita
https://qiita.com/kyrieleison/items/f726061803a0e536c3e1 -
node.jsã®ä»çµã¿ïŒãã³ããããã³ã°I/Oãšãã¹ã¬ãããšãïŒ - å ãªã¢å ãšã³ãžãã¢ã®ã¡ã¢
https://satoshun00.hatenadiary.com/entry/2012/08/02/172936 -
泚ç®ã®ãµãŒããµã€ãJavaScriptå®è¡ç°å¢ãNode.jsã | ææ°ã®æè¡ã»åãçµã¿ | IIJ
https://www.iij.ad.jp/company/development/tech/activities/nodejs/
-
éåæ I/O - Web/DB ããã°ã©ãã³ã°åŸ¹åºè§£èª¬
- (1/4)
http://keicode.com/windows/win03.php - (2/4) OVERLAPPED
http://keicode.com/windows/win04.php - (3/4) å®äºã«ãŒãã³
http://keicode.com/windows/win05.php - (4/4) I/O å®äºããŒã
http://keicode.com/windows/win06.php
- (1/4)
-
éåæ (Async) ããªãéèŠãªã®ã (.NET) â tsmatz
https://tsmatz.wordpress.com/2012/05/08/asp-net-mvc-async/ -
C#ã§éåæã«ããçç± ãâ²âå·ä¿£æ¶ã®çžåŽâãœãããŠã§ã¢âæè¡éèšã
http://mag.autumn.org/Content.modf?id=20130930175225 -
c# - When should I use Async Controllers in ASP.NET MVC? - Stack Overflow
https://stackoverflow.com/questions/30566848/when-should-i-use-async-controllers-in-asp-net-mvc
è£è¶³ïŒçŸåšã® .NET ã«ããã C10KïŒ: çµè«ãšããŠã
çŸåšã® ASP.NET Core ã§ã¯ C10K ã¯åé¡ã«ãªããªãããASP.NET CoreïŒKestrelïŒã ã»æåãããéåæ I/O åæãã§èšèšãããŠãã ã»ã¹ã¬ãã ããŒã« + IOCP / epoll ã»1 å°ã§ãæ°äžïœæ°åäžæ¥ç¶ããæ±ãã â TechEmpower ã®ãã³ãããŒã¯ã§ãäžäœã«äœçœ®ãã ã[ASP.NET Web Forms](MS_ASPNETWebForms) / æ§ ASP.NET ãšã®éãã ã»æ§æ¥ã¯åæåŠçãæ¢å® ã»[éšåæç»ãšJavaScript](MS_PartialRenderingAndJavaScript) ã®æä»£ã¯ æ¥ç¶ãçåœã ã£ãçŸåšãåææ¥ç¶æ°ã§åé¡ã«ãªãã®ã¯ããã以äžã§ããã
â ãã¹ã¬ãã ããŒã«æ¯æžãïŒåè¿°ïŒ â åæåŒã³åºãã 1 ç®æããã ãã§çºçãã â â¡ ãDB ã®ã³ãã¯ã·ã§ã³ ããŒã«æ¯æžã â ã¢ããªã¯éåæã§ããDB æ¥ç¶æ°ã«ã¯äžéããã â SQL Server ã®æ¢å®ã¯ 100 â ãã¢ããªã¯æããã DB ã§è©°ãŸããâ çŸåšã®å žåçãªããã«ãã㯠⢠ãå€éš API åŒã³åºãã® HttpClient ã®äœ¿ãæ¹ã â using ã§æ¯å new ãããšããœã±ããæ¯æžãïŒTIME_WAITïŒ â IHttpClientFactory ã䜿ã ⣠WebSocket / SignalR ã®æ¥ç¶ãããã®ã¡ã¢ãª â æ¥ç¶ããšã«ç¶æ ãæã€èšèšã¯èŠæ³šæ ïŒ[WebAssembly](MS_WebAssembly) ã® Blazor Server ã®é ãåç §ïŒãã€ãŸãã C10K åé¡ãã®ãã®ã¯ãã©ã³ã¿ã€ã ã解決ããã çŸåšã¯ããã®å ã®è³æºïŒDB æ¥ç¶ããœã±ãããã¡ã¢ãªïŒãã ããã«ããã¯ã«ãªã â
Tags: ç§»è¡, ã€ã³ãã©ã¹ãã©ã¯ãã£, Windows, ããã°ã©ãã³ã°, .NETéçº