ããã«ã¡ã¯ãMAéšã®è°·å£ïŒ case-k ïŒãš @gachi-muchi-engineer ã§ãã ç§éã®ããŒã ã§ã¯ããŒã±ãã£ã³ã°ãªãŒãã¡ãŒã·ã§ã³ã·ã¹ãã ã®éçºãéçšãããŠããŸããZOZOTOWNã§ã¯ããŒã±ãã£ã³ã°ãªãŒãã¡ãŒã·ã§ã³ã«ãã£ãŠãã¡ãŒã«ãPushãLINEãªã©åãã£ã³ãã«ã«å¯ŸããŠæ¥ã
é
ä¿¡ããŠããŸããé
ä¿¡æ¹æ³ã¯å€§ãã2çš®é¡ã«åããããç¹å®ã®ãŠãŒã¶ãŒã»ã°ã¡ã³ãåãã®ããã¹é
ä¿¡ããšãåå¥ã®ãŠãŒã¶ãŒã«æé©åããããããŒãœãã©ã€ãºé
ä¿¡ãããããŸããããŒãœãã©ã€ãºé
ä¿¡åºç€ã瀟å
ã§ã¯ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã ãRTMããšåŒãã§ããŸãããªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã ã¯éåãšåã«äœãããããšããããçŸåšãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã å
šäœã®ãªãã¬ã€ã¹ãé²ããŠããŸããæ¬èšäºã§ã¯ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã ã§çšããããŠããããªã¢ã«ã¿ã€ã ããŒã¿é£æºåºç€ããªãã¬ã€ã¹ããäºäŸãã玹ä»ããŸãã æ¢åã®ãªã¢ã«ã¿ã€ã ããŒã¿é£æºã·ã¹ãã ã®çŽ¹ä» æ¢åã®ãªã¢ã«ã¿ã€ã ããŒã¿é£æºã®ä»çµã¿ ãªããªãã¬ã€ã¹ãããã®ã Windows Serverã®éçšè² è·ãé«ã ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã å
šäœã®ãªãã¬ã€ã¹ã«å¿
èŠãªããŒã¿é£æºåºç€ãå¿
èŠ ãªãã¬ã€ã¹åŸã®é
ä¿¡çšãªã¢ã«ã¿ã€ã ããŒã¿åºç€ å®å
šã«ãªãã¬ã€ã¹ããããã®æ¹é 倿ŽååŸã®ããŒã¿ãååŸããæ¹æ³ãæ€èš 倿ŽååŸã®ããŒã¿ãååŸããã¯ãšãª 倿Žãã°ã®ååŸ ããŒã¿é£æºå®çžŸãã°ã®ååŸ å€æŽãã°ã®éèšïŒå€æŽããŒã¿ã®ååŸïŒ ããŒã¿é£æºå®çžŸãã°ã®éèšïŒå€æŽåããŒã¿ã®ååŸïŒ ããŒã¿é£æºå®çžŸãã°ã«å«ãŸããŠããªã倿ŽåããŒã¿ã®ååŸ å€æŽååŸã®ããŒã¿ãããŒãž ã¢ãŒããã¯ãã£æŠèŠãšåŠçã®æµã 倿ŽååŸã®ããŒã¿ååŸ ããŒã¿é£æºå®çžŸããŒãã« ã¡ãã»ãŒãžãããŒã«ãŒãžé£æº ããŒã¿é£æºAPIïŒAnalyzerïŒ AppendixïŒããŒã¿é£æºAPIïŒPush/LINEé
ä¿¡åºç€ïŒ æçµåæã¡ãã»ãŒãžãæžã蟌ã ååã®å
šéããŒã¿é£æº ç§»è¡ååŸã®è©äŸ¡ ããŒã¿ã®æŽåæ§ãè©äŸ¡ ããŒã¿ã®æ¬ æãè©äŸ¡ ããŒã¿ã®é
å»¶æéãè©äŸ¡ ç£èŠèšèš ãããã¥ãŒãµã®ç£èŠ ã³ã³ã·ã¥ãŒãã®ç£èŠ ãªãã¬ã€ã¹ã«ããæ¹åç¹ ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã å
šäœã®ãªãã¬ã€ã¹ã«å¿
èŠãªåºç€ãæ§ç¯ éçšè² è·ã®è»œæž ä»åŸã®èª²é¡ ããã©ãŒãã³ã¹ã®æ¹å ååå
šéããŒã¿é£æºåŠçã®å®å
šç§»è¡ ãŸãšã æåŸã« æ¢åã®ãªã¢ã«ã¿ã€ã ããŒã¿é£æºã·ã¹ãã ã®çŽ¹ä» æ¢åã®ãªã¢ã«ã¿ã€ã ããŒã¿é£æºã·ã¹ãã ã«ã€ããŠç޹ä»ããŸããæ¢åã®ãªã¢ã«ã¿ã€ã ããŒã¿é£æºã·ã¹ãã ã§ã¯é
ä¿¡åŠçã«å¿
èŠãªããŒã¿ããªã¢ã«ã¿ã€ã ã«SQL ServerããååŸããŠããŸããSQL Serverã®å€æŽããŒã¿ãæ€ç¥ããŠãå¿
èŠãªå å·¥åŠçãæœãããªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã ãžé£æºããŠããŸãã飿ºãããããŒã¿ã¯ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã ã«ãã£ãã·ã¥ããé
ä¿¡åŠçã§äœ¿ãããŸããZOZOåºæã®ãŠãŒã¶IDãé
ä¿¡çšã®ããŒã¯ã³ãžå€æããããé
ä¿¡ã®ããªã¬ãŒãšããŠãçšããããŠããŸããäŸãã°åšåº«åããèµ·ãããŠããååãå
¥è·ãããã®ãããªã¬ãŒã«é
ä¿¡ããä»çµã¿ããããŸãã 以éããªã¢ã«ã¿ã€ã ããŒã¿é£æºåºç€ããTrackerãã飿ºãããããŒã¿ãçšããŠé
ä¿¡åŠçãããŠããã¢ããªã±ãŒã·ã§ã³ããAnalyzerããšåŒã³ãŸããTrackerãšAnalyzerãå«ãåºç€ããªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã ãRTMãã§ããæ¬èšäºã§ã¯Trackerããªãã¬ã€ã¹ããäºäŸãã玹ä»ããŸãã RTMã«ã€ããŠã¯ä»¥äžã®èšäºãã確èªãã ããã techblog.zozo.com æ¢åã®ãªã¢ã«ã¿ã€ã ããŒã¿é£æºã®ä»çµã¿ ãªãã¬ã€ã¹åã®Trackerã®ããŒã¿é£æºã®ä»çµã¿ã«ã€ããŠã玹ä»ããŸãã Trackerã¯Javaã§æžãããŠãããWindows Serveräžã®ã¯ã©ã¹ã¿ã«ãããã€ãããŠããŸãããTrackerã¯SQL Serverã§å€æŽã®ãã£ãããŒã¿ãååŸããå å·¥åŠçãæœããäžã§ããŒã¿ã飿ºããŠããŸãã SQL Serverã®å€æŽããŒã¿ã®ååŸã«ã¯Change TrackingãšåŒã°ããSQL Serverã®æ©èœãçšããŠããŸãã倿Žè¿œè·¡ãçšããŠ60ç§ã«1åSQL Serverãžã¯ãšãªãæããAnalyzerã§å¿
èŠãšãªãå å·¥åŠçãæœããŠããŸããå å·¥ãããããŒã¿ã¯åããŒãã«ããšã«å®çŸ©ãããAnalyzerã®ãšã³ããã€ã³ããžãªã¯ãšã¹ããããŸãããªã¯ãšã¹ããããããŒã¿ã¯Analyzerã§ãã£ãã·ã¥ãããŠããŸãã Trackerã§å®æçã«æããŠãã倿Žè¿œè·¡ã¯ãšãªã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã SELECT a.SYS_CHANGE_OPERATION as changetrack_type, a.SYS_CHANGE_VERSION as changetrack_ver, #{columns} FROM CHANGETABLE(CHANGES #{@tablename}, @ååæŽæ°ããããŒãžã§ã³) AS a LEFT OUTER JOIN #{@tablename} ON a.#{@primary_key} = b.#{@primary_key} 倿Žè¿œè·¡ã®ããŒãžã§ã³ã¯ãSYS_CHANGE_VERSIONãã§ååŸã§ãã倿Žããããšã€ã³ã¯ãªã¡ã³ããããŸããæçµåæãã倿Žè¿œè·¡ã®ããŒãžã§ã³ã@ååæŽæ°ããããŒãžã§ã³ããæž¡ãããšã§ãæž¡ããããŒãžã§ã³ä»¥éã«å€æŽã®ãã£ããã©ã€ããªãŒããŒãååŸã§ããŸããååŸãããã©ã€ããªãŒããŒã倿Žã®ãã£ãããŒãã«ãšãLEFT JOINãããããšã§ã倿ŽåŸã®ããŒã¿ãååŸã§ããŸãã倿Žè¿œè·¡ã§ååŸã§ããã®ã¯å€æŽåŸã®ææ°ã®ããŒã¿ã®ã¿ã§ãã倿Žå±¥æŽã®ååŸã¯ã§ããŸããã倿Žã¿ã€ãã«ã¯ãSYS_CHANGE_OPERATIONãã«ã¯ä»¥äžã®3ã€ã®çš®é¡ãååšããŸããã©ã®ãããªå€æŽãSQL Serverã§å®æœãããã確èªã§ããŸãã 倿Žã¿ã€ã 説æ I æ°èŠç»é² U æŽæ° D åé€ SQL Serverã®å€æŽè¿œè·¡ã«ã€ããŠã¯ä»¥äžã®èšäºãã確èªãã ããã learn.microsoft.com ãŸããTrackerã§ã¯å€æŽåã®ããŒã¿ã飿ºããŠããŸãããAnalyzerã®ãã£ãã·ã¥ã«ã¯ã€ã³ã¡ã¢ãªãªããŒã¿ã¹ãã¢ãæ¡çšããŠãããKeyValue圢åŒã§ããŒã¿ãä¿åããŸããäžéšã®ãã£ãã·ã¥ã¯KEYãšããŠSQL Serverã®ãã©ã€ããªãŒããŒã§ã¯ãªããã¡ã³ããŒIDãEmailIDãçšããŠããŸããããŒã¿ã®åé€ãæŽæ°ããã£ãéãããã®ãã£ãã·ã¥ã«å¯ŸããŠåŠçãå¿
èŠã§ããã 倿Žè¿œè·¡ã®ä»çµã¿äžãååŸã§ããã®ã¯å€æŽã®ãã£ããã©ã€ããªãŒããŒãšå€æŽåŸã®ããŒã¿ã®ã¿ã§ããããã§ã倿Žåã®ããŒã¿ãååŸããããã«ãSQL Serverã®ããªã¬ãŒæ©èœãçšããŠããŸãããããªã¬ãŒãšã¯ãã¹ãã¢ãããã·ãŒãžã£ã«åé¡ãããSQL Serverã§ã€ãã³ããçºçãããšãã«èªåçã«å®è¡ãããŸããä»åã¯å€æŽåã®ããŒã¿ãå¿
èŠã§ãããããããªã¬ãŒæ©èœã®1ã€ã§ããDMLããªã¬ãŒãå©çšããŸããDMLããªã¬ãŒã¯DMLã€ãã³ããä»ããŠããŒã¿ã倿Žãããšãã«å®è¡ãããããªã¬ãŒã§ããDMLããªã¬ãŒã§ã¯deletedãšinsertedããŒãã«ãšãã2ã€ã®ç¹å¥ãªããŒãã«ã䜿çšãããŸãããã®2ã€ã®ããŒãã«ã¯SQL Serverãèªåã§äœæãã管çããŠããŸãã ãã®ããŒãã«ã®åœ¹å²ã¯ä»¥äžã®éãã§ãããã®2ã€ã®ããªã¬ãŒããŒãã«ãçšããŠãTrackerã§ã¯å€æŽåã®ããŒã¿ãååŸããŠããŸãã ããŒãã«å 説æ deleted ãDELETEããŸãã¯ãUPDATEãã§å€æŽãããåã«ã圱é¿ãåããè¡ã®ã³ã㌠inserted ãINSERTããŸãã¯ãUPDATEãã®åŸã«ãæ°ãããŸãã¯å€æŽãããè¡ã®ã³ããŒ å€æŽåã®ããŒã¿ãååŸããéã¯ä»¥äžã®ãããªããªã¬ãŒãçšããŠããŸãããç©çåé€ããã倿Žåã®ããŒã¿ãååŸããå Žåã¯çŽæ¥deletedããŒãã«ããååŸããã®ã§ã¯ãªããããŒã¿ã®æŽåæ§ãæ
ä¿ããããå¥ããŒãã«ãžæžãåºããããŒã¿ãå©çšããŠããŸããããã®ããŒãã«ããããŒã¿ãååŸããããšã§ã倿Žåã®ããŒã¿ãAnalyzerã«é£æºããŠããŸããã CREATE TRIGGER [Database].[SaveDeletedTable] ON [Database].[ Table ] AFTER INSERT , DELETE AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON ; -- delete unused primary key from DeletedTable DELETE FROM Database.DeletedTable WHERE primary_key IN ( SELECT primary_key FROM deleted UNION ALL SELECT primary_key FROM inserted); INSERT INTO dbo.DeletedTable SELECT * FROM deleted; END SQL Serverã®ããªã¬ãŒæ©èœã®è©³çްã¯ä»¥äžã®èšäºãã確èªãã ããã learn.microsoft.com ãªããªãã¬ã€ã¹ãããã®ã ãªãTrackerããªãã¬ã€ã¹ãããã®ãã玹ä»ããŸãã Windows Serverã®éçšè² è·ãé«ã Trackerã¯Windows Serveräžã§éçšãããŠããŸãããå
ã
瀟å€ã§äœãããåºç€ã§ãã£ããããããŒã å
ã«Windows Serverã®ç¥èŠãå°ãªããã€ã³ãã©ã®ã³ãŒãåããããã€ã®èªååãé£ãããšããããããŸããããŸããWindows Serverã®ã©ã€ã»ã³ã¹è²»çšãé«é¡ã§ãããéçšè² è·ã®é«ãWindows Serverããè±åŽããSQL Serverã廿¢ããããšèããŠããŸããã ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã å
šäœã®ãªãã¬ã€ã¹ã«å¿
èŠãªããŒã¿é£æºåºç€ãå¿
èŠ ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã ã®å
šäœã®ãªãã¬ã€ã¹ãé²ããäžã§ãAnalyzer以å€ã®åãã€ã¯ããµãŒãã¹ãžããªã¢ã«ã¿ã€ã ã«ããŒã¿é£æºã§ããä»çµã¿ãå¿
èŠã§ãããæ±çšçãªèŠä»¶ã«å¯Ÿå¿ã§ãããåããããªä»çµã¿ãäœããããšèããŠããŸãããä»åã®ã¿ã€ãã³ã°ã§æ°ããæ±çšçãªåºç€ãæ§ç¯ããTrackerããªãã¬ã€ã¹ããããšã«ããŸããã ãªãã¬ã€ã¹åŸã®é
ä¿¡çšãªã¢ã«ã¿ã€ã ããŒã¿åºç€ å
ã«è¿°ã¹ããããªèª²é¡ããããããæ¢åã®é
ä¿¡çšãªã¢ã«ã¿ã€ã ããŒã¿åºç€ã®èª²é¡ããªãã¬ã€ã¹ããŸããã以éãªãã¬ã€ã¹åŸã®é
ä¿¡çšãªã¢ã«ã¿ã€ã ããŒã¿åºç€ããæ°Trackerãããªãã¬ã€ã¹åã®åºç€ããæ§TrackerããšåŒã³ãŸãã å®å
šã«ãªãã¬ã€ã¹ããããã®æ¹é æ¢ã«è¿°ã¹ãããã«æ§Trackerã§ã¯å€æŽåã®ããŒã¿ãããªã¬ãŒæ©èœãçšããŠååŸããŠããŸããããªãã¬ã€ã¹ãé²ããã«ãããã倿Žåã®ããŒã¿ãååŸããæ¹æ³ãæ€èšããå¿
èŠããããŸãããæ¬æ¥ã¯å€æŽåã®ããŒã¿ããªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã åŽã®ãã£ãã·ã¥ãããšãæ¹ãæãŸããã§ãããããã飿ºå
ã®Analyzerã«å€§ããªæãå ããããšã¯å°é£ã§ãããAnalyzerã®ãããã€ã«ã¯æ°æéããããŸããåé ã§ç޹ä»ãããšãããã€ã³ã¡ã¢ãªãªããŒã¿ã¹ãã¢ãªã®ã§ãé害çããã£ãå Žåã¡ã¢ãªäžã®ããŒã¿ãå¹ãé£ã¶æžå¿µããããŸããããŒã¿ã®ãªã«ããªã«ã8ã9æéã»ã©ãããããããŒã«ããã¯ãããã®ã¯é£ããç¶æ
ã§ããããŸããç§»è¡å¯Ÿè±¡ãšãªãã¯ãšãªã22ããŒãã«ã»ã©ãããã¯ãšãªã«ãŠè€éãªå å·¥åŠçãæœããŠããŸããã ããã§ãAnalyzeråŽã«ã¯æãå ããªãæ¹éã§ãªãã¬ã€ã¹ãé²ããããšã«ããŸããããããªãã¬ã€ã¹åŸã«åé¡ãçºçããŠããAnalyzeråŽã«æãå ããŠããªããã°æ§Trackerã«åãæ»ããå¯èœã§ãããŸãããªãã¬ã€ã¹ã«äŒŽãããŒã¿è©äŸ¡ã®ç¹ã§ããæ§Trackerãšæ°Trackerã§åºåãããããŒã¿ãæããããšã§ããŒã¿ã®è©äŸ¡ãå¯èœã«ãªããŸãã 倿Žåã®ããŒã¿ããªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã ã®ãã£ãã·ã¥ããåãããã«ããããšã¯ãæ°Trackerãžãªãã¬ã€ã¹åŸã§ãå¯èœã§å®¹æã«ãªããŸããä»åã®ãªãã¬ã€ã¹ãå®äºããåŸã察å¿ããŠããããšã«ããŸããã 倿ŽååŸã®ããŒã¿ãååŸããæ¹æ³ãæ€èš æ°Trackerã§ã¯ãBigQueryäžã«æ§ç¯ãããå
šç€Ÿå
±éã®ããŒã¿åºç€ã§ãããªã¢ã«ã¿ã€ã ããŒã¿åºç€ãã倿ŽããŒã¿ãååŸããŠããŸãããªã¢ã«ã¿ã€ã ããŒã¿åºç€ã«ããããšã§ãSQL Serverããè±åŽããã©ã€ã»ã³ã¹è²»çšçã®ã³ã¹ããéçšè² è·ã®è»œæžãããã©ãŒãã³ã¹é¢ã§ã®æ¹åãæåŸ
ã§ããŸãã ãªã¢ã«ã¿ã€ã ããŒã¿åºç€ã¯æ°å¹Žåã«äœãããåãããã«SQL Serverã®å€æŽããŒã¿ã倿Žè¿œè·¡ã®æ©èœãçšããŠããªã¢ã«ã¿ã€ã ã§BigQueryãžããŒã¿é£æºããŠããŸããæ§Trackerã¯å
šç€Ÿå
±éã®ãªã¢ã«ã¿ã€ã ããŒã¿åºç€ãã§ããåãããã£ãã·ã¹ãã ã®ãããç¬èªã§SQL Serverã®å€æŽããŒã¿ãéããŠããŸãããä»åã®ãªãã¬ã€ã¹ã®ã¿ã€ãã³ã°ã§ãªã¢ã«ã¿ã€ã ããŒã¿åºç€ããããŒã¿ãååŸããããšã«ããŸããã ãªã¢ã«ã¿ã€ã ããŒã¿åºç€ã®è©³çްã¯ä»¥äžã®èšäºãã確èªãã ããã techblog.zozo.com ããŒã¿ãœãŒã¹ãSQL Serverãããªã¢ã«ã¿ã€ã ããŒã¿åºç€ã«ããããšã§ä»¥äžãèæ
®ããå¿
èŠããããŸããã ããŒã¿ã®éè€ ããŒã¿ã®é åº å€æŽåããŒã¿ã®ååŸæ¹æ³ æ§Trackerã§ã¯SQL Serverã®å€æŽè¿œè·¡ãçšããŠã倿Žã®ãã£ãããŒã¿ãååŸããŠãããããååŸããããŒã¿ã®é åºã¯ä¿èšŒãããŠãããããŒã¿ã®éè€ããããŸããã§ããã ãããããªã¢ã«ã¿ã€ã ããŒã¿åºç€ã§ã¯éçšãããããããat-least-onceããªèšèšã«ãªã£ãŠããŸããããŒã¿ã¯éè€ããé
å»¶ããŒã¿ãå
¥ãããé åºã¯ä¿èšŒãããŠããŸããã ãŸããæ§Trackerã§ã¯SQL Serverã®ããªã¬ãŒæ©èœãçšããŠå€æŽåã®ããŒã¿ãååŸããŠããŸããããªã¢ã«ã¿ã€ã ããŒã¿åºç€ãžç§»è¡ããããšã§ãããŒã¿ã®æŽåæ§ãæ
ä¿ãã€ã€å€æŽåã®ããŒã¿ãååŸããæ¹æ³ã®æ€èšãå¿
èŠã«ãªããŸãã 倿ŽååŸã®ããŒã¿ãååŸããã¯ãšãª ãããã®èŠä»¶ãæºããããã«ããªã¢ã«ã¿ã€ã ããŒã¿åºç€ããããŒã¿ãååŸããéã«ããŒã¿ã®éè€æé€ãšé åºä¿èšŒãããŠããŸãããŸãã倿Žåã®ããŒã¿ã¯é
ä¿¡åºç€ãžé£æºæžã¿ã®å®çžŸããŒãã«ããååŸããããã«ããŸãããå
·äœçã«ã©ã®ãããªã¯ãšãªãå®è¡ããŠãããã玹ä»ããŸãã 倿ŽååŸã®ããŒã¿ãååŸããã¯ãšãªã¯ããŒãã«é¢æ°ãšããŠçšæããŠããŸããæ¬¡ã®ããã«ã¿ã€ã ã¹ã¿ã³ããæž¡ãããšã§ãæž¡ããã¿ã€ã ã¹ã¿ã³ã以éã«å€æŽã®ãã£ã倿ŽååŸã®ããŒã¿ãååŸã§ããããã«ããŠããŸãã ããŒãã«é¢æ°ã®äœ¿ãæ¹ã¯æ¬¡ã®éãã§ãã SELECT * FROM `< table ID>`( ' 2023-05-01 ' ) ããŒãã«é¢æ°ã«ã¯ä»¥äžã®2çš®é¡çšæããŠããŸãã 倿ŽåŸã®ããŒã¿ã®ã¿ååŸãã颿° 倿ŽååŸã®ããŒã¿ãååŸãã颿° ããŒãã«é¢æ°å
ã§å
·äœçã«ã©ã®ãããªåŠçãããŠãããã玹ä»ããŸãã 倿Žãã°ã®ååŸ ãªã¢ã«ã¿ã€ã ããŒã¿åºç€ããã倿Žã®ãã£ãããŒã¿ãååŸããŠããŸããååŸããããŒã¿ã¯é åºä¿èšŒãããŠããããããŒã¿ã®éè€ããããŸãã詳现ã¯åŸè¿°ã®ã倿Žãã°ã®éèšïŒå€æŽããŒã¿ã®ååŸïŒãã§ã玹ä»ããŸãããé åºãä¿èšŒããããŒã¿ã®éè€ãæé€ããããã«ãã©ã€ããªãŒããŒãå¿
èŠã«ãªããŸãã察象ããŒãã«ã®ãã©ã€ããªãŒããŒãã«ã©ã ãšããŠäœããŸããã¯ãšãªå
ã®ãlast_sync_timeãã¯TIMESTAMPåã§ãããŒãã«é¢æ°ããæž¡ããããã©ã¡ãŒã¿ã§ããæçµåæããããŒã¿ã®æå»ãæž¡ãããšã§ãè©²åœæå»ããåŸã«å€æŽã®ãã£ãããŒã¿ãååŸã§ããŸãã ååŸæéã3æéã«ããŠããã®ã¯ããªã¢ã«ã¿ã€ã ããŒã¿åºç€ã®é
å»¶ããŒã¿ã«å¯Ÿå¿ããããã§ããåè¿°ãããšããããªã¢ã«ã¿ã€ã ããŒã¿åºç€ã§ã¯é åºä¿èšŒãããŠããªãããé
å»¶ããŒã¿ãèæ
®ããå¿
èŠããããŸããå®é3æéãé
ããããšã¯ãªãã®ã§ãããæçµåæãããæå»ã§ãããlast_sync_timeãã«é
å»¶æéãèæ
®ããŠå€æŽããŒã¿ãååŸããŠããŸããé
å»¶ããŒã¿ãèæ
®ããªããšã倿Žãã°ã®ååŸã®éã«ããŒãã£ã·ã§ã³å€ãšãªãããŒã¿ãæ¬ æããŠããŸããŸãã倿Žãã°ã®ååŸã«æ§Trackerã®ããã«å€æŽè¿œè·¡ã®ããŒãžã§ã³ã§ã¯ãªããã¿ã€ã ã¹ã¿ã³ããçšããŠããã®ãé åºä¿èšŒãããé
å»¶ããéã®ããŒã¿æ¬ æãé²ãããã§ãã streaming AS ( SELECT *, CONCAT (${ join ( " , " ,primary_key)}) AS primary_key FROM `${project_changetracking}.${dataset_changetracking}.${table_changetracking}` WHERE bigquery_insert_time >= TIMESTAMP_SUB( CAST ( FORMAT_TIMESTAMP( " %Y-%m-%d " , TIMESTAMP_SUB(last_sync_time , INTERVAL 3 Hour) , " Asia/Tokyo " ) AS timestamp ) , INTERVAL 9 HOUR ) ) ããŒã¿é£æºå®çžŸãã°ã®ååŸ ã¯ãšãªã§ååŸãã倿ŽååŸã®ããŒã¿ã¯å®çžŸããŒãã«ã«æžã蟌ãŸããŸãã以éãããŒã¿é£æºå®çžŸããŒãã«ããšåŒã³ãŸããããŒã¿é£æºå®çžŸããŒãã«ã®çšéã¯åŸè¿°ããŸãããããŒã¿é£æºå®çžŸããŒãã«ã«æžã蟌ãŸããããŒã¿ã¯æžã蟌ãŸããé ã«åãµãŒãã¹ãžããŒã¿é£æºãããŸããããããããšã§ãããŒã¿é£æºå®çžŸããŒãã«ãã倿Žåã®ããŒã¿ãååŸããããšã§ãAnalyzerã«ãã£ãã·ã¥ãããŠããããŒã¿ãšã®æŽåæ§ããšãããšãã§ããŸãã ãŸãããªã¢ã«ã¿ã€ã ããŒã¿åºç€ã§ååŸãããã°ãã飿ºæžã¿ã®å®çžŸãæé€ããããã«ãå©çšããŠããŸãããã®åŸã®ã倿ŽååŸã®ããŒã¿ãããŒãžãã«ãŠèª¬æããŸãã event_sync_logs AS ( SELECT realtime_message_unique_id, realtime_changetrack_ver, CONCAT (${ join ( " , " ,primary_key)}) AS primary_key,tracking_type FROM `${project}.${tracking_event_log_dataset}.${table_base}` WHEREÃ¥ tracking_start_time >= TIMESTAMP_SUB( CAST ( FORMAT_TIMESTAMP( " %Y-%m-%d " , TIMESTAMP_SUB(last_sync_time , INTERVAL 36 Hour) , " Asia/Tokyo " ) AS timestamp ) , INTERVAL 9 HOUR ) ) ååŸæéã36æéã«ããŠããã®ã¯ã倿Žåã®ããŒã¿ã®ååŸã«å
šç€Ÿå
±éããŒã¿åºç€ã®å
šéããŒã¿ãçšããããã§ããããŒã¿é£æºå®çžŸãã°ã§ååŸã§ããããŒã¿ã®ç¯å²ã«å€æŽåã®ãã°ãå«ãŸããŠãããšã¯éããŸãããäŸãã°æåŸã«æŽæ°ããããã°ã5æ¥åã®å ŽåããŒãã£ã·ã§ã³ã®ç¯å²å€ãšãªããŸãã å
šç€Ÿå
±éããŒã¿åºç€ã§ã¯æ¥æ¬¡ã®ãããåŠçã§ãSQL Serverã«ããããŒãã«ãå
šä»¶BigQueryãžé£æºããŠããŸãããããããŒã¿é£æºå®çžŸãã°ã®ååŸã®éãååŸæéãæ°æéã«ããŠããŸããšãå
šç€Ÿå
±éããŒã¿åºç€ã§ã¯æ¥æ¬¡ã®ãããåŠç飿ºåŸã«å€æŽã®ãã£ãäžéšã®ããŒã¿ãæ¬ æããŠããŸããŸããæ¥æ¬¡é£æºãããæå»ãããåããååŸããããšã§ããŒã¿ã®æ¬ æãé²ãããšãã§ããŸããããŒã¿é£æºåŽã®é
å»¶ãèæ
®ããŠã36æéãšããŠããŸãã å
šç€Ÿå
±éããŒã¿åºç€ã«ã€ããŠã¯ä»¥äžã®èšäºãã確èªãã ããã techblog.zozo.com 倿Žãã°ã®éèšïŒå€æŽããŒã¿ã®ååŸïŒ SQL Serverããå
±éåºç€ã§ãããªã¢ã«ã¿ã€ã ããŒã¿é£æºåºç€ãžã®ããŒã¿é£æºã«ã¯åé ã§ã玹ä»ããSQL Serverã®å€æŽè¿œè·¡ãçšããŠããŸããããŒãã«ã®ãã©ã€ããªãŒããŒãšææ°ã®å€æŽè¿œè·¡ããŒãžã§ã³ãéèšãã倿Žå±¥æŽãšJOINããããšã§ææ°ã®å€æŽããŒã¿ãååŸã§ããŸãããã®éèšã«ããããªã¢ã«ã¿ã€ã ããŒã¿åºç€å
ã®ããŒã¿éè€ãæé€ããé åºã®ä¿èšŒãããŠããŸãã倿ŽåŸã®ããŒã¿ã®ã¿å¿
èŠãªå Žåã¯åŸè¿°ããŠãã倿Žåã®ããŒã¿ãååŸããåŠçã¯äžèŠã§ãã streaming_latest_version AS ( SELECT primary_key, MAX (changetrack_ver) AS changetrack_ver_max, FROM streaming GROUP BY primary_key ), streaming_latest AS ( SELECT streaming.* FROM streaming INNER join streaming_latest_version ON streaming.primary_key = streaming_latest_version.primary_key AND streaming.changetrack_ver = streaming_latest_version.changetrack_ver_max ), ããŒã¿é£æºå®çžŸãã°ã®éèšïŒå€æŽåããŒã¿ã®ååŸïŒ ããŒã¿é£æºå®çžŸãã°ãã倿Žåã®ãã°ãååŸããŸããããŒã¿é£æºå®çžŸãã°å
ã®ããŒã¿ã倿Žåã®ããŒã¿ãšããŠå©çšããŸãã streaming_before_latest_version AS ( SELECT primary_key, MAX (realtime_changetrack_ver) AS realtime_changetrack_ver_max FROM event_sync_logs WHERE primary_key IN ( SELECT primary_key FROM streaming_latest ) AND tracking_type = 0 GROUP BY primary_key ), streaming_before_latest AS ( SELECT a.* FROM streaming AS a INNER join streaming_before_latest_version AS b ON a.primary_key = b.primary_key AND a.changetrack_ver = b.realtime_changetrack_ver_max ), ããŒã¿é£æºå®çžŸãã°ã«å«ãŸããŠããªã倿ŽåããŒã¿ã®ååŸ åè¿°ã®ãããŒã¿é£æºå®çžŸãã°ã®ååŸãã§è¿°ã¹ããšããã倿Žåã®ãã°ãããŒã¿é£æºå®çžŸãã°ã«å«ãŸããŠããªãå ŽåããããŸããããŒã¿é£æºå®çžŸãã°ã«å€æŽã®ãã£ããã©ã€ããªãŒããŒã®å€æŽåããŒã¿ããªãå Žåã¯æ¥æ¬¡ã®å
šéããŒã¿ãã倿Žåã®ããŒã¿ãååŸããŠããŸããããŒã¿ã®æŽåæ§ã®èгç¹ã§ããå
šéããŒã¿ããååŸãã倿Žåã®ããŒã¿ã¯Analyzerã«ãã£ãã·ã¥ãããŠããããŒã¿ãšãäžèŽããããåé¡ãããŸããã daily_before_latest AS ( SELECT streaming_latest_id.massage_unique_id, " ${dataset} " AS database_name, " ${table_base} " AS table_name, CAST ( NULL AS string) AS changetrack_type, CAST ( NULL AS int64) AS changetrack_ver, CAST ( NULL AS int64) AS changetrack_last_sync_ver, CAST ( NULL AS timestamp ) AS changetrack_start_time, CAST ( NULL AS timestamp ) AS bigquery_insert_time, streaming_latest_id.primary_key, ${ join ( " ,\n " ,columns)} FROM ( SELECT *, CONCAT (${ join ( " , " ,primary_key)}) AS primary_key FROM `${project_snapshot}.${dataset_snapshot}.${table_base}_20*` AS snapshot_table WHERE _TABLE_SUFFIX IN ( SUBSTR ( FORMAT_TIMESTAMP( " %Y%m%d " , TIMESTAMP_SUB(last_sync_time, INTERVAL 1 day), " Asia/Tokyo " ), 3 ) ) ) AS snapshot_table INNER join ( SELECT massage_unique_id, primary_key FROM streaming_latest ) AS streaming_latest_id ON snapshot_table.primary_key = streaming_latest_id.primary_key WHERE snapshot_table.primary_key NOT IN ( SELECT primary_key FROM streaming_before_latest_version ) ) 倿ŽååŸã®ããŒã¿ãããŒãž 倿ŽåŸãšå€æŽåã®ããŒã¿ãããŒãžããŠã倿ŽååŸã®ããŒã¿ãååŸããŠããŸãã倿ŽååŸã®ããŒã¿ãèå¥ã§ãããããtracking_typeããä»äžããŠããŸãã倿ŽåŸã¯ã0ã倿Žåã¯ã1ããšããŠãŸãããŸããå®çžŸãã°ãçšããŠé£æºæžã¿ã®ããŒã¿ã¯æé€ããŠããŸããéè€æé€ã«ã¯ã¡ãã»ãŒãžåäœã§ãŠããŒã¯ãšãªãã¡ãã»ãŒãžIDãrealtime_message_unique_idããå©çšããŠããŸãã SELECT massage_unique_id AS realtime_message_unique_id, 0 AS tracking_type, * FROM streaming_latest UNION ALL SELECT CONCAT (massage_unique_id, " 1 " ) AS realtime_message_unique_id, 1 AS tracking_type, * FROM streaming_before_latest UNION ALL SELECT CONCAT (massage_unique_id, " 2 " ) AS realtime_message_unique_id, 1 AS tracking_type, * FROM daily_before_latest) WHERE realtime_message_unique_id NOT IN ( SELECT realtime_message_unique_id FROM event_sync_logs ) ãã®ãããªã¯ãšãªãçšããŠã倿ŽååŸã®ããŒã¿ãååŸããŠããŸãã ã¢ãŒããã¯ãã£æŠèŠãšåŠçã®æµã æ°Trackerã®ã¢ãŒããã¯ãã£æŠèŠãšåŠçã®æµãã«ã€ããŠã玹ä»ããŸãã ã¢ãŒããã¯ãã£ã®å
šäœã¯æ¬¡ã®éãã§ããæ°Trackerã§ã¯ãªã¢ã«ã¿ã€ã ããŒã¿é£æºåºç€ãã倿ŽååŸã®ããŒã¿ãååŸããŠãã¡ãã»ãŒãžãããŒã«ãŒã«ãããªãã·ã¥ããŠããŸããã¡ãã»ãŒãžãããŒã«ãŒãžãããªãã·ã¥ãããããŒã¿ã¯Analyzerãå«ãåãµãŒãã¹æ¯ã«äœãããããŒã¿é£æºçšã®APIãçšããŠé£æºãããŸãã以éååŠçã®æµãã®è©³çްãã玹ä»ããŸãã 倿ŽååŸã®ããŒã¿ååŸ æ°Trackerã§ã¯ãªã¢ã«ã¿ã€ã ããŒã¿åºç€ãã倿ŽåŸã®ããŒã¿ãååŸããŠããŸãã倿Žåã®ããŒã¿ã¯åŸè¿°ããããŒã¿é£æºå®çžŸããŒãã«ããååŸããŠããŸãã æ°Trackerã¯GKEäžã«ããŒã ã¹ããŒã¹ãåããŠãããã€ããŠããŸããåãµãŒãã¹ããšã«åãããŒãã«ã§ãå¿
èŠãšãªãETLåŠçãç°ãªããŸãããŸããåãããŒãã«åã§ãDBåäœã§ããŒã¿ã¯ç°ãªããŸãããã®ãããåãªãœãŒã¹ã¯ãµãŒãã¹åäœã§ããŒãã«ã®èå¥ãã§ããããã«åããŠããŸãã ããµãŒãã¹å à ããŒã¿ããŒã¹å à ããŒãã«åã GKEã®ãããã€ã¡ã³ãã¯ä»¥äžã®ããã«ãªã£ãŠããŸãããµãŒãã¹ãšããŠã¯ãanalyzerããšãzozo-notification-deliveryãããããåãããŒãã«ã§ãå¥ã®ãªãœãŒã¹ãšããŠãããã€ãããŠããŸãã kubectl get pod -n realtime-datapump app-analyzer-table1-db1 1 / 1 Running 9 ( 46h ago ) 25d app-analyzer-table2-db2 1 / 1 Running 8 ( 27h ago ) 25dÃ¥ app-analyzer-table3-db3 1 / 1 Running 9 ( 16h ago ) 25d ..... app-zozo-notification-delivery-table1-db1 1 / 1 Running 9 ( 2d4h ago ) 25d app-zozo-notification-delivery-table2-db2 1 / 1 Running 9 ( 13h ago ) 25d app-zozo-notification-delivery-table3-db3 1 / 1 Running 6 ( 46h ago ) 25dåå ãªãœãŒã¹ããšã«èšå®ãã¡ã€ã«ãåããŠããŸãããããã€ããéã«ããµãŒãã¹å à ããŒã¿ããŒã¹å à ããŒãã«åããç°å¢å€æ°ãšããŠæž¡ããç°å¢å€æ°ã«åºã¥ããŠèšå®æ
å ±ãååŸããŠããŸããBigQueryãCloud Pub/Subã®ãªãœãŒã¹æ
å ±ãå¶åŸ¡ã§ããããã«ããŠãŸãããªã«ããªçãèæ
®ãããã€ã¯ããµãŒãã¹åäœã§ããŒãã«çãªãœãŒã¹ã¯åããŠç®¡çããŠããŸãã # analyzer [services.analyzer-db1-table1] gcp_project = "gcp_project" pubsub_topic_project = "pubsub_topic_project" message_reflesh_count = 50000 pubsub_topic = "<table1>" dataset_event_send_ids = "db1_tracking_event_send_ids" dataset_event_logs = "db1_tracking_event_logs" ... # zozo-notification-delivery [services.zozo-notification-delivery-db1-table1] gcp_project = "gcp_project" pubsub_topic_project = "pubsub_topic_project" message_reflesh_count = 50000 pubsub_topic = "<table1>" dataset_event_send_ids = "zozo_notification_delivery_<db1>_tracking_event_send_ids" dataset_event_logs = "zozo_notification_delivery_<db1>_tracking_event_logs" ãããã€ãããæ°Trackerã¯ã¹ããŒãã¬ã¹ã«ãªã£ãŠããããŸãæçµåæããã¡ãã»ãŒãžã«çŽã¥ãæå»ãååŸããŸããåŸè¿°ã®ãæçµåæã¡ãã»ãŒãžãæžã蟌ããã§ã玹ä»ããŸããããµãŒãã¹ã«ãããªãã·ã¥ãããæåŸã®ã¡ãã»ãŒãžã¯å¥ããŒãã«ã§ç®¡çãããŠããŸããæ°Trackerã®Podèµ·åæã«æçµåæããã¡ãã»ãŒãžã®æå»ãååŸããŸãã æçµåæã®æå»ããå
ã»ã©ã玹ä»ããããŒãã«é¢æ°ã«æž¡ãã倿ŽååŸã®ããŒã¿ãååŸããŸããåãã€ã¯ããµãŒãã¹ã§å¿
èŠãšãªãETLåŠçãããŠããŸãã ããŒã¿é£æºå®çžŸããŒãã« å å·¥ãããããŒã¿ã¯å¥ããŒãã«ãžæžã蟌ãŸããŸããæžã蟌ãŸããããŒã¿ã¯å€ãé ããå
šãŠé
ä¿¡åºç€åŽãžé£æºãããŸããå å·¥ãããããŒã¿ãäžåºŠæžãåºãçç±ãšããŠã¯ãåªçæ§ã®æ
ä¿ãšéè€æé€ã«ããããã©ãŒãã³ã¹ããããããã§ãã 倿Žåã®ããŒã¿ãããŒã¿é£æºå®çžŸããŒãã«ããåããªããšããªãã©ã€ãããå Žåã倿Žåã®ããŒã¿ããã£ãã·ã¥ãããŠããããŒã¿ãšäžèŽããªããªããŸããåããã©ã€ããªãŒããŒã«å¯ŸããŠãè€æ°åã®æŽæ°åŠçãèµ°ã£ãå Žåãèæ
®ãããšããªã¢ã«ã¿ã€ã ããŒã¿åºç€ã«ãã倿Žåã®ããŒã¿ãšAnalyzerã§ãã£ãã·ã¥ãããŠãã倿Žåã®ããŒã¿ãäžèŽããªããªãããã§ãããªã¢ã«ã¿ã€ã ããŒã¿åºç€ã«ãã倿ŽããŒã¿ãå¥ããŒãã«ãžæžãåºãããšã§ã倿ŽåããŒã¿ã®æŽåæ§ãæ
ä¿ããŠããŸãããŸããåè¿°ããã倿ŽååŸã®ããŒã¿ãååŸããã¯ãšãªãã§è¿°ã¹ããšããã倿ŽååŸã®ããŒã¿ãååŸããã«ã¯ã¿ã€ã ã¹ã¿ã³ããçšããŠããŸãããªã¢ã«ã¿ã€ã ããŒã¿åºç€ããããŒã¿æ¬ æããªãããé
å»¶ããŒã¿ãèæ
®ããŠã倿ŽããŒã¿ãååŸããããããã§ã«é£æºæžã¿ã®ããŒã¿ãååŸãããŠããŸããŸããããŒã¿é£æºå®çžŸããŒãã«ãçšããããšã§ã飿ºæžã¿ã®ããŒã¿ãé€å€ããããã©ãŒãã³ã¹ãåäžãããããã«ãå©çšããŸããããŒã¿é£æºå®çžŸããŒãã«ã«é£æºãããããŒã¿ã¯ãµãŒãã¹ãžé£æºããããããé害æã®åå 調æ»ã«ã圹ç«ã¡ãŸãã ã¡ãã»ãŒãžãããŒã«ãŒãžé£æº ããŒã¿é£æºå®çžŸããŒãã«ãžæžã蟌ãŸããããŒã¿ã¯å€ãããŒã¿ããé ã«åãåºãããã¡ãã»ãŒãžãããŒã«ãŒãžãããªãã·ã¥ãããŸããã¡ãã»ãŒãžãããŒã«ãŒãæãããšã§ãéåæåŠçãå¯èœãšãªãèé害æ§ãåäžããŸãããããã¡ãã»ãŒãžãããŒã«ãŒå
ã®ããŒã¿ãåŠçããŠããã³ã³ã·ã¥ãŒããé害ãèµ·ãããå Žåã§ããã¡ãã»ãŒãžãããŒã«ãŒãžããŒã¿ããããªãã·ã¥ãããããã¥ãŒãµã¯åœ±é¿ãããã«åŠçãç¶ç¶ã§ããŸãããŸããã¡ãã»ãŒãžãããŒã«ãŒãæãããšã§ãåãã€ã¯ããµãŒãã¹ãžã®ããŒã¿é£æºã§å¿
èŠãªã€ã³ã¿ãã§ãŒã¹ãæããããšãã§ãããããæ±çšæ§ã®é«ãã·ã¹ãã ãæ§ç¯ã§ããŸãã ããŒã¿é£æºå®çžŸããŒãã«ããããŒã¿ãåãåºãã¯ãšãªã¯ä»¥äžã®ããã«ãªã£ãŠããŸãããLastSyncTimeãã¡ãã»ãŒãžãããŒã«ãŒãžã®é
ä¿¡ãæåããæåŸã®ã¡ãã»ãŒãžã«çŽã¥ãæå»ãå
¥ããŸããããŒã¿é£æºå®çžŸããŒãã«ã«é£æºæžã¿ã§ããŸã ã¡ãã»ãŒãžãããŒã«ãŒãžé
ä¿¡ã§ããŠããªãã¡ãã»ãŒãžã®ã¿æœåºããŸãã SELECT * FROM `zozo-ma-realtime-datapump-{{.Env}}.{{.EventLogsDataset}}.{{.EventName}}` WHERE tracking_start_time > " {{.LastSyncTime}} " ORDER BY tracking_start_time ASC ã¡ãã»ãŒãžãããŒã«ãŒã«ã¯Cloud Pub/Subãæ¡çšããŠããŸããCloud Pub/Subã§é åºä¿èšŒããã«ã¯é åºä¿èšŒããŒãOrderingKeyããçšããå¿
èŠããããŸããSQL Serverã®ãã©ã€ããªãŒããŒãé åºä¿èšŒããŒãšããŠããããªãã·ã¥ããŠããŸããé åºãä¿èšŒãããããã¡ãã»ãŒãžãããŒã«ãŒãžã®ãããªãã·ã¥ã1ä»¶ã§ã倱æããå Žåãå®çžŸããŒãã«å
ã®æªé£æºããŒã¿ã¯å
šãŠå飿ºãããŸãã cloud.google.com Cloud Pub/Subãžã®ãããªãã·ã¥æã«ä»¥äžã®ããã«å±æ§æ
å ±ãAttributesããæž¡ããŠããŸãã publishResult := t.Publish(ctx, &pubsub.Message{ Data: [] byte (msg), Attributes: map [ string ] string { "event" : event.EventSourceName() + "-" + event.EventDatabaseName() + "-" + event.EventName(), "message_id" : event.MessageId(), "key" : event.RealtimeMessageKey(), "action" : event.Action(), }, OrderingKey: event.OrderId(), }) 屿§æ
å ±ã®åœ¹å²ã¯ä»¥äžã®éãã§ãã 屿§ 説æ event åã€ãã³ããèå¥ããããã«å©çš message_id ã¡ãã»ãŒãžã®ãŠããŒã¯å€ãèå¥ããããã«å©çš key SQL Serverã®ãã©ã€ããªãŒã㌠action 倿Žã®ãã£ãã€ãã³ãã¿ã€ããupsertããšãdeleteã ãããã®å±æ§æ
å ±ã«åºã¥ããåŸè¿°ããé
ä¿¡ç³»ãµãŒãã¹ãžããŒã¿é£æºãæ
ãAPIã§åŠçãããŠããŸãã ããŒã¿é£æºAPIïŒAnalyzerïŒ Cloud Pub/Subãžãããªãã·ã¥ãããããŒã¿ã¯AnalyzerãžããŒã¿é£æºãããŸããAnalyzerãžã®ããŒã¿é£æºAPIã«ã¯Cloud DataflowãçšããŠããŸããCloud Pub/Subãžãããªãã·ã¥æã«å±æ§æ
å ±ãšããŠæž¡ãããeventããçšããŠãã€ãã³ãåã«åºã¥ãAnalyzerãžã®ãšã³ããã€ã³ãã«å¯ŸããŠãªã¯ãšã¹ãããŸããAnalyzerã¯AWSç°å¢ã«ãããããGCPããAWSç°å¢ãžãªã¯ãšã¹ãããããã«ãZOZOå
ã®å
±éåºç€ã§ããShard VPCãçšããŠããŸãã ShardVPCã«ã€ããŠã¯ä»¥äžã®èšäºãã確èªãã ããã techblog.zozo.com åœæCloud RunãCloud Functionsãæ¡çšããªãã£ãã®ã¯åŸé課éã«ããã³ã¹ããæãããã£ãããã§ããCloud RunãCloud Functionsã®æ¯èŒçæ°ããæéäœç³»ã§ãããAlways on CPUãã ãšããªã¯ãšã¹ã課éãçºçããŸããã倧éã®ããŒã¿ãæ±ããã°åéåºç€ãªã©ã§ã¯ã¹ã±ãŒãªã³ã°ãéããã³ã¹ãé¢ã®è²»çšå¯Ÿå¹æãé«ãã§ãã cloud.google.com ãã ããä»åã¯Shard VPCãå©çšããããCloud RunãCloud Functionsã䜿ãå Žåã¯ãµãŒãã¬ã¹VPCãå©çšããå¿
èŠããããŸãããµãŒãã¬ã¹VPCã¯åŸé課éãšãªã£ãŠããŸããããéçšå®çžŸããããè²»çšåž¯å¹æã®é«ãCloud Dataflowãæ¡çšããŸããã cloud.google.com ããããå®éã«Cloud RunãéçšããŠã¿ãŠããã©ãŒãã³ã¹é¢ãæå°ã¯ãŒã«ãŒæ°ã®å¶åŸ¡çãCloud DataflowãããåªããŠããç¹ãå€ãããã«æããŸãããèŠä»¶æ¬¡ç¬¬ã§ã¯ãããŸãããä»åŸæ°èŠã§ã¹ããªãŒãã³ã°ç³»ã®ããŒã¿é£æºãããå Žåã¯ç©æ¥µçã«Cloud Runã䜿ããããšæããŸããã AppendixïŒããŒã¿é£æºAPIïŒPush/LINEé
ä¿¡åºç€ïŒ åè¿°ã®ããªããªãã¬ã€ã¹ãããã®ããã§ã玹ä»ãããšãããæ°Trackerã¯Analyzer以å€ã®åãã€ã¯ããµãŒãã¹ãžããªã¢ã«ã¿ã€ã ã«ããŒã¿é£æºã§ããŸããAppendixãšããŠé
ä¿¡åºç€ãžã®ããŒã¿é£æºã«ã€ããŠãç°¡åã«ã玹ä»ããŸãã ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã å
šäœã®ãªãã¬ã€ã¹ã«äŒŽããAnalyzerã®åãã£ã³ãã«ãžã®é
ä¿¡æ©èœãé
ä¿¡åºç€ãšããŠåãåºããã¢ãžã¥ãŒã«åããŠããŸããé
ä¿¡åºç€ã¯å
šç€Ÿã®å
±éåºç€ãšããŠZOZOå
éšã®ä»ã®ã·ã¹ãã ãããé
ä¿¡åŠçã宿œã§ããããã«äœãããŠããŸããé
ä¿¡åºç€ã®æ©èœãšããŠãé
ä¿¡åºç€ãžã®ãªã¯ãšã¹ãã«å«ãŸããŠããã¡ã³ããŒIDãçšããŠãéç¥èšå®ã®ç¢ºèªãPushãLINEé
ä¿¡ã«å¿
èŠãªããŒã¯ã³ãžã®å€æãããŠããŸããé
ä¿¡åºç€ã§å¿
èŠãªããŒã¿ãæ°TrackerãçšããŠé£æºããŠããŸãã é
ä¿¡åºç€çšã®ããŒã¿é£æºAPIã«ã¯Cloud Runãæ¡çšããŠããŸããCloud Runãæ¡çšããã®ã¯ãCloud Dataflowãããã¹ã±ãŒãªã³ã°ãéããããã©ãŒãã³ã¹é¢ã§åªããŠããããã§ãããŸãããAlways on CPUãã䜿ãã°ä»åŸããŒã¿éãå¢ããŠããªã¯ãšã¹ã課éã«ããæžå¿µã¯ãªããªããŸããé
ä¿¡åºç€çšã®ããŒã¿é£æºAPIã¯AWSãšçéããããšããªãããããµãŒãã¬ã¹VPCã®è²»çšãæ°ã«ããå¿
èŠããããŸããã é
ä¿¡åºç€ã®ã¹ãã¬ãŒãžã«ã¯GCPã®ãµãŒãã¬ã¹ã§NoSQLããŒã¿ããŒã¹ã§ããCloud FirestoreãDatastoreã¢ãŒãã§æ¡çšããŠãŸããé
ä¿¡åºç€ã«å¿
èŠãªããŒã¿ãããŒã¿é£æºAPIãçšããŠãCloud Firestoreã«ãã£ãã·ã¥ããŠããŸãã屿§æ
å ±ã®ãactionãã«åºã¥ããŠããŒã¿ã®æŽæ°ãšåé€ãããŠããŸããé
ä¿¡åºç€ã§ãAnalyzeråæ§ã«ååãªããã©ãŒãã³ã¹ãã§ããããCloud Firestoreã®KEYã«ã¡ã³ããŒIDãçšããŠããŸããMAéšä»¥å€ã®ã·ã¹ãã ãããé
ä¿¡ã§ããããã¡ã³ããŒIDãçšããŠé
ä¿¡ã«å¿
èŠãªããŒããã·ã§ã³ãªã©ã®æ
å ±ãååŸããããã§ããCloud Firestoreã«ãã£ãã·ã¥ãããããŒã¿ãAnalyzeråæ§ãå¿
èŠã«å¿ãåé€ããŠããŸããäŸãã°LINEã®é£æºãè§£é€ããéã«ãã£ãã·ã¥ãããããŒã¿ãæ¶ãå¿
èŠããããŸãã ãã ããAnalyzerã®ããã«ã¡ã³ããŒIDãªã©ã®å€æŽåã®ããŒã¿ã¯å¿
èŠãããŸããã以äžã®ããã«å±æ§æ
å ±ã®ãkeyãã§æž¡ãããSQL Serverã®ãã©ã€ããªãŒããŒãçšããŠã察象ã®ããŒã¿ãæœåºããŠåé€ãããŠããŸãã func (mdsrepository *EventCacheRepository) Delete(ctx context.Context, cacheLog entity.TableCatchLog) error { // delete datastore key from sql server primary key _, err := mdsrepository.client.RunInTransaction(ctx, func (tx *gcpdatastore.Transaction) error { query := gcpdatastore.NewQuery(mdsrepository.entityKind).Transaction(tx).FilterField(cacheLog.ToPrimaryKeyName(), "=" , cacheLog.ToPrimaryKey()) it := mdsrepository.client.Run(ctx, query) catchIterator := CatchIterator{ CatchName: cacheLog.ToCatchName(), Iterator: it, } for { catch, err := catchIterator.NextEvent() if err == iterator.Done { break } if err != nil { return err } key := gcpdatastore.NameKey(mdsrepository.entityKind, catch.ToKey(), nil ) if err := tx.Delete(key); err != nil { return err } } return nil }) if err != nil { mdsrepository.logger.Error( "Transaction Faile To Delete Entity" ) return err } return nil } é
ä¿¡åºç€ã®ã¹ãã¬ãŒãžã®éžå®æã«KEYã§ã¯ãªããã¯ãšãªã§ååãªããã©ãŒãã³ã¹ãåºãããå¿
èŠãªèŠä»¶ã§ãããSQL Serverã®ãã©ã€ããªãŒããŒãçšããŠãã£ãã·ã¥ã®æäœãããããã§ããçµææŽåæ§ã«ããããã©ãŒãã³ã¹ã§åªããŠããCloud Firestoreã¯è² è·æ€èšŒã®çµæ1åä»¶ãè¶
ããããŒã¿ã§ãé«éã«åŠçã§ããããšã確èªã§ããŸããã cloud.google.com ãªãããããã®æŽãæ¿ããªã©å€§éã«ããŒã¿ãåé€ããã«ã¯äžåããªã®ã§æ³šæãå¿
èŠã§ããå€éã§ããã°åé¡ãããŸããããé
ä¿¡äžãªã©ã«å®æœãããšã¯ãšãªã®ã¬ã€ãã³ã·ãæªåããŸããããã¥ã¡ã³ãã§ãè² è·æ€èšŒçã§ååãªããã©ãŒãã³ã¹ãã§ããæ€èšŒããããšãå§ããŠããŸãã cloud.google.com é
ä¿¡åºç€çšã®ããŒã¿é£æºã¯ãšãªã¯ãAnalyzerãšã¯ç°ãªã倿ŽããŒã¿ååŸã®éã«BigQueryã®ãªãœãŒã¹ãå€ãæ¶è²»ããããšããããŸãããAnalyzerã®ã€ã³ã¡ã¢ãªãªããŒã¿ã¹ãã¢ã§å®çŸã§ããã®ãããã©ãŒãã³ã¹ã®ç¢ºèªã¯å¿
èŠãšãªããŸãããä»åŸAnalyzerã«ãåæ§ã®æ¹ä¿®ãå
¥ããããšèããŠããŸãã æçµåæã¡ãã»ãŒãžãæžã蟌ã ã¡ãã»ãŒãžãããŒã«ãŒãžã®ãããªãã·ã¥ãå
šãŠæåããå Žåã¯æåŸã«ãããªãã·ã¥ãããã¡ãã»ãŒãžã®ã¡ãã»ãŒãžIDãšããŒã¿ã®ååŸéå§æå»ãBigQueryãžåæçã«æžã蟌ã¿ãŸããæçµåææå»ã倿ŽããŒã¿ååŸçšã«äœãããããŒãã«é¢æ°ãžæž¡ãã倿Žã®ãã£ãããŒã¿ãååŸããŠããŸãããŸãããã®ã¡ãã»ãŒãžIDãçšããŠãå®çžŸããŒãã«ããããŒã¿é£æºããããŒã¿ãçµã£ãŠããŸããåé ã§èª¬æããSQL Serverã®å€æŽè¿œè·¡ããŒãžã§ã³ãšåã圹å²ãæãããŠããŸããé害çºçæã®ãªã«ããªããã®æçµåæã¡ãã»ãŒãžã®æå»ãå·»ãæ»ãããšã§ãæçµåæããæå»ä»¥éã®ããŒã¿ãå飿ºå¯èœã§ãã ååã®å
šéããŒã¿é£æº æ°Trackerã§ååŸã§ããããŒã¿ã¯å€æŽããŒã¿ã®ã¿ã§ããååæã®ããŒã¿é£æºããªã«ããªæã«ã¯å
šéããŒã¿ã®é£æºãå¿
èŠã«ãªããŸãã以éãããŒããŒãããããšåŒã³ãŸããããŒããããã§ã¯DigdagãçšããŠãBigQueryã®ã¯ãšãªå®è¡çµæãCloud Storageãždumpãã䞊åã«Cloud Pub/Subãžãããªãã·ã¥ããŠããŸããCloud Pub/Subãžãããªãã·ã¥ãããããŒã¿ã¯åè¿°ããåãµãŒãã¹ããšã«äœãããããŒã¿é£æºAPIãçšããŠãã£ãã·ã¥ãããŸããã¹ããªãŒãã³ã°åŠçã§ããæ°Trackerã®å·®å飿ºããããåŠçã§ããDigdagãçšããå
šé飿ºã§äœ¿ãããŒã¿é£æºAPIã®å
±éåãå¯èœã§ãããããåŠçãšã¹ããªãŒãã³ã°åŠçã®äž¡æ¹ã§åãããžãã¯ã®ã¡ã³ããã³ã¹ãããå¿
èŠããªããããéçšè² è·ã軜æžã§ããŸãããŸããæ°TrackerãçšããŠæ°ããããŒã¿é£æºããå Žåã®å°å
¥å·¥æ°ãåæžã§ããŸãã ãªããCloud Pub/Subãžã®ãããªãã·ã¥ã§ååãªããã©ãŒãã³ã¹ãã§ãªãå Žåã¯ãCloud Pub/Subã¯ã©ã€ã¢ã³ãã®ãããã¡ãã»ãŒãžã³ã°ã®èšå®å€ã調æŽããå¿
èŠããããŸããä»åã¯max_messagesãããã©ã«ãã®100ãã1000ã«å€æŽããmax_latencyãããã©ã«ãã®10msãã1sã«å€æŽããŸãããããã«ãããçŽ1.7åä»¶ã®ããŒã¿ãCloud Pub/Subãžãããªãã·ã¥ããã®ã«10æéããã£ãŠãçµãããªãã£ãã®ããçŽ90åã»ã©ã§å®äºããããã«ãªããŸããã èšå®å€ã®è©³ãã説æã¯ã以äžã®å
¬åŒã®ããã¥ã¡ã³ããã確èªãã ããã cloud.google.com Digdagã«ã€ããŠã¯ä»¥äžã®èšäºãã確èªãã ããã techblog.zozo.com ç§»è¡ååŸã®è©äŸ¡ ãªãã¬ã€ã¹ã«ããã以äžã®èгç¹ã§ããŒã¿ã®è©äŸ¡ãããŸãããAnalyzerã«é£æºããŠããããŒãã«ã¯çŽ22ããŒãã«ã»ã©ããããã¹ã¿ããŒãã«çã®JOINçè€éãªå å·¥åŠçã宿œããŠããŸããç§»è¡æã®è©äŸ¡æ¹æ³ã«ã€ããŠã玹ä»ããŸãã ããŒã¿ã®æŽåæ§ãè©äŸ¡ ããŒã¿ã®æŽåæ§ãæ
ä¿ãããããæ§Trackerãšæ°Trackerã®ãã°ãæ¯èŒã§ããããã«ããŸãããæ§Trackerã®ãã°ã¯Windows Serverå
ããååŸããæ°Trackerã®æ¹ã¯Cloud Loggingã«ãã°ãæžãåºããŸãããäž¡æ¹ã®çµæãããã·ã¥å€ã§æ¯èŒããŠãããŒã¿ã®å€ãäžèŽããŠããã調ã¹ãŸãããèšèªä»æ§çã§ããããã£ãå Žåã¯åé¡ãªãã確èªããŠãããŸãããè©äŸ¡ã®éçšã§æ§TrackeråŽã®åé¡ãæ°TrackeråŽã®åé¡äž¡æ¹èŠã€ãããŸãããä¿®æ£ãå¿
èŠãªããŒãã«ã¯ã¯ãšãªãä¿®æ£ãã察å¿ããŸããã ããŒã¿ã®æ¬ æãè©äŸ¡ 次ã«ããŒã¿ã®æ¬ æã調ã¹ãŸãããããŒã¿æ¬ æã®èгç¹ã§ã¯æ§Trackerã§å€æŽã®ãã£ããã©ã€ããªãŒããŒãæ°Trackerã«å«ãŸããŠããã調ã¹ãŸãããé
å»¶ãèæ
®ãããŠã£ã³ããŠå¹
ã1æéçšåºŠã«èª¿æŽããŠèª¿ã¹ãŸããããã©ã€ããªãŒããŒã®æç¡ã§èª¿ã¹ãã®ã¯ãããŒã¿é£æºã®æ§è³ªäžãçãæéã«è€æ°åã®æŽæ°ãèµ°ã£ãå Žåã¯ãã©ã€ããªãŒããŒã«çŽã¥ãããŒã¿ãæ°æ§ã§äžèŽããªããªãããã§ãããã©ã€ããªãŒããŒã§ããã°ãæ§Trackerã«ããããŒã¯æ°Trackerã«ãªããšãããªããããããŒã¿ã®æ¬ æã調ã¹ãããšãã§ããŸããããŒã¿ã®æ¬ æããªãã確èªããåé¡ããªãããšã確èªããŸããã ããŒã¿ã®é
å»¶æéãè©äŸ¡ æ§Trackerããã³ãããŒã¯ã«ããŒã¿ã®é
å»¶æéã調ã¹ãŸãããæ§Trackerã®é
å»¶ã®èª¿æ»ã¯æ§Trackerãšãªã¢ã«ã¿ã€ã ããŒã¿åºç€ã®ãã°ãBigQueryäžã§çªåããŠèª¿ã¹ãŸããã æ°æ§Trackerã®ããŒã¿é
å»¶ã ãã§ã¯ãªãããªã¢ã«ã¿ã€ã ããŒã¿åºç€åŽã®ããŒã¿é
å»¶ã調ã¹ãŸããã調ã¹ããšããæ§Trackerã§ã¯æå€§ã§20åçšåºŠã®é
å»¶ãçºçããŠããããšã確èªã§ããŸãããäžæ¹ã§ãæ°Trackerã§ã¯BigQueryã®ã³ã³ãã¥ãŒãã£ã³ã°ãªãœãŒã¹ã§ããã¹ããããåå確ä¿ãããšãé
ããŠãæ°åç§ã»ã©ã§ã¯ãšãªã®å®äºã確èªã§ããŸãããããããæ°åããŒãã«ã®é£æºã§ååãªã¹ãããã確ä¿ããå Žåã¯600ã¹ãããã»ã©å¿
èŠãªããšãããããŸããã調æ»ãããšããäž»ã«å€æŽåã®ããŒã¿ååŸã§å€ãã®ã¹ããããæ¶è²»ããŠããããšãåãããŸããã éçšã§ã¯ã³ã¹ããæãããã100ã¹ãããã«åºå®ããŠããŸãã100ã¹ãããåºå®ã ãšããã©ãŒãã³ã¹ã¯é
ããªããŸãããæ§Trackerã®ããã©ãŒãã³ã¹ã¯è¶
ããããšãã§ããŸãããåŸè¿°ããŸãããAnalyzeråŽã«ä¿®æ£ãå ããããšã§100ã¹ããã以å
ã«ãå¿
èŠãªããã©ãŒãã³ã¹ãã ããäºå®ã§ãã ç£èŠèšèš æ°Trackerã®ç£èŠèšèšã«ã€ããŠç޹ä»ããŸãããªã¢ã«ã¿ã€ã ã«å·®åããŒã¿ãååŸããŠããã¢ããªã±ãŒã·ã§ã³ãããããã¥ãŒãµããã¡ãã»ãŒãžãããŒã«ãŒã®ããŒã¿ãåŠçããããŒã¿é£æºAPIããã³ã³ã·ã¥ãŒãããšåŒã³ãŸãã ãããã¥ãŒãµã®ç£èŠ ãããã¥ãŒãµã®ç£èŠã§ã¯Cloud MonitoringãæŽ»çšããŠãããŒã¿ã®é
å»¶ãšæ£åžžã«çšŒåããŠãããç£èŠããŠããŸãã倿ŽååŸã®ããŒã¿ãååŸããäžé£ã®åŠçãå®äºããéã«ãCloud LoggingãçšããŠç£èŠã§çšããã€ãã³ãæ
å ±ãæžãåºããŠããŸããäžå®æéãã£ãŠãã€ãã³ããæžã蟌ãŸããªãå Žåã¯ã¢ã©ãŒããé£ã°ãããã«ããŠããŸãã ã³ã³ã·ã¥ãŒãã®ç£èŠ ã³ã³ã·ã¥ãŒãã®ç£èŠã«ã¯Cloud Pub/Subå
ã®ACKãããŠããªãããŒã¿ãç£èŠããŠããŸããã³ã³ã·ã¥ãŒãã§é害ãçºçããåŠçãå®äºããªãã£ãå Žåã¯Exponential Backoffã§ãªãã©ã€ããããã«äœãããŠããŸãããªãã©ã€ããŠãæåããªãå Žåã¯Cloud Pub/Subå
ã§ACKãããŠããªãããŒã¿ãå¢ãç¶ããŸããCloud Pub/Subå
ã®ã¡ããªã¯ã¹ã§ãããoldest_unacked_message_ageããç£èŠããŠãã³ã³ã·ã¥ãŒãã®éå®³ãæ€ç¥ã§ããããã«ããŠããŸãã ãªãã¬ã€ã¹ã«ããæ¹åç¹ ãªãã¬ã€ã¹ããããšã«ããæ¹åç¹ãã玹ä»ããŸãã ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã å
šäœã®ãªãã¬ã€ã¹ã«å¿
èŠãªåºç€ãæ§ç¯ ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã å
šäœã®ãªãã¬ã€ã¹ãé²ããŠããäžã§ãå¿
èŠãªåºç€ãæ§ç¯ã§ããŸãããåãã€ã¯ããµãŒãã¹ã§å¿
èŠãªããŒã¿ããªã¢ã«ã¿ã€ã ã«é£æºãå¯èœãšãªããŸããããŸããååã®å
šéããŒã¿é£æºã®ä»çµã¿ãå
±éåã§ããŸãããæ°èŠã§ãµãŒãã¹ã远å ããå Žåã¯ãæ°ããã¯ãšãªããããã¯ç远å ããããšã§å®¹æã«ãªã¢ã«ã¿ã€ã ããŒã¿é£æºãå¯èœã§ãã éçšè² è·ã®è»œæž æ§Trackerãããªãã¬ã€ã¹ã§ããããšã§ãéçšè² è·ã®é«ãã£ãWindows Serverããè±åŽã§ããŸãããWindows Serverã«ãããã€ãããã¯ã©ã¹ã¿ã®éçšãSQL Serverèµ·å ã®é害ããªããªããŸããããªãã¬ã€ã¹ã«äŒŽããããã€ãèªååã§ãå®å¿ããŠå®æœã§ããããã«ãªããŸããããŸããå幎é倧ããªé害ãªãéçšãã§ããŠããŸãã ä»åŸã®èª²é¡ æåŸã«ä»åŸã®èª²é¡ã«ã€ããŠç޹ä»ããŸãããªãã¬ã€ã¹ã¯å®äºããŸãããããŸã ããã€ãæ¹åã®äœå°ããããŸãã ããã©ãŒãã³ã¹ã®æ¹å ä»åAnalyzerã«æãå ããªã圢ã§ä¿®æ£ããŸããããããã倿ŽåããŒã¿ãå®çžŸããŒãã«ããååŸããããšã§å€ãã®BigQueryã®ã³ã³ãã¥ãŒãã£ã³ã°ãªãœãŒã¹ïŒã¹ãããïŒãæ¶è²»ããŠããŸããAnalyzerã¯ãã©ã€ããªãŒããŒã§ã¯ãªããã®ãããŒã«ããŠããã£ãã·ã¥ãå€ãããã§ããååãªã¹ãããã確ä¿ã§ããã°ãé
ããŠãæ°åç§ä»¥å
ã§ã¯ãšãªã¯å®äºããŸããé
ä¿¡åºç€ã®ããã«Analyzerã倿Žåã®ããŒã¿ãSQL Serverã®ãã©ã€ããªãŒããŒããååŸããããæ¹ä¿®ããããšã§ãã³ã¹ããããã©ãŒãã³ã¹é¢ã§æ¹åãèŠèŸŒãŸããŸããä»åŸãã®åºç€ãçšããŠããã«ããŒã¿é£æºãããµãŒãã¹ãå¢ããŠããäºå®ãªã®ã§ã察å¿ããŠããããã§ãã ååå
šéããŒã¿é£æºåŠçã®å®å
šç§»è¡ åè¿°ããååå
šéããŒã¿é£æºããä»çµã¿ïŒããŒããããïŒã§ãããAnalyzerã®å
šéããŒã¿é£æºã§ã¯ãŸã å©çšã§ããŠããŸãããããŒããŒãããã®ä»çµã¿ãå©çšã§ããŠããã®ã¯é
ä¿¡åºç€ïŒPush/LINEïŒçšã®ããŒã¿é£æºã®ã¿ã§ããAnalyzerã§ãå
šéããŒã¿ãããŒãããããã®ä»çµã¿ããããã€ã³ã¡ã¢ãªäžã®ãã£ãã·ã¥ãå¹ãé£ãã æãªã©ã«çšããŠããŸãã ããããSQL Serverããå
šéããŒã¿ãååŸããã«ã¯æéãããããããŒãã«ã¯8ã9æéçšåºŠããããŸããä»å玹ä»ããããŒããŒããããžç§»è¡ã§ãããšãBigQueryããããŒã¿ãååŸã§ããã®ã§ãããã©ãŒãã³ã¹é¢ã§ã®æ¹åãæåŸ
ã§ããŸããDigdagã«Analyzerçšã®ã¯ãšãªã远å ããã°ãããããAnalyzerãããŒã¿é£æºAPIã«ã¯æãå ããã«ãªãã¬ã€ã¹ã§ããŸããããçãæéã§ãªã«ããªã§ããã°ãAnalyzerãéçšããŠããäžã§äžçªå€§ããªäžå®ãè§£æ¶ãããã®ã§ãä»åŸå¯Ÿå¿ããŠããããã§ãã ãŸãšã æ¬èšäºã§ã¯ãªã¢ã«ã¿ã€ã ããŒã±ãã£ã³ã°ã·ã¹ãã å
šäœã®ãªãã¬ã€ã¹ã«åããé
ä¿¡çšãªã¢ã«ã¿ã€ã ããŒã¿é£æºåºç€ããªãã¬ã€ã¹ããäºäŸãã玹ä»ããŸããã ãªãã¬ã€ã¹ã«äŒŽããéçšè² è·ã®é«ãWindows Serverããè±åŽã§ããŸãããä»åã®ãªãã¬ã€ã¹ã§å€æŽããŒã¿ã®ååŸå
ãSQL Serverããå
šç€Ÿå
±éã®åºç€ã§ãããªã¢ã«ã¿ã€ã ããŒã¿åºç€ã«å€æŽããŸãããããŒã¿ãœãŒã¹ã®å€æŽã«äŒŽãããããŒã¿ã®éè€ããããŒã¿ã®é åºãã倿ŽåããŒã¿ã®ååŸæ¹æ³ããèæ
®ããèšèšãå¿
èŠã§ãããããã«ãAnalyzerã®å¶çŽãèæ
®ããåãæ»ããè©äŸ¡ã§ããããå®å
šã«ãªãã¬ã€ã¹ãé²ããå¿
èŠããããŸããã æ§ç¯ããæ°Trackerã§é£æºã§ããããŒã¿ã¯å·®åããŒã¿ã®ã¿ãªã®ã§ãååã®å
šéããŒã¿ã飿ºããããã®ä»çµã¿ãå¿
èŠã§ãããéçšè² è·ãå°å
¥å·¥æ°ãèæ
®ããã¹ããªãŒãã³ã°åŠçãšãããåŠçã§åãããŒã¿é£æºçšã®APIãçšããŠããŸãã ä»åã®ãªãã¬ã€ã¹ã«äŒŽããæ§Trackerã®æ±ããŠãã課é¡ã解決ã§ããŸãããããŸã 課é¡ã¯æ®ã£ãŠããã®ã§ä»åŸå¯Ÿå¿ããŠããããã§ãã æåŸã« ãã®èšäºãèªãã§ããããèå³ãããããæ¹ã¯æ¯éæ¡çšããŒãžãããç³ã蟌ã¿ãã ããã https://hrmos.co/pages/zozo/jobs/0000196 hrmos.co