ã¿ãªãããããã«ã¡ã¯ããã°ãã¯ãClassiã®åºç¤ããã¯ã¨ã³ããã¼ã ã§ãããã¯ããæ©è½ãè¶ãã¦ãµã¼ããµã¤ããä¸å¿ã«å°ãäºãæåºã解決ããä»äºããã¦ãã
id:aerealã§ãã
ä»åã®è¨äºã§ã¯Classiã®ããã©ã¼ãã³ã¹æ¹åã®ããåãçµãã§ããdronã¨å¼ã°ããã¯ã©ã¦ããã¤ãã£ããªcronä»£æ¿ (Cloud Native Cron Alternative) ã®éçºã«ã¤ãã¦ãéç¨ãè¦æ®ãã¦ã©ã®ãããªèæ ®ãéããã®ããç´¹ä»ãã¾ãã
- èæ¯ã¨èª²é¡
- æ¹é
- è¨è¨
- éç¨æã®èæ ®äºé
- å½å
- ãããã«
- ä»é²: Cloud Native Cron Alternativeã¨ããã
èæ¯ã¨èª²é¡
dronã®èª¬æãããã«ããã£ã¦ãç¾è¡ã®éåæå¦çã·ã¹ãã (以ä¸ãç¾è¡ã·ã¹ãã ) ã®ç¨éã¨æ±ãã¦ãã課é¡ã«ã¤ãã¦ç°¡åã«ç´¹ä»ãã¾ãã
ç¾è¡ã®ã¯ã¼ã¯ãã¼ã
主ãªç¨éã¯ãµã¼ãã¹å éç¥ã®éä¿¡ã§ããAppleãGoogleã®ã¹ãã¼ãããã¤ã¹åãããã·ã¥éç¥ãµã¼ãã¹ã¸é©åãªãã¤ãã¼ããéãä»äºã大åã§ãã
åã ã®ã¸ã§ããè¦ããã³ã¹ãã¯å°ããã¨ããåæã«å¤§éã«è¦æ±ããããããããªãã«è¨ç®æ©è³æºãæ¶è²»ããã¨ããæ§è³ªãããã¾ãã
主ãªç¨éã¯éç¥ã¨è¿°ã¹ã¾ãããããããåç´ã«at least onceãªå®è¡ã¢ãã«ã®ã·ã¹ãã ã«è¼ãå¤ããã¨äºéã»ä¸éã«éç¥ãéä¿¡ãããã¾ãã éç¥ã¯ãã©ã³ã¶ã¯ã·ã§ã³å¦çã»ã©ã¯ãªãã£ã«ã«ãªå½±é¿ãããããã¾ããããã¨ã³ãã¦ã¼ã¶ã¼ãã¤ã³ã¿ã©ããããæ©è½ã§ããããã¤ã¼ããªå®è£ ã¯å©ç¨è ã®è² æ ã«ããªãã¾ãã
å ãã¦æªæ¥ã®æéã«æä¸ã®ãã¤ãã¼ãã§ã¸ã§ããå®è¡ããã¨ããäºç´å®è¡ã®ä»çµã¿ããããããã®ç§»æ¤ãæ±ãããã¾ãã
課é¡
DBã«ãããããªã
Classiã®å種ãã¼ã¿ã¯ä¸å¤®ã®RDBMSã§ç®¡çããã¦ãããåã³ã³ãã¼ãã³ããèªã¿æ¸ããã¦ãã¾ãã
Webãã¹ãã®çµæãæ ¡åè¨é²ãªã©ã³ã¢ã¨ãªãæ©è½ã®ãã¼ã¿ãéã¾ã£ã¦ããããã®ä¸å¤®DBã®è² è·ãä¸ããã¨Classiã®æ©è½ãã¹ã¦ã«å½±é¿ãããã¾ãã ç¾è¡ã·ã¹ãã ã¯ãã®ãµã¼ãã¹ã®æ ¹å¹¹ã¨ããããä¸å¤®DBããã¥ã¼ã¨ãã¦å©ç¨ãã¦ãã¾ãã
ããããããã¯æã¾ããç¨éã§ã¯ãªãã¨èãããã¾ãã
Webã¢ããªã±ã¼ã·ã§ã³ã«ããã¦ãªã¯ã¨ã¹ããåãã¦ã¬ã¹ãã³ã¹ãè¿ãã©ã¤ããµã¤ã¯ã«ããå¤ãã¦éåæã§å¦çãå®è¡ããã¢ããã¼ã·ã§ã³ã¯æ¦ãã¬ã¹ãã³ã¹ã¿ã¤ã ã®åä¸ãå³ãã¨ããä¸ç¹ã«éç´ãããã¨è¨ã£ã¦ããã¨æãã¾ãã ãããããã¼ã¿ã¹ãã¢ãå ±æãã¦ãããã¨ããç¾è¡ã·ã¹ãã ãä¸å¤®DBãéãã¦Classiã®ãµã¼ãã¹å ¨ä½ã®ããã©ã¼ãã³ã¹å£åãåã¼ãããç¶æ³ã«ããã¾ããã
ã¢ããªã±ã¼ã·ã§ã³ã®ã¬ã³ã¼ãã¨JOINãããããªãã¨ããªãåãDBã«ãã¥ã¼ãç¨æããå¿ ç¶æ§ã¯ç¡ãã®ã§ãã¨ã«ãããã«ãä¸å¤®DBã®å©ç¨ãããããã¨ããã§ãã
ã¹ã±ã¼ã«ã¢ã¦ãã®å°é£ãªã¢ã¼ããã¯ãã£
ä¸è¬ã«ãã¥ã¼ãå©ç¨ããéåæå¦çã·ã¹ãã ã§ã¯ãå®è¡ãããã¸ã§ãã®æ§è³ªã«åããã¦ã¹ã±ã¼ã©ããªãã£ã確ä¿ãããããã¥ã¼ãåé¢ããããå®è¡ç°å¢ãã¹ã±ã¼ã«ã¢ããã»ã¹ã±ã¼ã«ã¢ã¦ãããããã¨ãããã©ã¼ãã³ã¹æ¹åã®æã¨ãã¦æãããã¾ãã
ç¾è¡ã·ã¹ãã ã¯åè¿°ã®ããã«ä¸å¤®ã®RDBMSãå©ç¨ãPHPã§æ¸ãããç¬èªã®ãã¼ã¢ã³ã¨ãã¦å®è¡ããã¦ãã¾ãã æä»å¦çã¯èæ ®ããã¦ããªããããç´ æ´ã«ãã¼ã¢ã³ã®å®è¡æ°ãå¢ããã¨ç«¶åãèµ·ããã¾ãã
ããã«æ²ãããã¨ã«å®è¡ãããã¸ã§ãã®å®è£ ããã ä¸åº¦ (exactly-once) å®è¡ããããã¨ãæå¾ ãã¦ããããããããã°PHPã®ãã¼ã¢ã³ãæ¹ä¿®ããã¨ãã¦ãæ°ããã¸ã§ãã®å®è£ ãã²ã¨ã¤ã²ã¨ã¤ä¸å¯§ã«æä»å¶å¾¡ããªããã°ãããç¾å®çã¨ã¯ããã¾ããã
æ¹é
exactly-onceããã¼ã§ã®å®è¡ãã¸ã§ãã®äºç´ã®å®ç¾ãªã©è¤éãã¤ã¯ã¼ã«ã¼ã¨ãã¦è¤éãªè²¬åã¯åéãããåã¸ã§ãã®å®è£ (= ç¥è) ã¯åãã¼ã ã«æ ã£ã¦ããããã¨ã§æ¢åãå¹ããã¤ã¤å権ãçãã¾ãã
ãã®ããã«:
- åã¸ã§ãã®å®è£
ã¯ãã©ã¤ãã¼ããªHTTPã¨ã³ããã¤ã³ãã¨ãã¦åå®è£
ããã
- ãªã¯ã¨ã¹ããã¬ã¹ãã³ã¹ã®å½¢å¼ãªã©ã¢ããªã±ã¼ã·ã§ã³ãããã³ã«çå®ã¯åºç¤ããã¯ã¨ã³ããã¼ã ã主å°ãã
- åå®è£ ã¯åã¸ã§ãã®ãªã¼ãã¼ãæã¤ãã¼ã ã«ä¾é ¼ãã
- dronã¯åã¸ã§ãã®HTTPã¨ã³ããã¤ã³ããå¼ã³åºãã¨ããã¾ã§ã責任å¢çã¨ãã
â¦â¦ã¨ãã¾ãã
è¨è¨

