ã³ãã¯ã·ã§ã³ããŒã«ã®ä»çµã¿ â DBãžã®æ¥ç¶ã䜿ãåãæè¡
ã¢ããªãããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ãããšããæ¯åæ¥ç¶ããŠãããããªãã®ïŒ
å®ã¯ããã ãšãããé ããã ãDBæ¥ç¶ã£ãŠè£åŽã§ã¯TCPã®3ãŠã§ã€ãã³ãã·ã§ã€ã¯ãSSL/TLSããŽã·ãšãŒã·ã§ã³ãDBã®èªèšŒåŠçâŠãšäœæ®µéãã®æç¶ããèµ°ããã ãã1åã®æ¥ç¶ç¢ºç«ã«10ã100ããªç§ãããããšãããããªã¯ãšã¹ãã®ãã³ã«ããããã£ãŠããã1ç§éã«æ°çŸãªã¯ãšã¹ãæ¥ãWebã¢ããªã§ã¯ããã«ããã¯ã«ãªã£ã¡ãããã
ãããã©ããã£ãŠéãããŠãã®ïŒ
ããã§ç»å Žããã®ããã³ãã¯ã·ã§ã³ããŒã«ãã ãããããããäœæ¬ãã®DBæ¥ç¶ãäœã£ãŠãããŠãããŒã«ã«å ¥ããŠãããã¢ããªãæ¥ç¶ã䜿ããããšãã¯ããŒã«ãã1æ¬åããŠã䜿ãçµãã£ããããŒã«ã«è¿ããåããã»è¿ãã ãã ãããæ¯åãŒãããæ¥ç¶ãäœãã³ã¹ãããªããªããã ã峿žé€šã®æ¬ã®è²žãåºãã¿ãããªã€ã¡ãŒãžã ãã
ãªãã»ã©ïŒã§ãããŒã«ã«ã©ããããæ¥ç¶ãçšæããŠããã°ããã®ïŒ
ããŒã«ã®èšå®ã«ã¯ããã€ãéèŠãªãã©ã¡ãŒã¿ããããããŸããæå°ãµã€ãºïŒminimumIdleïŒãã¯ã¢ã€ãã«æã§ãç¶æããæ¥ç¶æ°ããæå€§ãµã€ãºïŒmaximumPoolSizeïŒãã¯ããŒã«ãæãŠãæ¥ç¶ã®äžéãä»ã«ããã¢ã€ãã«ã¿ã€ã ã¢ãŠããã§äœ¿ãããŠããªãæ¥ç¶ãäžå®æéåŸã«éãããããæå€§ã©ã€ãã¿ã€ã ïŒmaxLifetimeïŒãã§æ¥ç¶ã宿çã«äœãçŽããŠã¡ã¢ãªãªãŒã¯ãDBåŽã®ã¿ã€ã ã¢ãŠããé²ãã ããããã ã
å ·äœçã«ã©ããªããŒã«ã䜿ãããŠãã®ïŒ
Javaãªã HikariCP ãäºå®äžã®æšæºã ããSpring Bootã®ããã©ã«ãã«ããªã£ãŠããPostgreSQLã䜿ãããŒã ãªã PgBouncer ãšããå°çšã®ã³ãã¯ã·ã§ã³ããŒã©ãŒãéã«æãããšãå€ãããGoã® database/sql ããã±ãŒãžã«ã¯ããŒã«æ©èœãèšèªæšæºã§çµã¿èŸŒãŸããŠããã©ã®æè¡ã§ããæ¥ç¶ã䜿ãåããåºæ¬ææ³ã¯åãã ãã
ããŒã«ã®æ¥ç¶ãå šéšäœ¿ãåã£ã¡ãã£ããã©ããªãã®ïŒ
ããããããŒã«æ¯æžïŒPool ExhaustionïŒããšåŒã°ããæãç¶æ ã ããæ°ãããªã¯ãšã¹ããæ¥ãŠãç©ºãæ¥ç¶ããªããããã¿ã€ã ã¢ãŠããŸã§åŸ ãããããææªã®å Žåãæ¥ç¶ãåãããŸãŸè¿ããªãã³ãŒãããããšãããŒã«å ã®æ¥ç¶ãå šéšããã¯ãããŠãããããã¯ç¶æ ã«ãªãã1ã€ã®ã¹ããŒã¯ãšãªãå šäœãå·»ã蟌ãã§é害ã«ãªãã±ãŒã¹ããããããæ¥ç¶ã¯å¿ ã try-finally ã using ãããã¯ã§ç¢ºå®ã«è¿åŽããã®ãéåã ãã
ããŒã«ãå¥åº·ãã©ããã¯ã©ããã£ãŠèŠåŒµãã®ïŒ
ã¢ãã¿ãªã³ã°ã倧äºã ããèŠãã¹ãææšã¯äž»ã«3ã€ããã¢ã¯ãã£ãæ¥ç¶æ°ãã¯ä»äœ¿ãããŠããæ¥ç¶ããã¢ã€ãã«æ¥ç¶æ°ãã¯ããŒã«ã§åŸ æ©äžã®æ¥ç¶ããåŸ æ©ã¹ã¬ããæ°ãã¯ç©ºãæ¥ç¶ãåŸ ã£ãŠããæ°ã ããåŸ æ©ã¹ã¬ããæ°ãå¢ãå§ãããããŒã«ãµã€ãºãè¶³ããªããµã€ã³ãããšã¯ã¹ããŒã¯ãšãªã®æ€åºãéèŠã§ã1æ¬ã®é ãã¯ãšãªãæ¥ç¶ãé·æéå æãããšããŒã«å šäœã«æ³¢åãããããã
ãµãŒããŒã¬ã¹ç°å¢ã ãšã³ãã¯ã·ã§ã³ããŒã«ã£ãŠäœ¿ããã®ïŒ Lambda ãšã Cloud Functions ã¯æ¯åèµ·åããããïŒ
ãã質åã ãããµãŒããŒã¬ã¹ã¯ã³ãã¯ã·ã§ã³ããŒã«ã®å€©æµãšãèšããååšã ããLambda ãåæã«100åèµ·åãããšããããããããŒã«ãäœãããåèšã§æ°çŸãæ°åã®DBæ¥ç¶ãäžæ°ã«åŒµãããŠããŸããDBã® max_connections ãç°¡åã«è¶ ãã¡ãããã ããã®åé¡ã®è§£æ±ºçãšããŠãAWSãªã RDS ProxyãPostgreSQLãªã PgBouncer ãDBæåã«çœ®ããŠãLambda ããã®å€§éæ¥ç¶ããããã·åŽã§éçŽããæ¹æ³ãäž»æµã ãã
ãããã·ãæããšæ¥ç¶æ°ãæžãã®ã¯ãªãã§ïŒ
RDS Proxy ã PgBouncer ã¯ãå€å¯Ÿå°ãã®æ¥ç¶ãããã³ã°ãããŠããããã ãããšãã° Lambda åŽããã¯100æ¬ã®æ¥ç¶ãæ¥ãŠãããããã·ãDBåŽã«ã¯10æ¬ã ãæ¥ç¶ãç¶æããŠããªã¯ãšã¹ããé çªã«ãã°ããLambda ã®ã€ã³ã¹ã¿ã³ã¹ãæ¶ããŠãããããã·åŽã®DBæ¥ç¶ã¯ãã®ãŸãŸåå©çšã§ãããããæ¥ç¶ã»åæã®ãªãŒããŒããããæ¿æžãããã ãã
ããã®çŸå Žã§ã¯ããŒã«ãµã€ãºã£ãŠã©ããã£ãŠæ±ºããŠãã®ïŒ
HikariCP ã®äœè ãæå±ããæåãªå ¬åŒããããããæé©æ¥ç¶æ° = (CPUã³ã¢æ° x 2) + ãã£ã¹ã¯ã¹ãã³ãã«æ°ããSSDãªãã¹ãã³ãã«æ°ã¯1ãšèããããã4ã³ã¢ã®ãµãŒããŒãªã 4x2+1 = 9æ¬ãç®å®ãå€ããã°ããã£ãŠãã®ãããªããŠãããŒã«ã倧ãããããããšã³ã³ããã¹ãã¹ã€ãããDBåŽã®ã¡ã¢ãªæ¶è²»ãå¢ããŠéã«é ããªããã ãPostgreSQLã®å ¬åŒããã¥ã¡ã³ãã§ãæ°çŸã®æ¥ç¶ã¯éæšå¥šãšãããŠããã
å®éã«ããŒã«èšå®ã®ãã¹ã§å€§ããªé害ãèµ·ããããšã£ãŠããã®ïŒ
ããããHikariCP ã«ã¯ãpool-litterãæ€åºãšããæ©èœããã£ãŠãåããæ¥ç¶ãè¿ããªãã³ãŒããæ€åºããŠããããã ãleakDetectionThreshold ãèšå®ãããšãæå®æé以äžè¿åŽãããªãæ¥ç¶ã®ã¹ã¿ãã¯ãã¬ãŒã¹ããã°ã«åºããŠããããå®éã®çŸå Žã§ã¯ãæ¥ç¶ãªãŒã¯1ç®æãåå ã§ãµãŒãã¹å šäœã30åããŠã³ããäºäŸããããããŒã«ãµã€ãºãéé²ã«å¢ãããŠå¯ŸåŠãããšãä»åºŠã¯DBåŽãèããããªããªããæ ¹æ¬åå ã®ç¹å®ãæåªå ã ãã