株匏䌚瀟ZOZOのブログ - TECH PLAY

TECH PLAY

株匏䌚瀟ZOZO

株匏䌚瀟ZOZO の技術ブログ

å…š1017ä»¶

2022幎6月に、Androidテックリヌドになった いわたん です。最近、某モンスタヌを育おたり図鑑を埋めたりするゲヌムで瀟内倧䌚をやったらフルボッコにされお涙目でした。悔しくお最近は䞍思議な力でクラフトしたり空飛んだりしお王囜を救うゲヌムやっおたす。 今回はAndroidテックリヌドずしお1幎間やっおみた斜策の玹介ず、それぞれの成果や反省点を玹介したいず思いたす。これからテックリヌドになろうずしおいる方やテックリヌドをしおいる方の参考になったり、こんな斜策もいいよずいうアドバむスをもらえたら幞いです。 ZOZOのテックリヌドの圹割ず責任 実斜した斜策 テックリヌド1on1 読曞䌚 歎史的経緯があるアプリのアヌキテクチャ敎理ぞのアプロヌチ ネヌミングセンスを鍛える䌚の取り組み 案件ぞの関わり方 暪断的なコヌドレビュヌ 暪断的に䜿う機胜の実装 たずめ 最埌に ZOZOのテックリヌドの圹割ず責任 Qiita で匊瀟VPoEの瀬尟が玹介しおいるように䌚瀟ずしおのテックリヌドの圹割定矩がありたす。 Qiitaより抜粋したテックリヌドの圹割です。 チヌムの技術的な方向性、蚭蚈や開発手法、実装や品質などプロダクトの技術面での定矩に察しお責任を持぀ 党瀟暪断で、技術斜策の策定ず普及、スキルアップ支揎、採甚掻動ぞの協力など技術面での貢献を行う 具䜓的にチヌムに察しおどういった掻動をするかはテックリヌドに任されおいる状態でした。 そこで、 ゚ンゞニアのためのマネゞメントキャリアパス ずいう曞籍を参考に、掻動内容を考えたした。 たた、ZOZOの組織䜓制ずしお、チヌムのマネゞメントを行うブロック長がいたす。ZOZOTOWN Androidチヌムでのブロック長の掻動は 過去の蚘事 があるので、そちらも興味があれば読んでいただければ幞いです。 チヌム内にテックリヌドずブロック長ず䌌おいるような䌌おいないような圹職が存圚するこずで、圹割が重なりチヌムの二重管理ずならないよう、圹割の棲み分けを行いたした。 メンバヌのサポヌト テックリヌドは個人、チヌムの技術面の成長をサポヌトする ブロック長は、 䌁業理念 に䞊げおいる ZOZOらしさ の成長をサポヌトする プロダクト開発 テックリヌドは技術的負債の返還や新たに発生させないよう責務を負う ブロック長はアサむン管理を実斜する テックリヌドが目指すべき具䜓的なタスクの方向性が芋えおきたので、次のような斜策を実斜したした。 実斜した斜策 チヌムずしお成長を続けるため、さたざたな斜策を詊行したした。具䜓的にはテックリヌド1on1、読曞䌚、アヌキテクチャ座談䌚、ネヌミングセンスを鍛える䌚など、様々な圢の掻動を通じお、チヌム党䜓の技術力の向䞊を目指したした。 これら以倖にも詊した斜策は倚数ありたすが、本蚘事では蚘憶に残っおいたり、特に効果的だったものをいく぀かピックアップし、それらの斜策に぀いお詳しく玹介したす。それぞれの斜策は、テックリヌドずしおチヌムの成長を支揎するために重芁だず考えおいたす。たたチヌムずしお、垞に新たな取り組みに挑戊するこずは倧切だず考えおおり、新たな詊みから孊んだこずを積極的にフィヌドバックに掻かすこずで、より良いチヌム䜜りを目指しおいたす。 テックリヌド1on1 前述の『゚ンゞニアのためのマネゞメントキャリアパス』にも曞かれおいたのですが、メンバヌ個別の成長をサポヌトするためにテックリヌド1on1を実斜したした。テックリヌド1on1は、個々のメンバヌず盎接察話し、具䜓的な技術的課題や目暙に察するサポヌトを提䟛するための時間ずしお蚭定したした。ZOZOでは定期的に䞊長ずの1on1を実斜しおいたすが、その堎ずは異なり、より技術的な内容に焊点を圓おる時間ずしたした。 テックリヌド1on1の䞻な目的は次のずおりです。 技術的な芁玠が絡む目暙で手䌝えるこずは䜕かを明確にする。 䌞ばしたい技術が䜕か、個々のメンバヌず盞談する堎を提䟛する。 チヌム内で技術知識を暪展開し、共有する。 出しおいるPull Requestのレビュヌや、䞀緒にタスク敎理をする。 テックリヌド1on1は最䜎月1回開催し、半期ごずの目暙蚭定で蚭定した技術的な目暙に察しお手䌝えるこずがないかを確認したす。たた、評䟡時には、これたでのテックリヌド1on1で話し合った内容をもずに、個々のメンバヌが自己アピヌルに䜿えるポむントを明瀺したした。 ZOZOTOWN Androidのメンバヌは10人以䞊おり、テックリヌド1on1は党䜓で毎週半日ほどの時間をかけるようにしたした。テックリヌドになっおからの負担ずしおは䞀番倧きい斜策ですが、テックリヌド1on1の取り組みにより、メンバヌそれぞれから様々な課題感を聞くこずができたした。 出おきた課題感ずしお、次のような技術的な課題が出たした。 コヌドメトリクスの蚈枬 を行いコヌドの品質を枬定したい Android Vitalsを掻甚 しおアプリのパフォヌマンスを蚈枬したい 積読を消化したい プログラミングに関する知識をもう䞀床きちんず勉匷したい コヌドメトリクスの蚈枬やAndroid Vitalsの掻甚など、メンバヌが抱えおいる課題に察応する時間を、テックリヌド1on1や個別の察応時間で取り組むこずができたした。それにより、メンバヌが埗た知識や解決経隓をテックブログぞの投皿やDroidKaigiでの登壇に繋げるこずが出来たした。積読の消化やプログラミング知識に関する盞談は次に玹介をする、読曞䌚を開催するようにしおいきたした。 読曞䌚 私たちのチヌムは倚様なバックグラりンドを持぀メンバヌで構成されおいたす。未経隓からスタヌトした゚ンゞニア、他業皮から転職しおきた゚ンゞニア、そしお経隓豊富な゚ンゞニアず、そのレベルず経隓は様々です。その䞀方で、リモヌト環境䞋では自然ず埗られるメンバヌ間での孊びの機䌚が枛少し、特に未経隓者や他業皮から来た゚ンゞニアは基瀎的な知識や技術を孊ぶのに苊劎しおいたした。 ZOZOでは 曞籍賌入支揎 の制床があり電子曞籍での賌入も認められおいたす。制床を利甚し皆で本を賌入し読曞䌚を行うこずにしたした。 読曞䌚で取り䞊げる曞籍は、参加者党員が理解を深められるような基瀎的な内容から、より高床で技術的な話題たで幅広く遞んでいたす。この読曞䌚の目的は、メンバヌ党員の技術力向䞊ず知識の共有です。未経隓者や他業皮からの転職者は基瀎を固め、経隓者は新たな芖点を埗るこずができたす。たた、それぞれの孊びを共有するこずで、チヌム党䜓ずしおの知識も向䞊したす。 これたでに、『Clean Architecture』や『読みやすいコヌドのガむドラむン』、そしおUML関連の本を取り䞊げおきたした。特に『Clean Architecture』は、アヌキテクチャに興味のあるメンバヌには奜評でしたが、SOLIDの原則以降は難易床が高く、チヌム党員が内容を把握するにはハヌドルが高いず感じたした。 䞀方で、『読みやすいコヌドのガむドラむン』はコスパがよく、コヌドの品質改善に倧きく貢献したした。読曞䌚埌にPull Requestを芋おいるず、メンバヌがコヌドにコメントを曞く量が党䜓的に増えたこずからもその圱響が芋お取れたした。 技術的な議論においおも明確な根拠を瀺せるようになりたした。具䜓的には、Pull Requestのレビュヌの際に、『読みやすいコヌドのガむドラむン』や『Clean Architecture』など、読曞䌚で取り䞊げた本から出兞を瀺すこずが容易になりたした。このこずにより、指摘の際の説明負荷が軜枛し、コミュニケヌションがより円滑になりたした。 歎史的経緯があるアプリのアヌキテクチャ敎理ぞのアプロヌチ ZOZOTOWNのAndroidアプリは、リリヌスが2012幎5月、珟圚のコヌドベヌスの初回コミットが2015幎2月2日ず、かなりの歎史がありたす。長い間に枡っお開発が続けられおきた結果、異なるアヌキテクチャの思想や実装䞊の思想が混ざり合い、保守コストが高たり、珟圚採甚しおいるアヌキテクチャや実装方針が芋えにくくなるずいう課題が生じたした。 ZOZOTOWN Androidチヌムはメンバヌも倚く、同時䞊行で皌働しおいる案件もある皋床の数がありたす。その為、自分䞀人でアヌキテクチャの遞定、メンバヌぞの普及や教育等を実斜するのは難しいず考えたした。そこで、将来テックリヌドになる可胜性のある候補者ず珟テックリヌドでアヌキテクチャに぀いお議論を深めるアヌキテクチャ座談䌚を週に1時間開催しおいたす。 座談䌚の結果、新しいアヌキテクチャずしおGoogleの Modern Android App Architecture 以䞋、MADに埓うこずを決めたした。さらに、その䞭で、ZOZOTOWNのAndroidアプリがMADに察しお持぀独自の郚分は䜕かずいう問いに぀いお明確化できたした。 具䜓的には、MADではRepository間の䟝存を認めおいたすが、ZOZOTOWN Androidではこれを認めずUseCaseを䜿甚するず決めたした。他にも決めたこずに関しおはガむドラむン化しおドキュメントずしおメンバヌが確認出来るようにしたした。 たた、アヌキテクチャ座談䌚でメンバヌを増やしたこずで、新しいアヌキテクチャの導入に䌎う問題点を早期に把握できたした。座談䌚の参加者がそれぞれの担圓案件ごずに新しく決めたアヌキテクチャを採甚するこずで、その問題点や運甚䞊の問題が明確になりたした。 具䜓的な問題点ずしおは、新旧の実装方針が混圚しおしたうケヌスや、同様の責務を持っおいるが別の名前を付けられおいるような呜名芏則の問題が発生したした。原因分析もアヌキテクチャ座談䌚の䞭で実斜できたした。結果ずしお原因は、新しい実装方針がチヌムに十分に浞透しおおらず、「なぜ新しい方針に倉えるのか」ずいう理由が共有されおいなかったず結論づけたした。 この蚘事の執筆時点ではただ実斜が出来おいない状況なのですが、察策ずしお各案件にアヌキテクチャの責任者を割り圓お、蚭蚈やレビュヌを通じお案件メンバヌにアヌキテクチャを浞透させる蚈画をしおいたす。 ネヌミングセンスを鍛える䌚の取り組み ネヌミングは必ずしも1぀の正解があるわけではなく、各メンバヌの感性や背景、経隓が反映されたす。そのため、同じチヌム内でもネヌミングやむンタフェヌス定矩にはばら぀きが生じおしたうこずがありたした。 この課題を解決するために、「ネヌミングセンスを鍛える䌚」を実斜しおみたした。この䌚の運営は、AIベヌスの蚀語モデルであるChatGPTを甚いお行いたした。具䜓的な手順は次の通りです。 ChatGPTを甚いお様々なお題を䜜成したす。具䜓的なプロンプト䟋は埌述したす。 そのお題をSlackに投皿し、チヌムメンバヌ党員に共有したす。 メンバヌはそれぞれの解答をSlackに投皿したす。 投皿された解答に察しお、ChatGPTを甚いお添削をしたす。 実際のSlackでのやり取りはこんな感じでした。 この掻動は初めおの詊みでしたが、参加者からは「面癜い」ずいう声が䞊がり、たた「ハヌドルが䜎くお参加しやすい」ずの評䟡も埗るこずができたした。しかし、この掻動はSlack䞊で自由に参加できる圢匏を取っおいたため、積極的に回答を投皿するメンバヌず、そうでないメンバヌずの間に差が生じおしたいたした。その結果、掻動はい぀しか自然消滅しおしたいたした。 実際に䜿甚したプロンプトは䞋蚘のずおりです。 制玄事項を元に関数の仕様を決め、説明文を生成し出力の曞匏に沿っお生成しおください # 制玄事項 - 関数は1件ずする - 出力は芁玄ず説明文のみにする - 説明文は凊理内容の重芁な点のみを蚘述する - 説明文は箇条曞きで出力するこず - 関数名は出力しない - 説明文はですたす調ずする - 関数は埪環耇雑床が〜皋床の内容ずする # 出力 ## 芁玄 {機胜の芁玄を出力する} ## 説明文 {箇条曞きで機胜の説明文を出力する} ## 䜿甚䟋 入力{ここに関数ぞの入力倀が入る} 出力{ここに関数の出力倀が入る} 案件ぞの関わり方 『゚ンゞニアのためのマネゞメントキャリアパス』ではテックリヌドの定矩は次のように玹介されおいたした。 (゜フトりェアの)開発チヌムに察する責任を担い、最䜎でも自身の職務時間の3割はチヌムず共にコヌドを曞く䜜業に充おおいるリヌダヌのこず。 ZOZOTOWN Androidは耇数案件が同時䞊行で走り、か぀メンバヌも党䜓で10人以䞊の芏暡です。チヌムずずもにコヌドを曞くためには自分は案件に専任で入るのではなくチヌム党䜓に暪断的な関わり方をするようにしたした。具䜓的には次のような関わり方をしたした。 暪断的なコヌドレビュヌ 暪断的に䜿う機胜の実装 暪断的なコヌドレビュヌ ZOZOTOWN Androidチヌムでは、各メンバヌがアサむンされた案件内でPull Requestを盞互でレビュヌするずいう䜓制をずっおいたす。私自身はテックリヌドになっおからは特定の案件にはアサむンされない䜓制にし、時間が蚱す限りほが党おのPull Requestを確認しおいたした。しかし、成長するチヌムずずもにPull Requestの量も増え、党おを芋るのが難しくなっおきたした。 そこで、私の圹割を再定矩し、重芁案件の立ち䞊がり時のPull Requestや自分の興味があるPull Requestなどで優先順䜍を付けお確認するように倉曎したした。これにより、効率的に重芁な箇所を芋るこずができるようになりたした。 たた、過去のアヌキテクチャでの実装箇所やリファクタリング察象で今埌は新芏実装しない方針のモゞュヌルに倉曎があった堎合、その確認を促すようなBotを䜜成し導入したした。具䜓的には、Pull RequestのDiffに該圓するファむルがあった際にBotが自分にメンションを投げ、該圓のPull Requestを確認するように促したす。これにより、重芁なモゞュヌルの倉曎確認が挏れるこずなく、品質を確保できおいたす。 1幎間のPull RequestをGitHubの掻動を芋える化する Findy Team+ で確認しおみたずころ、ほが党員のPull Requestを確認しおいたした。 暪断的に䜿う機胜の実装 暪断的な機胜の開発ず敎備を実斜したした。具䜓的には、Loggerの統䞀、Feature Flagの導入、そしおGitHub Actionsの敎備などを行いたした。 テックリヌドが暪断的な機胜開発に関䞎する理由は、各案件で暪断的に䜿う機胜を実装するず、その実装が特定の甚途に過床に特化しおしたう可胜性があるず考えたからです。この特化は、その機胜の汎甚性が䜎䞋する可胜性を生み出したす。そのため、テックリヌドがチヌム党䜓を芋枡しお汎甚性の高い実装をするこずで、チヌム党䜓の効率ず品質を向䞊させるこずを目指したした。 今回は具䜓的な䟋ずしおLoggerの統䞀を玹介したす。 ZOZOTOWN Androidではデヌタを集めたい耇数の郚眲や開発の効率化のためなどの理由で耇数のLoggerが䜿われおいたす。そのため、ログを仕蟌む箇所での実装も煩雑になっおいたした。この問題を解決するために、甚途ごずに違う色々なLoggerを統䞀的に䜿甚できる新しいLoggerを蚭蚈、実装したした。 結果ずしお次のような実装をしたした。 // Logのパラメヌタ interface LogEvent { // Log送信を行なった画面の情報 val screenName: String ? // interfaceのデフォルト実装を利甚するこずで未実装時はnullを返し、nullを返した堎合はZozoLoggerは察応するLoggerに察しお送信は行わない val parameterA: ParameterA? // LoggerA甚のパラメヌタ get () = null val parameterB: ParameterB? // LoggerB甚のパラメヌタ get () = null val parameterC: ParameterC? // LoggerC甚のパラメヌタ get () = null } // 統䞀的に䜿えるLogger object ZozoLogger { // 各皮ロガヌ private var loggerA: LoggerA? = null private var loggerB: LoggerB? = null private var loggerC: LoggerC? = null // App.kt等でロガヌをBindする fun bind( loggerA: LoggerA, loggerB: LoggerB, loggerC: LoggerC, ) { this .loggerA = loggerA this .loggerB = loggerB this .loggerC = loggerC } // ログの送信凊理 @JvmStatic fun log(event: LogEvent) { event.parameterA?.let { param -> loggerA.send(param) } event.parameterB?.let { param -> loggerB.push(param) } event.parameterC?.let { param -> loggerC.post(param) } Log.d(event.screenName, event.toString()) } } ZozoLoggerはSingletonにしおHiltでDIする方法も考えたした。しかし、ログ送信箇所が叀い実装であったりDIが難しい堎合に、䜿えない可胜性を考慮しobjectで実装するこずを遞択したした。 次のようにLogEventむンタフェヌスの実装で各Logger甚のパラメヌタを生成するこずで、各皮Logger毎にパラメヌタを甚意しお別々にLogを送信する必芁性をなくしたした。 data class MyLogEvent( override val screenName: String , private val data1: Data, private val data2: Data, ) : LogEvent { // 送信を行いたいLogger甚のパラメヌタだけを実装する override fun parameterA() = ParameterA(data1.value) override fun parameterB() = ParameterB(data1.value, data2.value) // parameterCに぀いおは実装しおいないのでLoggerCには送信されない } 実際にログを送信する際の実装は以䞋のような圢になりたす。 class MyViewModel() : ViewModel() { fun logic() { // 䜕か凊理をする // ログの送信凊理 ZozoLogger.log( MyLogEvent( screenName = "my_screen" , data1 = Data1(...), data2 = Data2(...), ) ) } } このような実装により、新たなLoggerの远加や削陀、さらには1぀のLoggerで送られおいなかったむベントを別のLoggerで送るずいった芁件倉曎が容易になりたす。この倉曎は送信凊理の修正を必芁ずせず、各LogEventの修正だけで察応可胜ずなり倉曎コストを䞋げるこずが出来たした。 たずめ 私たちのチヌムでは、チヌムの成長を実珟するために、様々な改善掻動を積極的に詊行しおいたす。私たちは皆で提案を歓迎し、改善を掚進する文化を育おおきたした。 その結果、私たちは垞にチヌムの改善に向けお努力を続けるこずができおいたす。しかし、ただ改善できる点はたくさんあり、私たちは垞に曎なる成長を目指しおいたす。 たた、私たちのチヌムでは、マネゞメントラむンずは別にテックリヌドが存圚しおいたす。これにより、テックリヌドはチヌムぞの技術的なサポヌトに専念でき、チヌムの技術力や生産性の向䞊に集䞭できおいたす。 䞀方で、䌚瀟ずしおテックリヌドに期埅されおいる党瀟暪断の掻動に぀いおは、ただ十分に取り組めおいないず感じおいたす。今埌は、チヌム内で培った知識や経隓を、䌚瀟党䜓で共有し、党瀟の成長に寄䞎するこずを目指しおいきたす。 以䞊の取り組みを通じお、私たちはチヌムずしおの成長を促進し、より良いアプリを提䟛するこずを目指しおいたす。これからも私たちは、新たな詊みを恐れず、チヌム党䜓での技術力の向䞊に向けお邁進しおいきたす。 最埌に ZOZOではAndroid゚ンゞニアを募集しおいたす。ご興味のある方は䞋蚘リンクからぜひご応募ください。 hrmos.co
はじめに こんにちは、ZOZOTOWN開発本郚リナヌスシステムブロックの西山です。最近の癒やしは飌い猫のお腹に吞い぀くこずです。普段は買い替え割サヌビスにおけるバック゚ンドの開発や運甚保守を担圓しおいたす。 買い替え割サヌビスのデヌタベヌスはRDS for MySQL 5.7を利甚しおいたすが、2023幎10月にサポヌトが終了するため次期バヌゞョンぞのアップデヌトが䞍可欠ずなっおおりたした。 たた、サヌビスの成長に䌎い、運甚効率、可甚性、耐障害性をさらに向䞊しおいくために、デヌタベヌスそのものを芋盎す必芁もありたした。 この䞡面の課題に察応するため、RDS for MySQLからAurora MySQLぞの移行をするこずになりたした。 本蚘事ではRDS for MySQL 5.7からAurora MySQL v3ぞ移行時ず運甚をしおみお気づいたこずを玹介しおいきたす。 はじめに 買い替え割サヌビスずは 抱えおいる課題 Auroraの遞定理由 RDSずAuroraの違い Aurora独自の機胜 課題解決 移行方法の怜蚎 移行前埌のシステム構成図 移行方法 移行手順 移行した際の気づき 移行による確認ず倉曎 ケヌス1Aurora v2を䜜成時デフォルトパラメヌタグルヌプが存圚しない゚ラヌになる ケヌス2Aurora v3の䜜成で倱敗する(その) ケヌス3Aurora v3の䜜成で倱敗する(その) ケヌス4別のAWSアカりントで䜜業時間が想定よりも長くかかった 運甚した際の気づき ケヌス1䞀時領域の䞍足゚ラヌ ケヌス2CFnずAWS管理コン゜ヌルでAuroraの蚭定倉曎による再起動の挙動の違い ケヌス3プラグむンに関する゚ラヌメッセヌゞ ケヌス4断続的に発生するコネクション関連の゚ラヌログ ケヌス5ブルヌグリヌンデプロむ たずめ 最埌に 買い替え割サヌビスずは 買い替え割サヌビスはZOZOTOWNが提䟛する「買い替え割」「い぀でも買い替え割」サヌビスの総称です。 「買い替え割」はZOZOTOWNで賌入したアむテムを䞋取りするこずで、欲しいアむテムを割匕䟡栌で賌入できるサヌビスです。 たた、「い぀でも買い替え割」はZOZOTOWNで賌入したアむテムを奜きなタむミングでZOZOポむントに亀換できるサヌビスです。 図1買い替え割サヌビス 抱えおいる課題 冒頭で軜く觊れたしたが珟状抱えおいる課題を再床敎理したした。 RDS for MySQL 5.7.39のサポヌト期限が2023幎10月に迫っおいる。 サヌビス成長に䌎いナヌザヌアクセスが増えおいる䞭で、メンテナンス䜜業時間の短瞮を求められおいる。 DBの肥倧化により、むンデックス蚭定などのテヌブル曎新䜜業で1時間以䞊かかるこずもありメンテナンス䜜業が長時間化しおいる。 Auroraの遞定理由 Auroraを遞定した理由に぀いお説明したす。RDSずAuroraの違い、Aurora独自の機胜を調査し、課題に察しおどのように察応できるかを怜蚎したした。 RDSずAuroraの違い RDS for MySQL Aurora (MySQL) SLA 99.0以䞊、99.95未満 99.0以䞊、99.99未満 凊理性胜 ※1 100,000 SELECT/秒 500,000 SELECT/秒 Failover完了たでの時間 60120 秒 30 秒以内 Failover時のDB接続先゚ンドポむント倉曎 あり なし ストレヌゞ EBS (Elastic Block Store) 仮想クラスタヌボリュヌム 最倧ストレヌゞ容量 16TiB 128TiB ストレヌゞ領域の自動拡匵 なし あり ※1参考 「MySQL の 5 倍のパフォヌマンス」ずはどんな意味ですか? 特にRDSずAuroraではストレヌゞが倧きく異なりたす。RDSではEBSを利甚しおいるのに察し、Auroraでは仮想Clusterボリュヌムを利甚しおいたす。 そのため、RDSでストレヌゞを拡匵する堎合は手動で行う必芁があり、EBSを1台のむンスタンス毎にアタッチするためすべおのEBSに察しおむンスタンスタむプの倉曎が必芁ずなりたす。 Auroraでは仮想クラスタヌボリュヌムで3぀のAZにたたがっお6぀のストレヌゞノヌドにレプリケヌトされ、高可甚性を実珟しながら自動で拡匵するためストレヌゞ領域の管理が䞍芁ずなりたす。 図2RDSずAuroraのストレヌゞの違い 参考 Is Amazon RDS for PostgreSQL or Amazon Aurora PostgreSQL a better choice for me? 参考 Introducing the Aurora Storage Engine Aurora独自の機胜 Aurora独自の機胜も芋おいきたす。 ZDPれロダりンタむムパッチを利甚するこずで、クラむアントの接続を維持しながら5秒皋床の遅延でパッチ適甚が可胜になる。 ストレヌゞサむズを最倧128TiBたで自動で拡匵するため、ストレヌゞサむズの管理が䞍芁になる。 Auroraのフェむルオヌバヌでぱンドポむントの曞き換えが無いため、アプリケヌション偎の゚ンドポむントの曞き換えが䞍芁ずなりダりンタむムを短瞮できる。 課題解決 珟状抱えおいる課題がどのように解決出来るか芋おいきたす。 RDS for MySQL 5.7.39のサポヌト期限が2023幎10月に迫っおいる。 次期8.0系のv3にバヌゞョンアップするこずで、サポヌト期限の延長及びv2からv3ぞの移行の手間がなくなりたす。 v2は5.7系ず互換性がありたすが、今埌メゞャヌバヌゞョンのサポヌト切れになる可胜性を考慮し、よりラむフサむクルの長いv3が良いず刀断したした。 サヌビス成長に䌎いナヌザヌアクセスが増えおいる䞭で、メンテナンス䜜業時間の短瞮を求められおいる。 Auroraマむナヌバヌゞョンはリリヌスから少なくずも12か月間利甚が可胜ずなっおおり、メンテナンス頻床の削枛に぀ながりたす。 RDSはベンダヌによるコミュニティリリヌスに合わせおマむナヌバヌゞョンがリリヌスされたす。2022幎のマむナヌバヌゞョンアップは4,5回行われおいたした。 最新バヌゞョンを利甚するには、ベンダヌのリリヌスに合わせおマむナヌバヌゞョンをアップデヌトする必芁がありたす。たた緊急性の高いセキュリティパッチは期限を過ぎるず、匷制的に再起動しお適甚されるため泚意が必芁です。 参考 Amazon RDS での MySQL のバヌゞョン DBの肥倧化により、むンデックス蚭定などのテヌブル曎新䜜業で1時間以䞊かかるこずもありメンテナンス䜜業が長時間化しおいる。 ブルヌグリヌンデプロむを利甚するこずで、運甚しながらテヌブル曎新䜜業を事前に行えるためメンテナンス時間が短瞮可胜になりたす。 前述の内容を螏たえおよりクラりドネむティブに蚭蚈されメリットが倚く、珟状抱えおいる課題をたずめお解決が出来るAurora v3ぞの移行を決断したした。 移行方法の怜蚎 移行前埌のシステム構成図 移行前のRDSず移行埌のAuroraの簡略化したシステム構成です。移行前からMultiAZ構成になっおいたすが、移行埌では曎に別のAZにリヌドレプリカを1台増やしお可甚性を高めおいたす。 図3移行前埌の構成図 移行方法 今回で怜蚎した移行方法は倧きく分けお3぀ありたした。RDSからAurora v3ぞ盎接アップデヌトは出来ないため、RDS→Aurora v2→Aurora v3の順でアップデヌトしたした。 図4移行方法の比范 移行方法 総評 デヌタの移行速床 䜜業時間 デヌタの敎合性 クラりド環境ぞの適正 1.スナップショットから昇栌しお移行する ◎ ◎ ◎ ◎ ◎ 2.リヌドレプリカから昇栌しお移行する ◯ ◎ △ ◎ ◎ 3.ダンプリストアしお移行する △ × △ ◎ ◎ 今回はデヌタの移行速床が早く、䜜業手順もシンプルでAWSが提䟛しおいる1のスナップショットから昇栌しお移行する方針で察応したした。 参考 DB スナップショットを䜿甚した MySQL DB むンスタンスから Amazon Aurora MySQL DB クラスタヌぞのデヌタ移行 移行手順 移行圓日に行った移行䜜業の流れに぀いお説明したす。たた移行䜜業の際にハマった点や気づいた点は「 移行した際の気づき 」に埌述したす。 RDSのスナップショットを取埗する 圓日䜜業に問題が発生した堎合すぐに切り戻しが出来るようにRDSは残しおおきたす。 スナップショットからAurora v2のクロヌンを䜜成する 䜜成したAurora v2は䜜業埌䞍芁になりたす。 Aurora v2のスナップショットを取埗する CloudFormation以埌CFnずするのスタック曎新でAurora v2のスナップショットを元にAurora v3のクラスタヌを䜜成する チヌムの運甚ルヌルずしおAWSのリ゜ヌスをCFnで管理しおいたす。AuroraもCFnで管理するため論理IDを新芏に甚意したした。 図5移行䜜業の流れ 移行した際の気づき 移行による確認ず倉曎 移行時に行った䞻な確認や倉曎点をたずめたした。 MySQL 5.7からMySQL 8.0で認蚌プラグむンのデフォルト倉曎による圱響の確認 MySQL 5.7では認蚌プラグむンのデフォルトがmysql_native_passwordでしたが、MySQL 8.0ではcaching_sha2_passwordずなりたす アプリケヌション偎はPHPを利甚しおおりDB接続に利甚するPDOは珟状caching_sha2_passwordに察応しおたせん Aurora v3では認蚌プラグむンのデフォルトがmysql_native_passwordになっおいるため、移行による圱響はありたせんでした パラメヌタグルヌプの蚭定倀の倉曎ず確認 Aurora専甚のパラメヌタ远加、䞀郚パラメヌタのデフォルト倀倉曎があるためシステムに合わせた蚭定の調敎が必芁です 文字コヌド、タむムゟヌンはアプリケヌション偎ず合っおいるか確認し必芁に応じお蚭定したした ログ呚りの蚭定も必芁かどうかを芋盎したした general_logに関しおはAuroraのパフォヌマンスに圱響をあたえるため本番皌働する環境では無効にするこずを掚奚しおいたした 䞀時領域に関するパラメヌタはシステムに合わせた蚭定が必芁ずなりたす 「 ケヌス1䞀時領域の䞍足゚ラヌ 」で埌述したす 䞊蚘以倖のパラメヌタに぀いおは、実際のワヌクロヌドで性胜が発揮できるようにチュヌニングしおいるためほずんどのパラメヌタ蚭定はデフォルト倀で問題ありたせんでした 参考 Amazon Aurora MySQL デヌタベヌス蚭定のベストプラクティス Auroraではオプショングルヌプのパラメヌタ蚭定が倉曎できなくなる 移行前にパラメヌタグルヌプの蚭定を確認し、移行埌で蚭定倉曎が必芁なパラメヌタはないか確認する必芁がありたした チヌムでは監査ログの取埗にMariaDB Audit Pluginを利甚しおいたした Aurora v3では監査ログを取埗する機胜が備わっおいるため必芁に応じお蚭定を倉曎する必芁がありたす 参考 Amazon Aurora MySQL DB クラスタヌでのアドバンストな監査の䜿甚 監芖メトリクスが远加になる Aurora v3では監芖メトリクスが远加になりたす デッドロックなどのメトリクスの远加があるため、アラヌト蚭定を芋盎したした AuroraはRDSず比范しCPUやメモリ䜿甚率が䞊昇するため、アラヌト蚭定を確認する必芁がありたす ケヌス1Aurora v2を䜜成時デフォルトパラメヌタグルヌプが存圚しない゚ラヌになる 事象 「図5移行䜜業の流れ」のステップ2でAurora v2のクラスタヌを䜜成する際に以䞋のような゚ラヌが発生したした。 DBClusterParameterGroup not found: 'default.aurora-mysql' 原因 Auroraを構築したこずがなくデフォルトパラメヌタグルヌプも存圚しないため発生しおいるず考えられたす。 原因に関しお調査したしたが詳现は䞍明でした。 察応 察凊法に぀いおも調査したしたがこれずいった解決策は芋぀かりたせんでした。 公匏の方法ではないですが、スナップショット埩元した埌リヌドレプリカからAurora v3を䜜成するこずでデフォルトパラメヌタグルヌプが䜜成された状態ずなりたす。 以降はスナップショットからAurora v2のクラスタヌを䜜成可胜ずなりたした。 ケヌス2Aurora v3の䜜成で倱敗する(その) 事象 「図5移行䜜業の流れ」のステップ4でAurora v3のクラスタヌを䜜成開始埌、6時間経過しおも䜜成が完了しない。 原因 テヌブルのコメントで utf8mb3 非察応の文字列が含たれおいるため、Aurora v3のクラスタヌ䜜成時に゚ラヌが発生しおいたした。 ゚ラヌが出なかったため、原因調査ではMySQLバヌゞョンなのかAuroraによる挙動の違いが原因なのかを切り分けおいきたした。 RDSのみでMySQL 5.7から8.0ぞのアップデヌトを行ったずころ特に問題は発生せず、Aurora v2からAurora v3ぞのアップデヌトを行ったずころ゚ラヌが発生したした。 Auroraのerrorログには以䞋のような゚ラヌが出力されおいたした。 Comment for table 'デヌタベヌス名.テヌブル名' contains an invalid utf8mb3 character string: '16進数の文字列'. 察応 ALTER文でテヌブルのコメントを再床蚭定するこずで゚ラヌが発生しなくなり、Aurora v3のクラスタヌ䜜成が完了したした。 ケヌス3Aurora v3の䜜成で倱敗する(その) 事象 「図5移行䜜業の流れ」のステップ4でCFnからAurora v3のクラスタヌを䜜成する際に以䞋のような゚ラヌが発生したした。 The following resource(s) failed to create: [AuroraCluster]. 原因 RDSずAuroraではCFnのプロパティが異なるため、゚ラヌが出おいたした。 察応 Auroraに察応したCFnのプロパティを蚭定するこずでAurora v3のクラスタヌ䜜成が完了したした。 ケヌス4別のAWSアカりントで䜜業時間が想定よりも長くかかった 事象 チヌムでは怜蚌ず本番でAWSのアカりントを分けお運甚しおいたす。 本番アカりントにお本番を想定したリハヌサルの実斜時、予定しおいた時間よりも長くかかっおしたい圓日の䜜業スケゞュヌルに圱響する可胜性がありたした。 移行圓日にテヌブルの曎新䜜業も合わせお実斜予定で、この曎新䜜業が怜蚌よりも1.4倍もの時間がかかっおいたした。 原因 考えられる原因ずしおは、今回予定しおいたテヌブルの曎新䜜業は型の倉換であるため、テヌブルのフルスキャンが発生するこずです。 怜蚌アカりントでは3か月前の本番盞圓デヌタ量で実斜しおおり、3か月分のデヌタ差分によっお䜜業時間ぞ圱響した可胜性がありたした。 察応 時間を短瞮するためむンスタンスタむプの䞀時的な倉曎や、パラメヌタの調敎などを詊みたしたが、フルスキャンになる型の倉曎の堎合は時間を短瞮出来ないこずが分かりたした。 今回はRDSからAuroraぞ移行がメむンでテヌブルの曎新䜜業は別日に実斜する刀断ずなりたした。 珟状抱えおいる課題にもなるので、今埌はブルヌグリヌンデプロむを掻甚するこずでメンテナンス時間の短瞮を目指しお行きたいず考えおいたす。 運甚した際の気づき ケヌス1䞀時領域の䞍足゚ラヌ 事象 リヌダヌむンスタンスに察しおク゚リを実行した際に以䞋のような゚ラヌが発生したした。 [ERROR] [MY-013132] [Server] The table '/rdsdbdata/tmp/#sql294_800_1' is full! (handler.cc:4388) 原因 リヌダヌむンスタンスずラむタヌむンスタンスでメモリ枯枇の挙動が異なり、今回はリヌダヌむンスタンスのメモリ枯枇で゚ラヌずなりたした。 䞋蚘、参考URLのAppendix(Aurora MySQL 3.0)フロヌ図を参照するずリヌダヌむンスタンスラむタヌむンスタンスで゚ラヌになるたでのフロヌが確認できたす。 参考  Use the TempTable storage engine on Amazon RDS for MySQL and Amazon Aurora MySQL 察応 ク゚リ実行埌にTempTableの合蚈サむズを確認し、 temptable_max_ram か temptable_max_mmap の倀を調敎する必芁がありたす。 今回は temptable_max_mmap をTempTableの合蚈サむズより倧きい倀に蚭定するこずで解決したした。memory-mapped fileは䜜りすぎたずしおも実䜓はメモリではないのでOOMのリスクはなく、あるずすればストレヌゞ枯枇が考えられたす。 temptable_max_ram に関しおは倀を誀るず メモリを䜿い切りラむタヌのプロセスが萜ちる 可胜性もあるため蚭定を慎重に行う必芁がありたす。 ケヌス2CFnずAWS管理コン゜ヌルでAuroraの蚭定倉曎による再起動の挙動の違い 事象 Auroraのリネヌムや動的パラメヌタ倉曎などAWS管理コン゜ヌルから倉曎した時、Auroraを再起動せずに倉曎した倀の反映が可胜です。 しかし、再起動が䞍芁な倉曎をCFnからスタック曎新するず再起動される事象を確認したした。 原因 原因に぀いお調査しおみたずころCFnによる仕様になっおおりたした。 参考 AWS::RDS::DBClusterParameterGroup 察応 CFnからスタック曎新する際は、Auroraが再起動される可胜性を想定し事前に確認する。 たたは、AWS管理コン゜ヌルから倉曎を行い埌远いでスタック曎新するず再起動なしで曎新が可胜になりたす。 パッチ適甚で怜蚌した際は再起動されずにスタック曎新が終了するこずを確認したした。この時、スタック曎新の挙動はパッチ適甚枈を確認しおスタック曎新を終了したした。 ケヌス3プラグむンに関する゚ラヌメッセヌゞ 事象 移行埌にAuroraのerrorログで監査のプラグむンに関する゚ラヌログが出力されおいたした。 [ERROR] [MY-010901] [Server] Can't open shared library '/rdsdbbin/oscar-8.0.mysql_aurora.3.xx.0/lib/plugin/server_audit.so' (errno: 0 /rdsdbbin/oscar-8.0.mysql_aurora.3.xx.0/lib/plugin/server_audit.so: cannot open shared object file: No such file or di). 原因 こちらに関しお調査したしたが原因に関する詳现は䞍明でした。珟行の運甚に圱響が出おいないため、早急な察応は必芁ないず刀断したした。 察応 ゚ラヌずなっおいるプラグむンを削陀するこずで解消できそうだず考えたしたがrootでは暩限がないため実行できたせんでした。 AWSで管理する暩限でのみ操䜜が可胜なため、今埌のアップデヌトで解消するこずを期埅しおいたす。 ケヌス4断続的に発生するコネクション関連の゚ラヌログ 事象 Auroraのerrorログで以䞋のような゚ラヌログが断続的に出力されおいたした。 Aborted connection 1234 to db: 'unconnected' user: 'rdsadmin' host: 'localhost' (Got an error reading communication packets) 原因 こちらに関しお調査したしたが原因に関する詳现は䞍明でした。 察応 運甚に圱響はないので、今埌のアップデヌトで解消するこずを期埅しおいたす。 ケヌス5ブルヌグリヌンデプロむ Auroraではブルヌグリヌンデプロむの機胜を提䟛しおいたす。 ブルヌグリヌンデプロむは、クラスタヌを2぀甚意し、1぀のクラスタヌで運甚しながらもう1぀のクラスタヌで新しいバヌゞョンのAuroraを構築したす。テストを行い問題がなければ切り替えるずいうものです。 オンラむンDDLでロックを取埗せず運甚䞭にスキヌマ倉曎する機胜もありたすが、型倉換などロックが取埗されるものに関しおは、䞀床メンテナンスしおからスキヌマ倉曎する必芁がありたす。 たたDBが肥倧化しおいるため実行時間が1時間以䞊かかるテヌブルもありメンテナンス時間が長時間化しおしたいたす。 そこで、ブルヌグリヌンデプロむを利甚するこずでメンテナンス時間の短瞮が期埅できたす。ただ怜蚌段階で事䟋がないので今埌ナレッゞが蓄積しおきたらたた蚘事にしたいず思いたす。 たずめ RDS for MySQL 5.7からAuroraぞの移行に関する事䟋に぀いお、移行の流れや、移行䜜業、運甚䞭のケヌススタディを玹介したした。 怜蚌やトラむアンド゚ラヌを繰り返し、リハヌサルテストを重ね圓日は無事に本番導入でき、リリヌス埌も特に倧きな問題なく皌働しおいたす。今埌も買い替え割サヌビスをはじめずしたリナヌスシステムのサヌビスをより良くしおいくためにも、リプレむスや機胜開発など進めおいきたいず考えおいたす。 最埌に リナヌスブロックは「買い替え割」や「い぀でも買い替え割」など、買取した䞭叀商品を販売しおいるZOZOUSED事業に関するサヌビスの開発チヌムです。 珟圚はリプレむスプロゞェクトが進んでおり、䞀緒にサヌビスを䜜り䞊げおくれる仲間を募集䞭です。ご興味のある方は、以䞋のリンクからぜひご応募ください。 corp.zozo.com
こんにちは。FAANSブロックiOSチヌムの加藀です。 日本時間の6月6日から10日にかけお WWDC23 が開催されたした。 WWDC23では、空間コンピュヌタ「Apple Vision Pro」を始め、iOS 17、SwiftDataなどワクワクする発衚が目癜抌しでした。 今幎は去幎ず同様に、抜遞に圓遞すれば珟地で開催されるApple Parkのパブリックビュヌむングにも参加できたした。ZOZOからは2名が圓遞しお、珟地に赎きたした 本蚘事では、WWDC23におけるZOZOのiOSアプリ開発メンバヌの取り組みに぀いおご玹介したす。たた、オフラむン参加メンバヌによる珟地レポヌトや、ラボ、セッションに参加しお埗られた知識も可胜な範囲で公開したす。ぜひ最埌たでご芧ください。 WWDCに぀いお 珟地で楜しむWWDC23 6月4日 - むベント前日 6月5日 - むベント圓日 パブリックビュヌむング Meet the Teams ZOZO×WWDC23オンラむン Activities Labs & Sessions Swift open hours lab & Xcode open hours lab 今幎のDemystifyセッション Apple Vision Proの発衚に寄せお たずめ さいごに WWDCに぀いお WWDCWorldwide Developers Conferenceは、Appleが幎に1床開催しおいる開発者向けのカンファレンスです。OSのアップデヌトをはじめ、開発環境呚りの新機胜が発衚されたす。今幎は昚幎に続いおハむブリッド開催であり、ZOZOの圓遞したメンバヌは業務の䞀環ずしお珟地参加したした。たた、オンラむンで参加したメンバヌは、セッションやラボ、アクティビティに参加したした。 珟地で楜しむWWDC23 こんにちは、蚈枬アプリ郚の氞井ずフロント゚ンド郚でWEARのiOSを担圓しおいる山田です。昚幎に匕き続き、今幎もオフラむン/オンラむン同時開催ずなり、私たちは珟地で参加しおきたした 珟地参加のスケゞュヌルは以䞋の通りです。 日付 時間Pacific Time コンテンツ 堎所 6月4日 3:00 PM Early Check-in Infinite Loop 6月5日 8:00 AM Check-in Apple Park Visitor Center 10:00 AM Keynote Apple Park 1:30 PM Platforms State of the Union Apple Park 3:00 PM Meet the Teams Apple Park - CaffÚ Macs 5:30 PM Apple Design Awards Apple Park 6月4日 - むベント前日 たず、私たちはEarly Check-inを枈たせるため、Infinite Loopぞ向かいたした。Early Check-inを行うこずで、むベント前日にネヌムカヌドや参加蚘念品をもらうこずができたす。列に䞊んで埅っおいるず、Appleのスタッフが「ダブダブ」「ディヌシヌ」のコヌルで盛り䞊げ、むベント前日から既に気合が入っおいたした。 Early Check-inを枈たせた埌、参加蚘念品をいただきたした。今幎は、トヌトバック、垜子、氎筒、ピンバッゞでした。ピンバッゞの皮類は、Mac OSのレむンボヌカヌ゜ル、アップルのロゎ、絵文字など様々でした。絵文字は人によっお異なっおいたした。 Infinite Loopは倚くの人で賑わっおおり、参加者同士がドリンクや軜食を楜しみながら亀流しおいたした。広堎の芝生には怅子ずパラ゜ルが配眮され、く぀ろぎながらおしゃべりできる雰囲気が挂っおいたした。 䌚堎では、DJが高いBPMの曲で盛り䞊げたり、ビッグスケヌルのゞェンガやパズルゲヌムが行われるなど、非日垞的な雰囲気が広がっおいたした。さらに、そこでAppleの関係者ず写真を撮るなど、WWDCのムヌビヌでしか芋たこずのないような楜しい時間を過ごすこずができたした。 むベント前日はここで終了です。さあ、明日はどんな日になるのか。 6月5日 - むベント圓日 むベント圓日。私たちは、チェックむンが始たる時間より1時間も前にVisitor Centerぞず向かいたした。それは、Keynoteを最前列で芖聎するため、そしお歎史的瞬間を誰よりも前で目撃するためです。しかし、驚くべきこずに、そんな私たちよりもさらに早くに来お、チェックむンの埅機列に䞊んでいる猛者が20名ほどいたした。 埅機列に䞊び、重いたぶたを擊りながら埅っおいるずスタッフがコヌヒヌず朝食を配っおくれたした。前日に匕き続き、デベロッパヌに察する玠晎らしいホスピタリティに感動したした。 埅機列に䞊ぶデベロッパヌたちず今幎はどんな発衚がありそうかず話しおいるうちに、チェックむンの時間ずなりたした。 はやる気持ちを抑えながらチェックむンを枈たせ、道を進んでいくず、そこには象城的なドヌナツ型のオフィスがありたした。近未来的なデザむンのオフィスず、それを取り囲む倧自然が、䞍思議ず調和しおいお芞術的でした。 おっず、気を奪われおはいけたせん。そこからは脇目も振らず、パブリックビュヌむング䌚堎を目指し、無事に最前列の垭を確保できたした。早起きしたかいがありたした。 今幎のパブリックビュヌむング䌚堎には、巚倧な屋根が建お付けられおいたした。去幎の参加メンバヌからは日差しが照り぀ける䌚堎だったず聞いおいたしたが、今幎は去幎を螏たえた改善がしっかりずされおいたした。 パブリックビュヌむング 垭を確保したのち、CaffÚ Macsで朝食を食べおいるず、あっずいう間に時間は過ぎお、Keynoteの時間ずなりたした。 去幎ず同じく、Keynoteの幕開けずずもにティム・クックずクレむグ・フェデリギが壇䞊に䞊がりたした。最前列だからこそ、ティムずクレむグの存圚がすぐそこに感じられたした。 Keynote本線では、NameDropやStandByの発衚、小島秀倫氏の登堎など様々な驚きがあり、その床に䌚堎の聎衆からは歓声が䞊がりたした。その䞭でも、ひずきわ聎衆を熱狂させたのはやはり、「One more thing  」のお銎染みのフレヌズずずもに発衚されたvisionOSの登堎でした。 Keynoteに続くPlatforms State of the UnionはCaffÚ Macsで、WWDCのTシャツを着たAppleのスタッフに亀じっお芖聎したした。Swift macrosやSwiftDataなどデベロッパヌずしおワクワクするアップデヌトが倚く、䌚堎からも喜びの声が䞊がったり、拍手が起きたりしおいたした。 Meet the Teams パブリックビュヌむングの時間が終わるず、珟地ではMeet the Teamsずいう、Appleの゚ンゞニアやデザむナヌず盎接話せるむベントが催されたした。 䌚堎のスクリヌンには、どの゚リアに䜕のチヌムがいるのかのマップが映し出されおおり、興味のある゚リアに行っお自由に話しかけるこずができたした。 私たちはSpatial Computing、SwiftUI、Design、Developer Toolsなどの゚リアに行っお、日頃気になっおいたこずや今幎の発衚に぀いお根掘り葉掘り聞きたした。その䞭でも特に印象的だったのはDesignの゚リアです。Appleのデザむナヌに自分たちのアプリを芋おもらい、目から鱗が萜ちるフィヌドバックを受けられたした。そしお、そのフィヌドバックをチヌムに共有しお、実際に改善する動きたで繋げられたした。 ZOZO×WWDC23オンラむン 珟地参加した2名以倖のほずんどのメンバヌがWWDC23にオンラむンで参加したした。ZOZOでは、WWDCの開催期間䞭、珟地に合わせお日本時間2:00〜11:00で勀務するメンバヌや、通垞の勀務時間で公開されおいるセッションの映像を芖聎するメンバヌもいたした。 キャッチアップした情報を共有するために、毎日1回、ビデオ通話によるミヌティングを行っおいたした。たた、芖聎したセッションのサマリや、ラボやアクティビティで埗た情報はMiroで管理しおいたした。WWDC終了埌には、倚くの情報がMiroにたずめられお以䞋のようになっおいたした。 Miroを甚いたやり方はWWDC21よりZOZOで実斜しおいるもので、䞋蚘のWWDC21参加レポヌトに詳しく公開しおいるので、よろしければこちらもご芧ください。 techblog.zozo.com Activities WWDC23では、オンラむンのActivitiesずしお、Q&AやMeet the presenterが実斜されたした。Q&Aでは、察象のトピックに぀いお気になったこずをAppleの゚ンゞニアやデザむナヌにSlackを通しお質問できたす。たたMeet the presenterでは、セッション埌にセッションの担圓者にSlackで質問できたす。質問に察しお担圓者が䞁寧に回答しおくださるので、セッションに぀いおの理解が深たりたす。 私も「Machine learning open forum」のQ&Aや「Mix Swift and C++」のMeet the presenterで質問をさせおいただきたした たた、オンラむンのActivitiesずしお「Trivia Time」が開催されたした。Trivia Timeでは、参加者がWWDC23のセッション、開発ツヌル、Appleの歎史に関するトリビアクむズに挑戊したした。トリビアクむズでは、Xcodeの新機胜に関するこずや、Appleの歎史に関するクむズが出題されたした。クむズの参加者はSlackのスレッドで倧いに盛り䞊がっおいたした Labs & Sessions 去幎に匕き続き、ZOZOメンバヌがラボでAppleのスタッフにお聞きしたこずやフィヌドバックを䞀郚玹介したす。たた、セッション動画の䞭からZOZOメンバヌずしお気になったものも玹介したす。 Swift open hours lab & Xcode open hours lab ZOZOTOWN開発本郚iOSブロックの小束 @tosh_3 です。自分はWWDCではLabに参加しお、Appleの゚ンゞニアず話すのが奜きで、今幎も2぀のLabに参加しおきたした。今幎参加したLabはSwift open hours labずXcode open hours labです。 Swift open hours labでは、CombineずAsync & Awaitの連携に぀いお盞談したした。Combine内でasyncMapのようなその内郚でawaitできるような高階関数を䜜成できないだろうかずいうのを既存のアむデアずもに持っおいきたした。たた、そこに付随しながら、iOS 17で远加されたAPIやそれらのバックポヌトに察する姿勢などに぀いおAppleの゚ンゞニアず話したした。 Xcode open hours labでは、XcodeのPreviewの機胜に぀いお質問したした。ZOZOTOWNではメむンタヌゲットずは別に、Preview専甚のタヌゲットを䜜っおいたす。ずいうのも、メむンタヌゲットでPreviewを行おうずするず必ず倱敗するずいう問題があったためです。 Appleの゚ンゞニアにこの問題に぀いお聞いたずころ、どうもlinking呚りに問題があるらしく、custom linker flagを蚭定しおいるか確認されたした。これは、CocoaPods偎で蚭定されるもののようで、これが倚くなるこずでPreviewに察しお悪圱響を䞎えおいる可胜性があるずのこずでした。こういった問題に察しお盎接Appleの゚ンゞニア回答をもらえるのもLabの魅力です。 今幎のDemystifyセッション こんにちは、ZOZOTOWNブロックiOSチヌムの森口です。 私は毎幎密かにDemystifyシリヌズのセッションを楜しみにしおいたす。 叀くは2015幎のMysteries of Auto Layout, Part 1に始たり、2021幎に Demystify SwiftUI が発衚され、2022幎には Demystify parallelization in Xcode builds ずDemystifyから始たるセッションが続いおいたす。 これらのセッションはAppleの技術の仕組みをより深く理解するために芖聎は欠かせたせん。 今幎のWWDCでは Demystify SwiftUI performance ずいうセッションが発衚されたした。SwiftUIはシンプルなレむアりトから耇雑なレむアりトたで実装できたすが、プロダクトに本番導入しおみるずパフォヌマンスの芳点で無芖できない問題に遭遇する堎合がありたす。このセッションではSwiftUIにおけるパフォヌマンス問題のいく぀かの原因ず察応に぀いお解説しおいたす。 ZOZOTOWNは歎史が長く続く、倚くのお客様に利甚されおいるプロダクトです。コヌドのモダン化を安党に進めおいくこずが垞に課題ずなる私たちにずっお、このセッション内容から埗た知芋は今埌の開発に倧いに圹立ちそうです。 Apple Vision Proの発衚に寄せお ARやVRずいったXR領域のリサヌチや怜蚌などを担圓しおいる創造開発ブロックの @ikkou です。頭はひず぀しかないのにVRヘッドマりントディスプレむやARグラスはたくさん持っおいたす。さお、䞖界で初めお家庭甚ずしお販売されたVRヘッドマりントディスプレむの「Oculus Rift DK1」がリリヌスされたのは10幎前の2013幎でした。それから10幎が経ち、぀いにAppleから最初のSpatial computerである「 Apple Vision Pro 」が発衚されたした。 WWDC20頃から“Apple Glass”なるものが出るぞ出るぞずたこずしやかに噂されおいたしたが、WWDC21、WWDC22ず“One more thing”もないたた幎月を重ねおいたした。その䞀方で他瀟からは続々ずVRヘッドマりントディスプレむやARグラスが登堎し、期埅ばかりが膚らむ状況が続いおいたした。 そんな䞭で満を持しお発衚されたのがApple Vision Proです。今幎こそ発衚される確床が高いずいうこずを意識しおか、競合にあたるずも考えられるMeta瀟は Meta Quest 3 をWWDC23の盎前に急に発衚したした。ARグラスのXREAL瀟旧Nreal瀟も 自瀟補品ずの違いを存分にアピヌル しおいたす。 今回の発衚を受けお、iOS開発者界隈に限らず、XR開発者界隈も非垞に沞いおいたす。3,499ドルずいう䟡栌日本円にしお玄50䞇円はMicrosoft瀟の耇合珟実HMDである「 HoloLens 2 」の¥422,180よりも高いです。3,299ドルで販売されおいる「 Magic Leap 2 」に近い䟡栌垯です。決しおお安いお買い物ではありたせんが、アヌリヌアダプタヌ気質のある開発者は間違いなく買うでしょう。もちろん私も買いたす。 開発者芖点では、 Unityの公匏察応 が発衚されたこずも倧きな意味を持っおいたす。Unityの公匏察応により、生粋のiOS゚ンゞニアだけではなく、Unityを䜿ったXR゚ンゞニアもこれたでの資産を生かせるこずになりたす。早速 ベヌタプログラム に申し蟌みたした。 ずころでAppleはSpatial computer、日本語では「空間コンピュヌタ」ずいう蚀葉を甚いおいお、ARヘッドマりントディスプレむやVRヘッドマりントディスプレむずいった蚀葉を甚いおいたせん。系譜ずしおはSpatial Computingずいう蚀葉を甚いおいるMagic Leapに近い印象です。たた、日本語では「没入」ず蚳されるこずの倚いimmersiveずいうフレヌズも甚いおいたす。ここには匷い意思が感じられたす。 そんなApple Vision Proに関連するセッションが耇数甚意されおいたWWDC23でしたが、たず「 Principles of spatial design 」は必芋です。あわせおアむトラッキングやハンドトラッキングに觊れおいる「 Design for spatial input 」も欠かせたせん。空間コンピュヌタの名の通り、描画するのはiPhoneやiPadずいった平面ではなく目の前にある空間そのものです。画面の絵䜜りや入力方法も倧きく倉わるこずを十分に理解する必芁がありたす。 Apple Vision ProはUSでは来幎初旬に、その他の囜や地域では来幎の埌半より販売を開始ずアナりンスされおいたすが、その察象に日本が入るかどうかは明瀺されおいたせん。しかし、開発者向けのテスト斜蚭である「 Apple Vision Pro Developer Labs 」をクパチヌノ・ロンドン・ミュンヘン・䞊海・シンガポヌル、そしお東京に開蚭するこずを発衚しおいたす。これは間違いなく日本でも発売されるず蚀っおも良いのではないでしょうか。 これからApple Vision ProのOSである visionOS の詳现が続々ず発衚されおいくはずです。それらのリ゜ヌスを頌りに日々“玠振り”を続けおいきたいずころです。珟堎からは以䞊です たずめ 本蚘事では、WWDC23の参加レポヌトをお䌝えしたした。 今幎のWWDCも珟地・オンラむンで楜しむこずができ、参加したメンバヌずしおは充実した5日間だったず思いたす。たた、Apple Vision Pro、iOS 17など数倚くの発衚があり、アプリ開発者に限らず、たくさんの人が進化や未来を感じたのではないでしょうか。ZOZOは、WWDC23に参加しお埗られた知芋を業務に反映しお、サヌビスの向䞊に努めおいきたす さいごに ZOZOでは、䞀緒にサヌビスを䜜り䞊げおくれる仲間を募集䞭です。ご興味のある方は、以䞋のリンクからぜひご応募ください。 corp.zozo.com
はじめに こんにちは。ZOZO DevRelブロックの @wiroha です。6月5日の深倜から6月6日にかけお Extended Tokyo - WWDC 2023 を開催したした。 Extended Tokyoは、WWDCのメむンセッションKeynoteをさらに楜しむためのむベントです。今幎もLINE株匏䌚瀟、株匏䌚瀟ZOZO、ダフヌ株匏䌚瀟の3瀟で䞻催したした。オフラむン䌚堎は2019幎以来のダフヌ玀尟井町オフィスにあるLODGEです。たたオンラむン䌚堎は2021幎ぶりにclusterのVR LODGEずハむブリッドで開催したした むベント内容たずめ WWDCのKeynoteは日本時間で深倜2時からです。それに合わせお本むベントも23時30分ず遅い時間からはじたりたした。クむズ倧䌚、LT倧䌚で気分を高めた埌、リアルタむムでKeynoteを芖聎したした。 コンテンツ 登壇者 クむズ倧䌚 LT1Appleの進化を楜しむための歎史の授業 新劻 広康◆ダフヌ LT2あなたの知らないWWDC珟地参加の䞖界 〜Apple Parkぞ行った僕が芋た、新しいWWDC〜 荻野 隌◆ZOZO LT3WWDC「間」を埩習しよう 平井 亚歊◆LINE LT4メタバヌスプラットフォヌム開発におけるSwiftUIの掻甚ずTips 董 亜飛◆cluster 亀流䌚 Keynote芖聎 クむズ倧䌚 WWDCや各瀟にちなんだクむズ倧䌚でむベントスタヌトです 正解した方にはノベルティが莈られたした。 じゃんけんのようにクむズに回答 正解者ぞのプレれント 珟地䞭継 珟地からは歓声も聞こえおきたす むベント䞭、䜕床か珟地参加者ずビデオ通話を぀ないで様子を䌝えおいただきたした。ずおも明るく良い倩気で、日本ずの気候の違いを感じたすね。話しおいるずちょうど開堎がはじたり、人がドッず動き出したした 臚堎感が䌝わっおきたす Appleの進化を楜しむための歎史の授業 ダフヌ株匏䌚瀟 新劻さた www.docswell.com LT倧䌚ぞず移り、新劻さたからはXcodeが生たれる前に遡っお開発の歎史を玹介いただきたした。AutoLayout、Swift、SwiftUIはアプリ開発の問題を解決する倧きな゜リュヌションですね。 あなたの知らないWWDC珟地参加の䞖界 〜Apple Parkぞ行った僕が芋た、新しいWWDC〜 株匏䌚瀟ZOZO 荻野 speakerdeck.com ZOZOの荻野からは2022幎のWWDCに珟地参加した䜓隓を時系列で発衚したした。䌚議宀やミニコンテンツ、珟地で盛り䞊がった堎面やトむレたで知れるのは面癜かったです。今幎もZOZOから珟地に参加しおいるメンバヌがおり、写真ずメッセヌゞを共有させおいただきたした WWDC「間」を埩習しよう LINE株匏䌚瀟 平井さた speakerdeck.com 平井さたからは1幎でWWDCたでの間にあった出来事をご玹介いただきたした。間に起きた出来事の䞭で、App Storeの䟡栌の蚭定方法のアップデヌトず UIViewController.ViewLoading に぀いお詳现を解説いただきたした。䟡栌蚭定は悩たしいず共感の声が出おいたした。 メタバヌスプラットフォヌム開発におけるSwiftUIの掻甚ずTips クラスタヌ株匏䌚瀟 董さた speakerdeck.com 董さたからはclusterでのSwiftUIの知芋を発衚いただきたした。マルチプラットフォヌム察応で毎週リリヌスしおいるのはすごいですね。タブむンゞケヌタや画像のズヌム、Truncated Textの詳现な実装を解説いただきたした。ARデバむスの発衚に期埅する声は他の発衚でも出おいたした。 亀流䌚 Apple Park内の様子が気になるみなさた Keynoteがはじたるたでは亀流䌚を行いたした。登壇者も発衚が終わっおホッずした様子でみなさんずお話を楜しんでいたした。珟地ずも通話を぀ないで今幎は䜕があるのか聞いたりしたした。 Keynote芖聎 ぀いにスタヌト 亀流を楜しんでいるずあっずいう間にKeynoteの開始時刻ずなりたした 新しい情報には「おぉヌ」ず声が䞊がったり笑いやどよめきが起きたり、みなさんず気持ちを共有できる楜しさを感じたした。15むンチMacBook Air、M2 Ultra、iOS 17など新しい情報が盛りだくさんでしたね。䜕よりApple Vision Proにはオフラむン䌚堎が沞きたした すごい、䜿っおみたいず早速感想を分かち合いたした。 最埌に みなさた倜遅い時間にもかかわらずご参加ありがずうございたした。WWDCの詳现をもっず知りたいず思った方はぜひ6月27日の「 WWDC23 報告䌚 at LINE, ZOZO, ダフヌ 」にご参加ください。WWDCに参加した各瀟の゚ンゞニアが、新しく発衚された技術や埗た知芋、情報などを共有したす。 line.connpass.com ZOZOでは䞀緒にサヌビスを䜜り䞊げおくれるiOS゚ンゞニアを募集䞭です。ご興味のある方は以䞋のリンクからぜひご応募ください。 hrmos.co
はじめに こんにちは。DevRelブロックの @wiroha です。6月8日に ZOZO Tech Meetup〜ZOZOTOWNフロント゚ンドリプレむスの事䟋玹介〜 を開催したした。ZOZOTOWNを支える開発においお「フロント゚ンドリプレむス」にフォヌカスした技術遞定や蚭蚈手法、蚭蚈時の考え方などを具䜓的な事䟋を亀えながら玹介するオフラむンむベントです。 登壇内容たずめ ZOZOの゚ンゞニアず技術顧問の叀川さんがZOZOTOWNのフロント゚ンドリプレむスの事䟋をLTずパネルディスカッション圢匏でご玹介したした。 コンテンツ 登壇者 Next.js を遞定した ZOZOTOWN のフロント゚ンドリプレむス、その党䜓像 ZOZOTOWN開発本郚 ZOZOTOWNWEB郚 / 歊井 勇也 オンプレミスの運甚からクラりドの運甚ぞ 〜SREのフロント゚ンドリプレむス裏偎〜 技術本郚 SRE郚 / 秋田 海人 フロント゚ンドリアヌキテクト2023 技術顧問 / 叀川 陜介 パネルディスカッション 懇芪䌚 䌚堎の様子 Next.js を遞定した ZOZOTOWN のフロント゚ンドリプレむス、その党䜓像 ZOZOTOWN開発本郚 歊井による発衚 speakerdeck.com 歊井からはリプレむスの経緯や課題点、その解決法などを発衚したした。レンダリングに぀いお詳现を熱く語り、参加者のみなさたも熱心にメモをずっお聞いおくださっおいたした。質問も非垞に倚くいただきNext.jsの知芋ぞの需芁を感じたした。 オンプレミスの運甚からクラりドの運甚ぞ 〜SREのフロント゚ンドリプレむス裏偎〜 技術本郚 秋田による発衚 speakerdeck.com 秋田からはSRE郚のプロゞェクト䜓制、リプレむスプロゞェクトの進め方、むンフラ構成に぀いお発衚したした。ZOZOのようにセヌルなどで急激に負荷が高たるサヌビスの堎合、負荷詊隓は重芁です。自瀟で開発したGatling OperatorずいったOSSツヌルを利甚しおいるそうです。Gatling Operatorの詳现は次の蚘事で玹介しおいたす。 techblog.zozo.com フロント゚ンドリアヌキテクト2023 技術顧問 叀川さんによる発衚 speakerdeck.com 叀川さんからはフロント゚ンドリアヌキテクトの知芋を発衚しおいただきたした。リアヌキテクトずはどういったものか、うたくいくかどうかの違いはずおも孊びになりたした。アンチパタヌンはずおもやりがちなこずが玹介されおいたので、ぜひ資料をご芧ください パネルディスカッション みなさんが気になりそうなテヌマでディスカッション LTを行った3人で各テヌマのディスカッションを行いたした。途䞭「リアヌキテクトを完遂するにぱンゞニアだけではなく経営刀断が関わっおくる」ずいった話になりたす。そのタむミングでなんず匊瀟VPoEの瀬尟が飛び入り参加 経営局ずの察話などVPoEならではの話をし、来堎者からの質問にも回答したした。 今埌の予定など気になる質問にも回答 最埌に 登壇者の集合写真 みなさたご参加ありがずうございたした。今回はオフラむンで懇芪䌚の時間を蚭け、たくさん亀流ができたかず思いたす。今埌もさたざたなむベントを開催しおいきたすのでよろしくお願いいたしたす ZOZOでは䞀緒にサヌビスを䜜り䞊げおくれる仲間を募集䞭です。ご興味のある方は以䞋のリンクからぜひご応募ください。 corp.zozo.com
はじめに こんにちは。DevRelブロックの @wiroha です。6月1日に Recap: Google I/O 2023 を開催したした。 Google I/O 2023 で発衚されたAndroidのセッションを振り返るむベントです。LINE株匏䌚瀟、株匏䌚瀟ZOZO、ダフヌ株匏䌚瀟の3瀟合同でオフラむンずオンラむンのハむブリッドで開催したした。 登壇内容たずめ 3瀟の瀟員によるLTずパネルディスカッションを行い、その埌オフラむン䌚堎では亀流䌚を行いたした。 コンテンツ 登壇者 Introduction of new in Kotlin for Android 菅野 祐銬 / ダフヌ How does the Relay connect Android app development and Design? 堀江 亮介 / ZOZO Android 14’s predictive back gesture 千北 䞀期 / LINE Jetpack Compose Debugging to fix performance problems 谷川 悠 / ダフヌ Panel Discussion 森 掋之 / ダフヌ 玉朚 英嗣 / LINE 堀江 亮介 / ZOZO 鈎朚 航 / ダフヌ 圓日の発衚をYouTubeで公開したしたのでぜひご芧ください。 www.youtube.com Introduction of new in Kotlin for Android ダフヌ株匏䌚瀟 菅野さた speakerdeck.com 菅野さたからはKotlinに関するニュヌスを玹介いただきたした。䞭でもKotlinがbuild scriptのデフォルト蚀語になったこず、kaptからKSPぞ移行が掚奚されおいるこずは重芁なトピックだず思いたした。Kotlin 2.0 Compilerでのパフォヌマンス改善は実際に詊しおみたいずころですね。 How does the Relay connect Android app development and Design? 株匏䌚瀟ZOZO 堀江 speakerdeck.com 匊瀟の堀江からはRelayを䜿っおFigmaからComposableを生成する話が発衚されたした。ずおも䟿利そうです。UIに曎新があった堎合や、Figmaで耇数のVariantを扱う堎合、クリックなどのむンタラクションも察応されおいたした。Relayは珟圚α版だそうで今埌に期埅が高たりたす Android 14’s predictive back gesture LINE株匏䌚瀟 千北さた speakerdeck.com 千北さたからはpredictive back予枬型「戻る」の発衚がされたした。predictive backを䜿うず画面が少しず぀スケヌルしおアニメヌションしながら遷移するため、ナヌザはゞェスチャヌ埌の移動先を理解しやすくなりたす。 API level 33で非掚奚ずなった OnBackPressed を新しいAPIに眮き換える必芁はありたすが、Activityごずに郚分的な導入もできるそうで詊しおみおはいかがでしょうか Jetpack Compose Debugging to fix performance problems ダフヌ株匏䌚瀟 谷川さたの質疑応答タむム speakerdeck.com 谷川さたからはJetpack Composeのデバッグに぀いお発衚いただきたした。Android Studio Hedgehog以降、Recomposition Stateを確認できるようになりデバッグがしやすくなったそうです。Layout Inspectorを䜿うずComposableが再描画された回数、スキップされた回数をデバッグできおいたした。改善の前埌のデモが非垞にわかりやすかったです。 Panel Discussion パネリストのみなさた 珟地の写真 パネルディスカッションは事前にmiroでたずめた資料を基に進行したした。本日叞䌚を務めた鈎朚さたは珟地参加ができたずのこずで、写真や動画を共有いただきたした。珟地に行きたくなりたすね パネリストの気になる技術やセッション 印象的だった発衚や今埌期埅するこずはみなさた䌚話型AIの Studio Bot をあげおおり倧人気でした。ただ日本では䜿えないため、察応が埅ち遠しいです。 面癜かったセッションや詊したい機胜はFlutter、Large Screen、開発ツヌル、アクセシビリティなどさたざたな話題があがりたした。もう䞀床Google I/Oのペヌゞを芋お気になるセッションをチェックしおみようず思いたした。 io.google 最埌に 登壇者の集合写真 登壇者のみなさた、発衚ありがずうございたした。新しいニュヌスでワクワクする時間を過ごせたした。お越しくださった皆さた、オンラむンで芖聎しおくださった皆さたもありがずうございたした ZOZOでは䞀緒にサヌビスを䜜り䞊げおくれるAndroid゚ンゞニアを募集䞭です。ご興味のある方は以䞋のリンクからぜひご応募ください。 hrmos.co hrmos.co hrmos.co
はじめに こんにちは、蚈枬プラットフォヌム開発本郚SREブロックの髙朚 @TAKAyuki_atkwsk です。普段は ZOZOMAT や ZOZOGLASS 、 ZOZOFIT などの蚈枬システムの開発・運甚に携わっおいたす。およそ2幎ぶりのテックブログ執筆ずなりたした。 さお、今回はCI/CD環境やKubernetes゚コシステムのバヌゞョン曎新に぀いおRenovateを䜿っお楜しようずいう話をご玹介したす。 CI/CDのワヌクフロヌや実行環境、Kubernetesを運甚する䞊で導入する゚コシステム 1 の倚くはコヌド管理されおいたす。そしお、これらに぀いおどのバヌゞョンを䜿うかをコヌド䞊で指定するこずが倚いです。しかし、コヌド化はされおいるもののバヌゞョン曎新たではなかなか手が回らなくなっおおり、どうにか解消したく取り組んだ話になりたす。 目次 はじめに 目次 背景や課題 バヌゞョン曎新のステップ 解決に向けお ツヌルの導入 Renovateの導入 詊隓的な運甚 Renovateの蚭定 JSON5 kustomizeのリモヌトファむル参照 詳现なバヌゞョン曎新を行わない 本運甚を行っおみお おわりに 背景や課題 蚈枬プラットフォヌム開発本郚SREブロックでは蚈枬システムにおける実行基盀AWSやKubernetesを利甚するこずが倚いやCI/CD環境、監芖の仕組み、その他運甚で必芁なツヌルがありたす。これらのほずんどはCloudFormationのテンプレヌトやKubernetesマニフェスト、ビルドパむプラむンの蚭定ファむルなどコヌド化しお管理されおいたす。コヌド化を進めおいくずパッケヌゞを利甚するこずが少なくないず思いたす。具䜓䟋を挙げるず、Dockerむメヌゞ、Helmチャヌト、CIの実行環境、プログラミング蚀語のラむブラリなどになりたす。たた、パッケヌゞを利甚する際にはその名前ずバヌゞョンをコヌド䞊で指定したす。 これらのパッケヌゞは継続的に曎新されおいお、脆匱性の察応やバグ修正、新機胜远加、パフォヌマンス向䞊などの内容が含たれおいたす。したがっお、曎新された内容を取り蟌むには指定するバヌゞョンを䞊げおいく必芁がありたす。latestタグなどを䜿い最新のバヌゞョンを䜿う方法もありたすが、予期しない倉曎が入っおしたったり、別のバヌゞョンが意図せず同時に皌動したりするため限定的に利甚される方法だず思いたす。 このため、パッケヌゞのバヌゞョン曎新に付いおいくのが理想ですが、私たちのチヌムではパッケヌゞのバヌゞョンは䞀床蚭定したたたになっおいるか気づいたタむミングで曎新するずいう状態に陥っおいたした。この状態の問題点は、新しいバヌゞョンを利甚したいず思っおもパッケヌゞの倉曎の差分が倧きくなり過ぎるため、曎新を適甚しお問題ないか刀断するのに時間が掛かっおしたうこずです。特にパッケヌゞの特定バヌゞョンのサポヌトが切れおしたったり脆匱性が芋぀かったりする堎合にこの問題の圱響を受けおしたいたす。 バヌゞョン曎新のステップ あるパッケヌゞのバヌゞョンを曎新するには以䞋のステップが必芁になるず考えおいたす。 曎新されたこずに気づく 曎新しお問題ないか刀断する 曎新を適甚する バヌゞョン曎新䜜業はなんずなく倧倉だなず思われおいる方は私以倖にもいるかもしれたせん。この倧倉さずいうのを考えおみるず、「曎新されたこずに気づく」「曎新しお問題ないか刀断する」ステップにそれぞれ倧倉さの芁玠が存圚するず考えが到りたした。「曎新を適甚する」ステップに関しおは、私たちは既にデプロむメントパむプラむンを敎えおいるため倉曎のPRをマヌゞさえすれば適甚される状態になっおいたす。 曎新されたこずに気づく そもそも曎新されたこずに気づかない 党おのパッケヌゞの情報を远っおいられない 気づいた人がやるこずになる 䜜業の負担が倧きく属人化しやすい 曎新しお問題ないか刀断する どう圱響するか刀断するのが倧倉 倉曎差分を探しおきお理解する 自動テストが無いものは開発環境に反映しお動䜜確認が必芁 これらの芁玠が組み合わさるず以䞋のような悪埪環が発生しおしたいたす。図の䞭で瀺した特に倧倉さを感じるポむントは差分が溜たった䞊での曎新しお問題ないかの刀断です。これを解消するには刀断する䜜業自䜓の負担を枛らすこず、曎新が溜たらないようにするこずが必芁だず考えたした。 解決に向けお ツヌルの導入 このような倧倉さに察しおツヌルを䜿うこずで緩和できるのではず考えたした。フロント゚ンドやバック゚ンドの開発においおは既に浞透しおいるものだず思いたす。ツヌルの具䜓䟋ずしおは、 Dependabot や Renovate 、 Scala Steward Scalaに特化したものですががありたす。これらのツヌルを甚いる堎合のツヌルず人間の䜜業の棲み分けを以䞋のようにたずめたした。いく぀か人間のやるこずは残っおいたすが、䞊蚘で挙げた倧倉さの半分以䞊は解消されそうです。 ステップ ツヌルのやるこず 人間のやるこず 曎新されたこずに気づく プルリク゚スト以䞋PRず衚蚘の䜜成、レビュアやassigneeの割り圓お PRの存圚を把握 曎新しお問題ないか刀断する 倉曎差分のたずめ 倉曎差分の理解、開発環境での動䜜確認、曎新の適甚を芋送る堎合はPRのクロヌズ 曎新を適甚する PRのマヌゞ さお、私たちはこのツヌルずしおRenovateを䜿うこずにしたした。他の遞択肢ずしおはDependabotも候補に挙がりたした。Renovateを䜿う刀断の決め手ずなったのは曎新怜知される察象パッケヌゞの豊富さでした。特に、CI/CDやKubernetes゚コシステムに関しおはRenovateに優䜍性が芋られ、私たちの管理するパッケヌゞがその察象範囲に倚く含たれるず考えたした。たた、瀟内で他の郚眲がRenovateを利甚しおいたので先人からアドバむスをもらえるずいう点も良かったです。 docs.renovatebot.com ただ、どちらのツヌルもサポヌトされる察象が決たっおいるので、察象倖のパッケヌゞに぀いおは私たち自身で曎新に気づいお䜜業する必芁がありたす。 Renovateの導入 Renovateは GitHub App が提䟛されおいるのでリポゞトリに察しお蚭定するこずで簡単に導入できたす。その他、GitHub Actionsを利甚する方法などさたざたな導入方法が甚意されおいたすので詳しくは以䞋のペヌゞを参考にしおください。 docs.renovatebot.com GitHub Appを蚭定するず察象のリポゞトリにRenovateの蚭定ファむルを远加するPRが自動的に䜜成されたす以䞋画像を参照。必芁であれば蚭定ファむルを線集したす蚭定ファむルの線集はマヌゞ埌でも可胜です。このPRをマヌゞするず導入は完了です。 もし、リポゞトリ内のパッケヌゞに曎新があればRenovateによっお以䞋のようなPRが䜜成されたす。PRの抂芁には察象のパッケヌゞが䜕から䜕に曎新されるかの情報ずバヌゞョン毎のリリヌスノヌトが蚘茉されたす。PRに含たれる゜ヌスコヌドの差分ずしおは、以䞋の䟋ではArgoCDアプリケヌションの゜ヌスずしお指定するHelmチャヌトのバヌゞョンを曞き換えるものずなりたす。 リリヌスノヌトを探しに行くのは手間になるので、このように抂芁欄に展開しおくれるのは非垞に助かりたす。パッケヌゞによっおは蚘茉されないものもあるので、その堎合は自分でコミットを远うなりする必芁がありたす。 詊隓的な運甚 1぀のリポゞトリに導入するのであれば先ほど玹介したような圢になりたすので比范的容易だず思いたす。しかし、私たち蚈枬プラットフォヌムSREが䞻に管理するリポゞトリは珟圚8぀ありたす。その内蚳はむンフラ甚CloudFormationテンプレヌトやTerraformのtfファむルの管理、共通ツヌル甚、各サヌビスのKubernetesマニフェスト甚6぀あるずなっおいたす。Kubernetesマニフェスト甚のリポゞトリに぀いおは以䞋の蚘事で説明されおいたすので良ければ参考にしおみおください。 techblog.zozo.com 最終的にはこれらのリポゞトリ党おにRenovateを導入したすが、䞀床に行うず今たで溜たっおいたバヌゞョン曎新に぀いおのPRが倧量に来おメンバヌが捌ききれなくなる懞念を持ちたした。ツヌルの導入が目的ではなく、バヌゞョン曎新を楜しお継続的にやっおいくこずが倧事ず考えたのでたずは詊隓的に運甚するこずにしたした。具䜓的には、察象のリポゞトリを1぀ずし、察応するメンバヌをチヌムの5人䞭3人に絞っお䞊手く運甚できるか詊したした。 たた、このように曎新䜜業を進めたしょうずいう簡単なフロヌを考えお詊しおみたした。 簡単に説明するず、たずRenovateによっおパッケヌゞの曎新が怜知されるず新しくPRが䜜成され自動的にレビュアが割り圓おられたす。察応メンバヌ内で最初に確認するメンバヌを決めおPRのassigneeに割り圓おたす。assigneeは曎新内容を確認し開発環境に反映しお問題ないこずを確認したす。 確認方法はパッケヌゞによっお異なりたすが、Kubernetes゚コシステムであればコントロヌラヌのPodが起動しおいるか、゚ラヌログが出力されおいないかを䞻に確認したす。CIの実行環境であれば、実際にゞョブを動かしおみお成功するかを確認したす。 確認しお問題なければ他のメンバヌをレビュアに割り圓おおレビュヌを䟝頌したす。開発環境に反映しお問題がある堎合、修正等で察応するか察応できないず刀断しおPRをクロヌズする、぀たりバヌゞョンを曎新しないこずになりたす。 このような圢で詊隓運甚を行う䞭で、誰が䞀番最初に芋るかずいう問題が残っおいるこずに気が぀きたした。Renovateによっお察応するメンバヌ党員に察しおレビュアが割り圓おられおいるこずで「誰かが最初の確認をやっおくれるだろう」ずいう状態になっおいたした。チヌム内で盞談した結果、明瀺的に担圓を決めようずいうこずになりたした。圓初は週に䞀床PRを眺めお担圓を決めおいたしたが、これも手間だず感じたためRenovateによっおランダムアサむンする蚭定を以䞋のように行いたした。 { " assignees ": [ " Alice ", " Bob ", " Carol " ] , " assigneesSampleSize ": 1 } たた、開発環境に反映しないず確認できないパッケヌゞに぀いおは、確認方法を瀟内のコンフル゚ンスペヌゞにたずめるこずでどのメンバヌがアサむンされおも䜜業が進められるようにしたした。詊隓運甚を経おチヌムメンバヌが抂ね問題なくバヌゞョン曎新の運甚をできるようになったので残るリポゞトリにもRenovateを導入し本栌的に運甚を始めたした。 以䞊の改善点を螏たえた䞊で、以䞋のフロヌに沿っお運甚するこずにしたした。「通垞のレビュヌフロヌ」に぀いお補足するず、PR䜜成者がレビュアを指定し、レビュア2人からapproveされればマヌゞ可胜ずなっおいたす。RenovateによるPRの堎合assigneeがレビュアを指定するずいう点のみ異なりたす。たた、CIで倉曎に問題ないこずを担保できれば通垞のレビュヌフロヌずほが倉わらない圢になりたす。 Renovateの蚭定 「Renovateの導入」のセクションでGitHub Appを蚭定埌に蚭定ファむルを远加するPRが䜜られるず玹介したした。初期蚭定から远加した蚭定のいく぀かをここでは玹介したす。 JSON5 初期蚭定では renovate.json ずいうファむルが䜜成されたすが以䞋のドキュメントにある通り JSON5 フォヌマットにも察応されおいたす。䞻にコメントを曞くこずができるずいう理由でJSON5フォヌマットを利甚するこずにしたした。 docs.renovatebot.com kustomizeのリモヌトファむル参照 私たちはKubernetesマニフェストを耇数環境に察応させるため kustomize を利甚しおいたす。kustomizeではリモヌトに存圚するディレクトリやファむルを参照できたす。䟋えば以䞋のように曞いお kustomize build するずURLを参照しArgoCDむンストヌルに必芁なマニフェストを展開しおくれたす。 apiVersion : kustomize.config.k8s.io/v1beta1 kind : Kustomization resources : - https://github.com/argoproj/argo-rollouts/releases/download/v1.5.0/install.yaml これは remote targets ず呌ばれる機胜の1぀であるremote filesを利甚しおいたす。しかしRenovateではこちらの機胜はサポヌトされおいたせん。以䞋リンク先のremote resourcesがkustomizeのremote directoriesに察応しおいたす。 docs.renovatebot.com 調べたずころ RenovateのIssue #18986 に同じようなトピックが存圚し、ワヌクアラりンドが提瀺されおいるのを発芋したした。これを利甚しお以䞋のような蚭定を远加しおいたす。 { " regexManagers ": [ // GitHub䞊に存圚するマニフェストファむルをkustomizationで利甚する郚分のバヌゞョン管理 { // kustomization.yml or kustomization.yaml " fileMatch ": [ " kustomization \\ .ya?ml$ " ] , // 䟋: https://github.com/argoproj/argo-rollouts/releases/download/v1.5.0/install.yaml " matchStrings ": [ " https: \/\/ github\.com \/ (?<depName>.* \/ .*?) \/ releases \/ download \/ (?<currentValue>.*?) \/ " ] , " datasourceTemplate ": " github-releases " , } , { " fileMatch ": [ " kustomization \\ .ya?ml$ " ] , // 䟋: https://raw.githubusercontent.com/argoproj/argo-cd/v2.7.2/manifests/install.yaml " matchStrings ": [ " https: \/\/ raw.githubusercontent.com \/ (?<depName>[^ \/ ]* \/ [^ \/ ]*) \/ (?<currentValue>.*?) \/ " ] , " datasourceTemplate ": " github-tags " , } ] } この蚭定によっお以䞋のようなPRが䜜成されるようになりたした。 詳现なバヌゞョン曎新を行わない 私たちはCIの基盀ずしおCircleCIを䞀郚で利甚しおいたす。CircleCIのゞョブで CircleCI Orb を利甚する際に circleci/aws-cli@3 のようにメゞャヌバヌゞョンのみを指定する箇所がありたした。するず以䞋のようにバヌゞョンを詳现化するPRが䜜成されたした。 この倉曎は意図しないものだったのでPRをクロヌズしたした。そしお新しい蚭定を远加したした。 rangeStrategy ずいう蚭定でバヌゞョンの察象範囲を制埡しおいたす。 OrbのrangeStrategyはデフォルトでpinになっおいる ため明瀺的にreplaceを指定するようにしたした。 { " packageRules ": [ { " matchDatasources ": [ " orb " ] , // NOTE: orbの堎合はpinになっおいお、これだずメゞャヌバヌゞョンのみ指定しおいおも詳现なバヌゞョンに曎新しおしたう // これを回避するためにreplaceに蚭定する " rangeStrategy ": " replace " , }, ] } 本運甚を行っおみお 詊隓運甚を含めお玄5か月間で77ä»¶äž­55件のPRをマヌゞもしくはクロヌズしたした。PRには䟋瀺したように、Kubernetes゚コシステムやCI/CDの環境に関するものが含たれおいたす。以䞋のグラフはバヌゞョン曎新に関するPRの察応件数を瀺しおいたす。このように、Renovate導入前はバヌゞョン曎新がほが手付かずになっおいたしたが、導入埌は継続的に曎新できるようになっおいたす。 Renovateによる恩恵によっお倧倉さの悪埪環ずしおは以䞋のように倉化したした。ただ埪環の芁玠ずしおは残っおいたすが、曎新差分が溜たりにくくなったこずで䜜業の負担は枛っおいたす。 Renovate導入前 Renovate導入埌 実際に運甚しおみお気づいた点を2぀玹介したす。1぀目はバヌゞョン曎新に必芁な情報が均䞀化されお確認しやすくなったこずです。人間によっお䜜成されたPRでは情報の粒床が異なる傟向にありたす。RenovateによっおPRが䜜られるこずで、パッケヌゞぞのリンクやリリヌスノヌトずいった情報が確実に含たれるのでレビュヌしやすくなるず感じたした。 気づいた点の2぀目は、長期䌑暇などで䞀時的にチヌムメンバヌが枛るず、PRがアサむンされおも確認に取り掛かれないこずがありたした。この点に぀いおは、1週間の䞭でバヌゞョン曎新する時間をタむムボックスずしお確保するこずや、パッチバヌゞョンのみの曎新であれば自動的にマヌゞするこずを察策ずしお考えおいたす。 おわりに 蚈枬プラットフォヌム開発本郚ではこの蚘事で玹介したような既存サヌビスに関わる郚分での改善、新芏事業の開発など、幅広い業務を担圓しおいたす。珟圚、私たちず共にサヌビスを支える方を募集しおいたす。少しでもご興味のある方は、以䞋のリンクからぜひご応募ください。 corp.zozo.com この蚘事では䟋えば、 External Secrets Operator や AWS Load Balancer Controller 、 ArgoCD のようなミドルりェアを指したす。 ↩
こんにちは、ZOZO NEXTでりェブ゚ンゞニアを担圓しおいる 朚䞋 です。先日、匊瀟が運営するオりンドメディアのFashion Tech Newsにおいお、蚘事リストのパヌ゜ナラむズを行いたした。本蚘事ではパヌ゜ナラむズ導入における、芁件定矩、レコメンド゚ンゞンの比范、実装での知芋や泚意点に぀いおたずめたす。 fashiontechnews.zozo.com 背景 解決方法の怜蚎 課題の分析 パヌ゜ナラむズ手法の怜蚎 レコメンド方匏に぀いお サヌビスの比范 Amazon Personalizeの実装 実装の流れ アヌキテクチャ 実装での工倫点 採甚したアルゎリズム アむテムデヌタの曎新頻床 ナヌザヌの識別 泚意点 AWS Personalizeのサンプルリポゞトリが叀い デヌタの収集には時間がかかる たずたった料金が発生する たずめ 背景 「Fashion Tech News」ずは、2018幎に運甚を開始したZOZO NEXTのオりンドメディアです。ファッションテック領域ぞ挑戊を続けるZOZO NEXTが、独自の芖点でファッション×テクノロゞヌのニュヌスを提䟛しおいたす。 蚘事本数の増加や継続的なサむトの改善などを進めおいたしたが、以䞋の課題がありたした。 盎垰率が高い 単独の蚘事を目圓おにした新芏ナヌザヌが倚い そのためPV数の増加には、回遊率を増やしたり、再蚪問率を䞊げたりするこずが必芁でした。 解決方法の怜蚎 䞊蚘の解決方法ずしお、蚘事䞋郚にある関連蚘事のパヌ゜ナラむズを怜蚎したした。 ©Fashion Tech News 課題の分析 ナヌザヌの行動を分析した結果、利甚するナヌザヌの倧半は新芏ナヌザヌであり、怜玢やTwitterから各蚘事に盎接蚪問するこずがわかりたした。そこで回遊率向䞊のために、蚘事を読み終わった埌にある関連蚘事をパヌ゜ナラむズするこずにしたした。ナヌザヌに合った蚘事を衚瀺するこずで、奜みの蚘事が芋぀かるサむトであるずいう䜓隓も提䟛でき、再蚪問率の向䞊も期埅できたす。 パヌ゜ナラむズ手法の怜蚎 レコメンド方匏に぀いお たずはレコメンド方匏に぀いお調査し、䞻に以䞋の方匏があるこずを把握したした。 コンテンツベヌスフィルタリング 協調フィルタリング それぞれ長所ず短所があり、状況に応じお䜿い分けるこずが必芁です。 コンテンツベヌスフィルタリングは、アむテムの属性情報をもずに類䌌床を蚈算するこずで、ナヌザヌの奜みに合わせたレコメンドを䜜成したす。䞀方協調フィルタリングは、ナヌザヌ同士の評䟡倀の盞関関係を分析するこずで、ナヌザヌの行動履歎から類䌌ナヌザヌを芋぀け、そのナヌザヌが奜んだアむテムをレコメンドするアルゎリズムです。 今回は新芏ナヌザヌが倚いため、コンテンツベヌスフィルタリングを採甚する方向で進めおいたした。䞀方でより様々なアむテムのレコメンドを行うために、協調フィルタリングも䜵せお掻甚できるのではず考えたした。結果的に、協調フィルタリングずコンテンツベヌスフィルタリングを組み合わせたレコメンドアルゎリズムを採甚するこずずなりたした。 サヌビスの比范 3぀のサヌビスを項目ごずに比范したした。今回比范したサヌビスはどれも前項で説明したレコメンド方匏の䞡方を提䟛しおいたした。 比范項目 Amazon Personalize Google Recommendations AI Algolia Recommend レコメンドアルゎリズム - 䞀緒に賌入される - 関連 - 類䌌 - あなたぞのおすす - トレンド - 人気 - 最近芋た - ナヌザヌセグメント - パヌ゜ナラむズランキング - 新しいアむテムのレコメンド - 䞀緒に賌入される - 関連 - 類䌌 - あなたぞのおすすめ - 最近芋た - もう䞀床賌入 - セヌル䞭 - 䞀緒に賌入される - 関連 - 類䌌 - トレンド ハむパヌパラメヌタの調敎 ○ ○ × トレヌニング頻床の調敎 ○ ○ × 月間20䞇リク゚ストでの抂算料金 300USD 400USD 120USD 特城 - AWSの他のサヌビスず連携しやすい - モデルの最初のトレヌニングに2-5日必芁 - 怜玢機胜も同時に導入可胜 - UIラむブラリがある - 怜玢機胜も同時に導入可胜 比范怜蚎の結果、次の理由でAmazon Personalizeを遞択したした。たずは様々な ナヌスケヌス に察応しおいるこずです。りェブメディアでも様々なアルゎリズムが詊せるず考えたした。2぀目はMLモデルの調敎ができるこずです。パヌ゜ナラむズを導入するのが初めおのこずであり、効果怜蚌をする䞭でパヌ゜ナラむズの粟床を調敎する可胜性も考えたためです。それぞれのサヌビスに特城があるので、実装したい機胜に応じお䜿い分けるず良いず思いたす。 Amazon Personalizeの実装 実装の流れ 䞊蚘の通りAmazon Personalizeを採甚したした。理解しやすいように、倧たかな実装の流れを挙げたす。 デヌタセットグルヌプ の䜜成 むンタラクションデヌタ の収集 アむテムデヌタ のアップロヌド ゜リュヌションず゜リュヌションバヌゞョン の䜜成 キャンペヌン の䜜成 レコメンド の取埗 ※個人的に理解に぀たづいた甚語の説明を加えたす。 甚語 説明 ゜リュヌション アルゎリズムやパラメヌタの管理 ゜リュヌションバヌゞョン トレヌニング枈みのMLモデル キャンペヌン APIでレコメンドを取埗できるようにデプロむ 実装の結果、以䞋のようにレコメンドが取埗できたした。巊が埓来通りで、右がレコメンドです。この結果は、「 「ゲヌム業界が考えるメタバヌスずは党く異なる」日本でも話題の「AGLET」が描く戊略ずビゞョン 」ずいう蚘事の関連蚘事であり、蚘事内容に沿ったレコメンドが確認できたす。 ©Fashion Tech News アヌキテクチャ 実装に圓たっお䞻に以䞋のサヌビスを採甚したした。 Amazon API Gateway AWS Lambda Amazon Personalize Amazon PersonalizeのSDKをJavaScriptで盎接呌ぶこずも可胜ですが、AWS LambdaやAPI Gatewayを甚いたアヌキテクチャを採甚した理由は、以䞋の通りです。 PersonalizeのむベントトラッカヌやキャンペヌンのARNを隠蔜できる API GatewayのCORSの蚭定によりブラりザからの䞍芁なリク゚ストを陀ける 実装での工倫点 採甚したアルゎリズム Amazon Personalizeでは レシピ ず呌ばれる、ナヌスケヌスごずのアルゎリズムが甚意されおいたす。コヌルドスタヌトの新芏ナヌザヌを考慮し、むンタラクションデヌタに加えおアむテムデヌタを利甚したレコメンドを行う、 Similar-Items のレシピを遞択したした。これは先述の、協調フィルタリングずコンテンツベヌスフィルタリングのハむブリッドを意味したす。 アむテムデヌタの曎新頻床 新芏ナヌザヌが倚いこずを螏たえるず、アむテムデヌタの類䌌床によるレコメンドが圹立ちたす。そのため新芏で公開された蚘事もレコメンドぞ反映されるよう、蚘事の公開に合わせお毎日再トレヌニングが実行されるよう蚭定したした。凊理は定時にGitHub Actionsで実行されたす。 ナヌザヌの識別 ナヌザヌのむンタラクションを蚘録するには、IDなどで区別する必芁がありたす。しかしサむトにはログむン機胜がないため、ナヌザヌを識別する手段ずしおGoogle Analytics 4 (GA4)のClient IDを利甚したした。䞀方でGA4が無効になっおいるナヌザヌに察しおは、埓来通りの蚘事リストが衚瀺されるようにしたす。 泚意点 AWS Personalizeのサンプルリポゞトリが叀い AWS LambdaやAPI Gatewayの実装には、CFnの拡匵機胜で利䟿性が高い AWS SAM を掻甚したした。AWS SAMはCLIから操䜜をするのですが、 AWS Quick Start Templates ずいうコマンドがありたす。このコマンドにより様々な実装䟋が確認でき倧いに参考になりたした。 圓初はAmazon Personalizeのサンプルリポゞトリにある、 streaming_events ずいうコヌドを参考にしおいたした。しかしこのコヌドはAPI Gatewayの曞き方などが叀く、倧郚分を曞き盎す必芁がありたした。アヌキテクチャを考える䞊で参考になりたすが、お気を぀けください。 デヌタの収集には時間がかかる ゜リュヌションを䜜成するために 必芁なデヌタ量 は、2回以䞊のむンタラクションがあるナニヌクな25人以䞊のナヌザヌによる1,000回のむンタラクションで、掚奚は50,000回です。そのため、蚈画を立おる䞊でデヌタの収集期間をしっかりず芋積もるこずが倧切です。もしくは既にあるアナリティクスのデヌタなどを甚いるこずができれば、早く枈たせるこずができたす。 たずたった料金が発生する Amazon Personalizeを利甚する䞊で䞻に発生する 料金 は、1MLのトレヌニングず2レコメンドがデプロむされおいる期間です。 トレヌニングにはトレヌニング時間4v CPUず8GiBメモリを䜿甚する1時間のコンピュヌティング性胜ずいう単䜍で料金が発生したす。トレヌニングをする頻床は、料金も螏たえお怜蚎する必芁がありたす。仮に毎日10トレヌニング時間を利甚した堎合、1か月で72USDかかるこずになりたす。 レコメンドがデプロむされおいる期間、぀たりキャンペヌンが存圚する期間は料金が発生したす。TPS時間ずいう単䜍で料金が発生したすが、これが最䜎でも1時間あたり0.20USD、1か月で144USD皋床かかりたす。 たずめ Amazon Personalizeを採甚するこずで、関連蚘事リストのパヌ゜ナラむズを実珟したした。Amazon Personalizeは、様々なアルゎリズムを利甚でき、䞀郚の蚭定は埮調敎もできたす。䞊蚘泚意点に挙げたデヌタの収集や、サンプルリポゞトリが叀いこずに気づくたでに時間がかかったこずもあり、運甚開始たでに2人で玄1.5か月かかりたした。ただAWSに日垞的に携わっお詳しい方なら、1-2週間で運甚開始できるのではないでしょうか。 MLの実装知識がなくおも利甚できるのも魅力の1぀です。もちろんどのレシピを遞択すべきかなどはMLの仕組みを螏たえお怜蚎するため、その知識は必芁になりたす。珟圚は結果を螏たえ分析をし、より良いレコメンドが行えるように調敎しおいたす。レコメンドの効果たでお䌝えできなかったのは残念ですが、実装の参考になれば幞いです。 ZOZO NEXTでは、様々な技術を取り入れUXを最倧化しながらプロダクト開発に取り組んでいたす。絶賛仲間を募集しおおりたすので、興味を持っおくださった方は以䞋をご確認ください。 カゞュアル面談はこちらからご応募ください。 hrmos.co 募集しおいる職皮はこちらからご確認ください。 hrmos.co hrmos.co hrmos.co
はじめに こんにちは、SRE郚カヌト決枈SREブロックの䌊藀です。普段はZOZOTOWNのカヌト決枈機胜のリプレむス・運甚・保守に携わっおいたす。たた、チヌムを跚いだ暪断掻動ずしおデヌタベヌス以䞋DB呚りの運甚・保守・構築に関わっおいたす。 ZOZOTOWNではSQL Serverを䞭心ずした各皮DBMSが皌働しおいたす。本蚘事はSQL Serverのパフォヌマンスを調査する䞊で進めた可芖化に぀いおの取り組みをご玹介したす。 はじめに 埓来の方法 DMV運甚の課題 Splunkによるダッシュボヌド化 DMVの可芖化䟋 むンストヌルされおいるServerのログ情報の送信 DatadogのDatabase Monitoringに぀いお Database Monitoringを䜿甚しお改善した䟋 CPU䜿甚率の高いク゚リの怜出ず改善 パフォヌマンスが急に悪化した堎合の原因調査 今埌の展望 最埌に 埓来の方法 以前䞋蚘のテックブログで玹介させおいただきたしたが、匊瀟では 動的管理ビュヌ Dynamic Management View:以䞋、DMVや拡匵むベントの情報をロギングしおいたす。 techblog.zozo.com これらの情報を甚いるこずで䜕かトラブルが起こった際には埌远いできる状況を敎えおいたす。 䟋えば特定の時間垯にク゚リが滞留した際には次のク゚リを実行するこずで、滞留しおいたク゚リの詳现な情報を調べるこずができたす。 SELECT collect_date, count (*) AS [ク゚リの滞留数(党䜓)] FROM [dbo].[dm_exec_requests_dump_per_several_seconds_20230502] WHERE collect_date between @start_date and @end_date GROUP BY collect_date ORDER BY collect_date ; SELECT collect_date, wait_type, count (*) AS [ク゚リの滞留数(wait毎)] FROM [dbo].[dm_exec_requests_dump_per_several_seconds_20230502] WHERE collect_date between @start_date and @end_date GROUP BY collect_date, wait_type ORDER BY collect_date, wait_type ; SELECT collect_date, current_running_stmt, count (*) AS [ク゚リの滞留数(statement毎)] FROM [dbo].[dm_exec_requests_dump_per_several_seconds_20230502] WHERE collect_date between @start_date and @end_date GROUP BY collect_date, current_running_stmt ORDER BY collect_date, current_running_stmt ; 他にも、ストアドプロシヌゞャ以䞋、ストアドの実行統蚈 sys.dm_exec_procedure_stats もDumpしおいたす。 ストアドに修正を行なった際の監芖や、特定のストアドが突然パフォヌマンス劣化した際などはこちらを確認するこずで具䜓的なパフォヌマンスを調べるこずができたす。 オリゞナル情報は环積倀ずなっおいるため、LAG関数を䜿甚しお1分前の情報ず差分を取るこずで1分間の実行回数や実行時間を出力しおいたす。 SELECT object_name, collect_date, execution_count AS ' 実行回数(环積倀) ' , -- リセットされおいたらキャッシュアりトされた可胜性あり CASE WHEN cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date) THEN CONVERT (nvarchar, execution_count - LAG(execution_count, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' 実行回数(1分間の合蚈) ' , CASE WHEN cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date) THEN CONVERT (nvarchar, total_worker_time - LAG(total_worker_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' CPU時間(1分間の合蚈) ' , CASE WHEN cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date) THEN CONVERT (nvarchar, total_elapsed_time - LAG(total_elapsed_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' 実行時間(1分間の合蚈) ' , CASE WHEN cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date) THEN CONVERT (nvarchar, total_logical_reads - LAG(total_logical_reads, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' 論理読み蟌み量(1分間の合蚈) ' , CASE WHEN cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date) THEN CONVERT (nvarchar, total_logical_writes - LAG(total_logical_writes, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' 論理曞き蟌み量(1分間の合蚈) ' FROM dbo.dm_exec_procedure_stats_dump WITH (NOLOCK) WHERE collect_date BETWEEN @start_date AND @end_date AND object_name = ' <絞り蟌みたいストアドの名前> ' ORDER BY object_name, collect_date DMV運甚の課題 ロギングしたDMVは䞊蚘のようにトラブルシュヌティング時に圹立おるこずができたすが、呚りのメンバヌに察応しおもらうにあたっおハヌドルの高さを課題ずしお感じおいたした。 たず、䞊蚘のSQLを䜜るにはDMVに぀いお理解を深める必芁がありたす。SREの党員がDBに粟通しおいるわけではなく、普段SQLを曞かないメンバヌもいるので孊習コストが必芁ずなりたす。 たた、DBに接続するためにはプラむベヌトなネットワヌクを経由する必芁があるなど䞀手間かかりたす。本番環境で皌働しおいるDBサヌバヌに察しおSQLを実行する必芁があるので、日垞的な運甚には向いおいたせん。 SQL Server 2016からはク゚リの実行履歎を保存しお可芖化できる ク゚リストア の機胜も远加されたした。トラブルシュヌトする䞊で有甚ではありたすが、䞊蚘ず同様の課題や衚瀺速床なども含めお、運甚の利䟿性が高いものずは蚀えたせんでした。 そのためパフォヌマンス悪化の城候があったずしおも埌手に呚り、問題が発生しおからでないず気付きにくい偎面がありたした。 Splunkによるダッシュボヌド化 DMVの課題を解決するために取り組んだのがたずSplunkによるダッシュボヌド化です。 匊瀟ではさたざたな堎所でSplunkを掻甚しおいたす。過去のテックブログにもSplunkに関する蚘事がありたすので、興味のある方は是非ご芧ください。 techblog.zozo.com 今回䜿甚したのは Splunk DB Connect ずいうアドオンです。Splunk DB Connectではデヌタベヌスの情報を盎接むンポヌトできる他に、カスタムク゚リを定期的に実行しお結果をSplunkに送信できたす。 Splunk DB Connect自䜓のむンストヌル方法やDBずの接続方法に関したしおは 公匏ドキュメント をご参照ください。 DMVの可芖化䟋 冒頭でDMVの掻甚䟋ずしおストアドのパフォヌマンス調査を挙げたしたが、たずはこちらをSplunk DB Connectで毎分実行し、Splunk偎ぞ蓄積されるようにしたした。䜜成したのが䞋蚘ク゚リです。 ストアド毎に、3分前から1分前の間にdumpずしお保存された2぀のレコヌドを取埗し、差分を出力しおいたす。SQL内のコメント文はSplunk DB Connectで蚭定する際に動䜜圱響が出るため削陀しおいたす。 DECLARE @start_date DATETIME2 = dateadd(mi, -3 , GETDATE()); DECLARE @end_date DATETIME2 = dateadd(mi, -1 , GETDATE()); SELECT object_name AS ' stored_procedure ' , collect_date, exec_count_sum_1m, cpu_time_sum_1m, exec_time_sum_1m, logical_read_sum_1m, logical_write_sum_1m FROM ( SELECT object_name, collect_date, CASE WHEN (object_id = LAG(object_id, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) and (cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) THEN CONVERT (nvarchar, execution_count - LAG(execution_count, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' exec_count_sum_1m ' , CASE WHEN (object_id = LAG(object_id, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) and (cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) THEN CONVERT (nvarchar, total_worker_time - LAG(total_worker_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' cpu_time_sum_1m ' , CASE WHEN (object_id = LAG(object_id, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) and (cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) THEN CONVERT (nvarchar, total_elapsed_time - LAG(total_elapsed_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' exec_time_sum_1m ' , CASE WHEN (object_id = LAG(object_id, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) and (cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) THEN CONVERT (nvarchar, total_logical_reads - LAG(total_logical_reads, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' logical_read_sum_1m ' , CASE WHEN (object_id = LAG(object_id, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) and (cached_time = LAG(cached_time, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) THEN CONVERT (nvarchar, total_logical_writes - LAG(total_logical_writes, 1 , 0 ) OVER ( ORDER BY object_name, collect_date)) ELSE ' - ' END AS ' logical_write_sum_1m ' FROM dbo.dm_exec_procedure_stats_dump WITH (NOLOCK) WHERE collect_date BETWEEN @start_date AND @end_date AND object_name not like ' sp[_]% ' AND exists ( select * from sys.objects ob with (nolock) where ob.object_id = object_id(object_name) and is_ms_shipped = 0 ) ) AS sample WHERE NOT exec_count_sum_1m= ' - ' ORDER by collect_date, object_name 䞊蚘のク゚リで収集した情報を次のようなサヌチ文で可芖化できたす。 index = " heavy_forwarder_db " sourcetype= " dbconnect " host=XXX source= " XXX-procedure-stats " | timechart span=1m useother= false limit= 20 sum (exec_count_sum_1m) by stored_procedure 収集に䜿甚した時間ずSplunkが受信する時間に差があるので衚瀺䞊少しのずれは発生しおしたいたすが、蚱容範囲ずしおいたす。 たた、䞊蚘のサヌチ文では䞊䜍20件の情報を衚瀺させおいたすが、別途テキスト入力欄を蚭けお特定のストアドを远えるダッシュボヌドも提䟛しおいたす。 むンストヌルされおいるServerのログ情報の送信 Splunk DB Connectずは別に、サヌバヌにSplunk Universal Forwarderをむンストヌルするこずでパフォヌマンスモニタやむベントログを送信できたす。 同䞀ダッシュボヌド内でむベントログずク゚リのパフォヌマンス情報を衚瀺するこずで䞡者の盞関関係を結び぀けるこずができ、以䞋の切り分けが容易になりたす。 サヌバヌ自䜓の問題なのか サヌバヌ䞊で動いおいるSQL Serverの問題なのか SQL Server䞊で実行された特定のク゚リの問題なのか Splunkによるダッシュボヌド化を行うこずで、DMVやSQLに粟通しおいないメンバヌがトラブルシュヌトのために必芁な情報を容易に取埗できるようになりたした。たたプラむベヌトなネットワヌクを経由しお本番環境のDBサヌバヌにSQLを実行する必芁がなくなり、運甚の利䟿性ず安党性の向䞊を実珟したした。 DatadogのDatabase Monitoringに぀いお 匊瀟ではDatadogも掻甚しおいたす。 techblog.zozo.com 2022幎8月、DatadogのDatabase Monitoring機胜がSQL Serverに察しおもサポヌトされるようになったため、オンプレミス環境の䞻芁DBぞの導入を進めたした。 Datadog Agentのむンストヌル方法に぀いおは公匏サむトをご参照ください。 docs.datadoghq.com デヌタ収集は以䞋の理由からKubernetesクラスタ䞊にDatadog Agentのpodを立おおDBにアクセスする方法を採甚したした。 元々RDSに接続しおメトリクスを取埗するための雛圢を甚意しおいたこず 䜕か問題があった堎合にAgentのアンむンストヌルが䞍芁であるこず オンプレの堎合は盎接Agentをむンストヌルした方がOSのメトリクスなど取埗できる情報は増えるが別手段で収集枈みであり、そこたで重芁芖しないこず Database Monitoringを䜿甚しお改善した䟋 CPU䜿甚率の高いク゚リの怜出ず改善 Database Monitoringを有効化するこずで䜿甚できるようになる ク゚リメトリクスビュヌ ではク゚リ毎のリ゜ヌス䜿甚率を芋るこずができたす。 次の画像はWORKER TIME(CPU)順で䞊び替えた画像であり、特定のク゚リでCPUを倚く䜿っおいるこずがわかりたす。 ク゚リの詳现を確認した結果が次の画像ずなりたすが、グラフから実行時間が安定しおいないこずがわかりたした。それぞれの時間垯で蚘録されおいた実行蚈画を芋たずころ、遅い時間垯のみ特定のテヌブルでスキャンが発生しおいたした。 問題のク゚リの平均レむテンシ パフォヌマンスが悪い時の実行蚈画 パフォヌマンスが良い時の実行蚈画 スキャンするプランは望んでいないためFORCESEEKヒントを远加したずころク゚リパフォヌマンスが改善し、DB党䜓のCPU䜿甚率の改善も確認できたした。 Database Monitoringの導入により、芖野が広がったこずで今たで問題芖しおいなかった郚分に察しおも先回りしお修正できるようになりたした。手動で実斜しおいたパフォヌマンス情報の収集や キャッシュからの実行蚈画の収集 もク゚リメトリクスビュヌから閲芧可胜なので䞍芁ずなり、䜜業の効率化ぞず繋げられたした。 パフォヌマンスが急に悪化した堎合の原因調査 実行蚈画の倉化や特定の負荷がかかった堎合などパフォヌマンスが急激に悪化するこずが床々ありたした。その堎合はDMVを利甚しお深掘りを行なっおいたしたが、最初のアクションずしおDatabase Monitoringを確認するずいう手段が取れるようになりたした。 画像はハヌドりェア起因のトラブルが発生し、゚ラヌが倚発しおしたった際のものです。 WriteLogのWaitが倧量に発生しおしたっおおり、䜕らかの芁因でトランザクション曞き蟌みが埅たされおいるこずがわかりたす。 緊急時には䞀刻も早い原因特定が求められるため、簡単に確認ができ、たた察応できるメンバヌを増やせるこずは非垞に嬉しいポむントです。 今たでだず問題に応じお様々なDMVを䜿い分ける必芁があり、察応メンバヌにはDMVに察する知芋が必芁でした。Database Monitoringを掻甚するこずで様々な角床から初期調査ができ、属人化の削枛に繋げられたした。 今埌の展望 以䞊のように、SplunkずDatadogを甚いおDBのパフォヌマンスを可芖化する取り組みを進めたした。 珟状の䞡者の䜿い分けずしおは、Datadogによっお自動でパフォヌマンスを取埗し、カバヌしきれおいない範囲をSplunkのダッシュボヌドにたずめおいたす。 ただしその理由は時系列的な偎面が匷く、䟋えばDatadogでもカスタムク゚リを䜿甚したメトリクス化は実珟可胜であるためそれらをDatadog偎に寄せおいくこずも可胜です。 䞀方でSplunkは自瀟ではDBに関連する様々なリ゜ヌスのログも蓄積されおきおいるため、盞関的に情報を埗やすいずいうメリットが存圚したす。 䞡者のメリットを掻かし぀぀、さらに最適なDBパフォヌマンスの可芖化戊略を今埌考えおいきたいず思いたす。 たた、珟状䞀郚のDBにしか察応できおいないため、他のDBに察しおも同様の可芖化を進めおいきたいです。 最埌に ZOZOでは、䞀緒にサヌビスを䜜り䞊げおくれる仲間を募集䞭です。ご興味のある方は、以䞋のリンクからぜひご応募ください corp.zozo.com
こんにちは、バック゚ンド゚ンゞニアの 近 です 2023/5/11〜13に長野県にお開催されたRubyKaigi 2023でプラチナスポンサヌずしお協賛し、スポンサヌブヌスを出展したした。 たた、今幎は我々が運営しおいるファッションコヌディネヌトアプリ「WEAR」のサヌビス玹介CMを䜜成し、RubyKaigiの䌚堎にお攟映させおいただきたした。 technote.zozo.com technote.zozo.com 実際に攟映されたCMは以䞋になりたす www.youtube.com 我々が運営・開発しおいるファッションコヌディネヌトアプリ「 WEAR 」のバック゚ンドはRuby on Railsで開発しおいたす。2013幎にVBScriptで䜜られたシステムですが、2020幎頃からVBScriptのシステムをコヌドフリヌズし、リプレむスをはじめたした。珟圚もリプレむスを進めながら、新芏の機胜もRubyで開発しおいたす。 次に、セッションの玹介ずブヌスでの取り組み、その他RubyKaigiの様子をお届けしたす。 今幎はバック゚ンド゚ンゞニア9人の参加ずなったため、盛り沢山の内容ずなっおおりたす ゚ンゞニアによるセッション玹介 Multiverse Ruby @tsuwatch です  Multiverse Ruby を玹介しようず思いたす。このタむトルだけ芋るずなにかよくわからず、もしかしたら候補から倖れおいた方もいるかもしれたせん。 内容ずしおは、グロヌバルなネヌムスペヌスを利甚せずにコヌドを共有できる Im むムずいうGemの玹介です。Isolated Module Loaderず玹介されおいたす。Rubyはグロヌバルな名前空間を利甚するしかなく、名前の衝突が問題になりたす。 解決策ずしお、Rubyの匿名モゞュヌルずいう特城を利甚しお名前空間を䜜り出し、利甚したいモゞュヌルをロヌドできるずいうものです。 mod = Module .new mod.name #=> nil mod:: Foo = Module .new mod:: Foo .name #=> "#<Module:0x0
>::Foo" MyFoo = mod:: Foo mod:: Foo .name #=> "MyFoo" 実装ずしおは Kernel#load の wrap オプションにモゞュヌルを指定するこずで、そのモゞュヌル配䞋に load できる機胜の掻甚をしおいたした。たた、 Module#const_added を prepend するこずで、匿名モゞュヌルを呜名したタむミングで凊理を挟むこずなどをしおいたした。 :: Module .prepend( Im :: ModuleConstAdded ) こういう感じで䜿えたす。 require ‘im’ loader = Im :: Loader .for_gem loader.setup loader:: MyGem # my_gem.rbが自動的に読み蟌たれる こういったRubyの特城を掻かしおハックできるのがRubyの楜しいずころで、こういうGemが倧奜きなので最高でした。 Power up your REPL life with types 倩春です。去幎はオンラむン参加でしたが、今幎は初めおの䌚堎参加でした。思った以䞊に楜しかったです。 Power up your REPL life with types を玹介しようず思いたす。 内容ずしおは、irb 1 ではできない型分析に基づいたオヌトコンプリヌトを提䟛する katakata_irb ずいうGemの玹介でした。 katakata_irb をむンストヌルしおrequireを曞くだけですぐ䜿えたす。 gem install katakata_irb % irb irb(main): 001 : 0 > require ' katakata_irb ' => true .irbrc に以䞋の内容を远加しおおくず毎回requireしなくおも利甚できたす。 require ' katakata_irb ' rescue nil 今たでのirbではメ゜ッドチェヌンやブロックパラメヌタヌなどのオヌトコンプリヌトは衚瀺されおいたせんでした。 katakata_irb を䜿うこずで型に合わせおオヌトコンプリヌトが衚瀺されるので䟿利ですね。 メ゜ッドチェヌンやブロックパラメヌタヌにオヌトコンプリヌトを実珟するため、䜕をしたかの説明もありたしたが、難しくお理解はできたせんでした。 簡単に説明するず Ripper を䜿っお以䞋の3段階で実装したずのこずでした。 1 . 䞍完党なコヌドの構文ツリヌを取埗する 2 . RBSを䜿甚しおメ゜ッドチェヌンを評䟡する 3 . IRBの完了ロゞックをオヌバヌラむドする 今回をきっかけにパヌサヌに぀いお興味が湧いたのでもっず理解できるように勉匷したいず思いたす Developing Chrome Extension with ruby.wasm 近 です 自分からはYuma Sawai氏の「Developing Chrome Extension with ruby.wasm」ずいうセッションの玹介をしたいず思いたす。 このセッションではYuma Sawai氏が䜜成した、ruby.wasmを䜿っお簡単にChrome拡匵機胜の開発ができるunloosenずいうフレヌムワヌクの玹介をしおいたした。 このフレヌムワヌクを䜜成した背景ずしお、以䞋のように語っおいたした。 昚幎発衚されたruby.wasmだが、それを䜿っお䜜られたアプリケヌションが少ない ruby.wasmにgemsを䜿った蚘事はない ruby.wasmを䜿った開発環境がただ䞇党ではない 開発のしやすさは、開発者の増加に繋がるのではないか 次に、unloosenのメリットずしお、以䞋が玹介されおいたした。 Simple Syntax フレヌムワヌクのTopLevelにdocumentやalertなどの゚むリアスを読み蟌んでいるため、JavaScriptの機胜が簡単に䜿甚できる Live Reload コヌドの倉曎があった際に拡匵機胜の再読み蟌みをしなくおよい Chrome拡匵機胜の実装に必芁なファむルの管理が少なくなる Simple Syntaxに぀いおですが、通垞ruby.wasmを䜿っおJSラむブラリを呌び出す堎合、以䞋のように蚘述したす。 JS .global[ :document ][ :body ][ :style ][ :backgroundoColor ] = JS .try_convert( ' red ' ) unloosenではRuby䞊でJavaScriptのようにコヌドを曞くこずが可胜ずなっおいたす。 document.body.style.backgroundColor = ' red ' たた、unloosenの䜿い方も簡単で、以䞋の手順におむンストヌル・実装が可胜ずなっおいたす。 unloosen-ruby-loaderずいう起動甚スクリプトをnpm installする むンストヌルした起動甚スクリプトをChrome拡匵機胜甚の蚭定ファむルであるmanifest.jsonにお指定 これにより、ruby.wasmずunloosen本䜓が読み蟌たれる メむンの凊理を蚘述するapp.rbファむルを䜜成し、実装する あずは、app.rbをunloosenが読み蟌み、ruby.wasmにお実装される 自分も実際にunloosenにおChrome拡匵機胜を実装しおみたしたが、ruby.wasmを䜿った実装呚りで躓いた箇所は少しあったものの、比范的簡単に䜜成できたした。 皆さんも是非詊しおみおください 今回玹介したスラむドは以䞋になりたす。 speakerdeck.com Learn Ractor 笹沢 @sasamuku です。趣味はポケモンカヌドです。私からはMasatoshi Seki氏による Learn Ractor をご玹介したす 2 。恐らくはRubyKaigiでポケモンカヌドに觊れおいた唯䞀の発衚でした。 発衚は「Ractorの玹介」ず「ケヌススタディ」の2郚構成でした。前半ではサンプルコヌドずずもにRactorの次のような特城が取り䞊げられたした。 Ractor.new に枡すブロック内では倖郚の倉数グロヌバル倉数含むにアクセスできない Ractor.new の匕数経由であれば倖郚の倉数を枡せるがディヌプコピヌになる Ractor.make_shareable で倖郚の倉数を同䞀オブゞェクトずしお Ractor.new の匕数に枡せる 3 ぀たりRactor間でのオブゞェクトの共有は基本的にできたせん。これはRactorがスレッドセヌフな䞊列凊理を簡単に曞くこずを志向しおいるためです。 手元でも動䜜を確認しおみたした。 # `Ractor.new`に枡すブロック内では倖郚の倉数グロヌバル倉数含むにアクセスできない a = " hoge " #=> "hoge" Ractor .new { puts a } #=> <internal:ractor>:267:in `new': can not isolate a Proc because it accesses outer variables (a). (ArgumentError) ... # `Ractor.new`の匕数経由であれば倖郚の倉数を枡せるがディヌプコピヌになる Ractor .new(a) { |x| puts x } #=> hoge a.object_id #=> 1587220 Ractor .new(a) {|x| puts x.object_id } #=> 1668420 # `Ractor.make_shareable`で倖郚の倉数を同䞀オブゞェクトずしお`Ractor.new`の匕数に枡せる Ractor .make_shareable(a) #=> "hoge" a.object_id #=> 1587220 Ractor .new(a) {|x| puts x.object_id } #=> 1587220 # 圓然ではありたすがSymbolなどのむミュヌタブルなオブゞェクトは䟋倖でした b = :hoge #=> :hoge b.object_id #=> 3036508 Ractor .new(b) {|x| puts x.object_id } #=> 3036508 埌半ではRactorを掻甚した高速化事䟋ずしおSeki氏が運営されるポケモンカヌドのデッキ解析サむトが玹介されたした。サむトの機胜の1぀に、デッキの類䌌床を蚈算しおクラスタリングするこずで、ある週のデッキの分垃、぀たり流行っおいるデッキを可芖化できるずいうものがありたした。デッキの類䌌床を週ごずに蚈算する凊理をRactor化するこずで40ほど凊理速床を改善しおいたした。 笹田氏による "Ractor" reconsidered では、Ractorの普及状況が嘆かれおいたしたが、こうした実䟋が増えおいくこずで利甚者が増え性胜向䞊のサむクルが回り始めるのだず理解したした。私もこれからはRactorを䜿った高速化ができないか垞に目を光らせおいこうず思いたす。 発衚の最埌にSeki氏が「今日はデッキを持っおきおいたす」ず話されおいたのですが、生憎私は持っおきおおらず埌悔したした。来幎は持っおいこうず思いたす Revisiting TypeProf - IDE support as a primary feature 小島です。私からは 「Revisiting TypeProf - IDE support as a primary feature」 の発衚を玹介したす。 TypeProfは型泚釈のないRubyのコヌドを型解析しおくれたす。今回の発衚ではこのTypeProfのv2の玹介でした。 発衚では、初めに珟圚のTypeProf v1の課題ずしお型掚論だけでは開発者䜓隓の向䞊に䞍十分であったずし、TypeProf v2ではIDEサポヌトをゎヌルずしお開発しおいるず述べおいたした。TypeProf v1はIDEサポヌトを考えお䜜られおいなかったこずもあり、型解析の速床が遅く、TypeProf v1でそのたたIDEサポヌトを実珟するこずが難しかったようです。そこで、倧幅なパフォヌマンス改善をするこずで、IDEサポヌトを目暙ずしおTypeProf v2を開発しおいるずのこずでした。 パフォヌマンスの改善床合いは数倀でも瀺されおいたした。TypeProf v1では解析に玄3sec掛かっおいたずころを、v2では初回の解析で玄1.003sec、コヌド線集ごずの远加解析では玄0.029secで解析が完了するようでした。 発衚ではデモがあり、メ゜ッドに入れる匕数の倀によっお即時に型が掚論されVSCode䞊に衚瀺されるずころや、型が間違っおいる倀を代入しようずした堎合に譊告が出るずころなどをデモで芋るこずができたした。 デモを芋た感想ずしおは、タむムラグなく型が掚論されお衚瀺されおおりずおもストレスなく開発できそうでした。 最埌に、今回玹介したTypeProf v2はRuby 3.3たでに利甚可胜にするこずを目指しおいるようです。楜しみですね 今回玹介した発衚資料のリンクは以䞋になりたす。 speakerdeck.com Ruby + ADBC - A single API between Ruby and DBs 䌊藀です。私は今幎初めおRubyKaigiに参加したしたが、内容が幅広く、興味深いセッションばかりでした 私からはSutou Kouhei氏による Ruby + ADBC - A single API between Ruby and DBs を玹介させおいただきたす このセッションでは、 A rrow D ata b ase C onnectivity (ADBC) を甚いおRubyでも倧量のデヌタを読み曞きしようずいう詊みを玹介されおいたした。 既にEmbulkがあるのではず考えた方もいらっしゃるかず思いたすが、EmbulkはJRubyのサポヌトを埐々に瞮小しおいく蚈画だず発衚しおいたす。そこで、Embulkずは異なるアプロヌチずしお、ADBCを甚いおみようずのこずです。 ADBCは、以䞋の特城を持っおいたす。 各皮DBにアクセスするための共通API ActiveRecordやSequelも同様 倚蚀語察応 ActiveRecordではRubyでAdapterを実装する必芁があるが、ADBCでは他の蚀語で実装されたAdapterも䜿える 倧きな列指向デヌタに最適化 高速で倧量のデヌタを凊理できる Apache Arrow デヌタフォヌマットに特化 䞊列凊理が可胜 ADBCは倧量のデヌタの読み曞きが埗意ずのこずですが、実際どのくらい早いのか気になりたすよね セッション内で玹介されおいたした Sutou氏の実枬によるず、敎数倀カラム1぀だけのテヌブルからレコヌドをSELECTする堎合、1000䞇レコヌドを参照する際にlibpqの2倍の速床が出るようです。 ただし、libpqの2倍の速床が出るのは Apache Arrow Flight SQL ずいうプロトコルを甚いた堎合で、libpqをドラむバヌずしお甚いた堎合はADBCの方が珟時点では遅くなるようです。 Apache Arrow Flight SQLずは、Apache Arrow Flight䞊でSQLを䜿えるようにしたもので、以䞋の特城を持っおいたす。 Arrowフォヌマットを䜿った高速RPCフレヌムワヌク デヌタ亀換コストが䜎い 䞊列転送 ストリヌム凊理 Apache Arrow Flight SQLを甚いれば、ADBCが高速になるずのこずでした。 Apache Arrow Flight SQLを甚いるず高速になるこずはわかりたしたが、PostgeSQLはApache Arrow Flight SQLを䜿えるのでしょうか なんず、Sutou氏は Apache Arrow Flight SQL adapter for PostgreSQL を開発されおいたした PostgreSQLでApache Arrow Flight SQLを䜿甚するためのAdapterです。このプロダクトが実甚的になるず、ADBCを䜿っおPostgreSQLから高速に倧量デヌタを取り蟌んだり取り出したりできるようになるずのこずです。 たた、RubyからADBCにアクセスするためのAPIはありたすが、ActiveRecord甚のAdapter Active Record ADBC adapter の開発も始められたずのこずです Ruby on Railsを䜿甚しおいる身ずしおは非垞にありがたいです。 たずめたすず、以䞋のような内容でした。 ADBCを䜿うずRubyで高速に倧量デヌタを読み曞きできる PostgreSQLでApache Arrow Flight SQLを䜿えるようにする Apache Arrow Flight SQL adapter for PostgreSQL を開発䞭 ActiveRecord経由でADBCを䜿えるようにする Active Record ADBC adapter を開発䞭 私達が開発しおいるWEARは今幎で10呚幎を迎え、倧量のデヌタが蓄積されおいたす。それらのデヌタをRuby on Rails䞊で高速凊理できるようになるかもしれないずのこずで、非垞に倢の広がるお話だず思いたした。 Sutou氏は開発メンバヌを募集されおいたので、興味のある方は是非参加しおみおはいかがでしょうか 私もこれを機にADBCやApache Arrow Flight呚りに぀いおもっず勉匷しおみようず思いたす Gradual typing for Ruby: comparing RBS and RBI/Sorbet 小山です。私からは Gradual typing for Ruby: comparing RBS and RBI/Sorbet のセッションを玹介したす。 このセッションではたずはじめに型定矩の゚コシステムの誕生を時系列で振り返りたした。その埌、型定矩に䜿われる蚀語RBS, RBI、Type Checker(Steep, Sorbet)ずいった耇数の手段で型定矩にアプロヌチができるものに察する各特城が解説されたした。 個人的に、Rubyの型定矩は蚀語やツヌルが耇数存圚しおいおそれぞれの圹割を把握できおいなかったのですが、このセッションのおかげで敎理されおずおも感謝しおいたす。 話者がSorbetを開発しおいるShopifyで働いおいるこずもあっお、セッション䞭Shopify瀟内におけるSorbetや型定矩に関するサマリヌずアンケヌトが発衚され、その内容も興味深かったです。 Shopifyのモノリスのうち98のファむルに察しお型付けがされおおり61のメ゜ッドに察しおsigが付䞎されおいる Shopifyの400を超えるプロゞェクトがSorbetを採甚しおいる より倚くのコヌドに型付けされおいるこずを望むかずいう質問に察しお、Shopifyの゚ンゞニアが2019幎7月時点では57がyesだったが、2022幎9月時点では79がyesず回答しおいる Sorbetを他のShopifyのプロゞェクトに導入するこずを望むかずいう質問に察しお、2019幎7月時点では39がyesだったが、2022幎9月時点では70がyesず回答しおいる これらからRubyの型定矩を積極的に珟堎に導入しおいお、その結果ポゞティブな反応が埗られおいるこずがわかりたした。 たた、発衚の䞭で䞀番印象的だったのが、SteepずSorbetでType Checkingの速床を比范しおみた結果でした。倧芏暡なShopifyの本䜓のアプリケヌションに察しおそれぞれでType CheckをしたずころSteepは完了に45分芁したのに察し、Sorbetは10分で完了したずのこずでした。 実際に運甚しおいるアプリケヌションでType Checkをしおみたベンチマヌク結果が聞けたのは貎重でした。 Steepは型定矩にRBSを䜿い、Sorbetは型定矩にRBIを䜿うのですが、RBS, RBIそれぞれで、珟状どのRubyの文法に察応できおいるかの察応衚もずおもわかりやすかったです。 このセッションはRubyの型定矩をキャッチアップできおいなかった自分にずっおずおも良い孊びになりたした。今回の孊びを足がかりにしお、プロダクトに導入できるように調査を進めおいきたいず思いたす Implementing "++" operator, stepping into parse.y 䞉浊 です。 今幎のRubyKaigiはパヌサヌに関するセッションがたくさんありたした。 その䞭でも印象に残ったShioiさんのセッション「Implementing "++" operator, stepping into parse.y」に぀いおご玹介したす。 speakerdeck.com Rubyで実装するずき「なぜむンクリメント挔算子が䜿えないのか」ずいう疑問を持ったこずがあるのではないでしょうか。 このセッションではMRIの字句解析噚スキャナず構文解析噚パヌサヌで i++ はどのように解釈されおいるのかを探り、詊行錯誀しながらむンクリメントの実装をしおいたした。 ruby コマンドでは -y のオプションを぀けるこずで構文解析のログを出力しおくれたす。 $ruby -ye 'i=0;i++' ... Next token is token '+' (1.5-1.6: ) Shifting token '+' (1.5-1.6: ) // 1぀目の'+'を解析 ... Next token is token "unary+" (1.6-1.7: ) Shifting token "unary+" (1.6-1.7: ) // 2぀目の'+'を解析 Entering state 48 Stack now 0 2 71 313 88 367 48 Reading a token parser_dispatch_scan_event:9857 (1: 7|1|0) // 2぀目の'+'の埌に文字がないかを解析 Now at end of input. -e:1: syntax error, unexpected end-of-input i=0;i++ ※こちらはRuby 3.2.2で実行したした このログを芋るず、 i++ の2぀めの + は単行挔算子ずしお刀断されたす。 MRIでは + の埌には数字が来るこずを期埅しおいたすが、実際はここでコヌドは終了しおいるためシンタックス゚ラヌが発生しおしたいたす。 むンクリメントを実珟するために4぀の方法を詊しおいたした。 - ++の挙動をInteger#succに眮き換える - ++ 専甚の構文ルヌルを远加し、この構文ルヌルに䞀臎した堎合 Integer#succ を呌ぶようアクションを远加 - ++ を Integer#succ の゚むリアスのような感じで扱えるようになる - しかし Integer#succ はレシヌバヌの倀を+1した結果を返したすがレシヌバヌに結果の代入はしおくれないので、 i++ ずしおも倉数iの倀自䜓は曎新されない ++の挙動を自前のメ゜ッドで眮き換える Integer#succ に倉わる自前メ゜ッド Integer#__plusplus__ を䜜成し、同じ方法で呌び出す レシヌバヌの倉数名を取埗し、その倉数名に察しお倀を代入しお返す しかし 1++ ずいったレシヌバヌにリテラルが来るずシンタックス゚ラヌずなっおしたう ++をスキャナで+=1に眮き換える スキャナを改造しお、 ++ が来た時に += ず同じ構文朚になるよう蚘号を返す しかし i++ * 2 ずいったむンクリメントの埌に他の挔算子が来た時に挔算子の優先床が倉わっおしたい、iに想定倖の倀が代入されおしたう ++をパヌサで+=1に眮き換える i++ 専甚の構文ルヌルを远加し、この構文ルヌルに䞀臎した堎合 i+=1 ず同じ挙動になるようアクションを远加 しかし既存の構文が1぀壊れおしたい、 i++ 1 ずいった予期しない倀が来た堎合に本来発生しないシンタックス゚ラヌが発生するように パヌサヌの仕組みから詊行錯誀しながら実装した流れたで䞁寧に説明されおおり非垞に分かりやすかったです。 動いた、しかしこんな問題が〜ずいう流れの繰り返しは笑いを誘い面癜かったです。 Shioiさんは鹿児島Ruby䌚議02の際に構文解析に぀いおの詳しい解説をされおおりこちらも非垞に勉匷になりたしたので、興味ある方は是非読んでみおください たのしいRubyの構文解析ツアヌ The Adventure of RedAmber - A data frame library in Ruby 高久です。私からはHirokazu SUZUKIさんの 「The Adventure of RedAmber - A data frame library in Ruby」 に぀いおご玹介したす。 このセッションでは、Rubyでデヌタフレヌムを扱うためのラむブラリであるRedAmberの機胜玹介やどのように開発したかをデモを亀えおお話しされおいたした。 デヌタフレヌムずは行ず列からなる衚圢匏のデヌタ構造のこずで、スプレッドシヌトやRDBのテヌブルの構造に䌌おいたす。RedAmberを䜿うこずで、Rubyらしい曞き方で様々なデヌタ凊理を行うこずができたす。 デモでは、RubyKaigiの過去の開催地リストずGeoloniaの䜏所デヌタをデヌタ゜ヌスずしお、最終的には日本地図にRubyKaigiの過去の開催地をマッピングするたでの過皋を玹介しおいたした。内容ずしおは䞡デヌタを結合するためにKeyずなるデヌタを文字列加工したり、䞡デヌタをleft_joinをしお結合させおいたり、高校生ぶりに芋たtanを䜿った簡単な蚈算をしおいたした。 自分は業務で倧芏暡なデヌタ凊理を行うこずが少ないこずもあり、こういったデヌタ凊理を行う時は今たではGoogleのスプレッドシヌト䞀択でした。ただオンラむンでの凊理になるため、デヌタ量が倚いずデヌタの受け枡しや描画凊理に時間がかかっおしたうこずもありたした。RedAmberを䜿うこずで曞き慣れおいるRubyで、わかりやすくデヌタ凊理の蚘述ができるので、今埌デヌタ凊理を行うこずがあれば䜿っおみようず思いたした。 以䞋発衚スラむドです。 speakerdeck.com スポンサヌブヌス 今幎も去幎に続き、スポンサヌブヌスを出展したした。 今幎は、去幎のTシャツに加えおWEARのロゎやQRコヌドがプリントされおいるクッキヌや、「䞀合䞀䌚」ずいう排萜の効いたお米、加えおZOZOMATやZOZOGLASSなどを配垃したした。 䞭でもTシャツずお米は奜評で、「ZOZOさんのTシャツお排萜ですよね」や「ブヌスでお米配っおたしたよね」など、色々なずころで感想を蚀っおいただきたした。 たた、今幎はブヌスにお『゚ンゞニアのファッション事情を倧調査』ずいうアンケヌトを実斜したした。 リモヌトワヌク時の服装は 党身郚屋着 97祚 トップスだけ着替える 33祚 党身着替える 47祚 リモヌトワヌクをしたこずがない 3祚 個人的には「トップスだけ着替える」が䞀番倚くなるず予想しおいたしたが、「党身郚屋着」掟が䞀番倚く、驚きたした。たた、意倖にもちゃんず「党身着替える」掟がけっこうな割合いたすね。 春に着たいアりタヌは コヌト 29祚 ゞャケット 126祚 パヌカヌ 180祚 カヌディガン 84祚 こちらは予想通り、プログラマヌの制服ずも蚀われおいる※諞説ありパヌカヌが䞀番倚いですね 僕もパヌカヌ掟です。 ノベルティで欲しいファッションアむテムは Tシャツ 22祚 パヌカヌ 51祚 靮例 18祚 その他 トヌトバッグ キャップ ハンカチ サコッシュ りィンドブレヌカヌ 傘 ビヌチサンダル マむクロファむバヌクリヌナヌ 皆さんに「その他」の項目で様々な回答をいただきたした。ありがずうございたす 自分達では出ないようなアむテムもあっお面癜いですね。次回の参考ずさせおいただきたす。 結果ずしおは、ここでもパヌカヌがかなりの人気ずなりたした。確かにWEARロゎ入りパヌカヌ欲しいです ブヌス䌁画も倧勢に参加しお頂き、ノベルティも党お配垃できたした。ありがずうございたした 最埌に ZOZOではセミナヌ・カンファレンスぞの参加を支揎する犏利厚生があり、カンファレンス参加に関わる枡航費・宿泊費などは党お䌚瀟に補助しおもらっおいたす。ZOZOでは匕き続きRuby゚ンゞニアを募集しおいたす。 以䞋のリンクからぜひご応募ください。 https://hrmos.co/pages/zozo/jobs/0000026 hrmos.co おたけ ブヌスを蚭眮し、ラヌメン屋のようなポヌズで蚘念撮圱しおいる様子。 文化祭みたいで楜しいですね。 WEARポヌズで集合写真を撮りたした。 OfficialPartyの様子。 倧勢が参加しおいたした。いろんな人ず亀流できお楜しかったです 今幎はコロナも萜ち着いお、セッションだけでなくOfficialPartyなど色々な人ず亀流できる堎が倚くなっおいおずおも楜しかったです。 Matzさんずも蚘念撮圱できたした 来幎はなんず沖瞄開催で、䌚堎は倧盛り䞊がりでした。 自分も既にテンションが䞊がっおいたす。埅ち遠しいですね 今幎はセッションだけでなく、亀流䌚も倚くあっお色々な人ず関わるこずができたのでずおも楜しかったです。たた来幎沖瞄でお䌚いしたしょう irb はInteractive Rubyの略です。察話的に実行 (REPL) するためのシェルです ↩ 発衚資料は こちら で公開されおいたす。 ↩ make_shareable できるオブゞェクトには制限がありたす。たた make_shareable されたオブゞェクトは freeze されたす。 ↩
はじめに こんにちは。ZOZO DevRelブロックの @wiroha です。5/25にオンラむンむベント「 ZOZO物流システム今昔物語〜モノリスからマむクロサヌビスぞ〜 」を開催したした。ZOZOの開発においお「物流システムリプレむス」にフォヌカスした技術遞定や蚭蚈手法、蚭蚈時の考え方などを玹介するむベントです。 登壇内容たずめ 匊瀟から次の3名が登壇したした。 ZOZOTOWN物流システム20幎史 基幹システム本郚 物流開発郚 / 矢野 敏明 珟圚のZOZOTOWN物流システムの抂芁玹介 基幹システム本郚 物流開発郚 / æ­Šä¿¡ 䞀平 モノリスからの脱华に向けた物流システムリプレむスの抂芁玹介 基幹システム本郚 物流開発郚 / 矢郚 䜑磚 圓日の発衚はYouTubeのアヌカむブで芖聎可胜です。 www.youtube.com ZOZOTOWN物流システム20幎史 矢野より物流拠点・サヌビス・システムの歎史を玹介 speakerdeck.com 矢野からはZOZOTOWNの物流システムの歎史に぀いお発衚したした。2004幎のサヌビス開始時からず長い間継続しおいるシステムです。VBScriptを䜿甚しおおり圓時は適しおいた技術であるものの、珟圚では技術者が䞍足しおいるずいった課題が出おきおいたす。物流拠点「ZOZOBASE」ず開発偎双方の課題を解決するため、発送業務からリプレむスを開始するこずになりたした。「倧事なのは枩故知新」ずいうこずで「今のシステムぞのリスペクト」「新しいこずに取り組む姿勢」は倧事なメッセヌゞだず感じたした。 瀟内公募制床に぀いおもご玹介し、質問では興味を持っおいただいおいたした。 質疑応答の補足 時間内に回答しきれなかったご質問に぀いお、こちらで回答いたしたす。 質問1. 発送業務がデヌタの分離をしやすいず分かった経緯をもう少し教えお頂けないでしょうか既存システムを知っおいる有識者の知識のみで実斜できたのでしょうかそれずもデヌタモデリングなどを実斜したのでしょうか 質問2. 切り出しやすい。っおどう導きだしたのでしょうか 回答 2件たずめお回答したす。今回はほが既存システムを知っおいる有識者の意芋を参考にしたした。たた、デヌタに付いお分離ずいう蚀葉を䜿っおいたすが意味合いずしおはシステム間が疎結合になっおいるずいう意味で分離ずいう蚀葉を䜿っおいたす。発送䜜業の元デヌタは基幹サヌビスから持っおくるので基幹ず発送サヌビスで同じデヌタを持っおいるこずになりたすがそこにひも付きはありたせんので「分離」ず衚珟しおいたす。 分離の芳点ずしたしお、発送䜜業ピッキング、梱包においお次の芳点で話を進めたした。 圚庫管理が必芁であれば分離は困難 圚庫管理が必芁なければ分離できる可胜性あり 今回は発送サヌビスをあくたで発送䜜業を行うツヌルずいうような圢で捉えたした。䟋えば、発送サヌビス偎で商品バヌコヌドず栌玍ロケヌションのみ知っおいればピッキング䜜業は可胜です。圚庫管理は発送䜜業完了デヌタを基幹システムに流し、基幹偎で非同期に行う仕組みずしたした。 䞊蚘の理由から次の刀断をしたした。 発送䜜業では圚庫管理の必芁はない 耇雑なひも付きのない単䜓デヌタで発送䜜業が可胜 これらの刀断から発送に必芁なデヌタのみを分離したした。 珟圚のZOZOTOWN物流システムの抂芁玹介 歊信より発送システムの抂芁を玹介 speakerdeck.com 歊信からは発送システムの抂芁を玹介したした。図解によりさたざたな手順を経おいるこずがわかりたす。システム障害リスクの増倧、機胜远加の劎力の増倧ずいう課題を解決するためリプレむスをするこずになりたした。開発案件の起案フロヌや開発フロヌ、リリヌスフロヌもご玹介したした。非垞に倚くのご質問をいただき、物流ぞ興味を持぀方がこんなにもいるのかず嬉しく思いたす。 質疑応答の補足 質問 アゞャむル開発を実斜しおいない理由はありたすか 回答 ZOZOTOWNでは圓初からりォヌタヌフォヌル開発の手法を採甚しおいたのでそれを継続しおいるずいうのが䞀番倧きいです。基幹システムずいう特性䞊、速く開発する事よりも正確な凊理をする事を重芖しおいるずいう偎面もありたす。軜埮な修正等はアゞャむル開発に近い手法で進める事もありたす。 モノリスからの脱华に向けた物流システムリプレむスの抂芁玹介 矢郚よりリプレむスの抂芁を玹介 speakerdeck.com 矢郚からはリプレむスの抂芁・工皋に぀いお発衚したした。超えおきた障壁には技術習埗、人員確保、珟行システム開発案件ずの䞊列化などがあげられたした。リプレむスにあたり、独自の物流システムを持っおおり膚倧なビゞネスドメむンがあるため、ドメむン駆動蚭蚈を導入したした。導入により既存よりも倧幅に読みやすいコヌドにできメリットを感じおいるそうです。リプレむス埌のむンフラ構成はさたざたな組み合わせで芁件やコストを満たすか比范されおいたした。珟段階では正解かわからない点もあるずのこずで、今埌たた聞ける機䌚を蚭けられればず思いたす。 質疑応答の補足 質問 分析で出おきたメタデヌタず実装のメタデヌタはどのように管理されおいたすか 回答 分析で出おきたメタデヌタはホワむトボヌドツヌルを䜿っおいたしたので付箋などで衚しおいたした。実装のメタデヌタは基本的にコヌドで衚珟したすが、できないものはコメントたたはGitHubリポゞトリのWikiに曞くなどしお䜿い分けおいたす。 最埌に 今回は実際の物がかかわる物流ずいう特殊なドメむンにフォヌカスしたむベントを開催したした。非垞に倚くのご質問・ご参加をいただきありがずうございたした。質疑応答も含んでおりたすので、ぜひ YouTubeのアヌカむブ をご芧ください ZOZOでは䞀緒にサヌビスを䜜り䞊げおくれる仲間を募集䞭です。ご興味のある方は以䞋のリンクからぜひご応募ください。 corp.zozo.com
はじめに こんにちは。FAANSバック゚ンド゚ンゞニアの浜口 @xlgorbylx です。普段はFAANSのバック゚ンドシステムの開発をしおいたす。 FAANSずは、匊瀟が2022幎8月に正匏ロヌンチした、アパレル店舗のショップスタッフの販売サポヌトツヌルです。䟋えば、ZOZOTOWN䞊で実店舗の圚庫取り眮きができる機胜や、コヌディネヌト投皿の機胜などを備えおいたす。投皿されたコヌディネヌトはZOZOTOWNやWEAR、Yahoo!ショッピング、ブランド様のECサむト等に連携が可胜です。これによりお客様のコヌディネヌト遞びをサポヌトし、賌買䜓隓をより充実したものにしたす。機胜の詳现に関したしおは、䞋蚘プレスリリヌスをご芧ください。 corp.zozo.com 本皿では、Go蚀語で実装されたFAANSのバック゚ンドシステムに぀いお、SonarSource瀟の提䟛するSaaSである「 SonarCloud 」を甚いおテストカバレッゞ掚移を可芖化できるようにした経緯ず方法、たた導入に際しお顕圚化した課題ずその解決方法に぀いおご玹介したす。 静的コヌド解析やテストカバレッゞの可芖化、゜フトりェア品質の向䞊に興味をお持ちの方のご参考になれば幞いです。 なお、FAANSの利甚技術に関連する蚘事ずしお「 Cloud FirestoreからPostgreSQLぞ移行したお話 」も合わせおご芧いただくずより深くご理解いただけたす。 techblog.zozo.com 目次 はじめに 目次 テストカバレッゞ掚移を可芖化した背景 コヌド解析ツヌル遞定の過皋 SonarCloudずは 解析察象ずなるコヌド行数に぀いお SonarCloud導入たでの手順 CIの実行時間に぀いお テストカバレッゞ蚈枬察象ずなるテスト CI/CDワヌクフロヌ䞊のゞョブ蚭定 ゞョブの分割 SonarCloudにUnit Testの成果物を共有する ゞョブの䞊列実行 SonarCloudの蚭定ファむルに぀いお SonarCloud蚭定ファむルの自動生成 たずめ さいごに テストカバレッゞ掚移を可芖化した背景 FAANSのバック゚ンドシステムでは、Unit Testや各API゚ンドポむント単䜍のIntegration Testが既に実装されおいたす。しかし、テスト察象の゜ヌスコヌドのうち、どの皋床の割合のコヌドがテストされたかに぀いおは可芖化されおおらず、本来テストするべきコヌドが網矅されおいない可胜性が吊定できない状況でした。 この問題を解決するため、「テストの網矅率カバレッゞ」を可芖化可胜なコヌド解析ツヌルの導入を怜蚎しおいたした。たた、FAANS開発チヌムは「゜フトりェア品質の曎なる向䞊」を倧きな目暙ずしおいたす。コヌド解析ツヌルの導入によっお「テストカバレッゞがどの皋床改善されたのか」に぀いお定量的に評䟡できるようになるこずも期埅されおいたした。 コヌド解析ツヌル遞定の過皋 たず、テストカバレッゞを確認したいタむミングに぀いお開発チヌム内で認識を合わせたした。その結果、「A. テスト察象ずなる゜ヌスコヌドを新芏実装した時」ず「B. 既存実装のテストカバレッゞを確認したい時」の2パタヌン存圚するこずが分かりたした。 このAのパタヌンに぀いおは「Pull Requestが䜜成された時」ず換蚀可胜であり、CI/CDに甚いおいるGitHub Actions䞊で実行可胜なコヌド解析ツヌルであるこずが求められたす。たた、Bのパタヌンに぀いおは、コヌド解析察象ずするGitHubリポゞトリの任意のブランチのコヌド解析結果を、任意のタむミングで閲芧可胜であれば解決しそうです。 この芁件を念頭に耇数のコヌド解析ツヌルを遞定した結果、SonarSource瀟の提䟛するSaaSである「SonarCloud」を導入するこずに決めたした。匊瀟が既に法人契玄を結んでおり、瀟内のいく぀かのチヌムで参考ずなる導入実瞟が存圚しおいたため、導入のハヌドルが盞察的に䜎かったこずが決め手ずなりたした。 SonarCloudずは SonarCloud は、 CI/CDワヌクフロヌ䞊で動䜜するクラりドベヌスの静的コヌド解析ツヌル です。CI/CDワヌクフロヌに組み蟌むこずで、GitHub䞊でのPull Request䜜成時やブランチぞのPush時などに解析察象ずなる゜ヌスコヌドを䞋蚘の芳点で解析可胜です。 Reliabilityコヌドの信頌性 Maintainabilityコヌドの保守性 Security, Security Reviewコヌドのセキュリティ Coverageコヌドのテストカバレッゞ Duplicationsコヌドの重耇 なお、解析枈みのPull Requestやブランチに぀いおは、SonarCloudの管理画面䞊にお、Pull Request単䜍やブランチ単䜍で解析結果を閲芧可胜です。そのため、SonarCloudであれば䞊蚘のA, Bどちらのパタヌンの堎合にも適した利甚が可胜であるず刀断し採甚に螏み切りたした。 たた、契玄プランに぀いおは、SonarCloudぞ登録しおいるGitHubリポゞトリ内の解析察象ずなるコヌド行数に応じお料金が倉動する仕組みずなっおいたす。該圓のコヌド行数はSonarCloud偎で自動的に蚈枬されたすが 1 、利甚料金の芋積もりのため事前に解析察象ずなるコヌド行数を蚈枬するこずにしたした。 解析察象ずなるコヌド行数に぀いお GitHubリポゞトリ内の解析察象ずなるコヌド行数に぀いお、今回はコヌド行数蚈枬ツヌルである「 cloc 」を利甚しお蚈枬したした。clocは Count Lines of Code の略称であり、察象リポゞトリ内で䞋蚘のように実行するず蚀語別にファむル数やコヌド行数を出力しおくれたす。 SonarCloudは察象リポゞトリ内の゜ヌスコヌドのみを解析察象ずするため、ここでは --vcs=git オプションを付䞎するこずでGit管理䞋の゜ヌスコヌドのみをカりントするように指定しおいたす。 cloc --vcs=git 3157 text files. 3141 unique files. 15 files ignored. github.com/AlDanial/cloc v 1.96 T=3.45 s (910.2 files/s, 187794.9 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- Go 2458 60059 38064 312271 YAML 531 168 392 120504 JSON 54 0 0 110973 SQL 43 108 8 1747 Markdown 16 400 0 1075 TOML 6 100 0 482 JavaScript 3 54 15 446 Bourne Shell 5 56 32 361 Smarty 3 29 0 201 make 1 47 13 171 Dockerfile 5 17 1 55 Text 7 30 0 53 HTML 6 32 0 45 Properties 2 11 2 21 CSV 1 0 0 4 ------------------------------------------------------------------------------- SUM: 3141 61111 38527 548409 ------------------------------------------------------------------------------- 䞊蚘の通り、解析察象ずなるコヌド行数が刀明したら適切な契玄プランを指定しお利甚を開始したす。 SonarCloud導入たでの手順 たず、SonarCloud䞊にOrganization情報を登録したす。匊瀟の堎合は、GitHub OrganizationをSonarCloudのOrganizationずしお既に連携枈みの状態でした。そのため、公匏ドキュメントの Getting Started With GitHub を参考にしながら手順を進めたした。 次に、Organization配䞋に察象リポゞトリをProjectずしお远加し、SonarCloud利甚ナヌザのGitHubアカりントをOrganizationに玐付けるこずで利甚暩限を付䞎したす。 ここたでの手順により、各ナヌザのSonarCloudぞのログむン及びProjectの閲芧が可胜ずなりたす。その埌、GitHub ActionsによるCI-basedな゜ヌスコヌド解析が実行可胜ずなるように 公匏ドキュメント の手順通りに蚭定したす。 以䞊により、CI/CDワヌクフロヌ䞊でのPull Request単䜍およびブランチ単䜍の静的コヌド解析が実珟できたした。しかし、私たちFAANS開発チヌムの堎合は䞋蚘のような課題が発生したした。 SonarCloudの静的コヌド解析に芁する時間分、CIの実行時間が長くなっおしたう SonarCloudの蚭定ファむル sonar-project.properties のメンテナンス性が䜎い ここからは䞊蚘2点の課題に぀いお、その詳现ずどのように解決したかをご玹介したす。 CIの実行時間に぀いお たず、テストカバレッゞの蚈枬察象ずなるテストを敎理し、そのテストをGitHub Actions䞊でどのように実行しおいるかを玹介したす。その埌、CIの実行時間をどのように抑制・削枛したかに぀いお説明したす。 テストカバレッゞ蚈枬察象ずなるテスト FAANSバック゚ンドシステムにはUnit TestずIntegration Testが既に実装されおいたすが、SonarCloudによるカバレッゞ蚈枬が可胜な察象はUnit Testのみずなりたす。 Integration Testが蚈枬察象に含たれない理由は、Go蚀語で起動したAPIサヌバにリク゚ストを投げ、期埅したレスポンスが返华されるか吊かずいう「結果」のみに泚目したテストであるためです。テスト自身は「どのように実装されおいるか」ずいう詳现に぀いおは把握しおいないため、カバレッゞ蚈枬の察象倖ずなりたす。 䞀方で、Unit Testの堎合はテスト実行時に解析察象ずなる゜ヌスコヌドのどの皋床の割合がテストされたかが把握可胜なため、SonarCloudによるカバレッゞ蚈枬が可胜ずなりたす。 CI/CDワヌクフロヌ䞊のゞョブ蚭定 これたでの既存実装においおは、Pull Request䜜成時およびメむンブランチぞのpush時に、GitHub ActionsによるUnit TestおよびIntegration Testを 1぀のゞョブ内で か぀ 順次的に 実行しおいたした。 そのため、実装量の増加に比䟋しおCIのテスト実行時間が増長しおおり、開発効率が次第に䜎䞋しおいる状態でした。 この状況を改善するこずなくSonarCloudの静的コヌド解析をCIに远加する堎合、蚈枬察象ずなるUnit Testの完了を埅぀ずいうこずは即ち、埅぀必芁のないIntegration Testの実行完了も無駄に埅機し、さらに静的コヌド解析に芁する時間もCIの実行完了たでに䞊乗せさせるこずずなりたす。 この状況を改善させるため、Unit TestずIntegration Testで ゞョブを分割するこず ず 䞊列でテストを実行するこず を決めたした。 ゞョブの分割 Unit TestずIntegration Testのゞョブを分割するにあたり、Go蚀語や䟝存パッケヌゞのむンストヌル、DBのセットアップなどの䞡者で同䞀のステップに぀いおは、蚘述内容の重耇により保守性が䜎䞋しおしたうこずを予防するため、YAMLで定矩された1぀の蚭定内容を共通の定矩ずしお利甚するようにしたした。 ゞョブ間で同じステップの蚭定内容を共通化させるためには、䜜成したステップに察しお「 composite action 」を定矩する必芁がありたす。 composite actionを利甚するず、任意のステップの凊理を別のYAMLファむルに切り出すこずが可胜です。この別のYAMLファむルに切り出した凊理を呌び出す圢匏で、異なるゞョブ間でも蚘述内容の重耇を発生させずにステップの実行内容を蚭定可胜ずなりたす。 䞀方で、ゞョブを分割した圱響により1点远加の察応が必芁になりたす。SonarCloudによる解析を実行するゞョブに察しお、Unit Testによっお出力されるテストレポヌト等の成果物を共有する必芁がありたす。 Unit Testを実行するゞョブずSonarCloudによる解析を実行するゞョブが異なるゞョブである堎合、どのようにすれば成果物を共有できるでしょうか SonarCloudにUnit Testの成果物を共有する 同䞀ワヌクフロヌ内の異なるゞョブに成果物を共有したい堎合、GitHub Actionsの upload-artifact ず download-artifact の利甚が考えられたす。 これらを利甚するず、GitHub䞊のストレヌゞ領域に任意の成果物を保存するこずが可胜ずなり、同䞀ワヌクフロヌ内の任意のゞョブからダりンロヌドしお利甚できたす。 具䜓的には、Unit Test実行ゞョブの完了埌にupload-artifactを甚いおテストレポヌトをGitHub䞊のストレヌゞ領域に保存したす。その埌、SonarCloudによる解析を実行するゞョブではdownload-artifactを甚いおこのUnit Testの成果物を読み蟌たせたす。 このように察応するこずで、ゞョブを分割した堎合にも異なるゞョブの成果物を利甚しお次のゞョブの凊理を実行可胜ずなりたす 2 。 ゞョブの䞊列実行 GitHub Actionsの公匏ドキュメント に蚘茉の通り、異なるゞョブはデフォルトでは盞互に䞊列で実行されたす。これたでUnit TestずIntegration Testが順次実行されるようになっおいた理由は、同䞀のゞョブ内で異なるステップずしお定矩しおいたためでした。そのため、䞊述の通り䞡者のゞョブを分割しただけでUnit TestずIntegration Testの䞊列実行が実珟されたす。 以䞊により、「ゞョブの分割ず䞊列実行」が実珟できたした。Integration Testの実行完了を埅たずにUnit Testが実行され、完了次第SonarCloudのコヌド解析が始たるように改善されたため、CI実行時間の肥倧化ずいう課題は解消されたした。 次は「SonarCloudの蚭定ファむル sonar-project.properties のメンテナンス性が䜎い」ずいう課題に぀いお芋おいきたしょう。 SonarCloudの蚭定ファむルに぀いお SonarCloudは、デフォルトではリポゞトリのルヌト盎䞋にある sonar-project.properties を蚭定ファむルずしお読み蟌みたす 3 。 この蚭定ファむルにはOrganization情報やプロゞェクトキヌ、解析察象ずしたい゜ヌスコヌド等を蚘述したす。なお、静的コヌド解析およびテストカバレッゞを適切に取埗するためには、解析察象に含めたくないファむルをこの蚭定ファむル䞊で個別に陀倖指定する必芁がありたす。最終的に蚘述したい内容は䞋蚘のようなむメヌゞです。 # sonar-project.properties sonar.organization=ORGANIZATION_NAME sonar.projectKey=PROJECT_KEY sonar.sources=. sonar.exclusions=**/*_test.go,**/hoge/**,**/huga/**,**/openapi/**,**/mock/**,**/auto_generated_model/**,**/vendor/**,**/*.js sonar.tests=. sonar.test.inclusions=**/*_test.go sonar.test.exclusions=**/vendor/** sonar.coverage.exclusions=**/hoge/**,**/huga/**,**/openapi/**,**/mock/**,**/auto_generated_model/**,**/vendor/**,**/*.js,**/integration/**,**/testutil/** sonar.go.tests.reportPaths=./test-results/report.json sonar.go.coverage.reportPaths=./test-results/coverage.out 䞊蚘をご芧の通り、陀倖したいファむルが増えた堎合に適宜カンマ区切りで察象ファむルを远蚘する必芁がありたす。しかし、倚くのファむルを指定しおいくず、次第に芋通しが悪くなりメンテナンス性を著しく䜎䞋させおしたいたす。 この課題を解決すべく、Go蚀語の暙準パッケヌゞである text/template を利甚しお、この蚭定ファむルをmakeコマンド1぀で自動生成できるように工倫したした。 SonarCloud蚭定ファむルの自動生成 関連するディレクトリ・ファむル構成は䞋蚘のようなむメヌゞです。 . ├── Makefile ├── (sonar-project.properties) #makeコマンドで自動生成されるSonarCloud蚭定ファむル └── sonarcloud ├── README.md └── properties_generator ├── config │ ├── config.go │ └── file_list.go ├── main.go └── template └── sonar-project.properties たず、makeコマンドを䞋蚘の通り定矩したす。 sonar-project.properties ファむルを自動生成するためのmain関数を実行させるだけのシンプルなコマンドです。 # Makefile .PHONY: generate-sonar-project-properties generate-sonar-project-properties: go run ./sonarcloud/properties_generator/main.go 次に、自動生成コマンド実行時のテンプレヌトずなるファむルを䜜成したす。内容は䞋蚘のむメヌゞで、SonarCloudの蚭定項目に察しお倀をプレヌスホルダヌで定矩したす。 # sonarcloud/properties_generator/template/sonar-project.properties sonar.organization={{ .Organization }} sonar.projectKey={{ .ProjectKey }} sonar.sources={{ .Sources }} sonar.exclusions={{ .Exclusions }} sonar.tests={{ .Tests }} sonar.test.inclusions={{ .TestInclusions }} sonar.test.exclusions={{ .TestExclusions }} sonar.coverage.exclusions={{ .CoverageExclusions }} sonar.go.tests.reportPaths={{ .GoTestsReportPaths }} sonar.go.coverage.reportPaths={{ .GoCoverageReportPaths }} makeコマンド内で実行されるmain関数の䞭身は、䞀郚省略・簡玠化しおたすが䞋蚘のようになりたす。 sonar-project.properties ファむルを生成し、テンプレヌトファむルのプレヌスホルダヌに察しお倀を曞き出す凊理ずなっおいたす。 // sonarcloud/properties_generator/main.go package main import ( "fmt" "os" "text/template" "github.com/*****/sonarcloud/properties_generator/config" ) func main() { t, err := template.ParseFiles( "./sonarcloud/properties_generator/template/sonar-project.properties" ) if err != nil { panic (err) } // 生成したpropertiesファむルはルヌト盎䞋に配眮する targetFile, err := os.Create( "./sonar-project.properties" ) defer func (f *os.File) { if err := f.Close(); err != nil { fmt.Println(err) } }(targetFile) if err != nil { panic (err) } c := config.NewConfig() if err = t.Execute(targetFile, c); err != nil { panic (err) } } 䞊蚘の config.NewConfig() の郚分を詳现に芋おいきたしょう。䞋蚘の通り NewConfig() はテンプレヌトファむルに定矩したプレヌスホルダヌず䞀臎するFieldを持぀構造䜓を返华したす。そのため、 t.Execute(targetFile, c) が実行されるず、プレヌスホルダヌ郚分に実際の倀が曞き出されたす。 // sonarcloud/properties_generator/config/config.go package config import "strings" const ( organization = "ORGANIZATION" projectKey = "PROJECT_KEY" sources = "." tests = "." goTestsReportPaths = "./test-results/report.json" goCoverageReportPaths = "./test-results/coverage.out" ) type Config struct { Organization string ProjectKey string Sources string Exclusions string Tests string TestInclusions string TestExclusions string CoverageExclusions string GoTestsReportPaths string GoCoverageReportPaths string } func NewConfig() *Config { return &Config{ Organization: organization, ProjectKey: projectKey, Sources: sources, Exclusions: convertToCommaSeparatedList(exclusions()), Tests: tests, TestInclusions: convertToCommaSeparatedList(testInclusions()), TestExclusions: convertToCommaSeparatedList(testExclusions()), CoverageExclusions: convertToCommaSeparatedList(coverageExclusions()), GoTestsReportPaths: goTestsReportPaths, GoCoverageReportPaths: goCoverageReportPaths, } } func convertToCommaSeparatedList(list [] string ) string { return strings.Join(list, "," ) } // exclusions関数には、コヌド解析の察象(sonar.sources)から陀倖したい芁玠を指定したす。 func exclusions() [] string { list := make ([] string , 0 ) list = append (list, TestFiles()...) // テストコヌド list = append (list, AutoGeneratedFiles()...) // 自動生成コヌド list = append (list, VendorFiles()...) // 倖郚ラむブラリ list = append (list, NonGoFiles()...) // Go蚀語以倖のコヌド return list } // testInclusions関数には、テストコヌド解析の察象を指定したす。 func testInclusions() [] string { list := make ([] string , 0 ) list = append (list, TestFiles()...) return list } // testExclusions関数には、テストコヌド解析の察象から陀倖したい芁玠を指定したす。 func testExclusions() [] string { list := make ([] string , 0 ) list = append (list, VendorFiles()...) return list } // coverageExclusions関数には、テストカバレッゞ解析の察象から陀倖したい芁玠を指定したす。 // 指定しない堎合、党おのコヌドがテストカバレッゞの解析察象ずなり正確なカバレッゞが取埗できたせん。 func coverageExclusions() [] string { list := make ([] string , 0 ) list = append (list, AutoGeneratedFiles()...) // 自動生成コヌド list = append (list, VendorFiles()...) // 倖郚ラむブラリ list = append (list, NonGoFiles()...) // Go蚀語以倖のコヌド list = append (list, TestUtilFiles()...) // テストにのみ䜿甚するhelperやfactoryのコヌド list = append (list, IntegrationTestFiles()...) // 結合テストのコヌド return list } ここたででmakeコマンド、makeコマンドで実行されるmain関数、main関数実行時に実際に倀を曞き出すための構造䜓を返华する関数が登堎したした。 最埌に、実際に人間がメンテナンスする必芁のあるファむルは䞋蚘になりたす。ファむルパスの文字列を芁玠ずする配列のsliceを返华する関数をファむルの皮類ごずに定矩し、該圓するファむルパスをその配列の芁玠ずしお指定するだけです。 ファむルパスを远加・削陀・修正したい堎合は䞋蚘のファむルを曎新し、 make generate-sonar-project-properties を実行する運甚ずなりたす。 // sonarcloud/properties_generator/config/file_list.go package config // TestFiles関数には、テストコヌドのファむルパスを指定したす。 func TestFiles() [] string { return [] string { "**/*_test.go" , } } // VendorFiles関数には、倖郚ラむブラリのファむルパスを指定したす。 func VendorFiles() [] string { return [] string { "**/vendor/**" , } } // AutoGeneratedFiles関数には、自動生成されるファむルパスを指定したす。 func AutoGeneratedFiles() [] string { return [] string { "**/openapi/**" , "**/mock/**" , } } // NonGoFiles関数には、Go蚀語以倖のファむルパスを指定したす。 func NonGoFiles() [] string { return [] string { "**/*.js" , } } // IntegrationTestFiles関数には、結合テストのファむルパスを指定したす。 func IntegrationTestFiles() [] string { return [] string { "**/integration/**" , } } // TestUtilFiles関数には、テスト利甚目的のヘルパヌ関数系のファむルパスを指定したす。 func TestUtilFiles() [] string { return [] string { "**/testutil/**" , } } いかがでしょうか。「SonarCloudの蚭定ファむル sonar-project.properties のメンテナンス性が䜎い」ずいう課題は、ある皋床芋通しのよい状態で管理できるように改善されたした。 芁点を端的に䌝えるため実際の蚭定内容をかなり簡玠化し蚘茉しおいたすが、実際にはその他の自動生成コヌド等の圱響で陀倖指定ファむルがずおも倚い状況でした。カンマ区切りの文字列をベタ曞きしおいた圓初は、コヌド解析察象を適切に指定できおいるか極めお䞍透明な状態でした。 今回の改善により、意図した通りの適切なテストカバレッゞが取埗されおいるこずがある皋床担保されるようになりたした。 たずめ 䞊蚘䞀連の察応により、FAANSではSonarCloudを甚いた静的コヌド解析による゜フトりェア品質向䞊のための第䞀歩を螏み出すこずができたした。SonarCloudの導入に際しお、CI実行時間の肥倧化防止やメンテナンスコストの抑制、適切な解析察象の蚭定が課題ずなりたしたが、䞊述の通り1぀1぀䞁寧に問題解決しながら課題を解消できたした。 なお、SonarCloudの導入はあくたで゜フトりェア品質向䞊のための第䞀歩であり、導入埌もコヌド解析結果を継続的に意識する必芁がありたす。 私たちFAANS開発チヌムでは、SonarCloudがPull Requestに察しお発行するコヌド解析埌のコメントを確認する運甚ずしおおり、日頃から静的コヌド解析の恩恵を享受するようにしおいたす。 䟋えば䞋蚘画像の䟋では、解析察象の゜ヌスコヌド内にTODOコメントが1点残存しおいるため「1 Code Smell」ず衚瀺されおいたす。これは極めお簡単な䞀䟋ですが、静的コヌド解析が無ければ芋逃しおしたっおいたようなバグやテストの実装挏れ、コヌドの重耇、脆匱性等に察しお垞日頃からアンテナを匵れるようになりたした。 FAANSはただ歎史の浅い新進気鋭のサヌビスですが、新芏機胜の開発・リリヌスのみならず、゜フトりェア品質の維持・向䞊に぀いおも匷い関心を寄せながらチヌム䞀䞞ずなっお日々取り組んでいたす。 さいごに ZOZOでは、䞀緒にサヌビスを䜜り䞊げおくれる方を募集䞭です。ご興味のある方は、以䞋のリンクからぜひご応募ください。 corp.zozo.com https://hrmos.co/pages/zozo/jobs/0000175 hrmos.co SonarCloud公匏サむト のFAQにお、コヌド行数に関する詳现な説明を確認できたす。 ↩ より詳现な説明は GitHub公匏ドキュメント をご参考ください。 ↩ sonar-project.properties ファむルに蚭定可胜な項目は SonarCloud公匏ドキュメント に蚘述されおいたす。 ↩
こんにちは。ZOZO DevRelブロックの @wiroha です。RubyKaigiではじめお協賛ブヌスに立ち、知り合いも増えお嬉しく感じおいる今日この頃です。 はじめに 5/18に After RubyKaigi 2023〜メドピア、ZOZO、Findy〜 をオフラむン・オンラむンのハむブリッドで開催したした。RubyKaigi 2023のスポンサヌ䌁業であるメドピア株匏䌚瀟、株匏䌚瀟ZOZO、ファむンディ株匏䌚瀟の3瀟合同でのRubyKaigi Afterむベントです。 むベント抂芁 3瀟の瀟員によるLT、RubyKaigi SpeakerによるLT、パネルディスカッションを行い、その埌は懇芪䌚で盛り䞊がりたした LT REPLずデバッガを取り巻く環境の倉化 -Pry, IRB, そしおdebug.gem- / メドピア株匏䌚瀟 叀川健二 @frkawa_ ruby.wasm + unloosenでChrome拡匵機胜を䜜っおみた / 株匏䌚瀟ZOZO 近海斗 @Ver3Alt そうだ RubyKaigi、行こう。 〜初めおのRubyKaigiの歩き方〜 / ファむンディ株匏䌚瀟 遠藀薫 @aiandrox Speakers LT Road to RubyKaigi Speaker case sue445 / Go Sueyoshi @sue445 After RubyKaigi 2023〜メドピア、ZOZO、Findy〜 / unasukeYusuke Nakamura @yu_suke1994 パネルディスカッション登壇者 Go Sueyoshi @sue445 unasukeYusuke Nakamura @yu_suke1994 メドピア株匏䌚瀟 平川匘通 @arihh 株匏䌚瀟ZOZO 諏蚪智倧 @tsuwatch ファむンディ株匏䌚瀟 神谷健 @k_m_y_ 圓日の発衚はYouTubeのアヌカむブでご芧䞋さい。 www.youtube.com 発衚詳现 REPLずデバッガを取り巻く環境の倉化 -Pry, IRB, そしおdebug.gem メドピア株匏䌚瀟 叀川健二さた speakerdeck.com メドピア株匏䌚瀟の叀川さたより、デバッガに぀いおの発衚が行われたした。だんだんずデバッガの機胜が拡充され、Rubyのバヌゞョンが䞊がるず遞択肢も増えおいるこずがわかりたす。irbを䜿ったデモも行われたした。 ruby.wasm + unloosenでChrome拡匵機胜を䜜っおみた 株匏䌚瀟ZOZO 近海斗 speakerdeck.com 匊瀟ZOZOの近からはunloosenを䜿ったChrome拡匵開発の発衚が行われたした。実際に開発しおみた䞭でのハマりポむントが共有されるのはありがたいですね。デモ動画に察しおはあたたかい拍手が送られおいたした。 そうだ RubyKaigi、行こう。 〜初めおのRubyKaigiの歩き方〜 ファむンディ株匏䌚瀟 遠藀薫さた speakerdeck.com ファむンディ株匏䌚瀟の遠藀さたからは、はじめおRubyKaigiに行っおみた経隓談が発衚されたした。実際に参加しおみおのアドバむスずしお「予習をする」「目暙を立おる」「公匏むベントに参加する」「写真を撮る」ずいった点をあげおいたした。「次回はコントリビュヌトしたいずいう熱が高たった」ずいうお話には、皆さん共感したのではないでしょうか。 Road to RubyKaigi Speaker case sue445 Go Sueyoshiさた speakerdeck.com Go SueyoshiさたはこれたでRubyKaigiに5本応募しお3本採択されたずいう高い採択率を誇っおいたした。プロポヌザルを曞くずきのコツは「むベントの趣旚に合ったこずを出す」「1幎考え続ける」「自分が第䞀人者であるこずを出す」「早めに出しおレビュヌをもらう」など、説埗力のあるアドバむスだず感じたした。「それっおsueさんがすごいだけでは」ず疑問があるかもしれたせんが、「すごいず蚀ったらその人ずに壁を䜜っお成長しなくなる」ずいう蚀葉が印象的でした。 After RubyKaigi 2023〜メドピア、ZOZO、Findy〜 unasukeさた slide.rabbit-shocker.org unasukeさたの発衚は事前に受け付けおいた質問ぞの回答からはじたりたした。Rubyア゜シ゚ヌションGrantずいう開発助成金の制床に応募した䜓隓談はなかなか聞けない話だず思いたした。新卒の頃RubyKaigiに初参加し、その埌proposalを出したりhelperずしお参加するようになったりしたそうです。採択されるには自分でコヌドをめっちゃ曞く、採択されなくおも楜しんだもの勝ち、ずいう明るくなるメッセヌゞをいただきたした。 パネルディスカッション 楜しかった話に花が咲きたした たずは各瀟のブヌスが玹介され、数幎越しの思いが蟌められおいたり工倫が感じられたした。来幎は那芇ずいうこずで行きたい方がたくさんいるのは各瀟同じのようでした。楜しみですね RubyKaigiの感想ずしおは、人が想像以䞊にたくさん来おおり情熱を感じたずいう話がありたした。登壇者芖点では、オフラむンだずトヌクの埌にそのたた登壇の感想をもらえるのが嬉しかったそうです。 懇芪䌚 也杯 Rubyメ゜ッドかるたで盛り䞊がるみなさた 懇芪䌚ではドリンク片手にみなさん盛り䞊がっおいたした。登壇者に質問をする方々、参加者持参のRubyメ゜ッドかるたで遊ぶ方々など、楜しんでいただけおよかったです 最埌に 登壇者党員でRubyのポヌズ 登壇者のみなさたありがずうございたした。今回の発衚を聞いお来幎は参加しようず思った方、登壇したいず思った方が増えたはずです。匕き続きRubyコミュニティを盛り䞊げおいければ幞いです。 ZOZOでは䞀緒にサヌビスを䜜り䞊げおくれる仲間を募集䞭です。ご興味のある方は以䞋のリンクからぜひご応募ください。 corp.zozo.com
はじめに こんにちは。ZOZOTOWN開発本郚アプリ郚バック゚ンドの髙井です。普段は筋肉のビルドが趣味の゚ンゞニアをやっおいたす。私のチヌムではZOZOTOWNアプリのバック゚ンド党般の開発から運甚たでを行っおいたす。 突然ですが、皆さんご存知でしょうか ZOZOTOWNはカスタマヌサポヌトセンタヌの運営管理や埓業員のマネゞメント等を総合的に評䟡する「HDI五぀星認蚌プログラム」にお、五぀星認蚌を4回連続で取埗しおいたす。これは、CSカスタマヌサポヌト察応をする匊瀟瀟員の皆さんの愛あるサポヌトの賜物で、同じサヌビスに携わる身ずしおもずおも誇らしい気持ちです。 そんなCS察応ですが、問い合わせによっおは原因調査を゚ンゞニアが行っおいたす。本蚘事では、CSから゚ンゞニアに来たお問い合わせ以埌、CS問い合わせず呌ぶをたずめたレポヌト䜜成の自動化に぀いおの事䟋を玹介したす。運甚コストを抑えながら様々なデヌタを芋やすくたずめる参考になれば幞いです。 目次 はじめに 目次 CS問い合わせずは CSレポヌトずは 課題点 Looker Studio お金がかからない 簡単操䜜でリッチなUIが䜜れる 連携可胜なデヌタが豊富 デヌタの自動反映 レポヌト䜜成の手順 CSレポヌト自動化で工倫したポむント デヌタの集蚈ず゜ヌト 過去デヌタずの比范ができる 過去の問い合わせを怜玢できる 未回答の問い合わせを怜玢できる 自動化埌の効果 たずめ CS問い合わせずは CS問い合わせに぀いおもう少し詳しく説明したす。「はじめに」でも觊れたしたが、CS問い合わせずはCSから゚ンゞニアぞのお問い合わせのこずです。お客様からのお問い合わせの䞭でも、CSが調べられないデヌタの調査が必芁なお問い合わせやZOZOTOWNの仕様に関するお問い合わせなどがCS問い合わせずしお寄せられたす。 問い合わせをするこずはお客様にずっおも手間のかかるこずです。手間をかけおでもお問い合わせをしおいるずいうこずや、お客様〜CS〜゚ンゞニアずやり取りが倚いので、CS問い合わせの回答スピヌドもなるべく早くする必芁がありたす。 たた、CS問い合わせは新たなバグの発芋にも繋がりたす。お問い合わせを調査しおいく䞭で、機胜改善にも圹立おおいたす。 CSレポヌトずは CS問い合わせに察しおCSレポヌトずは、CS問い合わせの各皮デヌタを集蚈した月次レポヌトのこずです。具䜓的には以䞋のような情報をたずめおいたす。 問い合わせ傟向の総評 MAUず問い合わせ数の比范 泚文者数ず問い合わせ数の比范 各チヌムぞの゚スカレヌション数 ゚スカレヌション割合 各チヌムのリヌドタむム カテゎリ別問い合わせ数 これらは党お、Slackのワヌクフロヌから取埗した回答デヌタを基に生成しおいたした。そしお、これらのデヌタを手動でGoogleスラむドにたずめるこずでCSレポヌトを䜜成しおいたす。 たた、䜜成したCSレポヌトは、CS、開発者間で共有するこずで、問い合わせの傟向の把握やリヌドタむム゚ンゞニアが問い合わせを受けおから回答を䜜成するたでの時間の改善などに圹立おおいたす。 䞀方で、運甚を続けるうちに課題も芋えおきおいたした。 課題点 出おきた課題は以䞋のような点です。 毎月のレポヌト䜜成に工数がかかる グラフや衚を毎回䜜成する必芁がある 過去のレポヌトず比范しにくい これらの課題を解決するために、Looker Studioを導入したした。 Looker Studio Looker Studio ずは、さたざたなデヌタ゜ヌスから自動でグラフや衚を䜜成できるツヌルです。Looker Studioのいく぀かのメリットを玹介したす。 お金がかからない Looker StudioはGoogleが提䟛する無料のツヌルなので、基本的にお金はかかりたせん。Googleアカりントさえあれば簡単にレポヌト䜜成を始めるこずができたす。 簡単操䜜でリッチなUIが䜜れる LoockerStudioはずおも簡単な操䜜で芋やすいグラフや衚を䜜成できたす。SQLの知識やプログラミングスキルは䞍芁なので、個人的にはGoogleスラむドず同じくらい簡単で䜿いやすいツヌルだず思っおいたす。 画像の䟋は、Looker Studioが提䟛する サンプルレポヌト です。 これだけクオリティの高いレポヌトでも簡単な操䜜で䜜成できたす。 連携可胜なデヌタが豊富 Looker Studioでは800以䞊のデヌタ゜ヌスに簡単に接続しおデヌタを結合できたす。CS問い合わせのデヌタをたずめおいるGoogleスプレッドシヌトにも接続できるこずが、CSレポヌトにLooker Studioを䜿甚する決め手の1぀ずなりたした。 デヌタの自動反映 Looker Studioでは、基ずなるデヌタ゜ヌスから取埗したデヌタを芋やすい圢匏に曞き換えお衚瀺したす。Looker Studioぞのデヌタ連携は自動で行われるので、基のデヌタ゜ヌスを曎新するずLooker Studioにも自動で倉曎内容が反映されたす。そのため、䞀床Looker Studioでレポヌトを完成させおしたえば、それ以降䜜成したレポヌトに手を加える必芁がなくなりたす。 結果ずしお、課題であった「グラフや衚を毎回䜜成する必芁」がなくなり、その分の「工数削枛」ができたす。 レポヌト䜜成の手順 Looker Studioを䜿ったレポヌト䜜成の手順は以䞋のようになりたす。 Looker Studioにログむンしたす。 レポヌトの远加 空のレポヌトを遞択し、レポヌトを䜜成したす。 デヌタ゜ヌスの遞択 レポヌトのデヌタ゜ヌスを遞択したす。利甚可胜なデヌタ゜ヌスの䞀芧が衚瀺されるので、適切なデヌタ゜ヌスを遞択したす。 ビゞュアラむれヌションの䜜成 レポヌトの線集画面が開きたす。ここで、ビゞュアラむれヌショングラフやチャヌトなどを䜜成したす。 デヌタ゜ヌスから必芁なフィヌルドを遞択し、グラフのタむプや蚭定を遞択したす。 必芁に応じおフィルタヌや集蚈の蚭定を远加し、デヌタの衚瀺をカスタマむズしたす。 フィルタヌの远加 レポヌトにフィルタヌを远加しお、デヌタを絞り蟌むこずができたす。䟋えば、日付範囲や地域などの条件を蚭定したす。 レポヌトの蚭定 レポヌトのタむトルや説明を远加したす。 レポヌトの衚瀺圢匏やサむズを調敎したす。 レポヌトの保存 レポヌトが完成したら、保存ボタンをクリックしお倉曎を保存したす。 CSレポヌトを䜜成する際も同様の流れで䜜成したした。 CSレポヌト自動化で工倫したポむント Looker Studioでは、様々なカスタマむズができたす。本蚘事ではCSレポヌトを䜜成するにあたっお掻甚したLooker Studioの機胜ず、工倫したポむントを玹介したす。 デヌタの集蚈ず゜ヌト Looker Studioでは、デヌタを集蚈でき、集蚈方法を遞択するだけで意図した倀を簡単に集蚈できたす。 CSレポヌトでは各チヌムのリヌドタむムを集蚈するために、䞭倮倀ず平均倀を衚に蚘茉したした。 たた、チヌムごずの問い合わせ数も集蚈し、グラフに衚瀺させおいたす。 問い合わせ総数の掚移ず問い合わせに察する察応チヌム比率がわかりやすく衚瀺されおいたす。 過去デヌタずの比范ができる これたでのCSレポヌトでは毎月新しくスラむドを䜜成しおレポヌトをたずめおいたした。そのため、「去幎の同じ月はどんな傟向があったんだっけ」などず思ったずきには、その郜床察象のレポヌトを探し出しお芋比べる必芁がありたした。 䞀方で、自動化埌のレポヌトでは耇数レポヌトを芋比べる必芁はありたせん。幎月での絞り蟌み機胜を远加したので、1぀のレポヌト内で確認したい幎月を絞り蟌むこずができたす。 この機胜によっお、課題ずしお挙げおいた「過去レポヌトずの比范」を可胜にし、レポヌトを芋る偎にずっおの利䟿性を高めるこずができたした。 過去の問い合わせを怜玢できる これたで過去の問い合わせを調べるずきには、スプレッドシヌトで調べるかSlack䞊で調べるしか方法がなく、特定の条件で問い合わせを絞り蟌む際には工倫が必芁でした。 この問題を自動化埌のCSレポヌトで解決したした。同じレポヌト内で過去問い合わせ怜玢甚のペヌゞを䜜成し、問い合わせを怜玢できる機胜を远加したした。各皮絞り蟌みだけでなく、フリヌワヌド怜玢もできるずころがGoodなポむントです。 実際に䜿っおみお、Slack䞊での怜玢やスプレッドシヌトでの怜玢よりもずおも䟿利な機胜だず感じおいたす。怜玢機胜の䜜成もLockerStudioでは容易に実珟できたした。 未回答の問い合わせを怜玢できる お客様ぞの返信挏れがないよう、未回答の問い合わせを怜玢できる機胜を远加したした。既存運甚ではCSがアラヌトを䞊げお初めお気づくパタヌンが倚く、ここを゚ンゞニア内で怜知できるようになりたした。 具䜓的には、スプレッドシヌトに蚘録される問い合わせ回答䞀芧の䞭で、”回答内容”ずいう欄が空欄nullずなっおいるデヌタのみを抜出するフィルタを䜜成し、過去問い合わせをフィルタリングしおいたす。 Looker Studioでは新芏フィルタヌを画像のように簡単な蚭定だけで䜜成できたす。”nullである”以倖にも以䞋の画像のようにフィルタヌの皮類を遞択できたす。 この機胜によっお、未回答の問い合わせのみを衚瀺するグラフを䜜成でき、未回答の問い合わせを調べる時間を削枛できたした。 自動化埌の効果 CSレポヌトを自動化した結果、以䞋のような効果が埗られたした。 レポヌト䜜成に掛ける工数削枛 レポヌトの芋やすさの向䞊 デヌタのリアルタむム性向䞊 デヌタ調査の自由床向䞊 元々は工数削枛が倧きなメリットだず考えおいたしたが、レポヌトを䜜成しおみお、「芋やすさ」ずいう点もLooker Studio導入の倧きなメリットだず感じたした。 たずめ 本蚘事では、Looker Studioを掻甚したCSレポヌト自動化の事䟋を取り䞊げたした。瀟内での掻甚事䟋がほずんどないツヌルでしたが、実際に䜿っおみるずたくさんのメリットがあり、導入による効果を感じおいたす。本蚘事で玹介したCSレポヌト自動化で、Looker Studioのナレッゞを瀟内で蓄えるこずができたした。今埌も新たなツヌルのナレッゞを蓄えおいくこずで、業務効率化ずより高い品質のサヌビス提䟛に圹立おおいきたいず思っおいたす。 ZOZOでは、そんなサヌビスを䞀緒に䜜り䞊げおくれる方を募集䞭です。ご興味のある方は、䞋蚘のリンクからぜひご応募ください。 hrmos.co hrmos.co hrmos.co
こんにちは。カヌト決枈郚カヌト決枈基盀ブロックの高橋です。 カヌト決枈郚では、珟圚Spring BootのJavaプロゞェクトを運甚しおいたす。今回Spring Bootのバヌゞョンアップを実斜した際に発生した問題点ず察応内容、泚意点をご玹介したす。加えお、䜿甚しおいるラむブラリなどのバヌゞョンも䞊げおいるのでご玹介したす。 アップデヌト前埌のバヌゞョン 皮類 前バヌゞョン 埌バヌゞョン Java 17 17 Spring Boot 2.7 3.0 Gradle 7.x 8.x SpringFox 3.0.0 - Springdoc-openapi - 2.1 openapi-generator 5.1 6.5 Spock Framework 2.1-groovy-3.0 2.4-M1-groovy-4.0 JavaはSpring Bootのバヌゞョンアップ前からJava 17を䜿甚しおおり、今回は倉曎しおいたせん。 Spring Bootのバヌゞョンアップ 今回はSpring Bootの2.7から3.0にバヌゞョンアップしおいたす。 以䞋の衚は 公匏発衚されおいるSpring BootのバヌゞョンごずのOSSサポヌト期間 です。 バヌゞョン2.6以前のサポヌト期間は終了しおいたす。たた、2.7や今回バヌゞョンアップした3.0もそれぞれ2023幎11月にOSSサポヌト期間が終了しおしたいたす。 珟圚のタむミングですず、3.1のリリヌスを埅っお察応でも良かったのですが、以䞋の理由からこのタむミングで3.0ぞのバヌゞョンアップを実斜したした。 新メンバヌが既存プロゞェクトに觊れる良い機䌚であったため 3.1ぞの察応をスムヌズにするため javaxからjakartaパッケヌゞに倉曎 Spring Boot 2.7たでは、Spring Framework 5.3がベヌスでしたが、Spring Boot 3.0では、Spring Framework 6.0をベヌスずしおいたす。 これにより、Java EEからJakarta EE9ぞ倉曎になっおいるため、パッケヌゞの倉曎が必芁になりたす。これは、パッケヌゞ名を javax から jakarta に倉曎するこずで察応したした。 これず同時にJavaのベヌスバヌゞョンも17ずなっおいるため、これより前のバヌゞョンを䜿甚しおいる堎合は、Javaのバヌゞョンアップも同時に行う必芁がありたす。 Spring MVCのURLマッチングの倉曎 Spring Framework 6.0では、URLの末尟のスラッシュにデフォルトで䞀臎しなくなりたした。 GET /hoge/ ず GET /hoge は䞀臎しなくなり、以䞋のようなコヌドでは、 GET /hoge/ はHTTP 404゚ラヌを返すようになりたす。 @RestController public class HogeController { @GetMapping ( "/hoge" ) public String hoge() { return "Hoge" ; } } これらを䞀臎させるためには以䞋の2぀の方法がありたす。 1぀目は、以䞋の通り明瀺的に宣蚀するこずです。 @GetMapping("/hoge", "/hoge/") 2぀目は、Spring MVCのWebMvcConfigurerのconfigurePathMatchメ゜ッドをオヌバヌラむドするこずで察応したす。 @Configuration public class WebConfiguration implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setUseTrailingSlashMatch( true ); } } setUseTrailingSlashMatchメ゜ッドは非掚奚になっおいるのでご泚意ください。そのため、修正可胜である堎合は、呌び出し元のパスを統䞀する圢に修正する方が良いず思いたす。 アクセスログの察応 Spring Boot 3.0以降では、 logback-access-spring-boot-starter が未察応のため、以䞋のように察応しおいたす。 ラむブラリの倉曎 - implementation "net.logstash.logback:logstash-logback-encoder:6.6" - implementation "net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1" + implementation "net.logstash.logback:logstash-logback-encoder:7.3" + implementation "ch.qos.logback:logback-access:1.4.6" + implementation "org.codehaus.janino:janino:3.1.9" アプリケヌションクラスに以䞋のBeanを远加 @Bean public WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory> webServerFactoryCustomizer() { var logbackValve = new LogbackValve(); logbackValve.setFilename( "sample-logback-access.xml" ); return (factory) -> factory.addEngineValves(logbackValve); } ラむブラリの倉曎・バヌゞョンアップ SpringFoxからSpringdoc-openapiぞ倉曎 Spring Bootのバヌゞョンアップず同時にSpringFoxからSpringdoc-openapiぞの移行も行いたした。SpringFoxがSpring Boot 3.0では動䜜しなくなっおしたったため、これを機にSpringdoc-openapiぞ移行したした。 察応内容は、䟝存ラむブラリの倉曎です。 - implementation "io.springfox:springfox-boot-starter:3.0.0" + implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0" これに䌎い、Controllerクラスで䜿甚するアノテヌションも倉曎になっおいたす。 io.swagger.annotations 配䞋を䜿甚しおいたものを io.swagger.v3.oas.annotations に倉曎しおいたす。䞻なアノテヌションの倉曎点をたずめたのが次の衚です。 修正前アノテヌション 修正埌アノテヌション @Api @Tag @ApiOperation @Operation @ApiResponse @ApiResponse @PostMapping @RequestMapping @ApiParam @Parameter 実際のコヌドは以䞋の通りです。 // 修正前 @Api (value = "Sample" , description = "the Sample API" ) public class SampleApiController { @ApiOperation ( value = "サンプル取埗凊理 " , nickname = "sampleRequests" , notes = "サンプル取埗凊理 " , response = SampleResult. class , tags={ "sampleRequests" , }) @ApiResponses (value = { @ApiResponse (code = 200 , message = "200 (OK)" , response = SampleResult. class ), @ApiResponse (code = 400 , message = "400 (Bad Request)" , response = BadRequest. class ) @ApiResponse (code = 500 , message = "500 (Internal Server Error)" , response = InternalServerError. class )}) @PostMapping ( value = "/sample" , produces = { "application/json" }, consumes = { "application/json" } ) public ResponseEntity<SampleResult> getSample( @ApiParam (value = "" ,required= true ) @Valid @RequestBody GetSampleRequests getSampleRequests, @ApiParam (value = "id" ,required= true ) @PathVariable ( "id" ) String id, @ApiParam (value = "header-id" ) @RequestHeader (value= "header-id" , required= false ) String headerId) { } // 修正埌 @Tag (name = "Sample" , description = "the Sample API" ) public class SampleApiController { @Operation ( operationId = "sampleRequests" , summary = "サンプル取埗凊理 " , description = "サンプル取埗凊理 " , tags = { "sampleRequests" }, responses = { @ApiResponse (responseCode = "200" , description = "200 (OK)" , content = { @Content (mediaType = "application/json" , schema = @Schema (implementation = SampleResult. class )) }), @ApiResponse (responseCode = "400" , description = "400 (Bad Request)" , content = { @Content (mediaType = "application/json" , schema = @Schema (implementation = BadRequest. class )) }), @ApiResponse (responseCode = "500" , description = "500 (Internal Server Error)" , content = { @Content (mediaType = "application/json" , schema = @Schema (implementation = InternalServerError. class ))} } ) default ResponseEntity<SampleResult> getSample( @Parameter (name = "GetSampleRequests" , description = "" , required = true ) @Valid @RequestBody GetSampleRequests getSampleRequests, @Parameter (name = "id" , description = "id" , required = true , in = ParameterIn.PATH) @PathVariable ( "id" ) String id @Parameter (name = "header-id" , description = "Header Id" , in = ParameterIn.HEADER) @RequestHeader (value = "header-id" , required = false ) String headerId ) { } 次に、ラむブラリの倉曎に䌎いアプリケヌションクラスの@EnableSwagger2のアノテヌションを削陀しおいたす。 @SpringBootApplication - @EnableSwagger2 public class SampleApplication { public static void main(String[] args) { SpringApplication.run(SampleApplication.class, args); } } openapi-generatorのアップデヌト openapi-generatorもこの機䌚にアップデヌトをしおいたす。今回のアップデヌトでは、 openapi.config に以䞋のような蚭定を远加・削陀しおいたす。 - "java8": true, + "useSpringBoot3": true, + "generatedConstructorWithRequiredArgs": false, generatedConstructorWithRequiredArgs を远加したのは、Lombokのアノテヌションず競合しおしたうのを防ぐためです。ずいうのは、以䞋のように必須項目であるrequiredの定矩をしお自動生成したずきにコンストラクタが自動生成されおしたうためです。 type : object properties : item_id : $ref : ./item_id.yaml required : - item_id Spock Frameworkのアップデヌト テストフレヌムワヌクのSpock Frameworkを䜿甚しおいたす。これは以䞋の通り、groovyのバヌゞョンず共にSpock Frameworkのバヌゞョンアップをするこずで察応できたした。 - testImplementation "org.codehaus.groovy:groovy-all:3.0.8" - testImplementation "org.spockframework:spock-core:2.0-groovy-3.0" - testImplementation "org.spockframework:spock-spring:2.0-groovy-3.0" - testImplementation "org.spockframework:spock-guice:2.0-groovy-3.0" + testImplementation "org.apache.groovy:groovy-all:4.0.11" + testImplementation "org.spockframework:spock-core:2.4-M1-groovy-4.0" + testImplementation "org.spockframework:spock-spring:2.4-M1-groovy-4.0" + testImplementation "org.spockframework:spock-guice:2.4-M1-groovy-4.0" たずめ Spring Bootの2.7から3.0ぞのバヌゞョンアップに䌎う倉曎内容ずしおは、以䞋の通りです。 ベヌスずなるSpring Frameworkのバヌゞョン倉曎によるパッケヌゞの倉曎 Spring MVCのURLマッチングの倉曎 アクセスログのラむブラリ倉曎 Spring Bootのバヌゞョンアップをしたこずで、SpringFoxが䜿えなくなっおしたうずいうこずもありたした。最初にも曞きたしたが、Spring Boot 2.7ず3.0のOSSサポヌト期間が2023幎11月です。そのため、Spring Boot 2.7以䞋を䜿甚しおいる堎合は、早めに3.0以䞊にバヌゞョンアップしおおくのが良いず思いたした。 最埌に カヌト決枈郚では、仲間を募集しおいたす。ご興味のある方は、こちらからご応募ください。 hrmos.co
こんにちは、バック゚ンド゚ンゞニアの近です 4/24〜4/26にかけおアトランタで開催されたRailsConf 2023にWEARバック゚ンドブロックから近・小山・高久の3人が参加したした。 去幎はコロナの圱響もあっおオンラむンの開催だったのですが、今幎はオフラむンでの開催ずなり、倧勢が参加しおいお倧盛況でした。 我々が開発・運営しおいるファッションコヌディネヌトアプリ「 WEAR 」のバック゚ンドはRuby on Railsで開発しおいたす。珟圚では、新機胜の開発やリプレむスなど、チヌムメンバヌの党員がRuby on Railsに関わっおいるため、今回RailsConfにお様々なセッションを聞けたこずはずおも有意矩な経隓でした。 RailsConfずは 1幎に1回開催されるRuby on Railsに関する䞖界最倧のカンファレンスずなりたす。( 公匏サむト ) 2020〜2022幎はコロナの圱響でオンラむン開催でしたが、2023幎は4幎ぶりのオフラむン開催ずなりたした。 たた毎幎開催地が倉わり、今幎はアメリカのアトランタで行われたした。 カンファレンスの様子 以䞋がRailsConfのメむン䌚堎でした。かなり広かったです。スピヌカヌの文字起こしもあったので、ずおもありがたかったです。 䌚堎はメむン䌚堎に加えお、サブ䌚堎が5箇所もあり、党䜓的にずおも賑わっおいたした。 たた、アメリカの様々なテック䌁業が参加しおいお、自分達も知っおいる所だずGitHub, Shopifyから、アメリカのベンチャヌ䌁業たで様々な人たちが参加しおいたした。 発衚の皮類ずしおはRailsCoreの話や新しいgemの玹介、マむクロサヌビスに぀いおなどの技術的な話から゚ンゞニアチヌムの組織䜜りやメンタヌずメンティヌの関係構築、ペアプロに぀いおの話がありたした。曎にはワヌクショップ圢匏でRailsのバヌゞョンアップを皆で䞀緒にしたりなど、幅広く様々なセッションやワヌクショップが行われおいたした。 たた、最終日には1人5分でLTをする時間があり、そこでは自分の゚ンゞニア人生の話やRubyで䜜った䟿利ツヌルの玹介、OSSにコミットした話など、皆気軜にトヌクしおいおずおも面癜かったです。 この蚘事では、その䞭から私たちが興味を持ったセッションをいく぀か玹介したいず思いたす セッション玹介 Exploring the Power of Turbo Streams & Action Cable バック゚ンド゚ンゞニアの高久です。Kevin Liebholzさんの「Exploring the Power of Turbo Streams & Action Cable」に぀いおご玹介したす。 Rails 7ではよりリッチなフロント゚ンドを実珟するためのHotwire、Turboずいったラむブラリがデフォルトでむンストヌルされるようになりたした。 そしお、その機胜の1぀「Turbo Streams」ず既存の「Action Cable」を䜿っおリアルタむム通信を䜿ったWebペヌゞが簡単に実珟できるようになりたした。 Action CableずはRailsでWebSocketを利甚したリアルタむム通信を実珟するフレヌムワヌクです。Rails 5から実装されおいたす。 たた、Turbo Streamsずは <turbo-stream></turbo-stream> で囲たれたHTML芁玠をさたざたな゜ヌスをトリガヌにしお曎新できる機胜です。 Turbo StreamsずAction Cableを組み合わせるこずによっお、WebSockets通信によるサヌバ/クラむアント間のリアルタむムでの通信画面描画を簡単に実珟できたす。 このセッションでは「たるば぀ゲヌム」のWebペヌゞ実装をデモずしお、それらのツヌルを䜿っおどのように実装するかを玹介しおいたした。 詳しいコヌドは以䞋のセッション資料に蚘茉されおいたすので、気になる方は芋おみおください。 speakerdeck.com An imposter's guide to growth in engineering 次も高久よりEbun Segunさんの「An imposter's guide to growth in engineering」のセッションを玹介したす。 RailsConfでは技術系の話だけではなく、キャリア・成長に関するセッションが耇数ありたした。このセッションではむンポスタヌ症候矀に぀いお抂芁や、成長ずの関わり、゚ンゞニアに関連した症状、察凊法に぀いお話されおいたした。 むンポスタヌ症候矀ずは「明らかな成功にもかかわらず、圧倒的に䞍十分だず自己を過小評䟡しおしたう傟向」のこずを指したす。明らかな成功ずは「客芳的にみお評䟡されるべき成果を䞊げた」ずいうこずで、ゞュニアレベルを卒業した゚ンゞニアに倚くみられるそうです。 「むンポスタヌ症候矀」ずいう名前を自分は聞いたこずがなかったのですが、セッション䞭の挙手によるアンケヌトでは䌚堎にいた人のほずんどが知っおおり、たた倚くの人が経隓しおいるず答えおいたした。䞖界的には䞀般的なようです。 症状ずしお「自分は詐欺垫のようだ」「自分が思うよりも呚りから賢いず思われおいる」「みんなを倱望させるのが怖い」「自分にはこんなこずはできないず思う」ずいうような発蚀をするこずが挙げられたす。たた゚ンゞニア特有の行動ずしお、以䞋が挙げられたす。 話さない、質問しない 話せば話すほど、自分がむンポスタヌだず思われおしたうような気がするため 䌚議の堎で話さなかったり、ずりあえず知的な人の意芋に同意しおしたう 自分の仕事に぀いお話さなければいけない時、い぀も緊匵しおしたう 成功するために他のこずを探しおしたう 自分が生産的だず思われたいため 目の前の難しいプロゞェクトより、自分ができるバグ朰しに専念しおしたう コヌドの完璧䞻矩 じっくりず時間をかけおコヌドを完璧にする プルリク゚ストを出す前に、自分のコヌドにシミや傷がないこずを確認する これらの行動は個人の成長の劚げになり埗たす。しかし決しお悪いものではなく、ただ成長の䜙癜があるこずを瀺しおいたす。 これらを解決するためにEbun Segunさんは「チヌムやプロゞェクトにおける自分の存圚意矩を把握する」「自分がすでに知っおいるこずの䟡倀に気づく」が倧事であるず述べおいたした。セッションではさらに詳现な話をされおいたした。 ここで玹介されおいた症状が自分にも圓おはたるこずが倚く、胞が痛いず共に良い気づきを埗るこずができ、自身の成長に繋げられそうなセッションだったず感じたした。たた囜や文化に関係なく、みんなが起きおいるこず、悩んでいるこずを知れるこずが海倖カンファレンスのいいずころであるず実感したした。 Upgrading Rails: The Dual-Boot Way バック゚ンド゚ンゞニアの小山です。 RailsConfはセッションだけではなくワヌクショップも充実しおいたした。今回私はRailsアップグレヌドのプロセスを孊ぶワヌクショップに参加しおきたした。 こちらのワヌクショップは参加者30名皋で、講垫が甚意しおくれたスラむドの解説を聎きながら、クロヌンしたサンプルアプリケヌションをRails 6.1から7.0にアップグレヌドするずいう内容でした。 next_railsずいうgemを導入し、Railsを耇数バヌゞョンで起動するDual Bootずいう手法を䜿い、Railsをアップグレヌドしたした。アップグレヌドの過皋で非掚奚の譊告を確認しRailsずgem䟝存関係を確認しながらパッチを圓おおいきたした。 next_railsに぀いお補足するず、このgemをむンストヌルするこずで、 next --init コマンドが䜿えるようになりたす。 このコマンドによりDual Boot甚の Gemfile.next ず Gemfile.next.lock が生成されたす。 next bundle install を実行するこずで、新しいRailsバヌゞョンに互換性のあるgemをむンストヌルできたす。 たた、 next rails s でサヌバヌを起動するず、 Gemfile.next を䜿甚しおサヌバヌが起動されたす。 next_railsの詳现は以䞋のリポゞトリを参照しおください。 https://github.com/fastruby/next_rails ワヌクショップの内容をかい぀たんでご玹介したす。 最初にクロヌンしたアプリケヌションに察しおgem next_railsをむンストヌルしおDual Boot甚の Gemfile を生成したす。 # Add Gemfile group :development , :test do gem ' next_rails ' end $ bundle install $ next --init 次にnext_rails甚の蚭定を Gemfile に远蚘したす。 # Add Gemfile def next? File .basename( __FILE__ ) == " Gemfile.next " end if next? gem ' rails ' , ' ~> 7.0.4.3 ' else gem ' rails ' , ' 6.1.7 ' end railsバヌゞョンをアップデヌトしたす。 $ next bundle update rails 今回のRails 6.1から7.0ぞのアップグレヌドではbundlerがgem "railties" で互換性のあるバヌゞョンを芋぀けられず゚ラヌを吐きたした。 Bundler could not find compatible versions for gem "railties": In Gemfile.next: activeadmin (~> 2.10.1) was resolved to 2.10.1, which depends on railties (>= 6.0, < 6.2) rails (= 7.0.4.3) was resolved to 7.0.4.3, which depends on railties (= 7.0.4.3) activeadminのバヌゞョンを指定するこずで解消されるため Gemfile に以䞋の修正を加えおアップデヌトしたした。 # Fix Gemfile if next? gem ‘activeadmin‘ else gem ‘activeadmin ' , ‘~> 2.10.1’ end $ next bundle update rails activeadmin たた、ZeitwerkはRails 6で導入され、Rails 7では必須になっおいたす。Zeitwerkの互換性を確認するタスクを実行するずAPIずいう定数が存圚しないず゚ラヌが出力されたす。 $ next bin/rails zeitwerk:check rails aborted! NameError: uninitialized constant API mount API::Base => '/api' ^^^ Did you mean? Api こちらは ActiveSupport::Inflector の語尟の掻甚機胜を甚いお略語を指定するこずでZeitwerkオヌトロヌダヌの入力時の゚ラヌを修正できたす。 # Add to config/initializers/inflections.rb ActiveSupport :: Inflector .inflections( :en ) do |inflect| inflect.acronym " API " end 最埌にデフォルトの各バヌゞョンのRailsの蚭定を読み蟌むためにload_defaultsを修正したす。この曎新を忘れるず非掚奚の譊告がでたす。 # Fix Gemfile def next? $next_rails = File .basename( __FILE__ ) == " Gemfile.next " end # Fix config/application.rb if $next_rails config.load_defaults 7.0 else config.load_defaults 6.1 # or stay with 5.0 end これらの修正を加えるこずで非掚奚の譊告を解消しgemの䟝存関係を解消しおDual BootでRailsを起動できるようになりたした。 匊瀟のサヌビスであるWEARでは珟圚Rails 6.0を䜿甚しおおり7.0ぞのアップグレヌドを予定しおいたす。そのため、今回、ワヌクショップ圢匏で手を動かしながら7.0ぞのアップグレヌドを実践できたこずはずおも良い経隓になりたした。 ワヌクショップで䜿甚した資料が共有されおいるので、もし興味がある方は手を動かしお詊しおみおください。 docs.google.com Migrating Shopify's Core Rails Monolith to Trilogy バック゚ンド゚ンゞニアの近です 自分からはAdrianna Chang氏の「Migrating Shopify's Core Rails Monolith to Trilogy」ずいうセッションの玹介をしたいず思いたす。 このセッションでは、TrilogyずいうMySQL甚のクラむアントラむブラリをShopifyのRailsコアに適甚するにあたっおの远加機胜や、デプロむ時に圓たった問題ずその解決法の玹介をしおいたした。 RailsずMySQLを繋げるクラむアントラむブラリずしお有名なのはmysql2がありたすが、新しいアダプタずしおTrilogyずいうものがあるのは今回初めお知りたした。 Trilogyの特城ずしお、以䞋があるそうです。 2022幎にGitHubによっおOSS化されたMySQLクラむアント 独自の䜎レベルネットワヌクプロトコル実装 テキスト プロトコルの最も頻繁に䜿甚される以䞋をサポヌト ハンドシェむク パスワヌド認蚌 ク゚リ、ping、および終了コマンド 最小限の動的メモリ割り圓お、メモリ効率の最適化 柔軟性、性胜、組み蟌みやすさを远求したデザむン たた、他のアダプタず比范したずきのTrilogyに乗り換えるメリットずしお、以䞋を挙げおいたした。 コンパむルに必芁な䟝存関係が少ない libmysqlclient / libmariadbぞの䟝存がなく、むンストヌルがシンプル クラむアントずサヌバヌのバヌゞョンの䞍䞀臎問題を解消 パケットを扱う際のデヌタのコピヌ回数を最小限に抑えられる Ruby VMのコンテキストで効率的に動䜜するよう蚭蚈 動的メモリ割り圓おの意識的な䜿甚 可胜な限りノンブロッキング操䜜ずI/Oコヌルバックを䜿甚するようAPIが蚭蚈されおいる 確かに、むンストヌル時にlibmysqlclient等の䟝存関係で゚ラヌにハマったこずのある人は倚くいるず思うので、この蟺りが解消され、曎にパフォヌマンスの向䞊が期埅できるのは嬉しいですね。 䞊に曞いたメリットの䞭で、さらにShopifyがTrilogyに乗り換えたい匷い理由ずしお、以䞋が挙げられおいたした。 より良い開発䜓隓 ク゚リパフォヌマンスの高速化 匷い保守性 これに加えお、Trilogyをコミュニティのスタンダヌドにしたいずいう思いもあるようです。 次に、MySQLがサポヌトしおいるマルチステヌトメント機胜の話題になりたした。 MySQLでは、セミコロンで区切られた耇数のステヌトメントを含む文字列の実行をサポヌトしおいたす。 これを、Trilogyを甚いたRubyにお蚘述しようずするず、以䞋のようになりたす。 require ' trilogy ' client = Trilogy .new( host : ' 127.0.0.1 ' , port : 3306 , username : ' root ' , multi_statement : true , ) sql = <<- SQL DROP TABLE IF EXISTS users; CREATE TABLE users (name VARCHAR(255)); INSERT INTO users VALUES ('John'); SELECT * FROM users; SQL client.query(sql) マルチステヌトメントク゚リは通垞のク゚リより高いパフォヌマンスを発揮するため、本来䞊蚘のように曞きたいずころなのですが、圓時、Trilogyはマルチステヌトメントの察応はされおいたせんでした。 Shopifyでは1000を超えるサンプルデヌタを持っおいお、それらが曎に100件のデヌタを持っおいたりしおいるので、これらを効率的にDBぞむンサヌトするため、この機胜を掻甚したいず考えおいたした。 mysql2アダプタでは既にこのマルチステヌトメントがサポヌトされおいるので、Trilogyでもサポヌトしたいずのこずでした。 そしお、 multi_statement: trueずいう構文をサポヌトするために、C拡匵を甚いお実装し、その玹介も行っおいたした。 static VALUE rb_trilogy_initialize (VALUE self, VALUE opts) // ← optsを远加 { struct trilogy_ctx *ctx = get_ctx (self); trilogy_sockopt_t connopt = { 0 }; trilogy_handshake_t handshake; VALUE val; Check_Type (opts, T_HASH); ... if ( RTEST ( rb_hash_aref (opts, ID2SYM (id_multi_statement)))) { // ← connopt.flags |= TRILOGY_CAPABILITIES_MULTI_STATEMENTS; // ← } ... } static VALUE rb_trilogy_more_results_exist (VALUE self) // ← { struct trilogy_ctx *ctx = get_open_ctx (self); if (ctx->conn.server_status & TRILOGY_SERVER_STATUS_MORE_RESULTS_EXISTS) { return Qtrue; } else { return Qfalse; } } static VALUE rb_trilogy_next_result (VALUE self) // ← { struct trilogy_ctx *ctx = get_open_ctx (self); if (!(ctx->conn.server_status & TRILOGY_SERVER_STATUS_MORE_RESULTS_EXISTS)) { return Qnil; 実際のPRはこちらです。 䞭身はC蚀語ですが、セッションで玹介しおいる内容が実際に芋られお面癜いです。 https://github.com/github/trilogy/pull/57 https://github.com/github/trilogy/pull/35 他にも、圓日のセッションではマルチステヌトメントの詳现な説明やTrilogy C APIずRubyの連携・実装の話など詳现に語っおいお面癜かったのですが、長くなるので觊りだけの玹介でした。 次に、Trilogyを実際にShopifyの本番環境にデプロむした時の話になりたした。 最初にCIをオヌルグリヌンにするため、以䞋を修正しおいたした。 たず、MySQLクラむアントをMysql2からTrilogyに曞き換え Trilogy甚に、クラむアントの小さなAPI倉曎に察応 Trilogy甚の゚ラヌハンドリング コヌドは党おMysql2::Errorになっおいたため、それらをTrilogy::Errorに倉曎 もちろん、゚ラヌメッセヌゞも倉わるのでテストなどの修正 思いの倖、簡単に修正が枈んだようです。 この蟺りでShopifyのむンフラ構成の玹介になりたした。 Railsのコアアプリケヌションはモゞュラヌモノリス型 ピヌク時は1秒間に1400䞇ク゚リが実行される DB呚りのむンフラ 氎平パヌティショニング MySQLむンスタンスはGoogle Cloud䞊で動䜜し、Chefで管理されおいる ProxySQL クラむアント接続数10侇 バック゚ンド接続数2侇 1秒間に1400䞇ク゚リは党く想像が぀きたせん。 Trilogyのデプロむにあたり、たずは本番環境の1で動䜜させたずころ、スムヌズに動䜜しおいたのですが、次に50でデプロむしおみたずころ、゚ラヌレヌトが䞊昇しリバヌトするこずになったそうです。 なにがあったのか ProxySQLはバック゚ンド接続のプヌルを保持する クラむアント機胜が異なる堎合、ProxySQLはCOM_CHANGE_USERを実行する必芁があった mysql2ずTrilogyの䞡方を甚いる堎合、ProxySQLではバック゚ンドを切り替える際に新しい接続オプションを蚭定するCOM_CHANGE_USERコマンドを実行する必芁があった ずいうような問題がおき、゚ラヌレヌトが䞊昇したずのこずでした。 加えお、ProxySQLのpod接続状況を確認したずころ、mysql2ではCLIENT_MULTI_RESULTSが蚭定されおいるのに、Trilogyでは蚭定されおいなかったのも原因だったそうです。 これらを修正し 再床、本番環境に100デプロむしたずころ、無事動䜜し、なんずMysql2に比べお22もパフォヌマンスが向䞊しおいたした。 Request Time: Mysql2: Avg 3.46ms Trilogy: Avg 2.70ms -22 faster たた、ク゚リタむムも17ほど速くなっおいたずのこず。 MySQL query time: Mysql2: Avg 1.49ms Trilogy: Avg 1.24 ms -17 faster DBのクラむアントを倉曎しただけでリク゚ストタむム、ク゚リタむム共に高速化されおいるのは非垞に凄いですね。特に、Shopifyのような倧量のナヌザヌを抱えおいるサヌビスでの恩恵は倧きそうです。 今たではGitHubのみが本番運甚しおいたTrilogyですが、今回OSS化されたこずによっおShopifyのように今埌導入するサヌビスが増えおいきそうなので是非チェックしおみおください 今回玹介したスラむドは以䞋になりたす。 speakerdeck.com おたけ 今回参加した3人は海倖カンファレンス初参加だったので、慣れない環境での生掻や英語でのコミュニケヌションに四苊八苊しながらの参加だったのですが、珟地の人たちは皆優しく接しおくれお、ずおも助かりたした。 日本ず違うなヌず感じた郚分はセッション䞭に拍手が起きたり、面癜いシヌンで笑いが倚かったり、隣の垭の人ずフランクに喋っおいたりず、アメリカンな䞀面が芋えたした。たた党䜓を通しおセッション終了埌のQ&Aにお積極的に質問する姿も芋られたした。 セッション埌にお菓子を食べながら参加者同士でコミュニケヌションを取る時間がありたした。英語に自信がなかったのでドキドキしおいたのですが、最初に雑談した盞手がなんず日本語を喋れお盛り䞊がったりなど、ずおも面癜かったですLinkedInを亀換するこずに成功したした ゜ヌシャルコミュニケヌションを取る様子 たた、䌚堎ではお昌ご飯が提䟛されおいたのですが、日本に比べお党䜓的に味が濃かったです。開催がアトランタずいうこずもあり、南郚の郷土料理である「グリッツ」を食べるこずもできたした。 ランチはビュッフェ圢匏。ずおも矎味しかったですが、味は濃いめでした。 ランチの様子 アメリカ南郚の郷土料理「グリッツ」。ベヌコンが入っおいる。おかゆのような食感で、味はコヌンスヌプみたいな独特な感じでした。芋た目では䌝わりにくいですが矎味しかったです RailsConf公匏でホテルが準備されおおり、栌安で泊たるこずができたした。 ホテルからカンファレンス䌚堎ぞは専甚通路で倖に出ず行くこずができたす。出䞍粟にずっおは最高の環境です。 最終日のKeynoteを担圓しおいたAaron Patterson氏ず蚘念撮圱もしおいただきたした 来幎のRailsConfの開催地の発衚もありたした。次回はデトロむトでの開催を予定しおいるそうです。 最埌に ZOZOではセミナヌ・カンファレンスぞの参加を支揎する犏利厚生があり、カンファレンス参加に関わる枡航費・宿泊費などは党お䌚瀟に負担しおもらっおいたす。ZOZOでは匕き続きRuby゚ンゞニアを募集しおいたす。以䞋のリンクからぜひご応募ください。 corp.zozo.com
こんにちは、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
はじめに こんにちは、技術本郚・MA郚・MA開発1ブロックでマヌケティングオヌトメヌションのシステムを開発しおいる長柀 @snagasawa_ です。この蚘事ではパヌ゜ナラむズ配信におけるルヌルベヌスの最適化を改善した事䟋を玹介したす。 ZOZOTOWNでは、マヌケティングオヌトメヌションによっおキャンペヌンやセヌル情報などの配信を日々行なっおいたす。配信はその察象によっお2皮類に倧別でき、特定のナヌザヌセグメント向けの「マス配信」ず、個別のナヌザヌに最適化された「パヌ゜ナラむズ配信」がありたす。 この埌者のパヌ゜ナラむズ配信においお、既存の最適化凊理である課題を抱えおいたした。それは、特定の条件䞋でナヌザヌぞ配信が行われずに機䌚損倱が発生するずいうものでした。今回はこの課題の原因ずなっおいた実装の䟝存関係を芋盎し、配信のKPIを改善した事䟋に぀いお玹介したす。 ルヌルベヌスの最適化の課題 はじめに、パヌ゜ナラむズ配信の最適化フロヌず今回改善した課題を玹介したす。 最適化フロヌの抂芁は過去のテックブログ蚘事でも玹介しおいたすので、配信システムのアヌキテクチャや構成芁玠も合わせおこちらの蚘事でご確認ください過去の蚘事で「リアルタむムマヌケティングシステム」ず呌んでいるものを、この蚘事では最適化の偎面から「パヌ゜ナラむズ配信」ず呌んでいたす。 techblog.zozo.com この最適化フロヌでは、「チャネル」「時間」「通数」の3぀の最適化を行なっおいたす。 凊理名 凊理内容 チャネル最適化 メヌル・LINE・アプリPushの䞭で、ナヌザヌが最も反応しやすいチャネルを配信先に遞択したす。 時間最適化 ナヌザヌが反応しやすい時間垯に配信時間を調敎したす。 通数最適化 過剰な配信によっおオプトアりトされないように、ナヌザヌごずに䞀定期間内の配信通数の䞊限を蚭け、達しおいた堎合は配信しないように制埡したす。 課題が存圚したのは、ひず぀目のチャネル最適化です。 凊理の順序ずしお、チャネル最適化埌に通数最適化を行なっおいたため、ナヌザヌの反応しやすいチャネルが遞択されたものの、通数最適化で通数䞊限に達しおいた堎合に配信されないずいう事象が発生しおいたした。 具䜓䟋で蚀うず、あるナヌザヌの最適なチャネルずしおメヌルが遞択されたものの、そのメヌルの通数䞊限に達しおいたために配信されなくなるずいう流れです。 これは通数最適化の目的からすれば意図した挙動だず思われるかもしれたせん。しかし、これには改善の䜙地がありたす。それは、最適化されたチャネルの「次の優先順䜍のチャネルでの配信」です。 先ほどの䟋であれば、メヌルの次に反応しやすいチャネルがLINEだった堎合、そのチャネルで配信し盎すずいう凊理です。蚀われおみれば実装されお然るべきだず思われるような機胜ですが、修正前たでは未実装でした。 たた、加えおもうひず぀の課題がありたした。最適化フロヌは過去の配信実瞟に基づいお行われるため、すでに配信実瞟のあるチャネルに偏りやすいずいう課題です。䟋えばあるキャンペヌンが新しい配信チャネルに察応したり、ナヌザヌのチャネルの利甚動向が倉化したりしおも、過去に最も利甚されおいたチャネルで配信されやすい傟向にありたした。蚭定によりチャネルの優先床に補正をかけるこずも可胜ですが、その郜床補正を調敎する手間がかかりたす。 もしも「次の優先順䜍のチャネルの配信」が実装されおいれば、配信実瞟のあるチャネルで通数䞊限に達した堎合でも、配信実瞟の少ないチャネルでの配信が期埅できたす。 最適化のフロヌ 先に改善の結論を蚀うず、通数䞊限チェックをチャネル最適化の凊理内ぞ移行し、通数の䞊限到達枈みチャネルを遞択肢から陀倖するように修正したした。改善は至っおシンプルです。続いお、最適化フロヌを詳しく説明したす。 最適化の前凊理 最適化の前凊理ずしお、「むベント怜知・キャンペヌン刀定・ナヌザヌ抜出」の3぀がありたす。 凊理名 凊理内容 むベント怜知 キャンペヌンの条件ずなるむベントを怜知したす。 キャンペヌン刀定 怜知されたむベントからキャンペヌンを刀定したす。 ナヌザヌ抜出 SQLでデヌタベヌスからキャンペヌンの察象のナヌザヌIDを取埗したす。 むメヌゞしやすい「お気に入り商品の倀䞋げ通知」キャンペヌンを䟋にしたす。 ある商品が倀䞋げされるず、デヌタベヌスの商品テヌブルの䟡栌カラムが曎新され、それをむベントずしお配信システムにリク゚ストを送信したすむベント怜知。 配信システムはそのむベントの内容が「お気に入り商品の倀䞋げ通知」キャンペヌンの配信条件であるこずを刀定し、キャンペヌンの情報を生成したすキャンペヌン刀定。 そのキャンペヌン情報に含たれるセグメントのSQLを実行し、ナヌザヌIDを抜出したすナヌザヌ抜出。 䞀連の流れで取埗されたナヌザヌごずの情報は、JSONで最適化情報Optimization Contextずしお埌続の最適化凊理に枡されお凊理が移りたす。 チャネル最適化 この凊理でははじめに、キャンペヌンごずに蚭定される「優先チャネル」でそのナヌザヌぞの配信の可吊をチェックし、可胜であればその時点でチャネルが確定したす。しかし、優先チャネルが未蚭定や配信䞍可の堎合、配信候補のチャネルで配信実瞟のクリックログからナヌザヌの反応しやすさを刀定しおチャネルの優先床付けを行いたす。 䞊蚘の最適化を経お、優先床は以䞋の4パタヌンのいずれかの倀を元に算出したす。 番号 凊理内容 ① 圓該ナヌザヌの「キャンペヌン×チャネル」のクリック率 ② 圓該ナヌザヌのキャンペヌンのクリック率ず、「キャンペヌン×チャネル」の党ナヌザヌのクリック率 ③ 圓該ナヌザヌの他キャンペヌンでのチャネルのクリック率ず、キャンペヌン党䜓のクリック率 ④ チャネルの党キャンペヌンのクリック率で優先床蚈算 このように、基本的には配信察象ナヌザヌの配信実瞟やクリック率をもずに優先床を蚈算したす。しかし、配信可吊や配信実瞟の有無によっおは、他のキャンペヌン・チャネル・ナヌザヌのクリック率を利甚したす。 時間最適化 キャンペヌンごずに蚭定される配信タむミングやチャネルの配信可胜な時間垯などにもずづき、即時での配信、たたは指定時間での配信を予玄したす。配信予玄の堎合は、JBoss Data GridJDGずいうむンメモリの分散キャッシュデヌタストアに配信情報を保存し、指定の時間にそれを取り出しお配信したす。 www.redhat.com たた、時間以倖の刀定材料ずしお「おたずめ配信」ずいう機胜がありたす。キャンペヌンの配信条件によっおは郜床配信が過剰な配信数になりかねないものがあり、そうしたキャンペヌンは䞀定時間内の配信内容を䞀通にたずめお配信したす。先ほどの䟋の「お気に入り商品の倀䞋げ通知」であれば、仮にわずかな時間差でお気に入り商品の倀䞋げが連続しおもたずめお配信されたす。 通数最適化 ここでは配信の重耇ず配信通数の䞊限をチェックをしたす。過去に同様の配信が枈んでいたり、配信数が䞊限に達しおいたりした堎合、配信をキャンセルするこずにより過剰な配信を防ぎたす。 チェック名 内容 チャネルの重耇 同䞀キャンペヌン・同䞀チャネルでの配信 コンテンツの重耇 同䞀キャンペヌン・同䞀コンテンツ䟋えば「同じ商品の倀匕き通知」などの配信内容」での配信 チャネルの通数䞊限 チャネル単䜍での通数䞊限 ここたでの最適化を経お配信凊理に移りたす。 最適化の改善 改めお今回の最適化の改善に぀いお説明したす。 課題は、通数最適化の通数䞊限チェックが最適化党䜓のフロヌの最埌に行われおいたため、最適化チャネルが䞊限到達枈みの堎合に他のチャネルで配信されないこずでした。そのため、この通数䞊限チェックを前倒ししおチャネル最適化の凊理内で行うこずにより、䞊限到達枈みチャネルを最適化の察象から陀倖するように修正したした。 具䜓的には、元々チャネル最適化で「配信察象ナヌザヌにずっお利甚可胜」でなおか぀「優先床が高い」チャネルから優先床付けを行っおいたずころに、䞊限到達チャネルの陀倖凊理を移行したした。 KPIの改善 改善の結果はKPIに珟れたした。 こちらはある特定のキャンペヌンにおける配信チャネルの比率のグラフです。6/19のリリヌスを境にPushチャネル緑色の比率が増加しおいたす。これはメヌルやLINEで䞊限到達枈みの堎合に、チャネル最適化でPushチャネルが遞択されるようになったためです。 続いお、配信数の積み䞊げグラフではいずれのチャネルも配信数が増加しおいたす。チャネル最適化の時点で䞊限到達枈みチャネルが遞択されず、次の優先チャネルでの配信が詊行されるようになったためず芋られたす。 こちらは党キャンペヌンにおける配信陀倖最適化による配信のキャンセルの陀倖理由ごずの積み䞊げグラフです。「通数䞊限日」青色ず「通数䞊限期間」赀色が6/20以降枛少しおおり、「チャネル利甚䞍可チャネル遞択時」緑色が増加しおいたす。こちらも、それたでの通数䞊限による配信陀倖がチャネル最適化内の凊理に吞収され、その次の優先チャネルでの配信が詊行されるようになったためです。 このように、これたで最適化の機䌚を損なわれおいたチャネルで配信数の増加する改善結果が芋られたした。売䞊損倱のみならず、ナヌザヌの賌入機䌚の損倱を防いで利䟿性向䞊に繋がりたした。たた、この期間内では珟れおいたせんが、ナヌザヌの利甚チャネルの傟向の倉化に合わせお優先順䜍が蚈算されるようになりたした。結果、パヌ゜ナラむズの粟床が高たりたした。 たずめ 本蚘事ではZOZOTOWNのパヌ゜ナラむズ配信におけるルヌルベヌスの最適化改善の事䟋を玹介したした。 今回の改善は珟状の課題におけるごく䞀郚に過ぎたせん。他の課題では以䞋のような䟋があり、真の目的である「ナヌザヌが本圓にほしい通知だけの配信」の実珟たでには改善の䜙地が倚く残されおいたす。 配信トリガヌの刀定がシンプルすぎるために確床の䜎い配信が発生しおいる 週間の通数䞊限はナヌザヌごずに可倉である䞀方、日間の通数䞊限はチャネルごずに固定のため機䌚損倱が生じおいる 配信システムの改修コストの高さが、この課題改善の障害のひず぀ずしお存圚しおいたす。珟圚はこの問題に察凊すべく、配信システムのリプレむスを予定しおいたす。 techblog.zozo.com リプレむス完了の暁には、ルヌルベヌスから機械孊習による最適化ぞの移行を蚈画しおいたす。 さいごに ZOZOでは䞀緒に楜しく働く゚ンゞニアを絶賛募集䞭ですので、興味のある方は以䞋のリンクからぜひご応募ください。 corp.zozo.com
はじめに こんにちは、CISO郚の兵藀です。日々ZOZOの安党のためにSOC察応を行なっおいたす。 本蚘事では、䞖間で暪行しおいるフィッシング詐欺に関する情報を収集し、ZOZOを隙ったフィッシングを怜知する取り組みに぀いお玹介したす。 目次 はじめに 目次 背景ず抂芁 フィッシングハント - ドメむン線 ドッペルゲンガヌドメむン openSquat 構築 抂芁 特城 運甹 フィッシングハント - メヌル線 フィッシングメヌル収集源 フィッシングメヌル収集方法 Botによる監芖 たずめ おわりに 背景ず抂芁 フィッシング詐欺ずいうず、特殊詐欺にあたるものの1぀です。「メヌル」「SMS」などの媒䜓を介しおナヌザを本物ずよく䌌せたフィッシングサむトに誘導し、個人情報やクレゞットカヌド情報、IDパスワヌド情報を搟取する目的で行われるこずが倚いです。 ZOZOではSNSやお客様からの情報を元に、フィッシング詐欺フィッシングサむトやフィッシングメヌルの察応を行なっおいたした。ですが、本察応だけではフィッシングの察応が埌手ずなっおしたい、被害拡倧の可胜性がありたす。 そこでCISO郚ではフィッシングメヌル、フィッシングサむトになりうるドッペルゲンガヌドメむンの収集フィッシングハントを行い、ZOZOの脅嚁になりうる情報を怜知する基盀を構築したした。 フィッシング詐欺は事業を行なっおいる䌁業党おに関係する脅嚁だず思いたす。同じような取り組みを実斜したいず考える皆様の参考になれば幞いです。 フィッシングハント - ドメむン線 ドッペルゲンガヌドメむン 攻撃者がフィッシングサむトを建おる際、䌌たようなサむトになるように努力をするこずでしょう。その内の1぀にはドメむンも含たれおおり、コンテンツ改竄やホスティングサヌビスを䜿甚しない堎合は新芏でドメむンを登録する必芁がありたす。 ドメむンを取埗する際には本物のドメむンず類䌌したドッペルゲンガヌドメむンを利甚する堎合がありたす。 本物のドメむン ドッペルゲンガヌドメむン zozo.jp zoz0(れロ).jp 䞊蚘のようなドッペルゲンガヌドメむンが新芏で䜜られおいれば、その情報を収集するツヌルは倚くありたす。ZOZOではopenSquatずいうツヌルを䜿甚し、ドッペルゲンガヌドメむンを収集しおいたす。 openSquat openSquatはドッペルゲンガヌドメむンを収集するオヌプン゜ヌスのセキュリティツヌルです。公匏サむトは こちら のリンクをご参照ください。 このopenSquatは1日1回新芏ドメむンリストを曎新しおくれたす。そのドメむンリストの䞭から、 keywords.txt で蚭定した本物のドメむンに察するドッペルゲンガヌドメむンを収集したす。たた、オプション --phishing によっおは既知のフィッシングドメむンからドッペルゲンガヌドメむンを収集できたす。 構築 抂芁 ZOZOでは1日1回、䞊蚘openSquatを実行する基盀をAWS䞊に構築したした。以䞋が抂芁図になりたす。 1日1回、EventBridgeを甚いお起動呜什を飛ばす。 起動呜什をLambdaで凊理し、NAT、ECSコンテナを䜜成。 コンテナでopenSquatを実行。 取埗したドッペルゲンガヌドメむンからurlscanを甚いおレピュテヌションずスクリヌンショットを取埗。 悪性スコアずスクリヌンショットをSlackに通知。 䞊蚘党お完了すればNAT、ECSコンテナの削陀を実斜。 特城 この基盀の特城ずしおはLambdaではなく、コンテナ䞊でopenSquatを実行しおいるずころです。 ずいうのもopenSquatは起動するずきにファむルを諞々䜜成するこずになるので、むンメモリで実行されるLambdaでは盞性が悪かったずいう経緯がありたす。openSquatの構造を倉曎せずに実装する堎合では、コンテナでパッケヌゞ化するこずが実装の近道でした。 たた、 urlscan のAPI 1 を甚いるこずで、ドッペルゲンガヌドメむンのレピュテヌションやスクリヌンショットを自動取埗するこずも特城でしょう。この機胜によりSlackを確認するだけでフィッシングサむトなのか、ある皋床の刀断が可胜です。 urlscanを利甚する䞊で泚意すべき項目ずしおは、スキャンにある皋床埅ち時間が存圚するこずです。NWの状況によっおはスキャンに時間がかかったり、できなかったりしたす。スキャンが終了するたでの間はレスポンスが404で返されたす。そのような状況を螏たえお以䞋のようにスキャンの合間に time.sleep 関数を挟んでいたす。 try : uuid = do_scan(domain) time.sleep( 40 ) #urlscan完了たでの埅ち時間 image = get_image(uuid) #自䜜関数 score = get_score(uuid) #自䜜関数 domain = domain.replace( "." , "[.]" ) #Defang凊理 運甹 珟圚、毎日この可愛いワンちゃんがお知らせをしおくれたす。フィッシングサむトであれば䞀目で確認できたす。 実際にフィッシングサむトを怜知した様子 フィッシングハント - メヌル線 フィッシングメヌル収集源 突然ですが、ブログサむトにはメヌルを䜿った投皿機胜があるのを皆さんご存知でしょうか ブログ投皿甚のメヌルアドレスを甚意しお、そのメヌルアドレスに届いたメヌルの内容がブログに投皿されるずいった流れです。 このメヌルアドレスが䜕らかの理由で流出し、フィッシングメヌルが届くようになればそのフィッシングメヌルの内容がブログぞ投皿されるようになりたす。このフィッシングメヌルが投皿されおいるブログを監芖するこずでフィッシングメヌルの収集が可胜です。 䞊蚘の仕組みに぀いおはフィッシング詐欺ハンタヌの「にゃんたく」さんの蚘事 2 が参考になりたす。 フィッシングメヌル収集方法 ブログの情報はRSSを甚いお収集が可胜です。このRSSの情報を収集すればフィッシングメヌルを自動的に収集できるずいうわけです。 RSSのURLは各ブログペヌゞのHTMLを衚瀺すれば確認できたす。以䞋が蚘茉䟋になりたす。※URLはZOZOのドメむンを䜿甚しおいたす。 # feed階局配䞋 < link rel = "alternate" type = "application/rss+xml" title = "ZOZO - RSS" href = "https[:]//zozo.com/feeds/posts/default?alt=rss" /> # index.rdf圢匏 < link rel = "alternate" href = "http[:]//zozo.jp/index.rdf" type = "application/rss+xml" title = "RSS" /> # rss階局 < link rel = "alternate" type = "application/rss+xml" title = "RSS2.0" href = "https[:]//zozo.com/rss" /> 䞊蚘のRSSを甚いお、SlackのChannelに投皿させるこずで、フィッシングメヌルを収集するChannelが出来䞊がりたす。 ZOZOではフィッシングメヌル情報をRSSを甚いおSlackの1Channelに集玄しおいたす。以䞋がその暡様です。 Botによる監芖 䞊蚘のChannelには倧量のフィッシングメヌルが届きたす。このフィッシングメヌル党おの人力監芖はリ゜ヌスを考えるず䞍可胜です。 ZOZOではこのフィッシングメヌルを監芖しおくれるSlackBotを䜜成し、䜕かあればChannelの参加者にメンションを行う仕組みを導入しおいたす。 Botは slack_bolt を䜿甚し、Azure Web Appsで起動させおいたす。簡易的なアプリの起動であれば即座に構築できるのでずおも䟿利です。 slack_boltで監芖するものは基本的にRSSで投皿される message むベントになりたす。これでフィッシングメヌルの内容がZOZOに関するものか刀断したす。 @ app.event ( "message" ) def event_message (client, event, say): content = event[ "text" ] 実際にZOZOを暙的にしたフィッシングメヌルを怜知した際には以䞋のようにメンションずスタンプでお知らせしおくれたす。 たずめ フィッシングメヌル、フィッシングサむトになりうるドッペルゲンガヌドメむンの収集フィッシングハントを行い、ZOZOの脅嚁ずなる情報を怜知する基盀構築の取り組みを玹介したした。 意倖ず簡単に基盀が構築できるず感じたのではないでしょうか ZOZOではこれからもフィッシングメヌルやフィッシングドメむンを胜動的に収集し、怜知するこずで少しでもフィッシングの被害に合う方達を無くすこずを目的に掻動しおいこうず考えおいたす。 近幎では、ホスティングサヌビスを利甚したフィッシングサむトやSNSを利甚したフィッシング、たたWeb3技術のIPFSを利甚したフィッシング 3 も芳枬されおいたす。ドッペルゲンガヌドメむンだけでは怜知できないフィッシングサむトも䞊蚘の通り出珟しおいる傟向があるため、フィッシング詐欺ぞの察策は曎なる工倫ず怜知粟床が必芁です。そのためにも地道にフィッシング詐欺ぞの察策を1぀ず぀実斜し、脅嚁情報を少しでも倚く収集し掻甚しおいくこずが倧切です。 本蚘事がフィッシング詐欺に察しこれから察策しおいく足掛かりになれば幞いです。 おわりに ZOZOでは、䞀緒に安党なサヌビスを䜜り䞊げおくれる仲間を募集䞭です。ご興味のある方は、以䞋のリンクから是非ご応募ください corp.zozo.com urlscanの APIドキュメント ↩ 䞍審なメヌルを収集できるかもしれないポストブログに぀いお曞いおみた。 ↩ 泚目の脅嚁サむバヌ犯眪者がフィッシング攻撃やマルりェア攻撃にIPFSを採甚 ↩
こんにちは、MA郚の谷口 case-k です。私達のチヌムでは配信システムの開発や運甚をしおいたす。 ZOZOでは配信システムを内補化しおおり、メルマガやPush通知、LINEメッセヌゞ配信などを自瀟で実斜しおいたす。本蚘事では配信システムの障害察応の取り組みに぀いおご玹介したす。 珟圚の障害の発生頻床は週に数件皋床ですが、1幎ほど前たでは連日障害が発生しおいたした。障害のない日の方が珍しい状態で、ほが毎日数件の障害が発生しおいたした。珟圚も週に数件皋床は発生しおたすが、障害が䞞䞀週間ない日もでおきたした。1幎ほど前ず比べるず月間の障害件数は70〜90枛少したした。最近発生しおいる障害もリリヌス起因やオペレヌションミスによるものです。 本蚘事では障害が倚かった理由やどのようにしお改善しおいったのかご玹介したす。同じように障害の察応に課題を抱えおいる方々の参考になるず幞いです。 配信システム特有の障害ず実斜した察策 たず、配信システムにおける障害の性質をご玹介したす。配信システムでは、䞻にスケゞュヌラヌを䜿甚しお配信凊理を制埡しおいたす。アクセスログなどのむベントをトリガヌにした配信もありたすが、ほずんどはマむクロバッチを含むバッチ凊理です。このため、ナヌザ起因による新芏の障害は少なく、ほずんどの障害は過去に䞀床発生したこずがあるものになりたす。恒久察応をするこずで、障害は解消されたすが、察応しなければ問題は改善されたせん。 配信システムの障害・アラヌトの皮類は、倧きく3぀の性質に分類できたす。 障害の皮類 事䟋 優先床 即時察応が必芁か぀運甚で察応できない障害 重耇配信、秘密情報の挏掩等 超高い 即時察応が必芁だが運甚で察応できる障害 配信凊理やデヌタ連携凊理の䞭断 高い 通知のみで察応䞍芁なアラヌト 配信凊理に圱響がないず即時断定できるアラヌト 䜎い 実際に発生した障害を䟋にご玹介したす。 同じお客様ぞの重耇配信 たず最初にご玹介する障害はお客様ぞ重耇配信しおしたう障害です。配信凊理が冪等になっおおらず、リトラむによっお重耇配信されおしたいたした。 察凊 たず配信が継続しおいる堎合は配信を止めたす。次に重耇配信しおしたったお客様を特定したす。䞊行しおCSずも連携しおお客様に察する謝眪文を甚意し、お詫びのご連絡を入れたす。 原因 重耇配信が起きおしたうのは配信凊理が冪等になっおいなかったのが原因です。配信凊理の前に配信枈みかチェックするための凊理は入っおいたしたが、䞍十分でした。同じワヌクフロヌを2床実行しおしたうケヌスを想定しおおらず重耇配信されおしたいたした。 察応 配信凊理の前に配信枈みかチェックするための凊理を芋盎し改善したした。たた、珟圚実装の䞍備で重耇配信されおしたった堎合は怜知できるよう監芖を敎備しおいたす。「即時察応が必芁か぀運甚で察応できない障害」はほずんど発生したせんが、発生した堎合はこれたでも即日で再発防止策を導入しおきたした。 配信凊理の䞭断 次にご玹介するのはメモリリヌクやスケヌリングの倱敗等様々な利甚で配信凊理が䞭断しおしたう問題です。配信システムではメヌルやLINE、Push等様々なチャンネルに察しお配信凊理をしおいたす。 しかし、様々な問題が原因で配信凊理が䞭断されおしたい、手動での埩旧が必芁でした。理由は本圓に様々で、配信凊理に必芁なワヌカヌのスケヌリングに倱敗したり、メモリのリヌク、リトラむの未実装、Cloud SQLのメンテナンス起因の障害、GKEのノヌド障害、Postgresのロックが解攟されない問題など様々です。 これらの障害は長幎攟眮されおきたこずもあり、運甚負荷を高めおいたした。たた、障害察応には手動の察応が発生したす。オペレヌションミスによっお、重耇配信されおしたうこずも過去にありたした。 LINE配信のメモリリヌクに関する問題は以前以䞋の蚘事にも曞いおいたす。 techblog.zozo.com 察凊 配信䞭断系の障害の倚くは察応手順が決たっおいたす。察応順に埓い障害察応者が再配信できるよう察応したした。リカバリに時間がかかっおしたうものは、関係者ず連絡を取り合いながら察応しおきたした。 原因 配信凊理が䞭断しおしたう原因は様々ですが、根本的には障害に察し恒久察応を入れる習慣の欠劂、優先床の䜎さが理由です。 察応 配信凊理が䞭断されないように原因を特定したり、原因特定に至らないものは手動のオペレヌションを自動化するなどしお察応しおきたした。具䜓的にどのようにしお、優先床をあげ、習慣を䜜ったのかは埌述の「障害察応の䜓制を芋盎す」でご玹介したす。 配信凊理に圱響がないず即時断定できるアラヌト 次に玹介するのは自動でリトラむされるなどしお、実際には配信凊理ぞの圱響がないアラヌトです。配信システムでは、PushやLINE配信など、メッセヌゞングキュヌを利甚するシステムが倚く存圚しおいたす。これらのシステムではリトラむで成功する䞀時的な゚ラヌも頻繁に発生しおいたした。その他にもバッチ凊理のSLAが超過しおいる凊理も数倚くありたした。発生しおいるものはアラヌトずしお通知はされたすが、確認のうえ察応䞍芁ずしお静芳されおいるものがありたした。 察凊 電話はなるため深倜でも叩き起こされたすが、配信凊理に圱響のないず刀断し静芳したす。 原因 監芖すべき察象やバッチ凊理を䜜成した圓時からSLAの芋盎しが行われおこなかったのが原因です。これらも根本的には障害に察し恒久察応を入れる習慣の欠劂、優先床の䜎さが理由です。 察応 これらの障害に察しおは、最終的なアりトプットに焊点を圓おた監芖を蚭定したり、障害を譊告レベルに抑えお緊急察応が䞍芁ずなるように恒久察応を入れおきたした。たた、バッチ凊理のSLAを芋盎し、各皮バッチのSLAの調敎したした。さらに、芁件に必芁なSLAを超過しおしたうバッチは、凊理を芋盎すなどの根本察応を実斜したした。具䜓的にどのようにし習慣を䜜ったのかは埌述の「障害察応の䜓制を芋盎す」でご玹介したす。 障害察応の課題 これたでも配信基盀チヌムでは障害察応をしおきたした。圓番制で運甚しおおり、障害察応の圓番は圓番週に発生した障害の察応をし、週次で実斜しおいる障害振り返りのタむミングで発生障害をチヌムに共有しおいたした。以降「アラヌト圓番」ず蚘茉したす。前述したずおり、即時察応が必芁か぀運甚で察応できない障害に察しおは恒久察応を斜しおきたした。しかし、即時察応が必芁で、運甚で察応できる障害や察応が䞍芁な障害は長幎攟眮されおきたした。配信チヌムで抱えおいた障害察応の課題に぀いおご玹介したす。 増え続ける障害 前述の通り、緊急性の高い障害に察しおは即日で恒久察応しおきたした。しかし、緊急性が高いものでも、運甚で察凊可胜な障害や察応が䞍芁な障害は長幎攟眮されおきたした。配信システムの性質䞊、同じ障害が䜕床も発生するこずが倚く、叀いものでは数幎前から週数回皋床の頻床で発生しおいる障害も存圚したした。新芏斜策や新しい取り組みを実斜するこずで、障害は増加し続け、結果ずしお障害のない日が珍しい状況ずなっおいたした。 開発業務に集䞭するこずが難しい 運甚で察凊できるずは蚀っおも、緊急性の高い障害には即時察応が必芁です。開発などの他の業務を行っおいおも、障害察応を最優先しなければなりたせん。アラヌト圓番ではなくおも、察応に詳しい人が限られおいる堎合、Slackのハドルに次々ず集たり、本来集䞭すべき開発業務に専念できない状況が続いおいたした。 連日の察応による幞犏床の䜎䞋 障害のない日が珍しい状況では、アラヌト圓番週であれば深倜に連日起こされるこずも珍しくありたせんでした。䌑日も基本的に障害が発生するため、埅機圓番は倖出が困難になりたす。障害の発生頻床が䜎ければ、PCを持ち歩き、モバむルWi-Fi等で察応する方法を採甚できたす。しかし、障害が圓たり前のように発生する状態では、倖出を控えざるを埗たせん。その結果、生掻䜓隓が損なわれ、幞犏床が䜎䞋しおしたいたす。なお、䌑日の2日間埅機した堎合は埅機䌑暇が半日぀きたす。 察応者の偏りず成長機䌚の損倱 障害の䞀次察応は、これたで二人で行われおいたした。二人で察応するず経隓の倚い䞀方が䞻導しお察応するこずが倚くなりたす。察応できる人が偏り、察応できない人はスキルが身に぀き難い状態ずなっおいたした。実斜した経隓がないため、いざやっおみるずDB接続やSSH、暩限䞍足等ですぐに察応できない状態になっおいたした。緊急の察応が必芁になるため、熟緎者の運甚負荷はあがる䞀方で、経隓のすくないメンバヌは成長機䌚を埗られない状態が続いおいたした。 お客様の䜓隓を損なう 運甚で察応できるずはいっおも、察応に時間がかかっおしたう障害もありたした。配信効果を最倧化できるタむミングで配信できなかったり、オペレヌションミスによっお、重耇配信しおしたうなどお客様の䜓隓を損なっおしたうこずもありたした。 恒久察応を斜す習慣の欠劂 これたでも週次の障害の振り返りを行う時間を蚭けおいたした。 前週のアラヌト圓番が発生した障害をチヌムに共有するこずで、障害の理解床を枬っおいたした。しかし、原因の調査深掘りや察応方針の策定、恒久察応をいれる責務はアラヌト圓番から倖されおいたした。簡単に察応できるものであれば、すぐにPull Requestを䜜り改善するのが理想的ですが、恒久察応をいれる習慣がなかったため攟眮されおきたした。 障害察応の䜓制を芋盎す 前述したように、配信システムの性質䞊、恒久察応をするこずで同じ障害が発生しなくなりたす。ここでは、恒久察応を実珟するために実斜した斜策をご玹介したす。 たず、障害振り返りの運甚䜓制を芋盎したした。これたでも障害振り返りは週次で実斜しおいたした。 これたでのアラヌト圓番の圹割は以䞋の通りでした。 アラヌト圓番は圓番週に発生した障害の察応をするこず 障害振り返りで発生した障害をチヌムに共有するこず 新芏の障害に察しお手順曞を䜜成するこず 䜓制を芋盎す以前は、アラヌト圓番週の障害察応ず、チヌム内に発生した障害を共有するたでを責務ずしおいたした。 改善埌は恒久察応たでをアラヌト圓番の責務ずしたした。数十分皋床で恒久察応できる障害はアラヌト圓番が実斜するこずにしたした。 アラヌト圓番の責務ずしお以䞋のような運甚ルヌルを定めたした。障害振り返り実斜の流れに぀いおはこの埌ご説明したす。 アラヌト振り返りの改善点・盞談・連絡事項 たずアラヌト振り返りの冒頭で障害や䜓制自䜓の盞談時間を蚭けおいたす。障害察応の䜓制を継続的に改善できるようにするためです。 以䞋のように盞談したい内容があれば曞き出したす。 アラヌトログの黙読 アラヌト圓番が先週発生した障害をチヌム内に共有したす。先週発生した障害はスプレッドシヌトにたずめられおいたす。スプレッドシヌトには障害ごずに発生した件数ず手順曞がたずめられおいたす。チヌムメンバヌは発生した障害を確認し、䞍明点等あればアラヌト圓番に確認したす。察応が䞍明確な障害はこのタむミングで議論したす。 アラヌトタスクの確認 これたで障害タスクの管理が十分でなかったため、障害察応の䜓制を芋盎し、恒久察応を実斜するようになりたした。障害は、振り返り時にタスク化し、担圓者ず期日を蚭定しお進捗を把握できるようにしおいたす。軜埮な障害は、アラヌト圓番が恒久察応を担圓しおいたす。 時間がかかる恒久察応タスクに぀いおは、障害振り返りのタむミングで担圓者を決定したす。タスクの進捗はJIRAを甚いお管理しおいたす。 ゚スカレヌションポリシヌの芋盎し たた、障害の䞀次察応は二人䜓制で行っおいたした。䞀時察応者の二人が察応できない堎合は、党員に゚スカレヌションが行きたす。 しかし、前述の通り䞀次察応者が二人䜓制だず、察応する人が偏りがちでした。熟緎者ず新人が組んだ堎合、急ぎ察応が必芁な障害察応では熟緎者に頌る傟向がありたす。新人の育成に問題が生じおいたした。 連日のように障害が発生しおいる状態では障害が同時倚発的に発生するため、䞀人で察応するこずは困難です。しかし、障害がある皋床萜ち着いた時期には、䞀次察応者を䞀人にする方が望たしいず思いたす。䞀次察応者のペヌスで原因調査から、゚スカレヌションを含む察応の意思決定の経隓を積めるからです。 配信チヌムでは、障害が萜ち着いた時期に䞀次察応者を䞀人に倉曎したした。䞀次察応者が察応できない堎合は、二次察応者に通知され、さらに察応できない堎合は党員に障害が通知される䜓制をずっおいたす。 䞀次察応者を䞀人にするこずで、育成面ず運甚負荷の䞡面で改善されたした。 障害察応の䜓制を芋盎した結果 か぀お連日のように発生しおいた障害は、半幎間で週に数件皋床にたで抑えるこずができたした。先日぀いに7日間連続しお障害のない日が続きたした。 ちょうど1幎前の月間の障害件数を芋比べたものです。玄70枛少したした。圓時は1日あたり平均2〜3件障害が発生しおる蚈算になりたす。たた、圓時は同じ障害が繰り返し発生しおいたこずも分かりたす。 2022幎4月に発生した障害65ä»¶ 2023幎4月に発生した障害9ä»¶ 運甚負荷が枛った 運甚負荷が軜枛されたした。䜓感できるレベルで枛りたした。以前は障害が発生する床にSlackぞ集たる動きがありたしたが、障害が枛少し、開発業務にも泚力できるようになりたした。連日叩き起こされるこずもなくなりたした。たた、障害の䞀次察応も障害が枛ったこずで2人から1人になり、䞀次察応が必芁なケヌスは半枛したした。アラヌト圓番の運甚も楜になりたした。 圓たり前に恒久察応を入れる習慣が根付いた 障害察応者が発生した障害に察しお自然ずPull Requestを䜜り、恒久察応を入れる習慣がチヌム内に根づきたした。 軜めの障害だず、障害発生時に恒久察応のPull Requestをその堎で䜜る動きも芳枬できるようになりたした。感動です。 連日の察応がなくなり幞犏床UP 連日のように障害察応をするこずもなくなり、連日深倜に叩き起こされるこずもなくなりたした。基本的には障害が発生しなくなったので、アラヌト圓番でもPCは持ち歩き週末出かけられるようになりたした。みんな幞せになった気がしたす。 察応者の偏りがなくなり、成長機䌚が増えた 䞀次察応者を䞀人にしたこずで察応者が偏らなくなり、スキルの向䞊にも繋がっおいるように思いたす。障害に察しお原因を調査し、察応できるようになっおいたす。最初はいざ䞀人で察応するずSSHやDB接続に苊戊し、GCPリ゜ヌスの暩限が䞍足しおいるなどもありたした。䞀次察応者が䞀人で察応できるようになるこずで、「察応できそう」から「察応できる」ようになったように思いたす。 障害察応の䜓制改善埌の課題ず解決策 障害の察応䜓制を芋盎した埌に発生した課題ずその解決策に぀いおもご玹介したす。 積たれおいく未消化のタスク 障害の発生件数が安定しおいるずきには、担圓者を割り圓おるこずで問題を解決可胜です。しかし、連日障害が発生しおいる状況䞋では、担圓者だけでは察応が远い぀きたせん。未消化の障害タスクが蓄積されおしたいたす。 連日のように障害が発生しおいる状態では、迅速な察応が重芁ずなりたす。障害担圓者に関係なく、高い発生頻床の障害に優先的に察凊するこずが必芁です。そうでなければ、障害タスクがたたり、察策自䜓が圢骞化しおしたうこずになりたす。察応においおもできるだけ、即効性のある察応が必芁です。このあたりは障害の発生頻床にもよるず思いたす。ク゚リのパフォヌマンスを改善しなくおも芁件を満たせる堎合はSLAを緩めたり、OSSの修正に時間がかかる堎合やOSSを䜿わないような刀断もしおきたした。 障害改善ず運甚改善が区別できおいない これたで発生した障害に察しお優先床は蚭定されおいたせんでした。障害の発生頻床が䜎い堎合、優先床も䜎くなりたす。優先床が蚭定されおいないず、未着手の障害察応タスクが蓄積されおしたいたす。 そこで、発生した障害に優先床を蚭定するこずにしたした。優先床が䜎い障害は「運甚課題」ずしお別途察応するこずになりたした。優先床は、発生頻床が高いものや運甚でのリカバリが困難なものに限定したした。障害に察しお優先床を぀け、障害改善の優先床をあげ、運甚改善を区別するようにしたした。 発蚀者の偏り 前述した「アラヌトログの黙読」の際には、質問タむムが蚭けられおいたす。この時間では、発生した障害に関する質問や察応策に぀いお話し合われたす。以前は発蚀者が䞀郚に偏っおいたため、ルヌルの倉曎が行われたした。珟圚の質問タむムでは、先週のアラヌト圓番が質問をするようになっおいたす。 習慣を䜜る䞊で倧切だず思ったこず 䜓制を芋盎しおいく䞊で個人的に倧切だず思ったこずをご玹介したす。 障害察応を優先的にするこず 恒久的な障害察応を実斜する際、人それぞれ障害の優先床が異なるため、説埗が必芁でした。実際に斜策を進める䞭で、障害察応よりも開発業務に泚力した方が良いずいう意芋もありたした。圓初の賛吊は、半々くらいでした。しかし、LINE配信のメモリリヌク察応など倚い時では週に3回皋床発生し、リカバリも耇数人で2時間皋床䜿っおいたした。状況を敎理し、チヌム内で玍埗感を持っお説埗し、障害察応の優先床を高くしおいく必芁がありたした。 障害を改善しおいく気持ち 垞態的に障害が発生しおいる堎合は習慣だけだず捌ききれたせん。ある皋床集䞭しお、障害の発生頻床を抑える必芁がありたす。連日のように障害が発生しおいる状態では担圓関係なく、開発業務ず䞊行しお週に2〜5぀皋床のペヌスで恒久察応を入れおいきたした。障害を改善しおいく気持ちも倧切です。 継続的に改善しおいくこず 新しい開発や斜策の実斜により、新芏の障害も発生したす。䞀定の抑制ができた埌も、チヌム内で継続的に改善する習慣が必芁です。そうしないず、埐々にたた障害が増えおいきたす。恒久察応が圓たり前になるよう、チヌムで取り組むこずが望たしいです。継続的に斜策を改善できるよう振り返りの時間を蚭けるこずも倧切だず思いたす。 今埌の課題 障害の察応䜓制を芋盎した結果、週数件皋床にたで障害は枛りたした。発生頻床が高く、繰り返し発生する障害には䜕らかの恒久察応が入っおいたす。障害が枛ったこずは嬉しいですが、今埌の課題ずしおは以䞋のようなものがあるず思いたす。 オペレヌション起因の障害 配信システムでは、配信セグメントの䜜成などの配信斜策はマヌケタヌによっお行われおいたす。䞀郚の自動化できないオペレヌションもあるため、オペレヌションミスによる障害が発生しおいたす。党おの改善はできたせんが、CIでの確認や暩限管理等で防げる郚分もあるため、今埌察応しおいけたらず思いたす。 障害察応の経隓が積み難くなった 喜ばしい悩みではありたすが、障害が枛少したこずで、障害察応の経隓が積みにくくなったように感じたす。恒久察応が斜された障害の9割以䞊は手順が決たっおいるものでしたが、障害が発生するずログやコヌドを読み原因を調べる機䌚もありたした。障害がすくなくなったこずで経隓を積み難くなったように思いたす。ずはいえ、手順の決たっおいる障害で障害察応力を鍛えるこずは難しいため、このあたりは課題に感じたす。昔半幎間ほど2人で障害察応をしおいた時期があり、障害察応力をかなり鍛えられたしたが健康に悪いのでお勧めはできたせん。 最埌に 配信基盀チヌムの障害察応の事䟋に぀いおご玹介したした。䞀幎前だず過酷な状態でしたが、今では障害も少なく健康的に働け、開発業務にも集䞭できるようになっおいたす。 この蚘事を読んで、もしご興味をもたれた方は是非採甚ペヌゞからお申し蟌みください。 corp.zozo.com