
- TOP
- ã¿ã°äžèЧ
- Kubernetes
Kubernetes
ã€ãã³ã
該åœããã³ã³ãã³ããèŠã€ãããŸããã§ãã
ãã¬ãžã³
æè¡ããã°
ã¯ã©ãŠããã©ãããã©ãŒã ããŒã ã®é«éã§ãããã€ã¯ããµãŒãã¹ãã©ãããã©ãŒã ã®éçšã»æ¹åãæ
åœããŠããŸãã myTOKYOGASã®ãã€ã¯ããµãŒãã¹åã«ã€ããŠã¯ã以äžã®èšäºãåç
§ããŠãã ããã tech-blog.tokyo-gas.co.jp 2024幎11æã1ã€ç®ã®ãã€ã¯ããµãŒãã¹ããªãªãŒã¹ããŸãããåœæã¯ã³ã³ãããªãŒã±ã¹ãã¬ãŒã·ã§ã³ãµãŒãã¹ãšã㊠Amazon EKS ãæ¡çšããŠããŸããããã®1幎åŸã®2025幎11æãEKS ãã Amazon ECS / AWS Fargate ãžãšç§»è¡ããŸããã æ¬èšäºã§ã¯ãç§»è¡ã®èæ¯ãç§»è¡åŸã®æ§æãç§»è¡ã®ææã«ã€ããŠç޹ä»ããŸãã ç§»è¡ã®èæ¯ 2024幎11æã«1ã€ç®ã®ãã€ã¯ããµãŒãã¹ããªãªãŒã¹ãããã€ã¯ããµãŒãã¹ãã©ãããã©ãŒã ã®æ¬çªéçšãå§ãŸããŸããããããŠå幎ã»ã©ãçµã¡ãEKSã®èšèšã»æ§ç¯ã»éçšããªãŒãããŠããKubernetesã®æèè
ã瀟å
ç°åã§ããŒã ãé¢ããããšã«ãªããç§ãåŒãç¶ãããšã«ãªããŸããã ãã®æã以äžã®ç¶æ³ã§ããã ãã€ã¯ããµãŒãã¹ãã©ãããã©ãŒã ã®éçšã¡ã³ããŒã¯ãç§ãå«ããŠ2å Kubernetesã®éçšçµéšã¯ãç§ã¯ã»ãŒãªãããã1åã¯çµéšãã ããŒã ã®åœ¹å²ã¯ãã€ã³ãã©ã®éçšã»ä¿å®ããã©ãããã©ãŒã ã®æ¹åããœãããŠã§ã¢ãšã³ãžãã¢ããã®äŸé Œå¯Ÿå¿ãSREã®æšé²ãªã©å€å²ã«ããã ã¡ã³ããŒã®å¢å¡èšç»ã¯ãã£ããã®ã®ã人æäžè¶³ã¯åŠããŸããã§ãããç¹ã«ã以äžã®ç¹ã§EKSã¯ã©ã¹ã¿ãŒã®éçšã«èª²é¡ãæããŠããŸããã 1. 宿çãªããŒãžã§ã³ã¢ããã®äœæ¥è² è·ã倧ãã EKS ã¯åããŒãžã§ã³ã®ãµããŒãæéã 14 ã¶æã®ããã幎㫠1 åçšåºŠã¯ã¯ã©ã¹ã¿ãŒã®ããŒãžã§ã³ã¢ãããå¿
èŠã§ãããŸããããŒãžã§ã³ã¢ããäœæ¥ã«ã¯ãªã¹ã¯ã䌎ããããååãªæºåæéã確ä¿ããå¿
èŠããããŸãã ããã«ãEKS ã¯ã©ã¹ã¿ãŒæ¬äœã ãã§ãªããEKSã¢ããªã³ãããŒãã® AMIãIstioãArgo CD ãªã©ã®ãšã³ã·ã¹ãã ãããŒãžã§ã³ã¢ããããŠããå¿
èŠããããŸãã å°äººæ°ã®ããŒã ã®ãããããŒãžã§ã³ã¢ãã察å¿äžã¯ä»ã®æ¥åãé²ãŸãªããªãããšãäºæ³ãããŸãããäžã§ãããœãããŠã§ã¢ãšã³ãžãã¢ããã®äŸé Œå¯Ÿå¿ãåŸåãã«ãªããéçºã®ãªãŒãã¿ã€ã ã«åœ±é¿ãåºãŠããŸãããšãæžå¿µããŠããŸããã 2. æ¥åžžçãªéçšè² è·ãé«ã ECS ãšæ¯èŒããŠãEKS ããã³ Kubernetes ã¯èšèšã»èšå®ã®èªç±åºŠãé«ãã§ããããã¯å©ç¹ã§ããããŸãããèšå®å€æŽæã®èª¿æ»ãæ€èšŒã«ãããã³ã¹ãã ECS ãã倧ãããšæããŠããŸãããAWS ãšã®çµ±åã«ãããŠããECS ã§ã¯ãããŒãžãã§å®çµããéšåããEKS ã§ã¯è¿œå ã®èšå®ãèæ
®ãå¿
èŠã«ãªãããšããããŸãã ãŸãããã¡ãã¯ç§ãã¡åŽã®äºæ
ã«ãªããŸãããåææ§ç¯æã¯å°æ¥ã®ã¹ã±ãŒã«ãæ¡åŒµæ§ãèŠæ®ããèšèšãå¿
èŠã§ãããåœæã®å€æãšããŠã¯åŠ¥åœã ã£ããšæããŸããäžæ¹ã§ãéçšãç¶ããäžã§ãçŸæç¹ã®èŠæš¡ãå°æ¥ã®èŠéãã«å¯ŸããŠãããéå°ãªæ§æã«ãªã£ãŠããããšãåãã£ãŠããŸããããããéçšã³ã¹ããæŒãäžããäžå ãšãªã£ãŠããŸããã å ããŠãEKS ããã³ Kubernetes 㯠ECS ãšæ¯ã¹ãŠçè§£ãã¹ããªãœãŒã¹ã®çš®é¡ãåºæã®æŠå¿µãå€ããåŠç¿ã³ã¹ãã®é«ãã課é¡ã§ãããçµéšããªãã£ãç§èªèº«ããã£ããã¢ããã«èŠåŽããŸããããä»åŸããŒã ãæ¡å€§ããéã«ãããã¯ã«ãªããšèããŠããŸããã ç§»è¡ã®æææ±ºå® ç§ã¯éå»ã« ECS / Fargate ãéçšããçµéšããããECS ãžã®ç§»è¡ãåè¿°ã®èª²é¡è§£æ±ºã«ãªããšèããŸãããECS 㯠EKS ãšæ¯èŒããŠã·ã³ãã«ã§åŠç¿ã³ã¹ããäœããFargate ãšçµã¿åãããããšã§éçšã³ã¹ããæããããšãã§ããŸãã EKS ã®ãŸãŸæ§æãèŠçŽããŠéçšè² è·ãäžããæ¡ãæ€èšããŸããããEKSã¯ã©ã¹ã¿ãŒã®ããŒãžã§ã³ã¢ããè² è·ãåŠç¿ã³ã¹ãã®é«ãã¯åŒãç¶ãæ®ããŸãããã®ãããç§»è¡ããæ¹ãæãŸãããšèããŸããã ç§»è¡ãæ¬æ Œçã«æ€èšããã«ããã£ãŠã¯ã以äžã®2ã€ã®ç¹ãæèããŸããã ECS / Fargate ã«ç§»è¡ããããšã§ãçŸæç¹ã§æäŸã§ããªããªãæ©èœã¯ãªãã ECS / Fargate ã«ç§»è¡ããããšã§ãå°æ¥çã«å°ãããšã¯ãªãã 1ç¹ç®ã«ã€ããŠã¯ãçŸæç¹ã§ EKS åºæã®æ©èœã«äŸåããŠãããã®ããªãããšãäž»ã«ããŒã å
ã§ç¢ºèªããŸããã2ç¹ç®ã«ã€ããŠã¯ããœãããŠã§ã¢ãšã³ãžãã¢ãªã³ã°ããŒã ã®ã¡ã³ããŒãšãªãŒããŒããããŠå
補éçºããŒã ã管æããã°ã«ãŒããããŒãžã£ãŒãšå¯Ÿè©±ãè¡ããŸããã éçºçµç¹ã¯ä»åŸã©ã®ããã«æé·ããŠããããã ãã€ã¯ããµãŒãã¹ã¯ã©ã®ãããã®ããŒã¹ã§å¢ããã©ããããã®èŠæš¡ã«ãªãããã EKS ããã³ Kubernetes ã§ãªããã°æºãããªãèŠä»¶ãããã®å
åºãŠãããã ãããã確èªããã³æ€èšããçµæãå°ãªããšãåœé¢ã®ç¯å²ã§ã¯ãECS/Fargateã§èŠä»¶ãæºãããèŠéããåŸãããŸããã ãã¡ãããå°æ¥çã« EKS ã®æ¹ããããããèŠä»¶ãåºãŠããå¯èœæ§ã¯ãããŸãããããçŸæç¹ã§ã¯ãä»ç§»è¡ããããšã§éçšã³ã¹ããäžããæ¹åæ¥åãã¢ããªã±ãŒã·ã§ã³éçºãžãªãœãŒã¹ãå
ãŠãããšãã§ããããããããã¯ã䟡å€åäžãšäºæ¥è²¢ç®ã®èгç¹ã§å¹æãé«ããšå€æããECS ãš Fargate ãžã®ç§»è¡ã決å®ããŸããã ãããžã§ã¯ãäœå¶ãšæé ãã€ã¯ããµãŒãã¹ãã©ãããã©ãŒã ã®éçºã»éçšã¡ã³ããŒ2åã«ããœãããŠã§ã¢ãšã³ãžãã¢ãªã³ã°ããŒã ãã1åãå ãããèš3åã®äœå¶ã§ãããžã§ã¯ããé²ããŸãããæ¢åç°å¢ã®éçšã䞊è¡ããŠãããããé¢ä¿è
éã§åªå
é äœããããã€ã€é²ããŸããã ãããžã§ã¯ãã®ç«ã¡äžãããæ¬çªç°å¢ã®ç§»è¡å®äºãŸã§ãçŽ4ã¶æã§ããããã€ã¯ããµãŒãã¹ãæ¬æ Œçã«å¢ãå§ããåã®ã¿ã€ãã³ã°ã ã£ããããæ¯èŒççæéã§ããªã¹ã¯ãå°ããç¶æ³äžã§ç§»è¡ãè¡ãããšãã§ããŸããã èšèš EKS ãã ECS ãžç§»è¡ããå®è¡ç°å¢ã«ã¯ Fargate ãæ¡çšããŸãããæ¥æ¬¡ã®ãããåŠçã¯ãAmazon EventBridgeãAWS Step FunctionsãECS ãçµã¿åãããŠããŸãããããã€ã«ã¯ ecspresso ã䜿çšããŠããŸããéçšè² è·ã®åæžãç®çã«ããããŒãžããµãŒãã¹ãç©æ¥µçã«æŽ»çšããããšãæèããŸããã 以äžãç§»è¡åŸã®æ§æå³ã§ããECSã«é¢ããç®æã®ã¿ãèšèŒããŠããŸãã æ§æå³ ç§»è¡ã®ææ ç§»è¡ããå幎ãçµã¡ãåœåæåŸ
ããŠãã广ãåŸãããŠããããšã宿ããŠããŸããç¹ã«ãã¯ã©ã¹ã¿ãŒããšã³ã·ã¹ãã ã®ããŒãžã§ã³ã¢ãããäžèŠã«ãªã£ãããšã§ãã€ã³ãã©ä¿å®ã«å²ãæéã¯ã»ãŒãªããªããŸããã éçšè² è·ãäžãã£ãããšã§ãå°äººæ°äœå¶ã®ãŸãŸã§ãå®å®ããŠéçšã§ããããã«ãªããŸãããæ¥ã
ã®éçšã«è¿œããã«ãããªã£ãåãã³ã¹ãåæžã IaC ã®æšé²ãšãã£ãæ¹å掻åã«å ãããããã¯ãéçºã«ãè²¢ç®ã§ããããã«ãªã£ãŠããŸãã æåŸã« çŸæç¹ã§ã¯ ECS ãæé©ãšå€æããŸããããçµç¹ããããã¯ãã®æé·ãä»åŸã®èŠä»¶ã«åãããŠãç¶ç¶çã«èŠçŽããŠãããããšèããŠããŸãã æææ±ºå®ããç§»è¡å®äºãŸã§ã¹ããŒãã£ã«é²ããããã®ã¯ãå
補éçºãªãã§ã¯ã ãšæããŠããŸããä»åŸããçŽ æ©ãã客ããŸã«äŸ¡å€ãå±ãããããããæ¹åãç¶ããŠãããŸãã
technical howæ¬èšäºã¯ 2026 幎 5 æ 13 æ¥ ã«å
¬éãããã Sim-to-Real and Real-to-Sim: The Engine Behind Capable Physical AI ãã翻蚳ãããã®ã§ãã ã¯ããã« çŸå®äžçã§ç¥èŠã»æšè«ã»è¡åããããããããããã Physical AI ã·ã¹ãã ã®é²åãå éããŠããŸãããã®äžå¿ã«ããã®ã Sim-to-Real ãã€ãã©ã€ã³ã§ããããããå®éšå®€ã®å€ã§ãå®å®ããŠåäœããã¢ãã«ã®æ§ç¯ã¯ããã®åéã§æãé£ãã課é¡ã®äžã€ã§ããã·ãã¥ã¬ãŒã·ã§ã³ã§æ©èœãããã®ãšå®éã®ããŒããŠã§ã¢ã§æ©èœãããã®ã®éã«ããã®ã£ãããããå€ãã®ãããžã§ã¯ããè¡ãè©°ãŸãåå ã§ãã æ¬èšäºã§ã¯ãSim-to-Real (Sim2Real) ãš Real-to-Sim (Real2Sim) ããç©çç°å¢ã§åäœãã AI ã¢ãã«æ§ç¯ã«ãããŠæãéèŠãªæè¡ãšãªã£ãçç±ã解説ããŸããã·ãã¥ã¬ãŒã·ã§ã³ãšçŸå®ã®ã®ã£ããããªãåãŸãã«ããã®ããçŸä»£çãªã¢ãããŒãã§ã©ãå
æããã®ãããããŠãããã£ã¯ã¹ãããåŒãã Vision Language Action ã¢ãã« (VLA) ããã®ãã€ãã©ã€ã³ã®å質ã«å
šé¢çã«äŸåããŠããçç±ã«ã€ããŠã説æããŸãã å®äžçã®ããŒã¿ã ãã§ã¯ã¹ã±ãŒã«ããªãçç± ããããã«æäœã¿ã¹ã¯ãåŠç¿ãããã«ã¯ãç
§æã»ç©äœã®äœçœ®ã»è¡šé¢ãã¯ã¹ãã£ã»ã°ãªãããŒã®åããšãã£ãæ¡ä»¶ã暪æããŠæ±åããããã«ãéåžžæ°äžä»¶ã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ãå¿
èŠã§ããããã宿©ã§å®æœããã®ã¯æéãã³ã¹ãããããããªã¹ã¯ã䌎ããŸãã ãã®å¶çŽã¯ããããåéã«å
±éããŸããå庫ã®èªååã§ã¯éåžžãæ°åçš®é¡ã® SKU ããªãšãŒã·ã§ã³ãžã®å¯Ÿå¿ãå¿
èŠã§ããèªåé転è»ã¯éåžžãæ°çŸäžä»¶ã®èµ°è¡ã·ããªãªãå¿
èŠãšããŸããæè¡ããããã¯ãå®éã®æ£è
ã§å«ççã«ãªããŒãµã«ã§ããªãåŠçœ®ãæ±ããŸããå¿
èŠãªèŠæš¡ã§ã®ç©ççãªããŒã¿åéã¯ãçŸå®çã«äžå¯èœã§ãã ã·ãã¥ã¬ãŒã·ã§ã³ã¯ãã®èª²é¡ã«çŽæ¥å¯ŸåŠããŸããç©ççã«æ£ç¢ºãªä»®æ³ç°å¢ã§ã¯ãéåžžãã¯ããã«äœã³ã¹ãã§å®å
šãªç°å¢ããæ¡éãã®éãã§ãã¬ãŒãã³ã°ããŒã¿ãçæã§ããŸãããã ããçŽç²ã«ã·ãã¥ã¬ãŒã·ã§ã³ã§åŠç¿ããã¢ãã«ã¯ãåžžã«å€åãäºæž¬äžå¯èœãªç©çç°å¢ã§ã®åäœãšããæ§è³ªäžãå®äžçã«å±éãããšå€±æããã¡ã§ãããã®å€±æãã¿ãŒã³ã«ã¯ååããããŸããã·ãã¥ã¬ãŒã·ã§ã³ãšçŸå®ã®ã®ã£ãããããªãã¡ããªã¢ãªãã£ã®ã£ãããã§ãã ã·ãã¥ã¬ãŒã·ã§ã³ãšçŸå®ã®ã®ã£ãã ã·ãã¥ã¬ãŒã·ã§ã³ãšçŸå®ã®ã®ã£ãããšã¯ãã·ãã¥ã¬ãŒã·ã§ã³ã§åŠç¿ããã¢ãã«ã宿©ã«å±éãããšãã®æ§èœå·®ã®ããšã§ããã·ãã¥ã¬ãŒã·ã§ã³ã¯ãããŸã§è¿äŒŒã§ããããããã®ã®ã£ããã¯é¿ããããŸãããå®éã®ã«ã¡ã©ã¯ãã€ãºã»æªã¿ã»é²åºå€åããããããŸãããåæã¬ã³ããªã³ã°ã¯ããã©ã«ãã§ã¯ãããåçŸããŸãããå®éã®è¡šé¢ã«ã¯ãã©ã®ç©çãšã³ãžã³ãå®å
šã«ã¯ã¢ãã«åã§ããªãæ©æŠä¿æ°ããããŸããå®éã®ã¢ã¯ãã¥ãšãŒã¿ã«ã¯ããã¯ã©ãã·ã¥ã»é
å»¶ã»ç±ããªããããããŸããã¯ãªãŒã³ãªåæããŒã¿ã§åŠç¿ããã¢ãã«ã¯ã·ãã¥ã¬ãŒã·ã§ã³ã®å®å
šæ§ãå©çšããããšãèŠããŠããŸãããã®æåã¯çŸå®ã«ã¯è»¢çšã§ããŸããã ã®ã£ãããåããã«ã¯ãäºã€ã®è£å®çãªã¢ãããŒããå¿
èŠã§ãã ã·ãã¥ã¬ãŒã·ã§ã³ç²ŸåºŠã®åäž NVIDIA Isaac Sim ã®ãããªçŸä»£ã®ç©çã·ãã¥ã¬ãŒã¿ãŒã¯ãåäœãã€ããã¯ã¹ã»å€åœ¢å¯èœç©äœã»æµäœæåã»æ¥è§Šåããæ°å¹Žåã«ã¯å®çŸã§ããªãã£ãã¬ãã«ã®ç²ŸåºŠã§ã¢ãã«åããŸãããã¹ãã¬ãŒã·ã³ã°ãšç©çããŒã¹ãããªã¢ã«ãçšãããã©ããªã¢ãªã¹ãã£ãã¯ãªã¬ã³ããªã³ã°ã«ãããå®éã®ã«ã¡ã©æ åãšã®åºå¥ããŸããŸãé£ããèŠèŠå
¥åãçæãããŸãã Figure 1: Amazon EC2 G6e.4xlarge ã€ã³ã¹ã¿ã³ã¹äžã§åäœãã NVIDIA Isaac Sim ãã¡ã€ã³ã©ã³ãã åã åã«äžã€ã®ã·ãã¥ã¬ãŒã·ã§ã³ãå®å
šã«æ£ç¢ºã«ããã®ã§ã¯ãªãã倿°ã®ã©ã³ãã åãããããªãšãŒã·ã§ã³ã«ããã£ãŠåŠç¿ããŸããç
§æã»ãã¯ã¹ãã£ã»ç©äœã®è³ªéã»é¢ç¯æ©æŠã»ã»ã³ãµãŒãã€ãºãå€åãããããšã§ãå¹
åºãæ¡ä»¶ã®ååžã«å¯ŸããŠããã¹ããªããªã·ãŒãåŠç¿ããŸããéèŠãªã®ã¯ãçŽç²ãªããŒã¿éã§ã¯ãªããã·ãã¥ã¬ãŒã·ã§ã³ãã©ã¡ãŒã¿ã®ååãªå€æ§æ§ãšã«ãã¬ããžã§ããããã«ããããã¥ãŒã©ã«ãããã¯ãŒã¯ã¯å€æ§ãªç°å¢ã«ãããŠã察象ç©ã®ããŒãšãªãèŠçŽ ãèå¥ããããšãåŠç¿ããŸãã Figure 2: OpenAI ãå®èšŒãããã«ãŒããã¯ãã¥ãŒããè§£ãããããã(åºå
ž: OpenAI, https://openai.com/index/solving-rubiks-cube/) Real-to-Sim: ç©çäžçããã¬ãŒãã³ã°ã€ã³ãã©ã«å€ãã Real-to-Sim ãšã¯ãçŸå®ã®ç°å¢ããã£ããã£ããŠã·ãã¥ã¬ãŒã·ã§ã³å¯Ÿå¿ã®ããžã¿ã«è¡šçŸã«å€æããããã»ã¹ã§ããSim2Real ãåŠç¿æžã¿ããªã·ãŒã宿©ã«è»¢çšããããšãç®çãšãããªããReal2Sim ã¯ãã®ã·ãã¥ã¬ãŒã·ã§ã³ãããŒããŠã§ã¢ã®å®éã®åäœç°å¢ãåæ ããããšãä¿èšŒããããã®ãã®ã§ãã 䜿çšãããæè¡ã¯è€æ°ã®åéã«ãŸããããŸããLiDAR ã¹ãã£ã³ãšãã©ãã°ã©ã¡ããªãŒã¯ã3D ã¡ãã·ã¥ã«åŠçã§ããç¹çŸ€ãçæããŸãã Neural Radiance Fields (NeRF) ãš 3D Gaussian Splatting ã¯ãéåžžã®ã«ã¡ã©æ åããã·ãŒã³ã®ãžãªã¡ããªãšå€èгãåæ§ç¯ããç©çã·ãã¥ã¬ãŒã·ã§ã³ç°å¢ã«çŽæ¥åã蟌ããã¢ã»ãããçæããŸããããã¯ãªã¢ãªãã£ã®ã£ãããããªãã¡ä»®æ³ã¢ã»ãããšç©çã¢ã»ããã®ã¢ãã«åã«ãããæ§èœå·®ã®è§£æ¶ã«åœ¹ç«ã¡ãŸãããããã®ã¢ã»ããã¯ã倿§ãªç
§ææ¡ä»¶ãã«ã¡ã©ã¢ã³ã°ã«ã«ããã£ãŠçŸå®ã®èŠãç®ã質æãä¿æããæè¡ãçšããŠä»®æ³äžçã«åã蟌ãŸããŸãã Physical AI ã®ãã¬ãŒãã³ã°ãã€ãã©ã€ã³ã«ãããŠãReal2Sim 㯠é éæäœã«ããããŒã¿åé ã§ç¹ã«éèŠãªåœ¹å²ãæãããŸãã人éã®ãªãã¬ãŒã¿ãŒããã¢ã³ã¹ãã¬ãŒã·ã§ã³ã€ã³ã¿ãŒãã§ãŒã¹ãéããŠç©ççãªããããã¢ãŒã ãæäœãããšãã·ã¹ãã ã¯ãã®åããã·ãã¥ã¬ãŒã·ã§ã³äžã®ããžã¿ã«ãã€ã³ã«åæã«ãã©ãŒãªã³ã°ããŸããããã«ããçŸå®äžçã§èšé²ããã人éå質ã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ããŒã¿ã»ãããšãåãã¿ã¹ã¯ã®è¿œå çãªåæããªãšãŒã·ã§ã³ãçæã§ããåææžã¿ã·ãã¥ã¬ãŒã·ã§ã³ãã¬ãŒã¹ãšããäºã€ã®ããŒã¿ãåæã«åŸãããŸããã Figure 3: SO-101 ã䜿ã£ããã¬ãªãã¬ãŒã·ã§ã³ ãã®ã¢ãããŒããå®çšçãªå éææ®µãšãªãã®ã¯ã æš¡å£åŠç¿ ã®äžå¿çãªããã«ããã¯ã«å¯ŸåŠããŠããããã§ããæš¡å£åŠç¿ãšã¯ãå ±é
¬ããŒã¹ã®è©Šè¡é¯èª€ã§ã¯ãªã人éã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã芳å¯ããããšã§ãããããåŠç¿ããæ çµã¿ã§ããé«å質ãªäººéã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã¯æš¡å£åŠç¿ãäŸåãããã¬ãŒãã³ã°ã·ã°ãã«ã§ãããReal2Sim ã€ã³ãã©ã掻çšããããšã§ãç©çããŒããŠã§ã¢ã®ã³ã¹ããæ¯äŸçã«å¢ããããšãªããã®ã·ã°ãã«ãã¹ã±ãŒã«ã§ããŸãã åæããŒã¿ã®çæãšãã£ã«ã¿ãªã³ã° å®äžçããã³ãã¬ãªãã¬ãŒã·ã§ã³ã§åéããããŒã¿ã¯ååžã«æ²¿ã£ãæåž«ä¿¡å·ãæäŸããŸããã€ãŸãããã¬ãŒãã³ã°ãµã³ãã«ãããããã®å±éæã«å®éã«çŽé¢ããæ¡ä»¶ (ç
§æã»ç©äœã®çš®é¡ã»ã«ã¡ã©ã¢ã³ã°ã«) ãåæ ããŠããŸããã·ãã¥ã¬ãŒã·ã§ã³ã¯ã¹ã±ãŒã«ãæäŸããŸããçŸä»£ã® Physical AI ãã¬ãŒãã³ã°ãã€ãã©ã€ã³ã¯ãã®äºã€ãçµã¿åãããŸãã åæããŒã¿çæãšã¯ãã·ãã¥ã¬ãŒã·ã§ã³ç°å¢å
ã§ã©ãã«ä»ããã¬ãŒãã³ã°ãµã³ãã«ãããã°ã©ã çã«å€§èŠæš¡çæããããšã§ããæäœã¿ã¹ã¯ã§ã¯ãç°ãªãç©äœå§¿å¢ã»ç
§ææ¡ä»¶ã»ã°ãªãããŒæ§æã«ããã£ãŠææã·ããªãªã®æ°åããªãšãŒã·ã§ã³ãã¬ã³ããªã³ã°ããããããã«æ·±åºŠã»ã»ã°ã¡ã³ããŒã·ã§ã³ãã¹ã¯ã»ã¢ã¯ã·ã§ã³ã©ãã«ã®ã°ã©ãŠã³ããã¥ã«ãŒã¹ãèªåã¢ãããŒã·ã§ã³ããŸãã ããŒã¿éã ãã§ã¯äžååã§ãããã£ã«ã¿ãªã³ã°ãã€ãã©ã€ã³ã¯ãèªåå質ã¡ããªã¯ã¹ãšåŠç¿æžã¿èå¥åšã䜿ã£ãŠãååžå€ãŸãã¯ç©ççã«äžèªç¶ãªãµã³ãã«ããã¬ãŒãã³ã°ã»ããã«å
¥ãåã«é€å»ããŸããé©åã«æ§ç¯ããããã€ãã©ã€ã³ã®åºåã¯ãå®éã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã«ããç©ççãªæ ¹æ ãåæçæã®èŠæš¡ãããã³èªåãã£ã«ã¿ãªã³ã°ã«ããå質管çãåãããã¬ãŒãã³ã°ããŒã¿ã»ãããšãªããŸãã VLMã»VLA ãšãã·ãã¥ã¬ãŒã·ã§ã³å質ãã¢ãã«æ§èœã決ããçç± Physical AI ããŒã ãããããå¶åŸ¡ã®åºç€ã¬ã€ã€ãŒãšããŠæ³šç®ããŠããã¢ãã«ããVision Language Model (VLM) ãš Vision Language Action ã¢ãã« (VLA) ã§ãã VLM ã¯ãå€§èŠæš¡ãªç»åãšããã¹ãã®ã³ãŒãã¹ã§åŠç¿ãããã«ãã¢ãŒãã«åºç€ã¢ãã«ã§ããå¹
åºãèŠèŠççè§£ã§ãç»åå
ã®å
å®¹ãæšè«ãã空éçãªé¢ä¿ã説æããç©äœãèå¥ããèŠèŠçãªã³ã³ãã³ããåç
§ããèšèªæç€ºã«åŸãèœåãç²åŸããŸãã Amazon Bedrock äžã® Amazon Nova ãAnthropic ClaudeãQwenãMistral ãªã©ããã®ã¯ã©ã¹ã®äŸã§ããAmazon Bedrock ã¯ãåºç€ã€ã³ãã©ã管çããããšãªããããã®ã¢ãã«ã«ã¢ã¯ã»ã¹ããããã®ãããŒãžã API ã¬ã€ã€ãŒãæäŸããŸããããã¯ãç¬èªã®ã€ã³ãã©ã®è€éããæã€ Physical AI ãã€ãã©ã€ã³ã«èŠèŠçæšè«ãçµ±åããéã«éèŠã§ãã VLA ã¯ãVLMã®ãã©ãã€ã ãç©ççãªåäœãžãšæ¡åŒµãããã®ã§ããVLAã¯ãããã¹ããåºåããã®ã§ã¯ãªããèŠèŠçãªèгå¯ãšèšèªã«ããæç€ºã«å¿ããŠãããããã®åäœãé¢ç¯ã®äœçœ®ãé床æä»€ããšã³ããšãã§ã¯ã¿ã®è»éãªã©ãçæããŸããVLAã®ãã¬ãŒãã³ã°ç®æšã¯ãèŠèŠççè§£ãšç©ççãªå æé¢ä¿ã®äž¡æ¹ã«åºã¥ããæ¹éãåŠç¿ããããšã§ããã€ãŸãããèªåãèŠãŠãããã®ãšãèªåãããããã«æ±ããããŠããããšãèžãŸããŠãã©ã®ãããªè¡åããšãã¹ããïŒããåŠç¿ããŸãã ã·ãã¥ã¬ãŒã·ã§ã³ããŒã¿ã®å質ã¯ãVLAãæç€ºçã«åŠç¿ãããŠããªãã¿ã¹ã¯ã«å¯ŸããŠã©ãã ãããŸãæ±åã§ããããçŽæ¥å·Šå³ããŸããåŠç¿ã«äœ¿çšããèŠèŠãã¡ã€ã³ïŒåæã¬ã³ããªã³ã°ïŒãå±éãã¡ã€ã³ïŒçŸå®äžçïŒãšäžèŽããªãå ŽåãåŠç¿ãããããªã·ãŒã¯ç Žç¶»ããããã¡ãªãåäœå¶åŸ¡ãã¿ã¹ã¯ã®å€±æãããªã·ãŒè©äŸ¡ã®ç²ŸåºŠäœäžãšãã£ãããã©ãŒãã³ã¹äžã®åé¡ãå³åº§ã«çºçããŸãããã¡ã€ã³ã©ã³ãã åã¯ãé«å質ã®ããŒã¹ããŒã¿ã»ãããåã蟌ã¿ããããæ¡åŒµããŠãæ°ãããªããžã§ã¯ããç°ãªãç
§ææ¡ä»¶ãè²ãæã€ç°å¢ãªã©ãå«ãããã«é«å質ã®ããŒã¿ã»ãããçæããããšã§ãããªã·ãŒã®å
ç¢æ§ãé«ããŸããé«å¿ å®åºŠç©çæŒç®ã«ãããåäœåºåãç©ççã«æå³ã®ãããã®ãšãªãããšãä¿èšŒãããŸãã åæããŒã¿ãã€ãã©ã€ã³ã¯ãå®éã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã ãã§ã¯ã«ããŒã§ããªãã¿ã¹ã¯ååžããŸããªé害ã¢ãŒãããšããžã±ãŒã¹æ§æããããŠãŸã ç©ççã«ååšããªãç°å¢ã«å¯ŸããŠVLAãåŠç¿ãããããšãå¯èœã«ããŸãã ç£æ¥ãžã®å¿çš ãã®ãã€ãã©ã€ã³ãæãå³å¹æ§ã®ãã䟡å€ãããããæ¥çã«ã¯ãããå
±éã®ç¹åŸŽããããŸããããã¯ãç©ççãªç°å¢ããªã¹ã¯ãé«ããå€åã«å¯ã¿ãçŽæ¥åŠã¶ã«ã¯è²»çšãããã£ããå±éºã䌎ã£ãããããšããç¹ã§ãã è£œé æ¥ ã§ã¯ãå庫èªååã·ã¹ãã ã SKU ã®ããªãšãŒã·ã§ã³ã»æ¢±å
ã®æå·ã»ããã¢ã¬ã€ã¢ãŠãã®å€åã«å¯Ÿå¿ããæ±åèœåãå¿
èŠãšããŸããReal2Sim ãã£ããã£ãã·ãã¥ã¬ãŒã·ã§ã³ãã¬ãŒãã³ã°ã«äŸçµŠãããSim2Real 転çšã«ããå®äžçã®ããªãšãŒã·ã§ã³ã«èããããªã·ãŒãçæãããŸãã èªåè»æ¥ç ã§ã¯ãèªåé転ã·ã¹ãã ã¯éåžžãå®äžçã§ã¯å®å
šã«åçŸã§ããªãæ°çŸäžä»¶ã®ãšããžã±ãŒã¹ã·ããªãªã«ããããã¬ãŒãã³ã°ãå¿
èŠãšããŸãã å»çåé ã§ã¯ãæè¡ãæ£è
ã±ã¢ãžã®å¿çšã峿 Œãªå®å
šèŠå¶äžã®å¶çŽãåããŸããé«ç²ŸåºŠãªã·ãã¥ã¬ãŒã·ã§ã³ã«ãããæ£è
ãžã®æ¥è§Šãªãã«ã¢ãã«ã®ãã¬ãŒãã³ã°ãšæ€èšŒãé²ããããŸãã ãšãã«ã®ãŒã»å
¬çäºæ¥ ã§ã¯ãç¹æ€çšã®èªåŸãããããå€é»æã»ãã€ãã©ã€ã³ã»é¢šåçºé»æãªã©ã人éãç«ã¡å
¥ãããšã«å®éã®èº«äœçãªã¹ã¯ã䌎ãç°å¢ã§çšŒåããŸãã å°å£²æ¥ç ã§ã¯ãèªåŸåãã«ãã£ã«ã¡ã³ãã·ã¹ãã ã¯ãçµ¶ããå€åããã¬ã€ã¢ãŠãã®äžã§èšå€§ãªçš®é¡ã®SKUïŒåšåº«ç®¡çåäœïŒã«å¯Ÿå¿ããªããã°ãªããŸãããæ°åçš®é¡ãã®è£œåããªãšãŒã·ã§ã³ã«ããããã¬ãŒãã³ã°ããŒã¿ãçæããã·ãã¥ã¬ãŒã·ã§ã³ããããçç£èŠæš¡ã§ã®æ±çšåãå®çŸããå¯äžã®çŸå®çãªæ¹æ³ã§ãã ä»åŸã®å±æ æ¬èšäºã§ã¯ãPhysical AIã¢ãã«ãçŸå®äžçã§åäœãããããã®ã³ã¢ãšã³ãžã³ã§ããSim2Real/Real2Simãã€ãã©ã€ã³ã®ç®çãšå
容ã«ã€ããŠè§£èª¬ããŸãããæ¬ã·ãªãŒãºã®æ¬¡åèšäºã§ã¯ãLeRobot SO-101 AWS Sim2Real2Sim ãªãã¡ã¬ã³ã¹ãããžã§ã¯ãã®ãã³ãºãªã³æè¡è§£èª¬ãéããŠããããã®æŠå¿µãå
·äœåããŸããAWS ã€ã³ãã©ã¹ãã©ã¯ãã£ã»NVIDIA Isaac Simã»å
¬éãããŠãã LeRobot ãã©ãããã©ãŒã ã䜿ã£ãŠãšã³ãããŒãšã³ãã§å®è£
ãããå®å
šã«ãããã€å¯èœãªã¢ãŒããã¯ãã£ã玹ä»ããŸãã ãŸãã¯åºç€ã¢ãã«ãžã®ã¢ã¯ã»ã¹ã« Amazon Bedrock ããã·ãã¥ã¬ãŒã·ã§ã³ã¯ãŒã¯ããŒãã«æé©åããã Amazon EC2 G6e ã€ã³ã¹ã¿ã³ã¹ ãã確èªãã ããã <!-- '"` --> Dario Macagnano Dario Macagnano is a Physical AI Solutions Architect at AWS. With years of experience designing and deploying solutions spanning real-time simulation, digital twins, and edge inference â from rapid prototypes to large-scale production systems â Dario is passionate about the convergence of AI, robotics, and cloud infrastructure that brings intelligent systems into the physical world. Ignacio Sánchez Ignacio Sanchez is a Worldwide Specialist Solutions Architect for Physical AI in AWS, based in Madrid, Spain. He works with customers and partners globally to design and deploy AI solutions that bridge the digital and physical worlds, spanning spatial computing, robotics, and edge inference workloads on AWS. Ignacio is passionate about emerging technologies and their real-world applications. In his spare time, he enjoys reading, playing video games, and staying active through sports. Quinn Cheong Quinn Cheong is a Worldwide Specialist Solutions Architect for Physical AI at AWS, helping to shape the global Physical AI architectural strategy for the domain. Quinnâs expertise spans cutting-edge software development, and he has pioneered multiple solutions from World Generation and 3D Model Inferencing on Kubernetes, to creating WebXR augmented workers for AR Glasses. Quinn is also a seasoned AWS speaker, having presented at 30+ global events and summits. He is now focused on scaling Physical AI Infrastructure with Kubernetes and Agentic AI. 翻蚳㯠Visual Compute SSA 森ãæ
åœããŸãããåæã¯ãã¡ããã芧ãã ããã
ã¯ããã« ããã«ã¡ã¯ãã¿ã€ããŒã§ãšã³ãžãã¢ãããŠãã埳å¯( @yannkazu1 )ã§ãã ã¯ã©ãŠããã€ãã£ãäŒè°2026 ã§çºè¡šãããã ãã¢ãŒãºæ¬çªç°å¢ã§ã®cgroup-awareåãšã®æ»éé² ãããã¡ããã¡ãé¢çœãã£ãã®ã§ãèªåã®æã§ãäœæããããªããŸããã Goã®GOMAXPROCSãã³ã³ããã®CPUå¶éãç¡èŠããã£ãŠãå®éã«èŠããšã©ããªãã®ãïŒ éå°äžŠåã®ã¹ã«ãŒãããäœäžã£ãŠãæ°åã§èŠããšã©ã®ãããã€ã³ãã¯ããããã®ãïŒ ã¹ããããªã³ã°ãšã¹ã¬ããæ°ã®é¢ä¿ãèªåã®ç®ã§ããããããïŒ èªåã§åãããŠæ°åãèŠãªããšè
ã«èœã¡ãªãã¿ã€ããªã®ã§ã ããŒã«ã«ã®Macç°å¢ã§å
šéšåçŸããŠã¿ãŸããã çºè¡šã®èŠçŽ ãã¢ãŒãºã®ããã¯ãšã³ã pairs-main ã¯Go補ã§Amazon EKSäžã§çšŒåã48ã³ã¢ã®Nodeã§ limits.cpu: 5000m ïŒ5ã³ã¢ïŒã®PodãåããŠãããã Goã®GOMAXPROCSãããã©ã«ãã§48 ïŒïŒNodeå
šäœã®ã³ã¢æ°ïŒã«ãªã£ãŠãããããã«ãã以äžã®åé¡ãçºç: éå°äžŠå : 5ã³ã¢ãã䜿ããªãã®ã«48ã¹ã¬ãããèµ°ã â Goã¹ã±ãžã¥ãŒã©ã®ãªãŒããŒãããå¢å€§ CPUã¹ããããªã³ã° : cgroupã®ã¯ã©ãŒã¿ïŒCPUæéã®äžéïŒãã¹ã¬ãããå
±é£ã â å
šã¹ã¬ãããåæã«åæ¢ ç£èŠã®æ»è§ : CPU䜿çšçã¯æ£åžžã«èŠããããå®éã¯ã¹ããããªã³ã°ã§æç¶çã«åæ¢ åãåé¡ãHAProxyïŒ nbthread=48 ãCPUå¶é1ã³ã¢ïŒã§ãçºçããŠããã ããããcgroup-awareãªèšå®ïŒGOMAXPROCS=5, nbthread=1ïŒã«ä¿®æ£ãããšããã倧å¹
ã«æ¹åããããšãã話ã§ããã çšèªã®æŽç ããããå
ã§åºãŠãããã³ã¢ããGOMAXPROCSããã¯ã©ãŒã¿ããã¹ããããªã³ã°ããããããã³ãšæ¥ãªããŠã倧äžå€«ã§ããèšäºå
šäœã§ç¹°ãè¿ãç»å Žããã®ã§ãæåã«ãã£ããæŽçããŠãããŸãïŒãã§ã«éŠŽæã¿ãããæ¹ã¯ã¹ãããã§OKïŒã CPUã³ã¢ã»ããã»ã¹ã»ã¹ã¬ãã çšèª ãã£ããããæå³ CPUã³ã¢ èšç®ãå®è¡ããç©ççãªå®äœã1ã³ã¢ = åæã«1ã€ã®åŠçãé²ãããã ããã»ã¹ åããŠããããã°ã©ã 1ã€åã®åäœ ã¹ã¬ãã ããã»ã¹å
ã§å®éã«CPUã«å²ãåœãŠãããäœæ¥ã®åäœã1ããã»ã¹ã¯è€æ°ã¹ã¬ãããæãŠã ãã£ããèšããšã ã³ã¢ã®æ° = åæã«é²ããããã¹ã¬ããã®æ°ã®äžé ã§ãã8ã³ã¢ã®CPUãªããããäžç¬ã«é²è¡ã§ããã®ã¯æå€§8ã¹ã¬ãããŸã§ããã以äžã®ã¹ã¬ãããç«ã¡äžããå Žåã¯ãOSãé çªã«ã³ã¢ãå²ãåœãŠçŽããªããåããŸãïŒ= ã³ã³ããã¹ãã¹ã€ããïŒã ã³ã³ãããš cgroup çšèª ãã£ããããæå³ ã³ã³ãã åããµãŒããŒäžã§è€æ°ã®ã¢ããªãäºãã«å¹²æžããªãããã«åããä»çµã¿ïŒDocker ã Kubernetes ã®äžèº«ïŒãå®äœã¯ãã¹ãã®ã«ãŒãã«ããã®ãŸãŸäœ¿ã ãnamespaces ã§èŠããç¯å²ããcgroup ã§äœ¿ããéãå¶éããããã»ã¹ïŒçŸ€ïŒã ã«ããããVM ã®ããã«å°çšã«ãŒãã«ãæã€ããã§ã¯ãªã cgroup ïŒControl GroupsïŒ Linuxã«ãŒãã«ã®æ©èœã§ããã®ããã»ã¹çŸ€ã¯CPUããããŸã§ã»ã¡ã¢ãªã¯ãããŸã§ããšäžéãèšå®ããä»çµã¿ CPUå¶é ããã®ã³ã³ããã¯CPU 1ã³ã¢åãŸã§ãã®ãããªäžéèšå®ãå®äœã¯ cgroup ã® cpu.max ãã¡ã€ã« ã³ã³ããã®ãCPU 0.5ã³ã¢ãŸã§ããšããèšå®ã¯ãLinuxã«ãŒãã«ã cgroup ãéããŠã100msã®ãã¡50msãŸã§ããCPUã䜿ãããªãããšãã圢ã§åŒ·å¶ããŸãããã® 100msã®æ ããããªãªããããã®äžã§äœ¿ã£ãŠããæééããã¯ã©ãŒã¿ã ãšåŒã³ãŸãïŒ cpu.max: 50000 100000 ãªãã100msã®ãã¡50ms䜿ãã = 0.5ã³ã¢çžåœãïŒã CFS ã¹ã±ãžã¥ãŒã© Linux ã®ããã©ã«ãã® CPU ã¹ã±ãžã¥ãŒã©ã CFSïŒCompletely Fair SchedulerïŒ ãšåŒã³ãŸããå
ã»ã©ã®ãããªãªãããã¯ã©ãŒã¿ãã¯ãCFS ãæã€ 垯åå¶åŸ¡ïŒBandwidth ControllerïŒ ãšããæ©èœã®çšèªã§ãcgroup ã® cpu.max ã®å€ãå®éã«ã¹ã¬ãããžé©çšããïŒïŒã¯ã©ãŒã¿ã䜿ãåã£ãã忢ãããïŒã®ã¯ãã® CFS ã®ä»äºã§ãã ã€ãŸããcgroup ãå¶éå€ãæã¡ãCFS ãããã宿œããããšããåæ
é¢ä¿ãåŸã®å®éšã§åºãŠãã nr_periods ïŒCFS ãæéãåºåãåäœã®ç·æ°ïŒã nr_throttled ïŒCFS ã忢ãããããªãªãã®æ°ïŒãããã® CFS 垯åå¶åŸ¡ã®çµ±èšãèŠãŠããŸãã Goroutine ãš GOMAXPROCSïŒGoç¹æã®è©±ïŒ çšèª ãã£ããããæå³ goroutine Goã®è»œéã¹ã¬ãããOSã¹ã¬ããããé¥ãã«è»œãã1ããã»ã¹ã§æ°äžãæ°çŸäžåç«ã¡äžãããã OSã¹ã¬ãã OSãå®éã«CPUã«ã¹ã±ãžã¥ãŒã«ããã¹ã¬ãããã³ã¢ãåãåãã®ã¯ãã¡ã GOMAXPROCS Goã©ã³ã¿ã€ã ãåæã«èµ°ãããOSã¹ã¬ããã®æ°ã®äžéãããã©ã«ãã¯ãã¹ãã®CPUã³ã¢æ° goroutine ãäœäžåç«ã¡äžããŠããGoã©ã³ã¿ã€ã 㯠GOMAXPROCS åã® OSã¹ã¬ããã®äžã«ããããå€éåããŠå®è¡ããŸããã€ãŸãåæã« CPU ãæ¡ã£ãŠããã®ã¯æå€§ã§ã GOMAXPROCS åããã®å²ãåœãŠã管çããã®ã Goã¹ã±ãžã¥ãŒã© ã§ãã ãã€ã³ãã¯ã ã³ã³ããã®CPUå¶éãäžãã£ãŠãããã©ã«ãã® GOMAXPROCS ã¯ãã¹ãã®CPUæ°ã®ãŸãŸ ãšããããšããããããããä»åã®ããŒãã§ãåŸã®å®éšã§ãã®æåãå®éã«ç¢ºãããŸãã éå°äžŠå CPU å¶éãããå€ãã®ã¹ã¬ããïŒã goroutineãã¯ãŒã«ãŒïŒãåæã«èµ°ãããŠããç¶æ
ãæããŸããããšãã° 5 ã³ã¢çžåœã® CPU å¶éã«å¯Ÿã㊠GOMAXPROCS=48 ãªããçŽ 9.6 åã®éå°äžŠåãå®éã«èµ°ããã®ã¯å¶éåã®ã¹ã¬ããã ããªã®ã§ãæ®ãã¯ã¹ã±ãžã¥ãŒã©ã®äžã§é çªåŸ
ã¡ããã€ã€ãå
±æã¯ã©ãŒã¿ãæ©é£ããåãããšã«ãªããŸãã Go ã® GOMAXPROCS ã«éã£ã話ã§ã¯ãªããHAProxy ã® nbthread ãNginx ã® worker_processes ãPuma ã® workers ãªã©ã ãäžŠåæ°ã®ããã©ã«ãããã¹ã CPU æ°ã«äŸåãããèšå®ã¯ãã¹ãŠåãæ§é ã§éå°äžŠåãèµ·ãããŸã ã CPUã¹ããããªã³ã° cgroupã§CPU 0.5ã³ã¢åã«å¶éãããã³ã³ããããããããã®ã¹ã¬ããã§CPUãäžæ°ã«äœ¿ãããšãããšãLinuxã«ãŒãã«ã ãã¯ã©ãŒã¿ã䜿ãåã£ãã®ã§ã次ã®ããªãªããŸã§å
šã¹ã¬ããäžæåæ¢ã ãšåŒ·å¶çã«ãããã¯ããŸããããã CPUã¹ããããªã³ã° ã§ãã ã¹ããããªã³ã°ãé »çºãããšãã¬ã¹ãã³ã¹ãæç¶çã«æ¢ãŸã£ãããã¹ã«ãŒããããèœã¡ããããŸãããã®çµæãããªããé
å»¶ãã¹ãã€ã¯ãããåå ã«ãªã£ãŠããã±ãŒã¹ãå€ãã§ããçºçç¶æ³ã¯ /sys/fs/cgroup/cpu.stat ã«åºåãããŠãããæ¬èšäºã§ã¯ä»¥äžã®3ææšã远ããŸã: nr_periods : ã¹ã±ãžã¥ãŒã©ã®èšæž¬åäœïŒããªãªã = 100msïŒã®ç·æ° nr_throttled : ãã®ãã¡ã¹ããããªã³ã°ãèµ·ããããªãªãã®æ°ïŒåæ°ïŒ throttled_usec : ã¹ããããªã³ã°ã§å®éã«CPUãæ¢ããããçŽ¯ç©æéïŒãã€ã¯ãç§ïŒ ãåæ°ãã ãã§ãªãã 环ç©åæ¢æé ããèŠãã®ãéèŠã ããšããã®ãçºè¡šã®å±±å Žã®äžã€ã§ãåŸã®å®éš3ã§ãã®éããããããªåºãŸãã Thundering Herd ã¹ããããªã³ã°ã§åæ¢ããŠããå
šã¹ã¬ãããã æ¬¡ã®ããªãªãã®ãªã»ããã§äžæã«èµ°ãåºãããŸãäžç¬ã§ã¯ã©ãŒã¿ãé£ã朰ããŠåæã«æ¢ãŸã ããšãããµã€ã¯ã«ãç¹°ãè¿ãããç¶æ
ã ãThundering HerdïŒé·é³Žã®çŸ€ãïŒã ãšåŒã³ãŸããå
ã¯ãœã±ãã accept ãªã© I/O æèã®çšèªã§ãããcgroup ã®åž¯åå¶åŸ¡äžã§ãåãæ§é ã®åé¡ãèµ·ããŸããã¹ã¬ããæ°ãå€ãã»ã©è¢«å®³ã倧ãããªãã®ã¯ãããã«ç«¯ãçºããŠããŸããå®éš4ã§ãã®æåã芳å¯ããŸãã cgroup-aware ããã°ã©ã ãã©ã€ãã©ãªã cgroup ã®å¶éïŒ cpu.max ãªã©ïŒãèªåã§èªã¿åãããã®å€ã«åãããŠäžŠå床ã調æŽãã èšèšã®ããšã ãcgroup-awareã ãšåŒã³ãŸããGo 1.25 以éã®ã©ã³ã¿ã€ã ã uber-go/automaxprocs 㯠cgroup-aware ã« GOMAXPROCS ãèšå®ããŸããéã« Go 1.24 以åã®ããã« cgroup ãèŠãã«ãã¹ãã® CPU æ°ã ãèŠãæåã¯ãcgroup-aware ã§ã¯ãªããç¶æ
ã§ãä»åã®éå°äžŠåã¯ããããçãŸããŠããŸãã ãã®èšäºã§æ€èšŒããããš # æ€èšŒããŒã çºè¡šã§ã®ãã€ã³ã 1 GOMAXPROCSã®ããã©ã«ãå€ ã³ã³ããã®CPU Limitãç¡èŠããŠãã¹ãã®CPUæ°ã«ãªã 2 éå°äžŠåã®ããã©ãŒãã³ã¹åœ±é¿ GOMAXPROCSã倧ãããããšã¹ã«ãŒããããäœäžãã 3 CPUã¹ããããªã³ã°ã®çºç ã¹ã¬ããæ°ãå€ãã»ã©ã¯ã©ãŒã¿ãæ©ãæ¶è²»ãã忢æéãå¢ãã 4 ã¹ã¬ããæ°ãšã¹ããããªã³ã°ã®çžé¢ ã¹ã¬ããæ°ã«æ¯äŸã㊠throttled_usec ãå¢å ãã 1. ããŒã«ã«ç°å¢æ§ç¯ïŒMacïŒ åææ¡ä»¶ macOS ïŒApple Silicon / Intel 䞡察å¿ïŒ Docker Desktop ãã€ã³ã¹ããŒã«æžã¿ ãªãDockerã§æ€èšŒã§ããã®ã cgroupïŒControl GroupsïŒã¯ Linuxã«ãŒãã«ã®æ©èœ ã§ãmacOS èªäœã«ã¯ååšããŸãããããã Docker Desktop ã¯å
éšã§ Linux VM ãåãããŠãããã³ã³ããã¯ãã® Linux äžã§åäœããŸãã âââââââââââââââââââââââââââââââââââââââââââââââ â macOS â â ââââââââââââââââââââââââââââââââââââââââââ â â â Docker Desktop (Linux VM) â â â â ââââââââââââââââââââââââââââââââââââ â â â â â ã³ã³ãã â â â â â â /sys/fs/cgroup/cpu.max â ããïŒ â â â â â â /sys/fs/cgroup/cpu.stat â â â â â ââââââââââââââââââââââââââââââââââââ â â â ââââââââââââââââââââââââââââââââââââââââââ â âââââââââââââââââââââââââââââââââââââââââââââââ Docker ã® --cpus ãã©ã°ã¯ Kubernetes ã® limits.cpu ãšåãã cgroup ã® cpu.max ã«å€æãããŸããã€ãŸã Kubernetes ãšåãä»çµã¿ãããŒã«ã«ã§åçŸ ã§ããŸãã Docker Kubernetes cgroup v2 --cpus=0.5 limits.cpu: 500m cpu.max: 50000 100000 --cpus=1.0 limits.cpu: 1000m cpu.max: 100000 100000 --cpus=5.0 limits.cpu: 5000m cpu.max: 500000 100000 ã»ããã¢ããæé Step 1: Docker Desktop ã®ã€ã³ã¹ããŒã« Docker Desktop for Mac ããã€ã³ã¹ããŒã«ã docker --version # Docker version 27.x.x, build xxxxxxx Step 2: æ€èšŒçš Go ã¢ããªã±ãŒã·ã§ã³ æ¬èšäºã®æ€èšŒã³ãŒãã¯ä»¥äžã®ãªããžããªã«ãŸãšããŠããŸã: hirosi1900day/cgroup-throttling-lab git clone https://github.com/hirosi1900day/cgroup-throttling-lab.git cd cgroup-throttling-lab 3ã€ã®ã¢ãŒããæã€Goã¢ããªã±ãŒã·ã§ã³ãæžããŸããã ã¢ãŒã çšé info GOMAXPROCSã®å€ãšcgroupã®èšå®ã衚瀺 benchmark CPUè² è·ããããŠã¹ã«ãŒããããèšæž¬ throttle-demo CPUè² è·ããããŠã¹ããããªã³ã°ã® Before/After ã衚瀺 ã³ãŒã解説 åããŒããé ã«èŠãŠãããŸãã 1. CPUè² è·ãçºçããã颿° // cpuIntensiveWork ã¯CPUè² è·ããããèšç®åŠç // å¹³æ¹æ ¹ãšäžè§é¢æ°ã1äžåã«ãŒãããæå³çã«CPUã䜿ãåã func cpuIntensiveWork() float64 { result := 0.0 for i := 0 ; i < 10000 ; i++ { result += math.Sqrt( float64 (i)) * math.Sin( float64 (i)) } return result } ãã®é¢æ°ãå®éšã®èŠã§ãã math.Sqrt ãš math.Sin ã®èšç®ã1äžåç¹°ãè¿ãããšã§ã çŽç²ãªCPUè² è· ãçºçãããŸããI/OåŸ
ã¡ãäžåãªãã®ã§ãGOMAXPROCSïŒïŒã¯ãŒã«ãŒã¹ã¬ããæ°ïŒã®åœ±é¿ããã€ã¬ã¯ãã«çŸããŸãã 2. infoã¢ãŒã â Goã©ã³ã¿ã€ã ãšcgroupã®CPUèšå®ã衚瀺 func showRuntimeInfo() { // runtime.GOMAXPROCS(0) ã¯ãçŸåšã®å€ãè¿ãã倿Žããªãã // â ãããã³ã³ããã®CPUå¶éãšäžèŽããŠãããããã€ã³ã fmt.Printf( "GOMAXPROCS: %d \n " , runtime.GOMAXPROCS( 0 )) fmt.Printf( "NumCPU: %d \n " , runtime.NumCPU()) // --- cgroup ã®CPUå¶éãçŽæ¥èªã --- // /sys/fs/cgroup/cpu.max 㯠cgroup v2 ã®CPUå¶éãã¡ã€ã« // äžèº«ã¯ "ã¯ã©ãŒã¿ ããªãªã" ã®åœ¢åŒïŒäŸ: "100000 100000"ïŒ // Kubernetes ã® limits.cpu ã Docker ã® --cpus ãããã«åæ ããã if data, err := os.ReadFile( "/sys/fs/cgroup/cpu.max" ); err == nil { fmt.Printf( "cpu.max: %s" , string (data)) } // /sys/fs/cgroup/cpu.stat ã¯CPUã¹ããããªã³ã°ã®çµ±èšæ
å ± // nr_periods: CFSã¹ã±ãžã¥ãŒã©ã®ããªãªãïŒ100msïŒã®ç·æ° // nr_throttled: ã¹ããããªã³ã°ãçºçããããªãªãã®æ° // throttled_usec: ã¹ããããªã³ã°ã§CPUã忢ããçŽ¯ç©æéïŒÎŒsïŒ if data, err := os.ReadFile( "/sys/fs/cgroup/cpu.stat" ); err == nil { fmt.Printf( "cpu.stat: \n %s" , string (data)) } } ãã®ã¢ãŒãã§ã¯ã Goã©ã³ã¿ã€ã ãcgroupã®CPUå¶éãèªèããŠããã ãèŠãŸããGo 1.24以åã§ã¯ã GOMAXPROCS ããã¹ãã®CPUæ°ã®ãŸãŸãªã®ã確èªã§ããã¯ãã§ãã 3. benchmarkã¢ãŒã â ã¹ã«ãŒãããã®èšæž¬ func runBenchmark() { // ç°å¢å€æ°ã§ãã³ãããŒã¯æéãšgoroutineæ°ãå¶åŸ¡å¯èœã«ããŠãã duration := 10 * time.Second // BENCH_DURATION ã§å€æŽå¯ goroutines := 100 // BENCH_GOROUTINES ã§å€æŽå¯ // --- ãããããèšæž¬ã®ã³ã¢ --- var totalOps atomic.Int64 // goroutineéã§å®å
šã«ã«ãŠã³ããå
±æ var wg sync.WaitGroup // å
šgoroutineã®å®äºãåŸ
〠// ã¿ã€ããŒã§çµäºãéç¥ãããã£ãã« done := make ( chan struct {}) go func () { <-time.After(duration) close (done) // â å
šgoroutineã«ãçµäºããäŒãã }() // goroutinesåã®goroutineãèµ·åãããããããç¬ç«ã«CPUè² è·ãããã // ãããã®goroutine㯠GOMAXPROCS åã®ã¯ãŒã«ãŒã¹ã¬ããã« // Goã¹ã±ãžã¥ãŒã©ã«ãã£ãŠå²ãåœãŠããã for i := 0 ; i < goroutines; i++ { wg.Add( 1 ) go func () { defer wg.Done() localOps := int64 ( 0 ) // goroutineããŒã«ã«ã§ã«ãŠã³ãïŒç«¶åãé¿ããïŒ for { select { case <-done: totalOps.Add(localOps) // æåŸã«ãŸãšããŠå ç® return default : cpuIntensiveWork() // CPUè² è·ãããç¶ãã localOps++ } } }() } wg.Wait() // Ops/sec = åäœæéãããã®åŠçåæ° // ãã®å€ãé«ãã»ã©ã¹ã«ãŒããããè¯ã opsPerSec := float64 (totalOps.Load()) / elapsed.Seconds() } 100åã®goroutineã cpuIntensiveWork() ãåŒã³ç¶ããããããGOMAXPROCSåã®OSã¹ã¬ããäžã§ã¹ã±ãžã¥ãŒã«ãããæ§é ãCPUå¶éãããç°å¢ã§ã¯ãã¹ã¬ãããå€ãã»ã©cgroupã®ã¯ã©ãŒã¿ãæ©ã䜿ãåããã¹ããããªã³ã°ã§ã¹ã«ãŒããããèœã¡ãããã§ãã ïŒè±ç·ïŒãã³ãããŒã¯ã³ãŒãã®å·¥å€« â ãã£ãã·ã¥ã³ããŒã¬ã³ã·ã®è©± cgroup ã®æ€èšŒãšã¯çŽæ¥é¢ä¿ãªãã§ããããã®ãã³ãããŒã¯ã³ãŒãã«ã¯ãèšæž¬èªäœãçµæãæªããªãããã®å·¥å€«ããå
¥ã£ãŠããŸãããã£ãããªã®ã§è§£èª¬ããŸãã select + default ã§ãã³ããããã³ã°ã«çµäºãã§ãã¯ãã€ã€CPUåŠçãåãç¶ããããšããã®ã¯Goã®å®çªãã¿ãŒã³ãªã®ã§è»œãè§Šããã ãã«ããŠãæ¬é¡ã¯ã«ãŠã³ã¿ã®èšèšã§ãã localOps := int64(0) // goroutineããŒã«ã«ïŒæ®éã®intïŒ for { select { case <-done: totalOps.Add(localOps) // â çµäºæã«1床ã ãatomicæäœ return default: cpuIntensiveWork() localOps++ // â æ®éã®ã€ã³ã¯ãªã¡ã³ããè¶
é«é } } ã«ãŒãå
ã§ã¯ localOps++ ïŒæ®éã® int ã€ã³ã¯ãªã¡ã³ãïŒã ãã䜿ããçµäºæã«1床ã ã totalOps.Add(localOps) ïŒ atomic æäœïŒã§åç®ããŠããŸãã ãæ¯å totalOps.Add(1) ã§ããã®ã§ã¯ïŒããšæããããããŸããããããã ãš100åã® goroutine ãåãã¡ã¢ãªã¢ãã¬ã¹ã«æ¯ã«ãŒãæžã蟌ã¿åãã ãã£ãã·ã¥ã³ããŒã¬ã³ã·ïŒCache CoherencyïŒ ã®ãªãŒããŒãããã§æ§èœã倧ããèœã¡ãŸãã ãã£ãã·ã¥ã³ããŒã¬ã³ã·ãšã¯ ãŸãåæãšããŠãCPUãããŒã¿ã«ã¢ã¯ã»ã¹ããä»çµã¿ãæŽçããŠãããŸãã CPU ã®ã¡ã¢ãªéå±€ CPUã倿°ãããŒã¿ãèªã¿æžããããšããæ¯åã¡ã€ã³ã¡ã¢ãªïŒDRAMïŒãŸã§åãã«è¡ãã®ã¯é
ãããŸããããã§ CPU㯠ã¡ã¢ãªéå±€ïŒMemory HierarchyïŒ ãšãã倿®µã®ãã£ãã·ã¥æ§é ãæã£ãŠããŸã: âââââââââââââââââââââââââââââââââââââââââââââââââââ â CPU ã³ã¢ â â âââââââââââââ â â â ã¬ãžã¹ã¿ â â æéïŒ~0.3nsïŒãæ°åãæ°çŸå â â âââââââ¬ââââââ â â âââââââŽââââââ â â â L1 ãã£ãã·ã¥â â 32ã64KB / ã³ã¢ã~1ns â â â (ããŒã¿+åœä»€)â â â âââââââ¬ââââââ â â âââââââŽââââââ â â â L2 ãã£ãã·ã¥â â 256KBã1MB / ã³ã¢ã~3-10ns â â âââââââ¬ââââââ â â â ââââââââââââ â â â â TLB â â ä»®æ³âç©çã¢ãã¬ã¹ â â â â â 倿ã®ãã£ãã·ã¥ â â â ââââââââââââ â ââââââââââŒâââââââââââââââââââââââââââââââââââââââââ âââââââŽââââââ â L3 ãã£ãã·ã¥â â æ°MBãæ°åMBãå
šã³ã¢å
±æã~10-30ns âââââââ¬ââââââ âââââââŽâââââââââââââââââââ â ã¡ã€ã³ã¡ã¢ãªïŒDRAMïŒ â â æ°GBãæ°çŸGBã~50-100ns âââââââ¬âââââââââââââââââââ âââââââŽâââââââââââââââââââ â ã¹ãã¬ãŒãžïŒSSD/HDDïŒ â â ~10,000ns (SSD) ã 10,000,000ns (HDD) âââââââââââââââââââââââââ éå±€ 容é ã¬ã€ãã³ã· ç¹åŸŽ ã¬ãžã¹ã¿ æ°çŸãã€ã ~0.3ns CPUãçŽæ¥æŒç®ããå Žæ L1ãã£ãã·ã¥ 32ã64KB/ã³ã¢ ~1ns ããŒã¿çšãšåœä»€çšã«åé¢ãã³ã¢ããšã«å°æ L2ãã£ãã·ã¥ 256KBã1MB/ã³ã¢ ~3-10ns ã³ã¢ããšã«å°æïŒã¢ãŒããã¯ãã£ã«ããïŒ L3ãã£ãã·ã¥ æ°MBãæ°åMB ~10-30ns å
šã³ã¢å
±æ ããããã³ã¢éã®ããŒã¿ã®æ©æž¡ã TLB æ°çŸãæ°åãšã³ã㪠~1nsïŒãããæïŒ ä»®æ³ã¢ãã¬ã¹âç©çã¢ãã¬ã¹ã®å€æãã£ãã·ã¥ ã¡ã€ã³ã¡ã¢ãª æ°GBã ~50-100ns L1ã®50ã100åé
ã CPUã localOps++ ãå®è¡ãããšãããã®å€æ°ãã¬ãžã¹ã¿ã L1 ã«ããã° 1ns 以äžã§å®äºããŸããããã L1 ã«ãªãïŒãã£ãã·ã¥ãã¹ïŒãš L2 â L3 â ã¡ã€ã³ã¡ã¢ãªãšé ã«ãã©ãå¿
èŠããããææª100nsãããã L1ããããšã¡ã€ã³ã¡ã¢ãªã¢ã¯ã»ã¹ã§ã¯çŽ100åã®é床差 ãããããã§ãã TLBïŒTranslation Lookaside BufferïŒ ã¯å°ã圹å²ãéã£ãŠãä»®æ³ã¡ã¢ãªã®ã¢ãã¬ã¹å€æãé«éåãããã£ãã·ã¥ã§ããããã»ã¹ã䜿ãã¡ã¢ãªã¢ãã¬ã¹ïŒä»®æ³ã¢ãã¬ã¹ïŒãå®éã®ç©çã¢ãã¬ã¹ã«å€æããã«ã¯ããŒãžããŒãã«ãåŒãå¿
èŠããããŸãããæ¯ååŒããšã¡ã¢ãªã¢ã¯ã»ã¹ã2åã«ãªãã®ã§ããã䜿ãå€æçµæã TLB ã«ãã£ãã·ã¥ããŠããŸããTLB ãã¹ãçºçãããš ããŒãžããŒãã«ãŠã©ãŒã¯ ãèµ°ããæ°ånsã®è¿œå ã³ã¹ããããããŸããgoroutine ã倧éã®ã¹ã¿ãã¯ãããŒãã䜿ãã¯ãŒã¯ããŒãã§ã¯ãTLB ãã¹ãããã©ãŒãã³ã¹ã«å¹ããŠããŸãã ãã®åæãèžãŸãããšããã«ãã³ã¢ã§ã®ãã£ãã·ã¥äžè²«æ§ããªãéèŠããããããŸãã ãã£ãã·ã¥ã³ããŒã¬ã³ã·åé¡ ãã«ãã³ã¢CPUã§ã¯ãåã³ã¢ãç¬èªã® L1/L2ãã£ãã·ã¥ ãæã£ãŠããŸããããã³ã¢ã倿°ãæŽæ°ãããšãä»ã®ã³ã¢ãæã€åã倿°ã®ãã£ãã·ã¥ã©ã€ã³ã¯ å€ãå€ïŒstaleïŒ ã«ãªããŸãããããæŸçœ®ãããšåã³ã¢ãç°ãªãå€ãèŠãŠããŸããããããŒããŠã§ã¢ã¬ãã«ã§äžè²«æ§ãä¿ã€ä»çµã¿ãå¿
èŠã§ããããã ãã£ãã·ã¥ã³ããŒã¬ã³ã·ãããã³ã« ïŒä»£è¡šçãªãã®ã« MESI ãããã³ã« ïŒã§ãã MESI ãããã³ã«ã§ã¯ããã£ãã·ã¥ã©ã€ã³ã¯ä»¥äžã®4ç¶æ
ãé·ç§»ããŸã: ç¶æ
æå³ M odified èªã³ã¢ã ãã倿޿žã¿ã®å€ãæã€ E xclusive èªã³ã¢ã ããæã£ãŠããããã¡ã¢ãªãšåãå€ S hared è€æ°ã³ã¢ãåãå€ãæã£ãŠããïŒèªã¿åãå°çšïŒ I nvalid ä»ã³ã¢ãæŽæ°ããã®ã§ããã®ãã£ãã·ã¥ã©ã€ã³ã¯ç¡å¹ atomic 倿°ãžã®æžã蟌ã¿ãçºçãããš: æžã蟌ãã³ã¢ããã£ãã·ã¥ã©ã€ã³ã® æä»çæææš© ãèŠæ± ä»ã®å
šã³ã¢ã®åããã£ãã·ã¥ã©ã€ã³ã Invalid ã«å€ããïŒç¡å¹åïŒ æ¬¡ã«ãã®ã³ã¢ãåã倿°ã«ã¢ã¯ã»ã¹ãããšã ãã£ãã·ã¥ãã¹ â ã¡ã¢ãªïŒor ä»ã³ã¢ã®ãã£ãã·ã¥ïŒããåååŸ ãããæ¯ã«ãŒãã»100 goroutine ã§çºçãããš: [NG] æ¯å atomicïŒãã£ãã·ã¥ã©ã€ã³ã®ãã³ãã³ïŒ ã³ã¢1: totalOps.Add(1) â ãã£ãã·ã¥ã©ã€ã³ååŸ (Exclusive) â å€ãæŽæ° (Modified) â ä»ã®å
šã³ã¢ã®ãã£ãã·ã¥ã©ã€ã³ã Invalid ã« ã³ã¢2: totalOps.Add(1) â Invalid ãªã®ã§åååŸãå¿
èŠïŒãã£ãã·ã¥ãã¹ïŒïŒ â ã³ã¢1ãã転é â Exclusive â Modified â ä»ã®å
šã³ã¢ã®ãã£ãã·ã¥ã©ã€ã³ã Invalid ã« ã³ã¢3: totalOps.Add(1) â ãŸã Invalid â ãŸãåååŸ...ïŒä»¥äžãã³ãã³ç¶æ
ïŒ â å®éã®CPUèšç®ã§ã¯ãªãããã£ãã·ã¥ã®åæã«CPUæéãæ¶ãã ãã®ãã£ãã·ã¥ã©ã€ã³ã®å¥ªãåã㯠ããã£ãã·ã¥ã©ã€ã³ããŠã³ã·ã³ã°ã ã ãfalse sharingã ïŒåããã£ãã·ã¥ã©ã€ã³ã«å¥ã®å€æ°ãä¹ã£ãŠããå ŽåïŒãšãåŒã°ãããã«ãã¹ã¬ããããã°ã©ãã³ã°ã®æåãªããã©ãŒãã³ã¹èœãšã穎ã§ãã äžæ¹ãããŒã«ã«ã«ãŠã³ã¿ãªã: [OK] ããŒã«ã«ã«ãŠã³ã¿ + æåŸã«1åã ã atomic ã³ã¢1: localOps++ â èªã³ã¢ã®ã¬ãžã¹ã¿ or L1ãã£ãã·ã¥ã ããä»ã³ã¢ã«åœ±é¿ãªã ã³ã¢2: localOps++ â åäžãågoroutineãç¬ç«ããã¡ã¢ãªãè§Šã ... ïŒçµäºæã ã totalOps.Add â atomic æäœã¯10ç§éã§åèšãã£ã100åïŒ ã ãã³ãããŒã¯ãã®ãã®ã®ã³ã¹ãã§ãã³ãããŒã¯çµæãæªã ãã®ãé²ããã¯ããã¯ã§ããcgroup ã®ã¹ããããªã³ã°ãæ£ç¢ºã«æž¬ããªããèšæž¬ã®ãªãŒããŒãããã¯æ¥µååã£ãŠããããã 4. throttle-demoã¢ãŒã â ã¹ããããªã³ã°ã®èŠ³æž¬ func runThrottleDemo() { // GOMAXPROCSåã®ã¯ãŒã«ãŒãèµ·åïŒ= OSã¹ã¬ããæ°ãšäžèŽãããïŒ numWorkers := runtime.GOMAXPROCS( 0 ) // Before: ã¹ããããªã³ã°åã®çµ±èšãèšé² // cpu.stat ã® nr_throttled, throttled_usec ãç¢ºèª fmt.Println( "--- Before ---" ) readCgroupStat() // numWorkersåã®goroutineã§CPUè² è·ãããã // GOMAXPROCS=8 ãªã8æ¬ãGOMAXPROCS=1 ãªã1æ¬ // â ã¹ã¬ããæ°ã®éããã¹ããããªã³ã°ã«ã©ã圱é¿ãããã芳枬 for i := 0 ; i < numWorkers; i++ { go func () { for { cpuIntensiveWork() // å
šã¹ã¬ããã§CPUå
šé } }() } // 5ç§é CPUè² è·ããããåŸ... // After: ã¹ããããªã³ã°åŸã®çµ±èšãèšé² // Before ãšã®å·®åãããã®5ç§éã§çºçããã¹ããããªã³ã°ã fmt.Println( "--- After ---" ) readCgroupStat() } GOMAXPROCS ã®å€ããã®ãŸãŸã¯ãŒã«ãŒæ°ã«ãªããŸããGOMAXPROCS=8 ãªã8ã¹ã¬ãããåæã«CPUã䜿ãããšããã®ã§ãå
±æã¯ã©ãŒã¿ãäžç¬ã§é£ã朰ããŸããBefore/After ã® throttled_usec ã®å·®åã§ã å®éã«ã©ãã ãCPUãæ¢ããããã ãããããŸãã Dockerfile # ãã«ãã¹ããŒãž: Go 1.24 ã§ã³ã³ãã€ã« FROM golang:1.24-bookworm AS builder WORKDIR /app COPY go.mod ./ COPY main.go ./ RUN go build -o /app/cgroup-bench . # å®è¡ã¹ããŒãž: 軜éãªã€ã¡ãŒãžã§å®è¡ FROM debian:bookworm-slim COPY --from=builder /app/cgroup-bench /usr/local/bin/cgroup-bench ENTRYPOINT ["cgroup-bench"] CMD ["info"] Go ããŒãžã§ã³ã«ã€ã㊠Go ã®ææ°å®å®ç : 1.26.3ïŒ2026幎5ææç¹ïŒ container-aware GOMAXPROCS ãå°å
¥ãããããŒãžã§ã³ : Go 1.25 æ¬èšäºã§äœ¿ãããŒãžã§ã³ : Go 1.24ïŒ1.25çŽåã®æçµçïŒ Go 1.25以éã§ã¯ã©ã³ã¿ã€ã ãcgroupã® cpu.max ãèªåã§èªã¿åããGOMAXPROCSãCPUå¶éã«åãããŠèšå®ããŸããä»å㯠åé¡ãçºçããŠããåœæã®æåãåçŸ ããããããããŠGo 1.24ã䜿çšããŠããŸãã main.go å
šæïŒã¯ãªãã¯ã§å±éïŒ ```go package main import ( "encoding/json" "fmt" "math" "os" "runtime" "strconv" "sync" "sync/atomic" "time" ) type Result struct { GOMAXPROCS int `json:"gomaxprocs"` NumCPU int `json:"num_cpu"` CPULimit string `json:"cpu_limit"` Duration time.Duration `json:"duration_ns"` DurationStr string `json:"duration"` TotalOps int64 `json:"total_ops"` OpsPerSec float64 `json:"ops_per_sec"` GoroutineCount int `json:"goroutine_count"` } func cpuIntensiveWork() float64 { result := 0.0 for i := 0; i < 10000; i++ { result += math.Sqrt(float64(i)) * math.Sin(float64(i)) } return result } func main() { mode := "benchmark" if len(os.Args) > 1 { mode = os.Args[1] } switch mode { case "benchmark": runBenchmark() case "info": showRuntimeInfo() case "throttle-demo": runThrottleDemo() } } func showRuntimeInfo() { fmt.Println("=== Go Runtime Information ===") fmt.Printf("GOMAXPROCS: %d\n", runtime.GOMAXPROCS(0)) fmt.Printf("NumCPU: %d\n", runtime.NumCPU()) fmt.Printf("GOVERSION: %s\n", runtime.Version()) envGOMAXPROCS := os.Getenv("GOMAXPROCS") if envGOMAXPROCS == "" { fmt.Println("ENV GOMAXPROCS: (not set â using default)") } else { fmt.Printf("ENV GOMAXPROCS: %s\n", envGOMAXPROCS) } fmt.Println("\n=== cgroup CPU Information ===") if data, err := os.ReadFile("/sys/fs/cgroup/cpu.max"); err == nil { fmt.Printf("cpu.max: %s", string(data)) } if data, err := os.ReadFile("/sys/fs/cgroup/cpu.weight"); err == nil { fmt.Printf("cpu.weight: %s", string(data)) } if data, err := os.ReadFile("/sys/fs/cgroup/cpu.stat"); err == nil { fmt.Printf("cpu.stat:\n%s", string(data)) } } func runBenchmark() { duration := 10 * time.Second if d := os.Getenv("BENCH_DURATION"); d != "" { if parsed, err := time.ParseDuration(d); err == nil { duration = parsed } } goroutines := 100 if g := os.Getenv("BENCH_GOROUTINES"); g != "" { if parsed, err := strconv.Atoi(g); err == nil { goroutines = parsed } } maxprocs := runtime.GOMAXPROCS(0) var totalOps atomic.Int64 var wg sync.WaitGroup done := make(chan struct{}) go func() { <-time.After(duration) close(done) }() start := time.Now() for i := 0; i < goroutines; i++ { wg.Add(1) go func() { defer wg.Done() localOps := int64(0) for { select { case <-done: totalOps.Add(localOps) return default: cpuIntensiveWork() localOps++ } } }() } wg.Wait() elapsed := time.Since(start) ops := totalOps.Load() opsPerSec := float64(ops) / elapsed.Seconds() fmt.Printf("GOMAXPROCS=%d Ops/sec=%.2f Total=%d\n", maxprocs, opsPerSec, ops) jsonData, _ := json.Marshal(Result{ GOMAXPROCS: maxprocs, OpsPerSec: opsPerSec, TotalOps: ops, }) fmt.Printf("JSON: %s\n", string(jsonData)) if data, err := os.ReadFile("/sys/fs/cgroup/cpu.stat"); err == nil { fmt.Printf("\ncpu.stat:\n%s", string(data)) } } func runThrottleDemo() { fmt.Printf("GOMAXPROCS: %d\n", runtime.GOMAXPROCS(0)) fmt.Println("\n--- Before ---") if data, err := os.ReadFile("/sys/fs/cgroup/cpu.stat"); err == nil { fmt.Printf("%s", string(data)) } numWorkers := runtime.GOMAXPROCS(0) duration := 5 * time.Second if d := os.Getenv("DEMO_DURATION"); d != "" { if parsed, err := time.ParseDuration(d); err == nil { duration = parsed } } var wg sync.WaitGroup stop := make(chan struct{}) go func() { <-time.After(duration) close(stop) }() for i := 0; i < numWorkers; i++ { wg.Add(1) go func() { defer wg.Done() for { select { case <-stop: return default: cpuIntensiveWork() } } }() } wg.Wait() fmt.Println("\n--- After ---") if data, err := os.ReadFile("/sys/fs/cgroup/cpu.stat"); err == nil { fmt.Printf("%s", string(data)) } } ``` Step 3: ãã«ã docker build -t cgroup-bench go-app/ ããã§æºåå®äºã§ãã 2. å®éšãšçµæ æ€èšŒç°å¢: - macOSïŒApple SiliconïŒ - Docker Desktop - Docker VM: 11ã³ã¢ ïŒãããKubernetesã®ã48ã³ã¢Nodeãã«çžåœïŒ å®éš1: GOMAXPROCS ã¯ã³ã³ããã® CPU å¶éãç¡èŠãã äœã確èªããã çºè¡šã§ã¯ãã³ã³ããã® limits.cpu: 5000m ã«å¯Ÿã㊠GOMAXPROCS ã 48ïŒããŒãã®ã³ã¢æ°ïŒã«ãªã£ãŠããããšããåé¡ã®çºç«¯ã§ããããŸãã¯ã Goã©ã³ã¿ã€ã ãcgroupã®CPUå¶éãèŠãŠããªã ãšããç¶æ
ãããŒã«ã«ã§ç¢ºèªããŸãã å®è¡ã³ãã³ã # A: CPUå¶éãªã docker run --rm cgroup-bench info # B: CPUå¶é 1ã³ã¢ docker run --rm --cpus=1.0 cgroup-bench info # C: CPUå¶é 0.5ã³ã¢ docker run --rm --cpus=0.5 cgroup-bench info å®éã®çµæ A: CPUå¶éãªã === Go Runtime Information === GOMAXPROCS: 11 â Docker VMã®å
šCPUã³ã¢æ° NumCPU: 11 GOVERSION: go1.24.13 ENV GOMAXPROCS: (not set â using default) === cgroup CPU Information === cpu.max: max 100000 â "max" = äžéãªã B: CPUå¶é 1ã³ã¢ïŒ --cpus=1.0 ïŒ === Go Runtime Information === GOMAXPROCS: 11 â å¶éããããã®ã«11ã®ãŸãŸïŒ NumCPU: 11 GOVERSION: go1.24.13 ENV GOMAXPROCS: (not set â using default) === cgroup CPU Information === cpu.max: 100000 100000 â cgroupã«ã¯1ã³ã¢åã®å¶éãæ£ããèšå®ãããŠãã C: CPUå¶é 0.5ã³ã¢ïŒ --cpus=0.5 ïŒ === Go Runtime Information === GOMAXPROCS: 11 â ãŸã 11ã®ãŸãŸïŒ NumCPU: 11 === cgroup CPU Information === cpu.max: 50000 100000 â cgroupã«ã¯0.5ã³ã¢åã®å¶éãèšå®ãããŠãã çµæãèŠãŠã¿ã CPUå¶é cpu.maxïŒcgroupïŒ GOMAXPROCS éå°äžŠåã®åç ãªã max 100000 ïŒç¡å¶éïŒ 11 - 1ã³ã¢ 100000 100000 11 11å 0.5ã³ã¢ 50000 100000 11 22å å®å
šã«ç¡èŠããŠãŸããcgroupã«ã¯ cpu.max ãšããŠæ£ããCPUå¶éãèšå®ãããŠããã®ã«ã Go 1.24ã®ã©ã³ã¿ã€ã ã¯äžåèŠãŠããªã ãGOMAXPROCSã¯åžžã«ãã¹ãïŒDocker VMïŒã®CPUæ°=11ãããã©ã«ãã çºè¡šã®æ¬çªç°å¢ã§ã¯48ã³ã¢Nodeã§ limits.cpu: 5000m ã ã£ãã®ã§ã GOMAXPROCS=48ïŒçŽ10åã®éå°äžŠåïŒ ãèµ·ããŠãããããŒã«ã«ã§ãåãæ§é ã®åé¡ãåçŸã§ããŸããã cpu.max ã®èªã¿æ¹ : ã¯ã©ãŒã¿ ããªãªã ã®åœ¢åŒãããªãªãïŒããã©ã«ã100ms=100000ÎŒsïŒã®ãã¡ãã¯ã©ãŒã¿åã ãCPUã䜿ããã 50000 100000 ãªãã100msã®ãã¡50ms䜿çšå¯èœ = 0.5ã³ã¢åãã å®éš2: éå°äžŠåã¯ã¹ã«ãŒããããäœäžããã äœã確èªããã çºè¡šã§ã¯ GOMAXPROCS ã48â5ã«å€ãããã¹ã«ãŒãããã倧å¹
æ¹åãGoã¹ã±ãžã¥ãŒã©ã® CPU䜿çšçã50%ä»¥äžæžã£ããšã®ããšãåãäœéšãããŒã«ã«ã§ãæ°åã§èŠãŠã¿ãŸãã å®è¡ã³ãã³ã CPUå¶é1ã³ã¢ã®ç°å¢ã§ã100åã®goroutineã10ç§éèµ°ãããŸããå€ããã®ã¯GOMAXPROCSã ãã # GOMAXPROCS=1ïŒCPUå¶éã«äžèŽ = é©åïŒ docker run --rm --cpus=1.0 \ -e GOMAXPROCS=1 -e BENCH_DURATION=10s -e BENCH_GOROUTINES=100 \ cgroup-bench benchmark # GOMAXPROCS=8ïŒCPUå¶éã®8å = éå°äžŠåïŒ docker run --rm --cpus=1.0 \ -e GOMAXPROCS=8 -e BENCH_DURATION=10s -e BENCH_GOROUTINES=100 \ cgroup-bench benchmark å®éã®çµæ GOMAXPROCS=1ïŒé©åãªäžŠåæ°ïŒ: GOMAXPROCS=1 Ops/sec=21503.63 Total=215525 cpu.stat: nr_periods 101 nr_throttled 56 throttled_usec 43791 GOMAXPROCS=8ïŒéå°äžŠåïŒ: GOMAXPROCS=8 Ops/sec=6832.54 Total=68646 cpu.stat: nr_periods 102 nr_throttled 101 throttled_usec 70703432 çµæãèŠãŠã¿ã ææš GOMAXPROCS=1 GOMAXPROCS=8 å·®å Ops/secïŒã¹ã«ãŒãããïŒ 21,504 6,833 68.2% äœäž nr_throttled / nr_periods 56/101 (55%) 101/102 ( 99% ) ã»ãŒå
šããªãªãã§åæ¢ throttled_usecïŒçޝç©åæ¢æéïŒ 43,791ÎŒs (0.04ç§) 70,703,432ÎŒs (70.7ç§) 1,614å æ£çŽããããŸã§å·®ãåºããšã¯æã£ãŠããŸããã§ããã GOMAXPROCS ã1â8ã«ããã ãã§ã ã¹ã«ãŒããããçŽ3åã®1ã«èœã¡ã 10ç§éã®ãã¹ã㧠环èš70.7ç§ãã®CPU忢 ïŒ8ã¹ã¬ãããåçŽ8.8ç§ãã€æ¢ãŸã£ãèšç®ïŒ ã¹ããããªã³ã°ç99% â ã»ãŒæ¯ããªãªãã§å
šã¹ã¬ãããæ¢ããããŠãã çºè¡šã§èª¬æãããŠããã ã¯ã©ãŒã¿ãã¹ã¬ãããå
±é£ããã ãçŸè±¡ãã®ãã®ã§ãã âââââââââ 1ããªãªã (100ms) âââââââââ GOMAXPROCS=1 ã®å Žå: [ââââââââ å®è¡ ââââââââ][ââ 忢 ââ] â 1ã¹ã¬ããã§ç©ããã«äœ¿ã GOMAXPROCS=8 ã®å Žå: [â 8ã¹ã¬ããäžæå®è¡ â][ââââââââââââââââââââââ é·æé忢 ââââââââââââââââââââââ] â ã¯ã©ãŒã¿æ¯æž â å
šã¹ã¬ãããåæã«ã¹ããããªã³ã° å®éš3: ã¹ããããªã³ã°ã®æ·±å»åºŠã¯ã¹ã¬ããæ°ã§å€ãã äœã確èªããã çºè¡šã§ã æéãèŠãã°ãããªãªãã®%ãåãã§ãæ·±å»åºŠã®éããåãã ããšææãããŠããŸããããããå®éã« nr_throttled ïŒåæ°ïŒã¯åãããããªã®ã« throttled_usec ïŒåæ¢æéïŒã«ã¯å€§ããªå·®ãåºããšããããšãªã®ã§ãèªåã®ç®ã§èŠãŠã¿ãŸãã å®è¡ã³ãã³ã CPUå¶é0.5ã³ã¢ïŒããªãå³ããå¶éïŒã§GOMAXPROCS=8 vs 1 ãæ¯èŒã # éå°äžŠåïŒGOMAXPROCS=8, CPU=0.5ã³ã¢ïŒ docker run --rm --cpus=0.5 -e GOMAXPROCS=8 -e DEMO_DURATION=5s cgroup-bench throttle-demo # é©åãªäžŠåïŒGOMAXPROCS=1, CPU=0.5ã³ã¢ïŒ docker run --rm --cpus=0.5 -e GOMAXPROCS=1 -e DEMO_DURATION=5s cgroup-bench throttle-demo å®éã®çµæ GOMAXPROCS=8ïŒéå°äžŠåïŒ: --- After --- nr_periods 52 nr_throttled 51 â 98%ã®ããªãªãã§ã¹ããããªã³ã° throttled_usec 39039180 â 39ç§ã®CPU忢 GOMAXPROCS=1ïŒé©åïŒ: --- After --- nr_periods 51 nr_throttled 50 â 98%ã®ããªãªãã§ã¹ããããªã³ã°ïŒã»ãŒåãïŒïŒ throttled_usec 2644221 â 2.6ç§ã®CPU忢 çµæãèŠãŠã¿ã ææš GOMAXPROCS=8 GOMAXPROCS=1 å·®å nr_throttled / nr_periods 51/52 (98%) 50/51 (98%) ã»ãŒåã throttled_usec 39,039,180ÎŒs (39ç§) 2,644,221ÎŒs (2.6ç§) 14.8å æ°åãèªåã§äžŠã¹ãŠã¿ãŠãåããŠæ·±å»ããããããŸããã nr_throttled ã®å²åïŒã¹ããããªã³ã°çïŒã ãèŠããšã©ã£ã¡ã98%ã§å
šãåãã«èŠããŸããã§ã throttled_usec ïŒå®éã®åæ¢æéïŒã«ã¯14.8åãã®å·®ãããã ãããçºè¡šã§èšãããŠãããCPU䜿çšçã ãã§ã¯æ°ã¥ããªãããç£èŠã®æ»è§ãã®æ£äœã§ãã ãªãCPU䜿çšçã§ã¯èŠããªãã®ã ãããããå°ãæãäžããŸããå®ã¯ãã®å®éšã ã©ã¡ãã®ã±ãŒã¹ãCPU䜿çšçã¯çŽ100% ãšè¡šç€ºãããŸãããããGOMAXPROCS=8 ã®ã»ããé
ãã®ã«CPU䜿çšçã¯åãïŒããšæããããããŸããããããã«ã¯ã«ã©ã¯ãªããããŸãã CPU䜿çšçã®èšç®åŒã¯æ¬è³ªçã«ããã§ã: $$ \text{CPU䜿çšç} = \frac{\text{æ¶è²»ããCPUæé}}{\text{å²ãåœãŠã¯ã©ãŒã¿}} $$ ä»åã®å®éšã§ã¯ --cpus=0.5 ãªã®ã§ã1ããªãªãïŒ100msïŒãããã®ã¯ã©ãŒã¿ã¯ 50ms ã§ãã GOMAXPROCS=1 GOMAXPROCS=8 ã¯ã©ãŒã¿ 50ms / period 50ms / period æ¶è²»CPUæé 50msïŒäœ¿ãåãïŒ 50msïŒäœ¿ãåãïŒ CPU䜿çšç â100% â100% æ¶è²»ããŒã¹ 1ã¹ã¬ãã à 50ms = 50msãããŠåŸã
ã« 8ã¹ã¬ãã à 6.25ms = çŽ6msã§äžæ°ã« æ®ãã®æé 50mséã¯åæ¢ïŒç©ããïŒ 94msé å
šã¹ã¬ããåçµ ã©ã¡ããã¯ã©ãŒã¿50msã䜿ãåãã®ã§ãCPU䜿çšçã¯åã100%ã§ããããã æ¶è²»ã®ããŒã¹ããŸãã§éããŸã ã 1ããªãªãïŒ100msïŒã®å
èš³: GOMAXPROCS=1: |ââââââââââââââââââââââââââââââââââââââââââââââ| â 1ã¹ã¬ããã§50mså®è¡ ââ 50ms åŸ
æ© â CPU䜿çšç: 50/50 = 100% ã¬ã€ãã³ã·: å®å® GOMAXPROCS=8: |âââââââââââââââââââââââââââââââââââââââââââââ| â6msâââââââââââ 94ms å
šã¹ã¬ããåçµ âââââââââââ CPU䜿çšç: 50/50 = 100% ã¬ã€ãã³ã·: ã¹ãã€ã¯çºç GOMAXPROCS=1 ã¯1ã¹ã¬ããã§50msãç©ããã«æ¶è²»ããã®ã§ãåŠçã¯éåãã€ã€ãæ¯èŒçåçã«é²ã¿ãŸããäžæ¹ GOMAXPROCS=8 ã¯8ã¹ã¬ãããåæã«CPUãèŠæ±ããããããããçŽ6msã§ã¯ã©ãŒã¿ãé£ãå°œããã æ®ãã®94msã¯å
šã¹ã¬ãããå®å
šã«åçµ ããŸãã ã€ãŸãCPU䜿çšç100%ã®è£ã§èµ·ããŠããããšãå
šãç°ãªãã®ã«ã éçŽã¡ããªã¯ã¹ã§ã¯ãã®éããæ¶ããŠããŸã ãããããç£èŠã®æ»è§ãã®æ¬è³ªã§ãã ãŸãšãããš: nr_throttledçãåãã§ãã 8ã¹ã¬ãããåæã«æ¢ãŸã ã®ãš 1ã¹ã¬ããã ãæ¢ãŸã ã®ã§ã¯æ·±å»åºŠããŸãã§éã CPU䜿çšç㯠ã¯ã©ãŒã¿ãæ¶è²»ããé ãã瀺ããã æ¶è²»ã®ããŒã¹ïŒããŒã¹ãæ§ïŒãäžååæ ããªã throttled_usec ãåãããŠç£èŠããªããšãã¹ããããªã³ã°ã®å®æ
ã¯ã€ãããªã å®éš4: ã¹ã¬ããæ°ãšåæ¢æéã®çžé¢ äœã確èªããã ã¹ã¬ããæ°ãæ®µéçã«å¢ããããšãã throttled_usec ãæ¯äŸããŠå¢ããã®ããçºè¡šã¹ã©ã€ãã®ã ã¯ã©ãŒã¿ã¯ã¹ã¬ããéã§å
±æ ãã ã¹ã¬ãããå€ãã»ã©æ©ãæ¶è²» ããšãã説æããã°ã©ãã§äœæããŠã¿ãŸãã å®è¡ã³ãã³ã for MAXPROCS in 1 2 4 8 16; do echo "--- GOMAXPROCS=$MAXPROCS ---" docker run --rm --cpus=1.0 -e GOMAXPROCS=$MAXPROCS -e DEMO_DURATION=5s \ cgroup-bench throttle-demo 2>&1 \ | grep -E "nr_periods|nr_throttled|throttled_usec" | tail -3 echo "" done å®éã®çµæ --- GOMAXPROCS=1 --- nr_periods 51 nr_throttled 20 throttled_usec 21885 --- GOMAXPROCS=2 --- nr_periods 51 nr_throttled 50 throttled_usec 5075001 --- GOMAXPROCS=4 --- nr_periods 51 nr_throttled 50 throttled_usec 15053306 --- GOMAXPROCS=8 --- nr_periods 52 nr_throttled 51 throttled_usec 35847841 --- GOMAXPROCS=16 --- nr_periods 51 nr_throttled 51 throttled_usec 50338309 çµæãèŠãŠã¿ã GOMAXPROCS nr_throttled ã¹ããããªã³ã°ç throttled_usec 环ç©åæ¢æé 1 20 / 51 39% 21,885 0.02ç§ 2 50 / 51 98% 5,075,001 5.1ç§ 4 50 / 51 98% 15,053,306 15.1ç§ 8 51 / 52 98% 35,847,841 35.8ç§ 16 51 / 51 100% 50,338,309 50.3ç§ åæ¢æé (ç§) 50 †â GOMAXPROCS=16 â â± 40 †Ⱡâ â± 35 †â â± GOMAXPROCS=8 â â± â± 20 †Ⱡâ â± 15 †â â± GOMAXPROCS=4 â â± â± 10 †Ⱡâ â± 5 †â â± GOMAXPROCS=2 â â²â± 0 â€â GOMAXPROCS=1 ââââ¬âââ¬âââ¬âââ¬âââ¬âââ¬ââ 1 2 4 8 12 16 GOMAXPROCS GOMAXPROCS=1ã8ã®ç¯å²ã§ã¯ã»ãŒç·åœ¢ã«æ¯äŸããŠããŸãã GOMAXPROCS=1 â 0.02ç§ïŒã»ãŒåæ¢ãªãïŒ GOMAXPROCS=16 â 50.3ç§ïŒ5ç§ã®ãã¹ãã§çޝèš50ç§åã®åæ¢ïŒïŒ ãã ã GOMAXPROCS=16 ã§ã¯ãåæã«CPUã䜿ããã¹ã¬ããæ°ã Docker VM ã®ç©çCPUæ°ïŒ11ã³ã¢ïŒã§é æã¡ã«ãªããããçŽç²ãªç·åœ¢ã¢ãã«ã®äºæž¬ïŒ75ç§ïŒããäœã50.3ç§ã«é£œåããŠããŸãã16ã¹ã¬ããäžãåæã«å®è¡ã§ããã®ã¯æå€§11ã¹ã¬ãããªã®ã§ã忢æé㯠$\min(n, 11) \times P - Q$ ã«è¿ã¥ããŸãã GOMAXPROCS=8 以äžã§ã¯ç©çCPUæ°ã®å¶çŽãåããªãããããããã« $n \times P - Q$ ã®ç·åœ¢ã¢ãã«ãšäžèŽããŠããŸãïŒ8ã¹ã¬ããæã®äºæž¬35ç§ vs 宿ž¬35.8ç§ïŒã çºè¡šã§ãã Thundering Herd åé¡ ãã®ãã®ã§ãã¯ã©ãŒã¿ãªã»ããã§å
šã¹ã¬ãããäžæã«åé â å
±æã¯ã©ãŒã¿ãç¬æ®º â å
šã¹ã¬ããåæåæ¢ãã®ãµã€ã¯ã«ãç¹°ãè¿ãããã 3. èå¯: ãªãã¹ã¬ãããå¢ãããšãé
ããªããã®ã å®éš4ã®çµæãæ¹ããŠèŠããšã throttled_usec ãã¹ã¬ããæ°ã«ã»ãŒæ¯äŸããŠå¢ããŠããŸãããã¹ã¬ãããå¢ããã»ã©æããããã£ãŠãçŽæã«åããŸãããCFS 垯åå¶åŸ¡ã®ä»çµã¿ããæ°åŒã§èª¬æã§ããŸãã CFS 垯åå¶åŸ¡ã®æ°ç â ã¯ã©ãŒã¿æ¶è²»ã®ã¢ãã« cgroup ã® CPU å¶éã¯ã1ããªãªãïŒ100msïŒããã $Q$ ã ã CPU ã䜿ããããšããã¯ã©ãŒã¿å¶ã§ãã --cpus=1.0 ãªã $Q = 100\text{ms}$ ã§ãã $n$ æ¬ã®ã¹ã¬ãããåæã«ãã«çšŒåãããšãCPU æé㯠$n$ åã®éåºŠã§æ¶è²»ãããŸããã€ãŸã: ã¯ã©ãŒã¿æ¯æžãŸã§ã®æé : $\frac{Q}{n}$ æ®ãã®ããªãªã : å
š $n$ ã¹ã¬ãããåæã«åæ¢ 1ã¹ã¬ãããããã®åæ¢æé : $\text{ããªãªã} - \frac{Q}{n}$ 环ç©åæ¢æé ïŒ= throttled_usec ïŒ: $n \times \left(\text{ããªãªã} - \frac{Q}{n}\right)$ -cpus=1.0 ïŒ$Q = 100\text{ms}$ãããªãªã $= 100\text{ms}$ïŒã§ $n = 8$ ã®å Žå: ã¯ã©ãŒã¿æ¯æž: $\frac{100}{8} = 12.5\text{ms}$ ã§äœ¿ãåã åã¹ã¬ããã®åæ¢: $100 - 12.5 = 87.5\text{ms}$ 1ããªãªããããã®çޝç©åæ¢: $8 \times 87.5 = 700\text{ms}$ 5ç§éïŒ50ããªãªãïŒãªã $50 \times 700\text{ms} = 35\text{ç§}$ãå®éš4ã® GOMAXPROCS=8 ã®çµæïŒ35.8ç§ïŒãšã»ãŒäžèŽããŸãã USL ã§èŠããšã¹ã«ãŒãããæªåã説æãã€ã ãã®çŸè±¡ãã¹ã±ãŒãªã³ã°æ³åã®èгç¹ããèŠããšãNeil Gunther ã® USLïŒUniversal Scalability LawïŒ ãåœãŠã¯ãŸããŸã: $$ S(n) = \frac{n}{1 + \alpha(n-1) + \beta \cdot n(n-1)} $$ ãã©ã¡ãŒã¿ æå³ cgroup ç°å¢ã§ã®å
·äœäŸ $\alpha$ ç«¶å â çŽååããã«ã㣠Go ã¹ã±ãžã¥ãŒã©ã®ããã¯ç«¶åãã©ã³ãã¥ãŒç®¡ç $\beta$ äžè²«æ§ â ã¹ã¬ããéã®å調ã³ã¹ã CFS ã¯ã©ãŒã¿ã®å
±ææ¶è²» + å
šã¹ã¬ããäžæåæ¢ USL ã§å¹ããŠããã®ã¯ $\beta$ ã®é
ã§ãã$\beta \cdot n(n-1)$ 㯠$n 2 $ ãªãŒããŒã§å¢å€§ãããããããéŸå€ãè¶
ãããšã¹ã«ãŒãããã ããŒã¯ããæžå°ã«è»¢ããŸã ãå®éš2ã®ãGOMAXPROCS=8 ã§ 68% äœäžãã¯ããã® retrogradeïŒéè¡ïŒé åã«å
¥ã£ãçµæã§ãã ã¹ã«ãŒããã â â ããŒã¯ïŒGOMAXPROCS=1ïŒ â â±â² â â± â² â USL ã® retrograde é å â â± â² ââ± â² â GOMAXPROCS=8ïŒ68%äœäžïŒ ââââââââââââ ã¹ã¬ããæ° cgroupå¶éäžã§ã¯ãã¹ã¬ãã1æ¬ããããŒã¯ã å¢ããã»ã©ã¯ã©ãŒã¿ã®å¥ªãåãã§æãããã éåžžã®äžŠåããã°ã©ãã³ã°ã§ã¯ãã³ã¢æ°ãŸã§ã¯ã¹ã±ãŒã«ãããã®ãåžžèã§ãããcgroup ã§ãªãœãŒã¹ãå¶éãããç°å¢ã§ã¯ ã¹ã¬ãã1æ¬ããã§ã«æé©è§£ ãšããçŽæã«åããçµæã«ãªããCPU æéã®ç·éãåºå®ããããŒããµã ç°å¢ãªã®ã§ãã¹ã¬ãããå¢ããã»ã©ãã¯ã©ãŒã¿ã®å¥ªãåã â äžæåæ¢ â åé â ãŸãæ¯æžãã®ãµã€ã¯ã«ãéããªãã ãã ãI/O åŸ
ã¡ãããå Žåã¯ã©ããªã®ãïŒã ãããŸã§ã®å®éšã¯ cpuIntensiveWork() ã«ãã çŽç²ãª CPU ããŠã³ãåŠç ã§ãããI/O åŸ
ã¡ããããªãã¹ã¬ãããå¢ãããã»ãããããããïŒããšæããŸããããäžè¬è«ãšããŠã¯ãã®éãã§ãã¹ã¬ããã I/O ã§åŸ
ã£ãŠããé㯠CPU ã¯ã©ãŒã¿ãæ¶è²»ããªãã®ã§ãCPU æ°ããå€ãã¹ã¬ãããæå¹ãªå Žé¢ã¯ãããŸãã ãã ã Go ã®å Žåã¯è©±ãå¥ ã§ããGoã©ã³ã¿ã€ã ã«ã¯ä»¥äžã®ä»çµã¿ãããã®ã§ãGOMAXPROCS ã I/O ã®ããã«å¢ããå¿
èŠã¯åºæ¬çã«ãªãã§ã: I/O ã®çš®é¡ Goã©ã³ã¿ã€ã ã®æå GOMAXPROCS ãžã®åœ±é¿ ãããã¯ãŒã¯ I/O netpoller ãéåæåŠçãgoroutine ã¯åŸ
ã€ã OS ã¹ã¬ããã¯ãããã¯ããªã 圱é¿ãªã ããããã³ã° syscall ïŒãã¡ã€ã« I/O, CGO çïŒ ã©ã³ã¿ã€ã ã GOMAXPROCS ãšã¯ å¥ã«è¿œå ã® OS ã¹ã¬ãããèªåçæ åœ±é¿ãªã ã€ãŸã Go ã§ã¯ããããã¯ãŒã¯ I/O 㯠goroutine ã¬ãã«ã§å€éåãããããããã³ã° I/O 㯠GOMAXPROCS ã®æ å€ã§åŠçããããGOMAXPROCS ãå¶åŸ¡ããã®ã¯ CPU ãå®éã«äœ¿ãã¹ã¬ããã®æ° ã ããªã®ã§ãI/O ã®å€å¯¡ã«é¢ããã GOMAXPROCS = CPU å¶é ãæ£è§£ã§ãã DB ã¯ãšãªã API åŒã³åºãã倧éã«è¡ã Web ãµãŒãã¹ã§ããGOMAXPROCS=5ïŒCPU å¶éã«äžèŽïŒã§å€§å¹
ã«æ¹åããäºäŸãããã®ã¯ããã®ä»çµã¿ãããããã§ãã äžæ¹ãGo 以å€ã®ã©ã³ã¿ã€ã ã§ã¯ãããããäºæ
ãéãã®ã§æŽçããŠãããŸã: ã©ã³ã¿ã€ã 䞊åã®ä»çµã¿ cgroup ã®åœ±é¿ Java ã¹ã¬ããããŒã«ïŒForkJoinPool çïŒã§äžŠååã Runtime.availableProcessors() ã®å€ãåºæºã«ããŒã«ãµã€ãºã決ãŸãããšãå€ã ã¹ã¬ããããŒã«ãµã€ãºã CPU limit ãã倧ããå€ã«ãããšã¹ããããªã³ã°çºç Node.js ã¡ã€ã³ã¹ã¬ããã¯ã·ã³ã°ã«ã UV_THREADPOOL_SIZE ïŒããã©ã«ã4ïŒã§ fs/dns çã®ããããã³ã° I/O ãåŠçãCPU ããŠã³ãåŠç㯠worker_threads ã§äžŠåå worker_threads ã®æ°ã CPU limit ãã倧ããå€ã«ãããšã¹ããããªã³ã°çºç Ruby (CRuby) GVLïŒGlobal VM LockïŒããããããã¹ã¬ãããå¢ãããŠã CPU ããŠã³ãåŠçã¯äžŠåå®è¡ãããªã ãPuma çã® Web ãµãŒããŒã¯ workers ïŒfork ã«ãããã«ãããã»ã¹ïŒã§äžŠåå Puma ã® workers ã CPU limit ãã倧ããå€ã«ãããšã¹ããããªã³ã°çºç 4. çºè¡šã®å
容ãããŒã«ã«ã§åçŸã§ãããïŒ å
šæ€èšŒçµæãŸãšã # çºè¡šã®ãã€ã³ã ããŒã«ã«æ€èšŒã®çµæ åçŸ 1 GOMAXPROCSã¯cgroupã®CPUå¶éãèæ
®ããªãïŒGo 1.24以åïŒ --cpus=0.5 ã§ã GOMAXPROCS=11ïŒãã¹ãCPUæ°ïŒã®ãŸãŸ åçŸ 2 limits.cpu 㯠cgroup ã® cpu.max ïŒã¯ã©ãŒã¿/ããªãªãïŒã«å€æããã --cpus=0.5 â cpu.max: 50000 100000 ãç¢ºèª åçŸ 3 éå°äžŠåã¯ã¹ã«ãŒããããäœäžããã GOMAXPROCS 1â8 ã§ Ops/sec ã 68.2% äœäž ïŒ21,504 â 6,833ïŒ åçŸ 4 ã¯ã©ãŒã¿ã¯ã¹ã¬ããéã§å
±æãããå€ãã»ã©æ©ãæ¶è²»ããã ã¹ã¬ããæ°ãš throttled_usec ãã»ãŒç·åœ¢ã«æ¯äŸ åçŸ 5 ã¹ããããªã³ã°æã¯å
šã¹ã¬ãããåæã«åæ¢ãã GOMAXPROCS=16ã§5ç§éã«çޝèš50.3ç§åã®åæ¢ãç¢ºèª åçŸ 6 CPU䜿çšçã ãã§ã¯ã¹ããããªã³ã°ã«æ°ã¥ããªã nr_throttled çã¯åã98%ã§ã throttled_usec ã«14.8åã®å·® åçŸ 7 GOMAXPROCSãCPUå¶éã«åããããšæ¹åãã GOMAXPROCS=1 ã§åæ¢æéã 1/1,614 ã«æ¹å åçŸ ãã¹ãŠæå
ã§åçŸã§ããŸããã Docker ãš Go 1.24 ã ãã§ãããŸã§äœéšã§ããã®ã¯ããã£ãŠã¿ãŠããã£ããšçŽ çŽã«æããŸãã å人çã«å°è±¡ã«æ®ã£ãæ°å æ¯èŒ éå°äžŠåã®å Žå é©åãªäžŠåã®å Žå åç Ops/secïŒã¹ã«ãŒãããïŒ 6,833 21,504 3.1åã®å·® throttled_usecïŒåæ¢æéïŒ 70.7ç§ 0.04ç§ 1,614åã®å·® GOMAXPROCS=16ã®åæ¢æé 50.3ç§ - 5ç§ã®ãã¹ãã§50ç§åæ¢ æ¬çªç°å¢ãšã®å¯Ÿå¿é¢ä¿ çºè¡š ããŒã«ã«æ€èšŒ 48ã³ã¢Node 11ã³ã¢ Docker VM limits.cpu: 5000m --cpus=0.5 GOMAXPROCS=48ïŒããã©ã«ãïŒ GOMAXPROCS=11ïŒããã©ã«ãïŒ éå°äžŠååç: çŽ10å éå°äžŠååç: æå€§22å /sys/fs/cgroup/cpu.max åããã¹ïŒDockerå
LinuxïŒ cpu.stat ã® nr_throttled åãã¡ããªã¯ã¹ æ¬çªã§ã¯ããã«HAProxyïŒ nbthread=48 , CPUå¶é1ã³ã¢ = 48åã®éå°äžŠå ïŒã§ãåãåé¡ãèµ·ããŠããããã§ãGoã«éã£ã話ã§ã¯ãªããšããããšãããããŸãã ãŸãšã 1. 䞊åèšå®ã cgroup-aware ã«ãã GOMAXPROCS ã«éããã ã³ã³ããå
ã§åããã¹ãŠã®ããã»ã¹ã®äžŠåèšå® ã¯ç¢ºèªããã»ããããã§ãã ãœãããŠã§ã¢ 䞊åèšå® å¯ŸåŠ Go GOMAXPROCS Go 1.25+ ã§èªåå¯Ÿå¿ / 1.24以å㯠uber-go/automaxprocs Ruby (Puma) WEB_CONCURRENCY / workers CPUå¶éã«åãããŠæç€ºæå®ãcgroupé察å¿ã® auto èšå®ã«æ³šæ Java ã¹ã¬ããããŒã«ãµã€ãº JDK 10+ 㯠availableProcessors() ã cgroup èªèãã©ã€ãã©ãªåŽãèŠç¢ºèª Node.js worker_threads æ° CPU ããŠã³ãåŠçã®äžŠåæ°ã CPU å¶éã«åããã HAProxy nbthread æåã§CPUå¶éã«åãããŠèšå® Nginx worker_processes auto ã¯cgroupé察å¿ã®å Žåãããæç€ºæå®ãå®å
š 2. ã¹ããããªã³ã°ãç£èŠãã CPU䜿çšçã ããããªããŠã ã¹ããããªã³ã°ã®ã¡ããªã¯ã¹ãã»ããã§èŠã ããããæ ããšå®éš3ã§èŠããããªæ»è§ã«ããããŸãã ã¡ããªã¯ã¹ Linux Datadog 忢æé throttled_usec kubernetes.cpu.cfs.throttled.seconds 忢ããªãªãæ° nr_throttled kubernetes.cpu.cfs.throttled.periods 3. throttled_usec ãŸã§èŠã ä»åã®å®éšãéããŠäžçªã®åç©«ã¯ã nr_throttled ã®å²åãåã 98% ã§ãã throttled_usec ã« 14.8åã®å·®ããã ãšèªåã®æã§ç¢ºèªã§ããããšãã¹ããããªã³ã°çã ãèŠãŠãã å®éã«ã©ãã ãæ¢ãŸã£ãŠãããã¯èŠããªã ã CPUããã£ãšç¥ããããªã£ãæ¹ãž â å人çãªããããæ¬ ä»åã®æ€èšŒãéããŠããã£ãšCPUã®äžèº«ãçè§£ããããªã£ãããšããæ¹ã«ãå人çã«åŒ·ããããããããäžåããããŸãã ãããã°ã©ããŒã®ããã®CPUå
¥é â CPUã¯åŠäœã«ããŠãœãããŠã§ã¢ãé«éã«å®è¡ãããã ãã€ãã©ã€ã³ãã¹ãŒããŒã¹ã«ã©ãåå²äºæž¬ããã£ãã·ã¥ãã¡ã¢ãªãªãŒããªã³ã°ãšãã£ãã æ®æ®µã¯æèããªãããã©æ§èœã«çŽçµããCPUå
éšã®ã¡ã«ããºã ããããã°ã©ããŒã®ç®ç·ã§äžéãæŽçãããŠããæ¬ã§ããæ¬èšäºã®è±ç·ã§è§Šãããã£ãã·ã¥ã³ããŒã¬ã³ã·ãŸãããããã®æ¬ãèªããšããè
ã«èœã¡ããšæããŸãã ããªããã®ã³ãŒãã¯éãã®ãïŒé
ãã®ããããããŒããŠã§ã¢å¯ãã®èŠç¹ããèããããããã«ãªãæ¬ãªã®ã§ãcgroup ã®æåã®å
ãèŠããŠã¿ããæ¹ã«ãŽã£ããã§ãã åè ãã¢ãŒãºæ¬çªç°å¢ã§ã®cgroup-awareåãšã®æ»éé²ïŒçºè¡šã¹ã©ã€ãïŒ â æ¬èšäºã®ããŒã¹ãšãªã£ãçºè¡š ã¯ã©ãŠããã€ãã£ãäŒè°2026 ã»ãã·ã§ã³ããŒãž Container-aware GOMAXPROCS | Go 1.25 Release Notes uber-go/automaxprocs â Go 1.24以åã§äœ¿ããcgroup-aware GOMAXPROCS Kubernetes CPU limits and requests: A deep dive | Datadog æ€èšŒã³ãŒã æ¬èšäºã®æ€èšŒã«äœ¿ã£ãã³ãŒãã¯ä»¥äžã®ãªããžããªã«ãããŸã: git clone https://github.com/hirosi1900day/cgroup-throttling-lab.git cd cgroup-throttling-lab docker build -t cgroup-bench go-app/ ./scripts/run_experiments.sh # å
šå®éšãäžæ¬å®è¡

















