èšäºã¯ã Jiga Akhaltsev ã Jigaã代衚ããŠå
¬éãããŠããŸãã
ä»æ¥ã®Tinkoff.ruã¯åãªãéè¡ã§ã¯ãªããITäŒæ¥ã§ãã éè¡ãµãŒãã¹ã ãã§ãªããããããåãå·»ããšã³ã·ã¹ãã ãæ§ç¯ããŸãã
Tinkoff.ruã§ã¯ãããŸããŸãªãµãŒãã¹ãšããŒãããŒã·ãããçµã³ã顧客ãµãŒãã¹ã®å質ãåäžãããæ¹åãæ¯æŽããŠããŸãã ããšãã°ããããã®ãµãŒãã¹ã®1ã€ã«ã€ããŠè² è·ãã¹ããšããã©ãŒãã³ã¹åæãå®æœããŸãããããã¯ãã·ã¹ãã ã®ããã«ããã¯ãèŠã€ããã®ã«åœ¹ç«ã¡ãŸãã-OSæ§æã«ééçãªå·šå€§ããŒãžãå«ãŸããŠããŸãã
ã·ã¹ãã ããã©ãŒãã³ã¹ã®åææ¹æ³ãšãã®çµæãç¥ãããå Žåã¯ãcatãžããããã
åé¡ã®èª¬æ
çŸåšããµãŒãã¹ã¢ãŒããã¯ãã£ã¯æ¬¡ã®ãšããã§ãã
- HTTPæ¥ç¶ãåŠçããããã®Nginx WebãµãŒããŒ
- PHPããã»ã¹å¶åŸ¡ã®PHP-FPM
- ãã£ãã·ã¥çšã®Redis
- ããŒã¿ã¹ãã¬ãŒãžçšã®PostgreSQL
- ã¯ã³ã¹ãããã·ã§ããã³ã°ãœãªã¥ãŒã·ã§ã³
次ã®é«è² è·æã®è²©å£²ã§èŠã€ãã£ãäž»ãªåé¡ã¯ãCPUã®äœ¿çšçãé«ãããšã§ããããã«ãŒãã«ã¢ãŒãã®ããã»ããµæéïŒã·ã¹ãã æéïŒã¯å¢å ãããŠãŒã¶ãŒã¢ãŒãã®æéïŒãŠãŒã¶ãŒæéïŒãããé·ããªããŸããã
- ãŠãŒã¶ãŒæé-ããã»ããµãŒããŠãŒã¶ãŒã®ã¿ã¹ã¯ã«è²»ããæéã ããã¯ãããã»ããµã賌å
¥ãããšãã«æ¯æãäž»ãªãã®ã§ãã
- ã·ã¹ãã æé-ã·ã¹ãã ãããŒãžã³ã°ãã³ã³ããã¹ãã®å€æŽãã¹ã±ãžã¥ãŒã«ãããã¿ã¹ã¯ã®èµ·åãããã³ãã®ä»ã®ã·ã¹ãã ã¿ã¹ã¯ã«è²»ããæéã
ã·ã¹ãã ã®äž»èŠãªç¹æ§ã®æ±ºå®
ãŸããçç£æ§ã«è¿ããªãœãŒã¹ã§è² è·åè·¯ãåéããéåžžã®éåžžã®è² è·ã«å¯Ÿå¿ããè² è·ãããã¡ã€ã«ãã³ã³ãã€ã«ããŸããã
ã¬ããªã³ã°ããŒãžã§ã³3ãç ²æããŒã«ãšããŠéžæãããç ²æèªäœã¯gitlab-runnerãä»ããŠããŒã«ã«ãããã¯ãŒã¯å
ã§å®è¡ãããŸããã åãããŒã«ã«ãããã¯ãŒã¯å
ã®ãšãŒãžã§ã³ããšã¿ãŒã²ããã®å Žæã¯ãããã¯ãŒã¯ã³ã¹ãã®åæžã«ãããã®ã§ãããããã·ã¹ãã ãå±éãããŠããã€ã³ãã©ã¹ãã©ã¯ãã£ã®ããã©ãŒãã³ã¹ã§ã¯ãªããã³ãŒãèªäœã®å®è¡ã®ç¢ºèªã«éç¹ã眮ããŠããŸãã
ã·ã¹ãã ã®äž»èŠãªç¹æ§ã決å®ããå Žåãhttpæ§æã§è² è·ãçŽç·çã«å¢å ããã·ããªãªãé©ããŠããŸãã
val httpConfig: HttpProtocolBuilder = http .baseUrl("https://test.host.ru") .inferHtmlResources()
ãã®æ®µéã§ãã¡ã€ã³ããŒãžãéããŠãã¹ãŠã®ãªãœãŒã¹ãããŠã³ããŒãããã¹ã¯ãªãããå®è£
ããŸãã
ãã®ãã¹ãã®çµæãæ倧æ§èœã¯1500 rpsã§ãããè² è·åŒ·åºŠãããã«å¢å ãããšãsoftirqæéã®å¢å ã«äŒŽãã·ã¹ãã ã®å£åãçºçããŸããã
Softirqã¯é
延å²ã蟌ã¿ã¡ã«ããºã ã§ãããkernel / softirq.sãã¡ã€ã«ã«èšè¿°ãããŠããŸãã åæã«ãããã»ããµãžã®åœä»€ã®ãã¥ãŒããããããŠãŒã¶ãŒã¢ãŒãã§æçšãªèšç®ãè¡ããªãããã«ããŸãã å²ã蟌ã¿ãã³ãã©ãŒã¯ãOSã¹ã¬ããã§ã®ãããã¯ãŒã¯ãã±ããã®è¿œå äœæ¥ãé
ãããããšãã§ããŸãïŒã·ã¹ãã æéïŒã ãããã¯ãŒã¯ã¹ã¿ãã¯ã®ä»äºãšæé©åã«ã€ããŠç°¡åã«ã¯å¥ã®èšäºã§èŠã€ããããšãã§ããŸãã
äž»ãªåé¡ã®çãã¯ç¢ºèªãããŸããã§ãããããã¯ããããã¯ãŒã¯ã¢ã¯ãã£ããã£ãå°ãªãã補åã®ã·ã¹ãã æéãéåžžã«é·ãããã§ãã
ãŠãŒã¶ãŒã¹ã¯ãªãã
次ã®ã¹ãããã¯ãã«ã¹ã¿ã ã¹ã¯ãªãããéçºããåçä»ãã®ããŒãžãéãã ãã§ã¯ãªãããšãè¿œå ããããšã§ããã ãããã¡ã€ã«ã«ã¯ãéçãªãªãœãŒã¹ãæäŸããWebãµãŒããŒã§ã¯ãªãããµã€ããšããŒã¿ããŒã¹ã®ã³ãŒããæ倧éã«å«ããéãæäœãå«ãŸããŠããŸããã
å®å®ããè² è·ã§ã®ãã¹ãã¯æ倧å€ãããäœã匷床ã§éå§ããããªãã€ã¬ã¯ãé·ç§»ãæ§æã«è¿œå ãããŸããã
val httpConfig: HttpProtocolBuilder = http .baseUrl("https://test.host.ru") .inferHtmlResources()
ã·ã¹ãã ã®æãå®å
šãªäœ¿çšã¯ãã·ã¹ãã æéã¡ããªãã¯ã®å¢å ãšå®å®æ§ãã¹ãäžã®å¢å ã瀺ããŸããã å®çšŒåç°å¢ã®åé¡ãåçŸãããŸããã
Redisãšã®ãããã¯ãŒãã³ã°
åé¡ãåæãããšããã·ã¹ãã ã®ãã¹ãŠã®ã³ã³ããŒãã³ããç£èŠããŠããããã©ã®ããã«æ©èœããäŸçµŠãããè² è·ãã·ã¹ãã ã«äžãã圱é¿ãç解ããããšãéåžžã«éèŠã§ãã
Redisã¢ãã¿ãªã³ã°ã®åºçŸã«ãããã·ã¹ãã ã®äžè¬çãªã¡ããªãã¯ã§ã¯ãªãããã®ç¹å®ã®ã³ã³ããŒãã³ããèŠãããšãå¯èœã«ãªããŸããã ã¹ãã¬ã¹ãã¹ãã®ã·ããªãªãå€æŽãããŸãããããã¯ãè¿œå ã®ç£èŠãšãšãã«ãåé¡ã®ããŒã«ã©ã€ãºãžã®ã¢ãããŒãã«åœ¹ç«ã¡ãŸããã
ç£èŠã§ã¯ãRedisãCPU䜿çšçãšåæ§ã®ç¶æ³ãèŠãŸããããCPUæéã®äž»ãªäœ¿çšçãSETæäœãã€ãŸãå€ãä¿åããããã®RAMã®å²ãåœãŠã«ããéãã·ã¹ãã æéã¯ãŠãŒã¶ãŒæéãããããªãé·ããªããŸãã
Redisãšã®ãããã¯ãŒã¯çžäºäœçšã®åœ±é¿ãæé€ããããã«ã仮説ããã¹ãããRedisãtcpãœã±ããã§ã¯ãªãUNIXãœã±ããã«åãæ¿ããããšã決å®ãããŸããã ããã¯ãphp-fpmãããŒã¿ããŒã¹ã«æ¥ç¶ãããã¬ãŒã ã¯ãŒã¯ã§è¡ãããŸããã ãã¡ã€ã«/yiisoft/yii/framework/caching/CRedisCache.phpã§ãhostïŒportã®è¡ãããŒãã³ãŒãredis.sockã«çœ®ãæããŸããã ãã®èšäºã§ãœã±ããã®ããã©ãŒãã³ã¹ã«ã€ããŠè©³ããèªãã§ãã ãã ã
protected function connect() { $this->_socket=@stream_socket_client(
æ®å¿µãªãããããã¯ããŸãå¹æããããŸããã§ããã CPU䜿çšçã¯å°ãå®å®ããŸããããåé¡ã¯è§£æ±ºããŸããã§ãã-CPU䜿çšçã®ã»ãšãã©ã¯ã«ãŒãã«ã¢ãŒãã³ã³ãã¥ãŒãã£ã³ã°ã§ããã
ã¹ãã¬ã¹ã䜿çšããŠTHPåé¡ãç¹å®ãããã³ãããŒã¯
ã¹ãã¬ã¹ãŠãŒãã£ãªãã£ã¯ãåé¡ã®å Žæãç¹å®ããã®ã«åœ¹ç«ã¡ãŸãã-POSIXã·ã¹ãã çšã®åçŽãªã¯ãŒã¯ããŒããžã§ãã¬ãŒã¿ãŒã¯ãCPUãã¡ã¢ãªãIOãªã©ã®åã
ã®ã·ã¹ãã ã³ã³ããŒãã³ããããŒãã§ããŸãã
ãã¹ãã¯ããŒããŠã§ã¢ãšOSããŒãžã§ã³ã§è¡ãããŸãïŒ
Ubuntu 18.04.1 LTS
12Intel®Xeon®CPU
ãã®ãŠãŒãã£ãªãã£ã¯ã次ã®ã³ãã³ãã䜿çšããŠã€ã³ã¹ããŒã«ãããŸãã
sudo apt-get install stress
è² è·ãããã£ãç¶æ
ã§CPUãã©ã®ããã«äœ¿çšãããããèŠãŠã300ç§éã®å¹³æ¹æ ¹ãèšç®ããã¯ãŒã«ãŒãäœæãããã¹ããå®è¡ããŸãã
-c, --cpu N spawn N workers spinning on sqrt() > stress --cpu 12 --timeout 300s stress: info: [39881] dispatching hogs: 12 cpu, 0 io, 0 vm, 0 hdd
ãã®ã°ã©ãã¯ããŠãŒã¶ãŒã¢ãŒãã§ã®å®å
šãªäœ¿çšçã瀺ããŠããŸããã€ãŸããã·ã¹ãã ãµãŒãã¹ã³ãŒã«ã§ã¯ãªãããã¹ãŠã®ããã»ããµã³ã¢ãããŒããããæçšãªèšç®ãå®è¡ãããŸãã
次ã®ã¹ãããã¯ãioãéäžçã«äœ¿çšãããšãã«ãªãœãŒã¹ã䜿çšããããšã§ãã syncïŒïŒãå®è¡ãã12人ã®ã¯ãŒã«ãŒãäœæããŠã300ç§éãã¹ããå®è¡ããŸãã syncã³ãã³ãã¯ãã¡ã¢ãªã«ãããã¡ãªã³ã°ãããããŒã¿ããã£ã¹ã¯ã«æžã蟌ã¿ãŸãã ã«ãŒãã«ã¯ãé »ç¹ã«ïŒéåžžã¯é
ãïŒãã£ã¹ã¯ã®èªã¿åãããã³æžã蟌ã¿æäœãåé¿ããããã«ãããŒã¿ãã¡ã¢ãªã«ä¿åããŸãã syncïŒïŒã³ãã³ãã¯ãã¡ã¢ãªã«ä¿åãããŠãããã¹ãŠã®ãã®ããã£ã¹ã¯ã«æžã蟌ãŸããããã«ããŸãã
-i, --io N spawn N workers spinning on sync() > stress --io 12 --timeout 300s stress: info: [39907] dispatching hogs: 0 cpu, 0 io, 0 vm, 12 hdd
ããã»ããµã¯äž»ã«ã«ãŒãã«ã¢ãŒãã§åŒã³åºããåŠçããiowaitã§å°ãåŠçããŠããããšãããããŸãããŸãããã£ã¹ã¯ãžã®35k opsæžã蟌ã¿ã確èªã§ããŸãã ãã®åäœã¯ãã·ã¹ãã æéãé·ãåé¡ã«äŒŒãŠããããã®åå ãåæããŠããŸãã ããããããã«ã¯ããã€ãã®éãããããŸãïŒãããã¯iowaitã§ãããiopsã¯ããããçç£çãªåè·¯ããã倧ãããããã¯ç§ãã¡ã®å Žåã«ã¯åããŸããã
ããªãã®èšæ¶ããã§ãã¯ããæã§ãã 次ã®ã³ãã³ãã䜿çšããŠã300ç§éã¡ã¢ãªãå²ãåœãŠãŠè§£æŸãã20人ã®ã¯ãŒã«ãŒãèµ·åããŸãã
-m, --vm N spawn N workers spinning on malloc()/free() > stress -m 20 --timeout 300s stress: info: [39954] dispatching hogs: 0 cpu, 0 io, 20 vm, 0 hdd
ããã«ãã·ã¹ãã ã¢ãŒãã§CPUã®äœ¿çšçãé«ããªãããŠãŒã¶ãŒã¢ãŒãã§CPUã®äœ¿çšçãå°ãé«ããªãã2 GBãè¶
ããRAMã䜿çšãããããšãããã«ããããŸãã
ãã®ã±ãŒã¹ã¯ãè² è·ãã¹ãã§ã¡ã¢ãªã倧éã«äœ¿çšããããšã§ç¢ºèªãããprodã®åé¡ãšéåžžã«ãã䌌ãŠããŸãã ãããã£ãŠãã¡ã¢ãªæäœã§åé¡ãæ¢ãå¿
èŠããããŸãã ã¡ã¢ãªã®å²ãåœãŠãšè§£æŸã¯ããããmallocåŒã³åºããšfreeåŒã³åºãã䜿çšããŠè¡ããããããã¯æçµçã«ã«ãŒãã«ã·ã¹ãã ã³ãŒã«ã«ãã£ãŠåŠçãããŸããã€ãŸããã·ã¹ãã æéãšããŠCPU䜿çšçã«è¡šç€ºãããŸãã
ã»ãšãã©ã®ææ°ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã¯ãããŒãžã³ã°ã䜿çšããŠä»®æ³ã¡ã¢ãªãç·šæãããŸãããã®ã¢ãããŒãã§ã¯ãã¡ã¢ãªé åå
šäœãåºå®é·ã®ããŒãžã«åå²ãããŸãïŒããšãã°ã4096ãã€ãïŒå€ãã®ãã©ãããã©ãŒã ã®ããã©ã«ãïŒïŒãããšãã°ã2 GBã®ã¡ã¢ãªãå²ãåœãŠãå Žåãã¡ã¢ãªãããŒãžã£ã¯åäœããå¿
èŠããããŸã500,000ããŒãžä»¥äžã ãã®ã¢ãããŒãã§ã¯ã管çã«å€§ããªãªãŒããŒãããããããHuge PageãšTransparent Huge Pagesãã¯ãããžãŒãããããåæžããããã«çºæãããŸãããããšãã°ãããŒãžãµã€ãºãæ倧2MBãŸã§å¢ããããšãã§ãããããã¡ã¢ãªããŒãå
ã®ããŒãžæ°ã倧å¹
ã«åæžãããŸãã ãã¯ãããžãŒéã®å¯äžã®éãã¯ãHuge Pageã®å Žåãç°å¢ãæ瀺çã«èšå®ããããã°ã©ã ã®æäœæ¹æ³ãæããå¿
èŠãããã®ã«å¯ŸããŠãTransparent Huge Pagesã¯ããã°ã©ã ã«å¯ŸããŠãééçã«ãæ©èœããããšã§ãã
THPãšåé¡è§£æ±º
ãã©ã³ã¹ãã¢ã¬ã³ããã¥ãŒãžããŒãžã«é¢ããæ
å ±ãã°ãŒã°ã«æ€çŽ¢ãããšãæ€çŽ¢çµæã«ãTHPããªãã«ããæ¹æ³ããšãã質åã®ããããŒãžãå€æ°è¡šç€ºãããŸãã
çµå±ã®ãšããããã®ãã¯ãŒã«ãªãæ©èœã¯Red Hat Corporationã«ãã£ãŠLinuxã«ãŒãã«ã«å°å
¥ãããŸããããã®æ©èœã®æ¬è³ªã¯ãã¢ããªã±ãŒã·ã§ã³ãå®éã®Huge Pageã§åäœãããã®ããã«ã¡ã¢ãªãééçã«åäœã§ããããšã§ãã ãã³ãããŒã¯ã«ãããšãTHPã¯æœè±¡ã¢ããªã±ãŒã·ã§ã³ã10ïŒ
é«éåããŸãããã¬ãŒã³ããŒã·ã§ã³ã§è©³çŽ°ã確èªã§ããŸãããå®éã«ã¯ãã¹ãŠãç°ãªããŸãã å Žåã«ãã£ãŠã¯ãTHPã¯ã·ã¹ãã ã®CPUæ¶è²»ãäžåœã«å¢å ãããŸãã 詳现ã«ã€ããŠã¯ãOracleã®æšå¥šäºé
ãåç
§ããŠãã ããã
ãã©ã¡ãŒã¿ã確èªããŸãã å€æããããã«ãTHPã¯ããã©ã«ãã§ãªã³ã«ãªã£ãŠããŸãã次ã®ã³ãã³ãã§ãªãã«ããŸãã
echo never > /sys/kernel/mm/transparent_hugepage/enabled
THPããªãã«ããåãšåŸã«ãè² è·ãããã¡ã€ã«ã§ãã¹ãã§ç¢ºèªããŸãã
setUp( MainScenario.inject( rampUsers(150) during (200 seconds)), Peak.inject( nothingFor(20 minutes), rampUsers(5000) during (30 minutes)) ).protocols(httpConfig)
THPããªãã«ããåã«ãã®åçãèŠãŸãã
THPããªãã«ãããšããªãœãŒã¹äœ¿çšçããã§ã«äœäžããŠããããšãããããŸãã
äž»ãªåé¡ã¯ããŒã«ã©ã€ãºãããŸããã çç±ã¯OSã§ããã©ã«ãã§æå¹åãããŠããŸãã
éæãªå€§ããªããŒãžã®ã¡ã«ããºã ã THPãªãã·ã§ã³ãç¡å¹ã«ããåŸãã·ã¹ãã ã¢ãŒãã§ã®CPU䜿çšçãå°ãªããšã2åæžå°ãããŠãŒã¶ãŒã¢ãŒãçšã®ãªãœãŒã¹ã解æŸãããŸããã äž»ãªåé¡ã®åæäžã«ãOSãšRedisã®ãããã¯ãŒã¯ã¹ã¿ãã¯ãšã®çžäºäœçšã®ãããã«ããã¯ããçºèŠãããŸãããããããããæ·±ãç 究ã®çç±ã§ãã ããããããã¯ãŸã£ããç°ãªã話ã§ãã
ãããã«
çµè«ãšããŠãããã©ãŒãã³ã¹ã®åé¡ãæ£åžžã«æ€çŽ¢ããããã®ãã³ããããã€ã玹ä»ããŸãã
- ã·ã¹ãã ã®ããã©ãŒãã³ã¹ã調æ»ããåã«ããã®ã¢ãŒããã¯ãã£ãšã³ã³ããŒãã³ãã®çžäºäœçšã泚ææ·±ãç解ããŠãã ããã
- ãã¹ãŠã®ã·ã¹ãã ã³ã³ããŒãã³ãã®ç£èŠãæ§æããæšæºã®ã¡ããªãã¯ãååã§ãªãå Žåã¯è¿œè·¡ããããã«æ·±ãããŠæ¡åŒµããŸãã
- 䜿çšæžã¿ã·ã¹ãã ã®ããã¥ã¢ã«ããèªã¿ãã ããã
- OSããã³ã·ã¹ãã ã³ã³ããŒãã³ãã®æ§æãã¡ã€ã«ã®ããã©ã«ãèšå®ã確èªããŸãã