ã³ã³ãã¼ãã³ãæ¦èª¬
Facade
- ã¯ã©ã¤ã¢ã³ããè¡ããæä½ãHTTP APIã¨ãã¦æä¾ãã
- API Gateway + Lambdaã§å®è£ ããã
Job Executor
- ã¸ã§ããå®è¡ããStep Functionsã®ã¹ãã¼ããã·ã³
- Lambdaã®å¼ã³åºããçµ±åããã¦ããã ãã§ã¯ãªãDynamoDBã®GetItem/PutItem/UpdateItemãªã©ã®å種APIå¼ã³åºããLambdaãèµ·åãããã¨ãªãç´æ¥è¡ããã®ã§ã³ã¼ãã®åæ¸ãã¬ã¤ãã³ã·ã®ç¹ã§åªä½æ§ããã
- 失æå¯è½æ§ã®ããå¦çã®ãªãã©ã¤ãç¶æ é·ç§»ãç§»è²ãããã¨ã§ã¢ããªã±ã¼ã·ã§ã³ãç´ æ´ã«ä¿ã¦ã
- 並åå®è¡ã«å¶ç´ã¯ã»ã¼ãªããã¹ã±ã¼ã©ãã«ã§ãã
Job Scheduler
- CloudWatch Eventsã§æ¯æèµ·åãããStep Functionsã®ã¹ãã¼ããã·ã³
- Job Reservationããã¸ã§ãæ å ±ãåå¾ãJob Executorã並åã«å®è¡ãã
Endpoint Data
- Worker Endpointã®URLãä¿åããDynamoDBã®ãã¼ãã«
- ä¸åº¦ç»é²ãããURLã¯å¤æ´ã§ããªã
- æ°ããURLãç¨ããå ´åã¯æ°ããã¨ã³ããã¤ã³ãã¨ãã¦ç»é²ãã
- éå»ã®ããæç¹ã®ã¸ã§ããã©ã®URLã¸ã¢ã¯ã»ã¹ããããã追跡ãããããããã
- ã¸ã§ãã®å®è¡è¦æ±ãã¨ã«ä»»æã®URLãåãåãå ´åãççµã«ãã誤ã£ãURLã§ãã£ã¦ããã®å¦¥å½æ§ã夿ã§ããªã
- äºåã«URLãç»é²ããã¸ã§ãã®å®è¡è¦æ±ã«ã¯ã¨ã³ããã¤ã³ãã®èå¥åãå«ããã¨ç»é²æ¸ã¿ãã©ããã§typoãªã©ã®ççµãçºè¦ã§ãã
- å°æ¥çã«ãã®ãã¼ãã«ãæ¡å¼µãã¦æé«ä¸¦åæ°ãæãããããURLãã³ãã¬ã¼ãã¨ãã¦Facadeã¸ã®ä¸åº¦ã®å®è¡è¦æ±ããè¤æ°ã®URLã¸ã¸ã§ããå®è¡ã§ããå«ã¿ãæããã¦ãã
Job Data
- ã¸ã§ãã®æ å ±ãä¿åããDynamoDBã®ãã¼ãã«
- ä¸åº¦æ¿å ¥ããããã¯ã©ã¤ã¢ã³ãã®æä½ã«ãã£ã¦åé¤ã»æ´æ°ã¯ãããªã
- ä¸å¤ãã¼ã¿ã¨ãããã¨ã§éå»ã®ç¶æ ãåç¾ããæéããªããªã調æ»ããããããªã
- Job Executorã«ãã£ã¦ããã¯ã¨ãã¦æ©è½ããå®è¡ä¸ãã©ã°ã¨å®äºæå»ã¯æ´æ°ããã
Job Reservation
- ããæ¥æã«å®è¡ãã¹ãã¸ã§ããä¿åããDynamoDBã®ãã¼ãã«
- æ¥æãéãã¦ãåã¢ã¤ãã ã¯æ´æ°ãåé¤ãããªãã®ã§ãããã¸ã§ãã確ãã«ããæ¥æã«äºç´ããããã¯ããããæç¹ãã追跡å¯è½
Worker Kicker
- Lambdaã¨ãã¦å®è£ ããã
- URLã¨HTTPã¡ã½ããããªã¯ã¨ã¹ãããã£ãä¸ãããé©åãªã¿ã¤ã ã¢ã¦ããè¨å®ãã¦HTTPãªã¯ã¨ã¹ããWorker Endpointã¸éä¿¡ãã¬ã¹ãã³ã¹ãè¿ã
Worker Endpoint
- åã¸ã§ãã®å®éã®å¦çãè¡ãHTTPã¨ã³ããã¤ã³ã
- Endpoint Dataã¯å°ãªãã¨ãã²ã¨ã¤ã®Workerã«å¯¾å¿ãã
- åå©ç¨è ã¢ããªã±ã¼ã·ã§ã³ã®ä¸é¨ã¨ãã¦æ§ç¯ããã
- æ¡ä»¶ãæºããã°Classiãç´æ¥ç®¡çããªãHTTPã¨ã³ããã¤ã³ããWorker Endpointã¨ãããã¨ãã§ãã (ä¾: Twitter API)
éç¨æã®èæ ®äºé
追跡ã»ãã¬ã¼ã·ã³ã°
ã¸ã§ãã®è¿½å ãå®è¡ãæåãããã»ã©ã®ã¯ã©ã¤ã¢ã³ããã©ã®ã¸ã§ãã追å ãããã¨ãã£ãæ å ±ã¯é¡§å®¢ã®åãåããã«å¯¾å¿ããããããã°ãç®çã¨ãã¦X-Rayã«ãããã¬ã¼ã·ã³ã°ããã³Step Functionsã«ããå®è¡ãã°ã«ä¿åãããã®ã§ãããå©ç¨ã§ãã¾ãã
ã¸ã§ãã®è¿½å ããã³å®è¡ã®å®å ¨ãªè¿½è·¡ã¯X-Rayã®å¶éã«ããæå¤§30æ¥éã«ãã¸ã§ãã®å®è¡ã®é¨åçãªè¿½è·¡ã¯Step Functionsã®å¶éã«ããæå¤§90æ¥éã«å¶éããã¾ãã
- çæéã§ã¯X-Rayã§FacadeâJob Executorã®å®è¡éå§ã¾ã§è¿½è·¡ã§ãã
- çã䏿ã§ã¯Step Functionsã®å®è¡å±¥æ´ã辿ãã¨Job ExecutorâWorker Kickerããã³Job SchedulerâJob Executorã®å®è¡ã追跡ã§ãã
- 2020/9/14ã®ã¢ãããã¼ãã§Step FunctionsãX-Rayããµãã¼ãããããã«ãªã£ãã®ã§Job Executor/Job Schedulerã®å®è¡ãå«ãã¦è¿½è·¡å¯è½
å½å
cronã®æ¬¡ãç®æã ('c'.succ + 'ron') ã¨ãããã¨ã§dronã¨åä»ãã¾ããã
ããã¾ã§ã«è¿°ã¹ã¦ããæ¢åã·ã¹ãã ã®ç½®ãæãã§ã¯cronã®å®æå®è¡ã¨ããä»çµã¿ã¯å¿ é ã§ã¯ãªãã¾ãç¾æç¹ã§å®è£ ãããã¦ããªãã«ãé¢ãããcron alternativeãæ¨æ¦ãã¦ãããã㯠exactly-onceã§å¦çãå®è¡ããã·ã¹ãã ã®é£ãã ã«çç®ããcronã¯ãããé¨åçã«ãã解決ãã¦ãããã¨ã«ç±æ¥ãã¾ãã
cronã®exactly-onceå®ç¾ã¯SPOFãæã¡è¾¼ããã¨ã¨è¡¨è£ä¸ä½ã§ãã®ã§ãã¯ã©ã¦ããµã¼ãã¹ãæ´»ç¨ãå¯ç¨æ§ãé«ãã¤ã¤å®ç¾ãããã¨ã§æ¢åã®ã¯ã¼ã¯ãã¼ãããã®å®¹æãã社å ã®å©ç¨è ã«ä¼ãããã¨ãé¡ã£ã¦ãã¾ãã
ãããã«
ã·ã¹ãã ã®ããã©ã¼ãã³ã¹æ¹åã¨ãã大ããªããã·ã§ã³ã®ããã«ã¯ãæã«ã¯åã ã®ã³ã³ãã¼ãã³ãã®ç½®ãæãã¨ãã£ã大èãªææ®µãã¨ãå¿ è¦ãããã¾ãã
ãããã大èãªå¤æãã¨ãæç¾©ã¨å¿ è¦æ§ãçè§£ããä¸ã§ããã¥ã¼ã«ãã¼ã®ç§ã«ããã¸ã§ã¯ãã®ãªã¼ããä»»ãã¦ãããããæ»ãã¨å®ãã«ã¡ãªããªã®ã¤ããå¥å ¨ãªæè¡æ±ºå®ã®ã§ããçµç¹ã«ãªã£ã¦ããã¨å®æã楽ããæã£ã¦ãã¾ãã
ãµã¼ãã¹ã®æ¹åã¨ããå¤§ç®æ¨ã¸ã®éç¨ã¯ã¾ã å§ã¾ã£ãã°ããã§ããããã£ã¨è¨ãã°ãã¤ã«ã¹ãã¼ã³ã¯ãã£ã¦ãçµãããªã©ãªãã®ã§ãããããã§ã大äºãªä¸æ©ã«å°ãªãããè²¢ç®ã§ããã¨èªè² ãã¦ãã¾ãã
ä»é²: Cloud Native Cron Alternativeã¨ããã
å ã çè ã¯qronã¨ããAWSä¸ã§ä¸è¨ã«ä¼¼ãã·ã¹ãã ãæ§ç¯ããããã®AWS CDKã©ã¤ãã©ãªãéçºã»å ¬éãã¦ãã¾ãã
ã¡ããã©Classiã«åå ãã¦ã©ããªããã¸ã§ã¯ããæ å½ããããã¨ãã話ãããä¸ã§ããã®è¨äºã§æãã課é¡ã»ããã¸ã§ã¯ããåè£ã«ä¸ãã£ã¦ããå½åã¯ã¬ãã¥ã¢ã¼ã¨ãã¦ããããã£ã解決çãããããã¨ææ¡ããç«å ´ã§ããããå è¡ãã¦ã©ã¤ãã©ãªãä½ã£ã¦ãããã¨ããã主æ å½ã¨ãªãã¾ããã
qronã«ã¤ãã¦YAPC Kyoto 2020ã§çºè¡¨äºå®ã§ããããCOVID-19ã®æ¡å¤§ã«ä¼´ãã¤ãã³ãã®éå¬ãè¦éããããã¨ããã£ã¦ãã®ã¢ã¤ãã¢ã«ã¤ãã¦ç´¹ä»ããæ©ä¼ãè¦ã¤ããããæ®å¿µã«æã£ã¦ãããã¨ããããå®éç¨ã¸æå ¥ããäºä¾ãç´¹ä»ã§ãããªãã¨ããæããããã¾ããã
æ¬å½ã«å¶ç¶ãéãªã£ãçµæã§ããæ°å¥ãªå·¡ãåãããæããã«ã¯ãããã¾ããã ãã£ã¦å½åæã«ãqronãã¤ã³ã¹ãã¤ã¢ããååã«ãã¾ããã