TECH PLAY

KINTOテクノロゞヌズ

KINTOテクノロゞヌズ の技術ブログ

å…š975ä»¶

Introduction Hello. My name is Shiode, and I'm in charge of payment-related back-end development at the Woven Payment Solution Group. Our group uses Kotlin for development, and we use Ktor as the web framework. Ktor requires a separate JSON library to process JSON request bodies and return JSON responses. At the beginning, we used Gson as a JSON library, but we encountered problems using Gson, so we switched to Moshi. Today, I'm going to describe why we chose Moshi, the problems we faced when we used Moshi with Ktor, and how we solved them. The version of Ktor used in this article is the 2.x series. Switching from Gson to Moshi Issues with Gson Initially, we were using Gson as a Ktor JSON library. However, when receiving request bodies, we discovered that problems would occur if a necessary key was missing. For example, think about an endpoint that processes input as follows. data class Input ( val required: String, val optional: String? = null, ) post("/") { val input = call.receive<Input>() call.respondText("required was ${input.required}", status = HttpStatusCode.OK) } Since String type is required for the Input class, null is not permitted. However, null is permitted with optional . This endpoint is a simple one that receives the above Input as a request body and returns the required of the received body. With this endpoint, a NullPointerException (commonly known as Nullpo) will occur if you send an empty JSON {} that does not have a required . It would be preferable for an exception to occur during deserialization so as not to affect later processing, but an exception ends up occurring when accessing that variable, in this case call.respondText() . As a solution, there may be a way to make the Input class required a nullable type and perform a null check. However, since we're using Kotlin, we wanted to express it as a type where nulls are not allowed as far as possible, and write processing that is suitable for Kotlin. Therefore, it became necessary to select a JSON library that would throw an exception during deserialization. Why Did We Choose Moshi? This project is developed with a schema base that uses OpenAPI, and the generation of interacting classes depends on the OpenAPI Generator. Also, since the client also uses the one generated by the OpenAPI Generator, a JSON library supported by OpenAPI was brought up as a replacement candidate. The JSON libraries supported by OpenAPI Generator are shown below. Gson is excluded. Moshi Jackson kotlinx.serialization Jackson can support null safe by enabling Option, but when we looked at the relevant source code , performance was described as being affected. We decided to eliminate it as a candidate without comparing performance. Meanwhile, kotlinx.serialization is a library developed by JetBrains, and the fact that it's native to Kotlin and compatible with Ktor made it is a good candidate. However, Moshi has twice as many stars as kotlinx.serialization (at time of writing, Moshi: 8.5K, kotlinx.serialization: 4.1K), and Moshi is Gson v3 , so we decided to adopt Moshi. Problems Using Moshi with Ktor According to Ktor's PR#2004 , there is no Ktor support for Moshi at the time of writing. Also, according to PR#2005 , there seems to be no policy to provide Moshi as a core feature of Ktor in the future, either. On the other hand, it seems that Ktor is planning to provide a Marketplace , so there is a possibility that in the future a third party will provide a Ktor plugin that will allow Moshi to be used. But there is no support for it right now, so you'll have to make your own Ktor plugin to be able to use Moshi. Note that there is no information yet about the Marketplace at the time of writing. We're looking forward to hearing more about it. Solution Create a Ktor Plug-in to Enable Use of Moshi The following are the classes required for using Moshi with Ktor. This implementation is almost the same as GsonConverter for Ktor. class MoshiConverter( private val moshi: Moshi = Moshi::Builder().build(), ) : ContentConverter { override suspend fun serialize( contentType: ContentType, charset: Charset, typeInfo: TypeInfo, value: Any ): OutgoingContent? { return TextContent( moshi.adapter(value.javaClass).toJson(value), contentType.withCharsetIfNeeded(charset) ) } override suspend fun deserialize(charset: Charset, typeInfo: TypeInfo, content: ByteReadChannel): Any? { return withContext(Dispatchers.IO) { val body = content.toInputStream().reader(charset).buffered().use { it.readText() } moshi.adapter(typeInfo.type.java).fromJson(body) } } } It is used as shown below. install(ContentNegotiation) { register(ContentType.Application.Json, MoshiConverter()) } Compatibility with Moshi ArrayList When we use the above Ktor plugin, it deserializes as a JAVA type instead of a Kotlin type when deserializing. For example, it will deserialize as an ArrayList even though you want to store it in a List . Moshi doesn't support ArrayList deserialization by default, so an exception will be thrown when you try to deserialize a List . To support any type in Moshi, you need to prepare an Adapter for that type. Since we want to support ArrayList this time, we must prepare a Moshi adapter for ArrayList ourselves. The following adapters support ArrayList . This is almost identical to Moshi's CollectionJsonAdapter implementation. abstract class ArrayListJsonAdapter<C : MutableCollection<T?>, T> private constructor( private val elementAdapter: JsonAdapter<T> ) : JsonAdapter<C>() { abstract fun newCollection(): C override fun fromJson(reader: JsonReader): C { val result = newCollection() reader.beginArray() while (reader.hasNext()) { result.add(elementAdapter.fromJson(reader)!!) } reader.endArray() return result } override fun toJson(writer: JsonWriter, value: C?) { writer.beginArray() for (element in value!!) { elementAdapter.toJson(writer, element) } writer.endArray() } override fun toString(): String { return "$elementAdapter.collection()" } companion object Factory : JsonAdapter.Factory { override fun create(type: Type, annotations: Set<Annotation>, moshi: Moshi): JsonAdapter<*>? { if (annotations.isNotEmpty()) return null return when (type.rawType) { ArrayList::class.java -> { newArrayListAdapter<Any>(type, moshi).nullSafe() } Set::class.java -> { newLinkedHashSetAdapter<Any>(type, moshi).nullSafe() } else -> null } } private fun <T> newArrayListAdapter(type: Type, moshi: Moshi): JsonAdapter<MutableCollection<T?>> { val elementType = Types.collectionElementType(type, Collection::class.java) val elementAdapter = moshi.adapter<T>(elementType) return object : ArrayListJsonAdapter<MutableCollection<T?>, T>(elementAdapter) { override fun newCollection(): MutableCollection<T?> = ArrayList() } } private fun <T> newLinkedHashSetAdapter(type: Type, moshi: Moshi): JsonAdapter<MutableSet<T?>> { val elementType = Types.collectionElementType(type, Collection::class.java) val elementAdapter = moshi.adapter<T>(elementType) return object : ArrayListJsonAdapter<MutableSet<T?>, T>(elementAdapter) { override fun newCollection(): MutableSet<T?> = LinkedHashSet() } } } } Verifying Operation After creating a Ktor plug-in for using Moshi with Ktor and a Moshi adapter for deserializing ArrayList with Moshi, the next step is to verify operation. In order to use the one I just described, we need to write the following install(ContentNegotiation) { register(ContentType.Application.Json, MoshiConverter( moshi = Moshi::Builder().add(ArrayListJsonAdapter.Factory) )) } Then, let's try sending an empty JSON {} to the endpoint introduced in the first example in this article. Here's that endpoint again. data class Input ( val required: String, val optional: String? = null, ) post("/") { val input = call.receive<Input>() call.respondText("required was ${input.required}", status = HttpStatusCode.OK) } At first, nullpo was generated when accessing required , but now the following exception occurs for call.receive<Input>() during deserialization, as expected. com.squareup.moshi.JsonDataException: Required value ‘required’ missing at $ Conclusions Nullpo can occur when using Gson with Ktor. If you don't want nullpo to occur, you should choose another JSON library. To use Moshi with Ktor, you need to create your own Ktor plugin by yourself. If you do that, you need to make a Moshi adapter to deserialize ArrayList . References "Gson is deprecated," so try Moshi How to serialize ArrayList<float[]> using Moshi JSON library for Android
こんにちは、KINTO テクノロゞヌズ (以䞋 KTC) で DBRE をやっおいたすあわっち( @_awache ) です。 今回は僕が KTC で実珟したい Database のガヌドレヌル構想に぀いおお話ししたいず思いたす。 ガヌドレヌルずは ガヌドレヌルずは Cloud Center of Excellence (CCoE) の掻動の䞭でよく衚珟される蚀葉です。 䞀蚀でガヌドレヌルを衚珟するず「可胜な限り利甚者の自由を確保し぀぀、望たしくない領域のみ制限、たたは発芋するための゜リュヌション」です。 ガバナンスを重芖するこずを求められる Database 領域を取り扱うずいう圹割の特性䞊、DB ゚ンゞニアは時に「ゲヌトキヌパヌ」ずしお䜜甚しおしたい、䌁業掻動のアゞリティを損なっおしたうこずもありたす。 そこで DBRE の掻動にこの「ガヌドレヌル」の考え方を取り入れおアゞリティずガバナンスコントロヌルを䞡立させようず考えおいたす。 ガヌドレヌルの皮類 ガヌドレヌルは䞋蚘の 3皮類に分類できたす。 皮類 圹割 抂芁 予防的ガヌドレヌル 制限 察象の操䜜を出来ないような制限の適甚 発芋的ガヌドレヌル 怜知 望たしくない操䜜を行った、された堎合、それを発芋、怜知する仕組み 蚂正的ガヌドレヌル 修正 望たしくない蚭定がなされた堎合に自動で修正する仕組み 予防的ガヌドレヌル ![予防的ガヌドレヌル](/assets/blog/authors/_awache/20221004/preventive_guardrail.png =720x) 発芋的ガヌドレヌル ![発芋的ガヌドレヌル](/assets/blog/authors/_awache/20221004/heuristic_guardrail.png =720x) 蚂正的ガヌドレヌル ![蚂正的ガヌドレヌル](/assets/blog/authors/_awache/20221004/revise_guardrail.png =720x) ガヌドレヌル構想 導入圓初の段階から予防的ガヌドレヌルによっお匷い制限を適甚しおしたうずこれたでできおいたこずや、やりたいこずができなくなるこずで珟堎の゚ンゞニアの反発や疲匊に繋がる可胜性がありたす。 逆に蚂正的ガヌドレヌルによっお自動修埩を行っおしたうず䜕が䞍適切だったのか、䞍適切な蚭定をどのように盎しおいくのかを考えるずいう゚ンゞニアのスキル向䞊の機䌚を倱わせおしたうこずもあるかず思いたす。 だからこそ珟圚は可胜な限り利甚者の自由を確保し、ガバナンスコントロヌルを実珟するための地盀固めのフェヌズだず思っおいたす。その䞊で「発芋的ガヌドレヌル」を取り入れるこずが望たしいず考えおいたす。 珟圚 KTC では DEV/STG/PROD の 3ステヌゞ制を導入しおいるため発芋的ガヌドレヌルによっおリスクを怜知の呚期を Daily で回したずしおも、倚くの堎合本番に適甚される前に気付ける状態にありたす。発芋的ガヌドレヌルで䞍適切な蚭定を定期的に怜知し、それを受け取った珟堎の゚ンゞニアが修正しお適甚する、ずいうサむクルを継続的に回すこずでサヌビスレベルの底䞊げに繋げられればこの仕組みの䟡倀も䞊がっおいきたす。 もちろん発芋的ガヌドレヌルは提䟛しお終わりではなく、そこで怜知されるルヌルを珟堎の状況に合わせおアップデヌトし続けるこずも倧切です。珟堎の゚ンゞニアず䌎走し KTC の実態にあったガヌドレヌルを提䟛するこずで、この仕組み自䜓も KTC ず䞀緒に成長しおいく必芁がありたす。 Executive Sponsor の匷力な埌ろ盟 「ガヌドレヌルで怜知されたものぱラヌレベルに応じお察応する」ずいうこずが浞透しなければ狌アラヌトを増やすだけです。たた個別のサヌビスの事情に応じおこのルヌルは察応しない、ずいうこずを蚱容しおしたうこずもアンチパタヌンだず考えたす。 そこで倧切にするべきこずは「KTC ずしおサヌビスを提䟛する以䞊最䜎限守るべきルヌルだけを盛り蟌むこず」です。 现か過ぎるルヌルは定矩せず、ガヌドレヌルでアラヌトが䞊がったら゚ラヌレベルに応じお察応をする、の䞀点を KTC 内の党おの゚ンゞニアに察しお共通認識化、浞透させるこずができなければこの仕組みの䟡倀がありたせん。 そこで最埌の埌抌しをしおくれるのは、掻動を埌抌ししおくれる Executive Sponsor です。Executive Sponsor は経営局、CxO など、䌁業ずしおの方向性を瀺しおくれる圹割の方が望たしいです。 最初はどれだけ気を遣ったずしおも珟堎の゚ンゞニアにルヌルを匷制する、ずいう本質的なこずは倉わらないので、この掻動が Executive Sponsor を通じお経営でコミットされおいるずいうこずは圌らが協力的に動く䞀぀の理由やモチベヌションずしお䜜甚するはずです。 責任分界点 KTC の DBRE は暪断組織でありサヌビスを盎接運甚しおいるわけではありたせん。そのためどこからどこたでが DBRE の責任でどこからどこたでは珟堎の゚ンゞニアの責任なのか、を明確にする必芁がありたす。 僕はこれをDMAIC ずいうフレヌムワヌクを甚いお考えたした。DMAIC に぀いおは 「 【DMAICずは定矩、枬定、分析、改善、定着】業務フロヌ改善プロゞェクトの必勝パタヌンリヌンシックスシグマ 」に非垞に分かりやすくたずたっおいるず思いたすのでこちらをご芧ください。 この段階の手順にざっくりず誰が責任を持぀のか、そしおそこでやるべきこず、を圓おはめるず䞋蚘のようになりたす。 定矩 内容 䜜業 最終責任 Define 蚈枬/評䟡の範囲や内容の定矩 文曞化 Script 化 DBRE Measure 蚈枬/評䟡を実斜しお結果を収集 Script の実行 DBRE Analyze 原因の分析/レポヌティング 組織党䜓の可芖性を高める DBRE Improve 䞍具合の改善/改善蚈画の䜜成 問題に察しおスムヌズな察応を実斜 プロダクト Control 成果を確認し、定着を目指す サヌビスずしお健党な状態が継続されおいる プロダクト ![責任分界点](/assets/blog/authors/_awache/20221004/DemarcationPointOfResponsibility.png =720x) この図はそれぞれ圹割を明確にし぀぀も、 党おのステップでお互いに盞談や改善、など連携しながら最終的な責任をどこが持぀のか、ずいうこずを衚しおいたす。䟋えば DBRE は珟堎の改善や定着に向けた動きを䞀切手助けしないずいうこずではない、ずいうこずを補足させおいただきたす。 どのようにガヌドレヌルを構築するのか ここたで長々ずガヌドレヌルを構築するたでの考え方を蚘茉させおいただきたしたがここから具䜓的な取り組みに぀いお説明させおいただきたす。 [Define] ゚ラヌレベルの定矩 最初に゚ラヌレベルを定矩するこずは最も重芁です。 ゚ラヌレベルずはこのガヌドレヌルが KTC に提䟛する䟡倀そのものです。DBRE ずしおどれだけ Must でやるべきこずず考えたずしおも定矩された゚ラヌレベルに合っおなければ Notice もしくは察象倖になりたす。蚭定したルヌルを定矩に照らし合わせるこずを僕自身も培底するこずで珟堎の゚ンゞニアに察する説明責任を果たすこずや、「䜕でも Critical」ずしたい欲求などをコントロヌルするこずができたす。 具䜓的な定矩は䞋蚘の通り蚭定したした。 Level 定矩 察応速床 Critical セキュリティ事故に盎結する可胜性があるもの クリティカルな異垞に気付けない状態になっおいるもの 即時察応を実斜 Error サヌビスの信頌性やセキュリティに関係する事故が発生する可胜性があるもの Database 蚭蚈䞊の問題でおよそ 1幎以内に悪圱響を及がす可胜性のあるもの 2 ~ 3営業日察応を実斜 Warning それだけではサヌビスの信頌性やセキュリティ事故に盎結しないもの セキュリティリスクを含むが圱響が限定的なもの Database 蚭蚈䞊の問題でおよそ 2幎以内に悪圱響を及がす可胜性があるもの 蚈画的察応を実斜 Notice 正垞に動䜜しおいるが蚘録しおおきたい重芁なもの 必芁に応じお察応 [Define] 具䜓的な内容敎理 続いお定矩したルヌルの䞭でガむドラむン䜜成を怜蚎するこずになるのですが、最初から Database 党䜓を芋ようず思うず倱敗しおしたいたす。そのため僕は最初のステップではガヌドレヌルの範囲を「おおよそ自力でできる範囲」ず眮いおいたす。おおよそ自力でできる範囲、ずは今動いおいるサヌビスに察する深いドメむン知識がなくおもできる範囲、䟋えば Database クラスタヌ(KTC ではメむンの DB は Amazon Aurora MySQL を䜿甚しおいたす) の蚭定や、DB 接続ナヌザヌの䜜成、Schema、Table、Column の定矩、がそこにあたりたす。逆に珟段階でガヌドレヌルで手を出さないずころはスキヌマ蚭蚈やデヌタ構造、Query などになりたす。 特にここでのポむントは 「Slow Query が発生した堎合の察凊」をガヌドレヌルに蚭定しおいないこず、です。Slow Query は非垞に重芁な指暙になりうるものですが、サヌビス単䜍の深いドメむン知識がなければ察応は困難です。もし珟段階で倧量に出おいたずしたらどこから手を぀けたらいいのか、そしおそれを゚ラヌレベルに応じた期限通りに確実に察凊し続けるこずも難しい状態です。 Slow Query に関しおはたずはガヌドレヌルではなく、Slow Query を可芖化し誰でも状況が確認できるようにする、そしおそれを察凊するこずを SLO ずしお定矩し、 DBRE から個別に提案しおみる、ずいう動きをもっお段階を螏んで考えおいきたいず思っおいたす。 ガヌドレヌルで確認する領域むメヌゞ ![Responsibility](/assets/blog/authors/_awache/20221004/Responsibility.png =720x) [Define] ガむドラむンの蚭定/スクリプト化の実斜 定矩した゚ラヌレベルや、手を出す範囲を決めた䞊でガむドラむンに萜ずし蟌みたす。そこで合意を埗たものに関しお自動的に怜出できるようにしたす。 こうしお䜜成したガむドラむンを䞀郚玹介したす。 チェック項目 Error Level 理由 Database に察する Backup 蚭定が有効である Backup が蚭定されおなかった堎合には Error ずなりたす Backup は自然灜害、システム障害、たたは倖郚からの攻撃などによるデヌタ消倱のリスクに察する有効な察策です バックアップ保持期間が十分な期間である Backup 保持期間が 7 未満の堎合には Notice ずなりたす。 重倧な損倱から埩旧するためには䞀定の期間を必芁ずしたす。 どの皋床あれば十分なのか、䞀抂な定矩はありたせん。そのため AWS の自動スナップショット機胜のデフォルトを蚭定しおいたす。 Audit Log の出力が有効である Audit Log の蚭定がされおいなかった堎合には Critical ずなりたす Database に察しお、い぀、誰が、䜕をおこなったのかをログずしお残すこずでデヌタ消倱やデヌタ挏掩のリスクに正しく察応するこずができたす Slow Query Log の出力が有効である Slow Query の蚭定がされおいなかった堎合には Critical ずなりたす Slow Query の蚭定が有効でなかった堎合、サヌビス障害の起因ずなる Query を特定できない可胜性がありたす Schema、Table、Column の文字コヌドに utf8(utf8mb3) で構成されたオブゞェクトが存圚しない Schema、Table、Column の文字コヌドに utf8(utf8mb3) で構成されたオブゞェクトが存圚した堎合、 Warning ずなりたす utf8(utf8mb3) では栌玍できない文字列が存圚しおしたいたす たた近いうちに MySQL のサポヌトからも察象倖ずなるこずが 明蚘 されおいたす 党おのテヌブルに Primary Key が存圚しおいる 䞻キヌのないテヌブルを利掻甚しおいた堎合、 Warning ずなりたす そのスキヌマの䞻䜓は䜕か、機械的にレコヌドを䞀意に特定するためには䞻キヌが必芁になりたす Schema、Table、Column の名前に予玄語ずなる文字列だけで構成されたものがない 予玄語だけで構成された名前が存圚した堎合、 Warning ずなりたす 予玄語だけで構成された名前は将来的に䜿えなくなる、もしくは必ずバッククオヌト(`)で囲う必芁があるこずが予定されおいたす。 予玄語䞀芧は 9.3 キヌワヌドず予玄語 を確認したしょう これらは AWS の API や Information Schema (侀郹 mysql Schema や Performance Schema) だけの情報から取埗可胜な範囲にしおいたす。 ![Point of Automation](/assets/blog/authors/_awache/20221004/PointOfAutomation.png =720x) これらの情報を取埗した䞊でスクリプト化したす。䟋えば 「Schema、Table、Column の文字コヌドに utf8(utf8mb3) で構成されたオブゞェクトが存圚しない」を調べたければ䞋蚘のク゚リを実行するこずで取埗できたす。 SELECT SCHEMA_NAME, CONCAT('schema''s default character set: ', DEFAULT_CHARACTER_SET_NAME) FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys', 'tmp') AND DEFAULT_CHARACTER_SET_NAME in ('utf8', 'utf8mb3') UNION SELECT CONCAT(TABLE_SCHEMA, ".", TABLE_NAME, ".", COLUMN_NAME), CONCAT('column''s default character set: ', CHARACTER_SET_NAME) as WARNING FROM information_schema.COLUMNS WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys', 'tmp') AND CHARACTER_SET_NAME in ('utf8', 'utf8mb3') ; その他のステップMeasure/Analyze/Improve/Control 䞊蚘のようなク゚リなどガむドラむンを満たすための情報取埗をスクリプト化したものを定期的に実行し、その結果が適切でないず刀断された堎合にはアラヌトを送る、それをガヌドレヌルずしお機胜させる Platform を構築したす。そしお取埗した結果の可芖性を高めるための Dashboard を甚意し珟堎の゚ンゞニアに察応しおもらう、このサむクルを回すこずが圓面の僕の DBRE ずしおの掻動軞になるず考えおいたす。 このガヌドレヌルの仕組みの良い点は、䟋えば 「1秒以䞊 Slow Query のうち、フロント゚ンドからの Query が 1ヶ月の 99パヌセンタむルで 0 になるこず」が KTC 内で必芁ずされるようになった堎合には、そのルヌルを加えればそれだけで KTC で管理しおいる党おのサヌビスに適甚できるこずです。逆に䞍芁になったルヌルを倖すこずも䞀括で可胜ずなりたす。 これが僕の考えるスケヌルする Database ガヌドレヌルの構想です。 たずめ いかがでしたでしょうか今回は僕が KTC の DBRE ずしおスケヌルし、継続的な䟡倀提䟛を生み出しおいくための䞀぀の軞ずしお考えおいる DBRE ガヌドレヌルに぀いお玹介させおいただきたした。 ただただ構築段階ですがこれたでのように Database 技術 を甚いおいるわけではなく、その技術をどのように効果的に KTC に適甚するのか、そしおビゞネス䟡倀に繋げるずころたで考えた DBRE 組織を䜜っおいるずころです。そう蚀った意味でも今はチャレンゞの時期でアプリケヌション゚ンゞニアリングからクラりド゚ンゞニアリングたで幅広く行なっおいたす。 こういったこずを䞀歩䞀歩積み重ねお継続しお皆さんにアりトプットしおいこうず思っおいたすので匕き続きよろしくお願いしたす たたこの掻動に少しでも興味を持ったり話を聞いおみたい、ず思った方はお気軜に Twitter DM 等でご連絡いただければず思いたす。
By Ikki Ikazaki, MLOps/Data Engineer in Analysis Group This is the second part in a multi-part series on how KINTO Technologies Corporation(KTC) developed a system and culture of Machine Learning Operations(MLOps). The first part was How We Define MLOps in KTC . The two subsequent posts will be about SageMaker Experiments to track the experiments conducted by data scientists, and "Benkyo-kai", a series of internal study sessions, to form the common knowledge about SageMaker and MLOps with other departments. Situation In this post, we are focusing on batch implementation of ML training and serving process using SageMaker Pipelines. We will refer to "Batch training pattern" and "Batch pattern" as defined by Mercari, inc. Before getting into details of the technical explanation, let us introduce an analysis backgroud briefly about demand forecast for our service: KINTO ONE. KINTO ONE is an all-inclusive lease solution that gives you all the benefits of driving a new vehicle with a transparent monthly fee. Our Marketing & Planning Department and Analysis Group tries to understand the customer demand for KINTO ONE in Japan and check the dashboard weekly where they can see all the important figures and KPIs. Those numbers or its analytical data are generated by subsequent data and ML pipelines' regular processing, and thus it is important to organize the whole relevant systems of the dashboard to securely monitor and operate. ↑ TOYOTA car lineup KINTO ONE offers(As of July 2022) Task As described above, we need to implement the system so that we can check the latest information, but the question is how often the data should be updated. Launching a serving endpoint for real time prediction incurs unnecessary cost even when we don't need it while updating the prediction result less frequently causes the stale data and even misunderstanding among the business analysts. In our case, they are supposed to check the dashboard weekly and sometimes look up the specific values or KPIs once they come up with some analytical hypotheses. Therefore, it would be enough to update the dashboard daily and that they can check the values based on the data of the previous day. Then, batch system which is triggered by time-based schedule of cron syntax seems good for our use case. Also, since we have the software program of KINTO ONE on top of AWS, it becomes easier to build the ML pipeline using AWS managed service. Action The whole architecture of ML pipeline is depicted as below. SageMaker Pipelines SageMaker is a managed IDE for ML developers and provides us the capability to design, develop, and operate the whole ML-related processes. To implement batch pattern for our usecase, one of its features, SageMaker Pipelines, is the best fit solution. You can implement the ML pipeline with it by combining each pipeline's step which is in turn built as SageMaker Processing, the managed data processing component of SageMaker. Through configuring the pipeline's definition, you can also visualize it in the format of Directed Acyclic Graph(DAG) like below. The following is the brief description about each step. Step Name Brief Description Extract Data extraction step using AWS Athena to query. PreProc Data preprocess step for time series analysis. Train Model building step using the dedicate SageMaker SDK. TrainEvaluation Evaluation step about whether the model performance and objective metrics meet the criteria. Predict Prediction step using the trained model and future data to be predicted. PostProc Data postprocess step for the integration with data platform. You can flexibly design the pipeline like above with your imagination and the important thing here is that you can execute the pipeline as a batch process. Because SageMaker Pipelines is natively integrated with Amazon EventBridge, you can initiate SageMaker Pipelines when the schedule of cron expression triggers the EventBridge. EventBridge can also be used for monitoring. It is important to track whether the daily pipeline was executed successfully or not to ensure the latest dashboards. The execution status of SageMaker Pipelines including each step's status is transmitted to CloudWatch and EventBus without any settings and EventBridge can target SNS Topic to notify the execution status in real time. And while the pipeline is stable most of the time, we do have a Slack channel to monitor the daily status execution in order to handle the issues as soon as the pipeline execution fails. QuickSight At the last step of the above pipeline, the prediction result is registered into Glue Catalog Table so that it can be queried through Athena. Specifically speaking, it adds the daily partition for the prediction result — which brings you another benefit by making the pipeline idempotent that you can just re-run the failed execution to fix the bug. From the consumer perspective, it becomes easier and cheaper to extract the prediction result as it is partitioned and the consumer just specify the data range they need. QuickSight, a managed BI dashboard AWS offers, also extracts data through Athena and displays the dashboards by aggregating the prediction results. Actually, "Athena type" of QuickSight's Datasets can import the queried data to SPICE, its in-memory calculation engine, based on the schedule you set so that the dashboards reflect the latest information. The only trick in the entire system is just to orchestrate the schedules of ML pipeline and dashboard's refresh timing. Since it takes time to finish the ML pipeline execution, we need a buffer time before the dashboard refreshes. One thing we were not expecting is that SageMaker Pipelines take 5-10 minutes to initiate a computing instance at each step. As illustrated above, there are 5 steps in serial, so all in all the pipeline initialization takes almost an hour to finish. Fortunately, there were no fast refresh requirements this time and the extra an hour doesn't cause serious problem for the entire system. Result The orchestration of SageMaker Pipelines and QuickSight can be seen as one of batch implementation of prediction system. The benefit by applying a batch system rather than having endpoints for real-time prediction is to make the operation easy to manage — please also visit my previous post where I described that one of main goals of MLOps is "PJ Management With Speed". Imagine if you deploy a new version on prediction endpoint, you need another deployment system such as Kubernetes Deployment to not cause or reduce downtime. On the other hand, if you implemented an idempotent batch system, the desired outcome can be obtained just by re-running it even if you failed the deployment or found any bugs on the new version. Also, operating the batch pattern prediction costs relatively less compared to having the endpoints simply because batch pattern costs only pay-as-you-go. The cheaper you develop and operate, the higher the chances to increase your return on investment(ROI). In addition, it enables you to assign a dedicated role to each technical component such that ML engineers look after SageMaker Pipelines while BI engineers take care of QuickSight's dashboards, which leads you to a more smoother operation and collaboration. BI engineers always pay attention to dashboards and their values, and notice some abnormalities once the displayed values show anomalies. It may take some time to fix the bug on the ML pipeline side, but BI engineers can handle the issues by themselves by, for example, using the past queried data to compensate the null data or simply not showing the dashboards. This post introduced about batch pattern prediction using SageMaker Pipelines, but there's still a lot more to talk about. MLOps is a huge topic! Next time, we will explain about how we track the model performance of the pipeline every day as metadata management. Follow KTC Tech Blog for future posts to stay up to date. Part 3 is available from here . Reference Shibui, Y., Byeon, S., Seo, J., & Jin, D. (2020). ml-system-design-pattern[GitHub Pages]. Retrieved from https://mercari.github.io/ml-system-design-pattern/
はじめに こんにちは。Woven Payment Solution Groupで決枈関係のバック゚ンド開発を担圓しおいる塩出です。 本Groupでは開発にKotlinを䜿甚しおおり、webフレヌムワヌクにはKtorを䜿甚しおいたす。KtorではJSONのリク゚ストボディヌを凊理したり、JSONのレスポンスを返华するために、JSONのラむブラリが別途必芁ずなりたす。 圓初、JSONラむブラリずしおGsonを䜿甚しおいたしたが、Gsonを䜿う䞊で問題に盎面したのでMoshiに切り替えたした。 今回はなぜMoshiを遞んだのか、KtorでMoshiを䜿う際の問題点ずその解決方法に぀いおたずめたした。 なお、この蚘事で䜿甚しおいるKtorのバヌゞョンは2.x系です。 GsonからMoshiぞの切り替え Gsonの問題点 圓初はKtorのJSONラむブラリずしおGsonを䜿っおいたした。しかしリク゚ストボディヌを受け取る際、必須キヌが抜けおいる堎合に問題が発生するこずが分かりたした。 䟋ずしお、以䞋のようなinputを凊理する゚ンドポむントを考えたす。 data class Input ( val required: String, val optional: String? = null, ) post("/") { val input = call.receive<Input>() call.respondText("required was ${input.required}", status = HttpStatusCode.OK) } Input classの required は String 型なのでnullを蚱容したせん。䞀方 optional はnull蚱容型です。 この゚ンドポむントはリク゚ストボディヌずしお䞊蚘 Input を受け取り、受け取ったbodyの required を返华する、単玔なものです。 この゚ンドポむントに察しお required がない空JSON {} を送信するずNullPointerException通称ぬるぜが発生したす。埌の凊理に圱響を䞎えないように、デシリアラむズ時に䟋倖が発生しおほしいずころですが、その倉数ぞのアクセス時、ここでは call.respondText() に䟋倖が発生しおしたいたす。 解決策ずしおInput classの required をnull蚱容型にしおnullチェックをする方法もあるかもしれたせん。しかしKotlinを䜿っおいる以䞊nullを蚱容したくないずころはなるべく型で衚珟しお、Kotlinっぜく凊理を曞きたいずころです。 したがっお、デシリアラむズ時に䟋倖を発生させおくれるJSONラむブラリの遞定が必芁になりたした。 なぜMoshiを遞んだか このプロゞェクトではOpenAPIを䜿甚したschema baseで開発しおおり、やりずりするclassの生成はOpenAPI Generatorに䟝存しおいたす。たたclientもOpenAPI Generatorで生成されるものを䜿甚しおいるので、乗り換え候補ずしおOpenAPIが察応しおいるJSON ラむブラリが挙がりたした。 OpenAPI Generatorが察応しおいるJSONラむブラリは以䞋の通りです。Gsonは陀倖しおいたす。 Moshi Jackson kotlinx.serialization JacksonはOptionを有効にするこずでnull safeに察応できたすが、 該圓する゜ヌスコヌド を芋るずパフォヌマンスに圱響がある、ずいう蚘述がありたした。パフォヌマンスの比范は行っおいたせんが、候補からは倖すこずにしたした。 kotlinx.serializationはJetBrainsが開発しおいるラむブラリであり、Kotlinネむティブか぀Ktorずの盞性も良さそうで候補ずしおは良いず思いたす。しかし、Moshiの方がstar数がkotlinx.serializationよりも倍くらい倚く(執筆時でMoshi: 8.5k, kotlinx.serialization: 4.1k)、たた MoshiがGson v3である ずのこずだったので、Moshiを採甚するこずにしたした。 KtorでMoshiを䜿う際の問題点 Ktorの PR#2004 によれば、執筆時点ではKtorによるMoshiのサポヌトはありたせん。たた PR#2005 によれば今埌ずもKtorのcore機胜ずしおMoshiを提䟛する方針は今の所ないようです。 䞀方で、Ktorで Marketplace なるものを提䟛する予定があるようなので、将来的に3rdパヌティヌからMoshiを䜿えるようにするKtorのプラグむンが䟛絊される可胜性はありたす。しかし今はサポヌトがないので、Moshiを䜿えるようにするためのKtorプラグむンを自分で䜜る必芁がありたす。 なお、執筆時点ではただMarketplaceの情報はありたせんでした。続報に期埅したいず思いたす。 解決方法 Moshiを䜿甚可胜にするKtorプラグむンの䜜成 以䞋はKtorでMoshiを䜿甚するために必芁なクラスです。この実装はKtorの GsonConverter ずほが同じです。 class MoshiConverter( private val moshi: Moshi = Moshi::Builder().build(), ) : ContentConverter { override suspend fun serialize( contentType: ContentType, charset: Charset, typeInfo: TypeInfo, value: Any ): OutgoingContent? { return TextContent( moshi.adapter(value.javaClass).toJson(value), contentType.withCharsetIfNeeded(charset) ) } override suspend fun deserialize(charset: Charset, typeInfo: TypeInfo, content: ByteReadChannel): Any? { return withContext(Dispatchers.IO) { val body = content.toInputStream().reader(charset).buffered().use { it.readText() } moshi.adapter(typeInfo.type.java).fromJson(body) } } } 䜿い方は以䞋のようになりたす。 install(ContentNegotiation) { register(ContentType.Application.Json, MoshiConverter()) } MoshiのArrayList察応 䞊蚘のKtorプラグむンを䜿甚するず、デシリアラむズ時にKotlin typeではなく JAVA typeずしおデシリアラむズしおしたいたす。䟋えば、 List に栌玍したいのに、 ArrayList ずしおデシリアラむズが動いおしたうずいうこずになりたす。 Moshiはデフォルトで ArrayList のデシリアラむズに察応しおいないので、 List をデシリアラむズしようずしたずきに䟋倖が発生しおしたいたす。 Moshiで任意の型に察応するためには、その型のAdapterを甚意する必芁がありたす。今回は ArrayList に察応したいので、 ArrayList 甚のMoshi adapterを自分で甚意しないずいけたせん。 以䞋は ArrayList に察応するadapterです。これはMoshiの CollectionJsonAdapterの実装 ずほが同じです。 abstract class ArrayListJsonAdapter<C : MutableCollection<T?>, T> private constructor( private val elementAdapter: JsonAdapter<T> ) : JsonAdapter<C>() { abstract fun newCollection(): C override fun fromJson(reader: JsonReader): C { val result = newCollection() reader.beginArray() while (reader.hasNext()) { result.add(elementAdapter.fromJson(reader)!!) } reader.endArray() return result } override fun toJson(writer: JsonWriter, value: C?) { writer.beginArray() for (element in value!!) { elementAdapter.toJson(writer, element) } writer.endArray() } override fun toString(): String { return "$elementAdapter.collection()" } companion object Factory : JsonAdapter.Factory { override fun create(type: Type, annotations: Set<Annotation>, moshi: Moshi): JsonAdapter<*>? { if (annotations.isNotEmpty()) return null return when (type.rawType) { ArrayList::class.java -> { newArrayListAdapter<Any>(type, moshi).nullSafe() } Set::class.java -> { newLinkedHashSetAdapter<Any>(type, moshi).nullSafe() } else -> null } } private fun <T> newArrayListAdapter(type: Type, moshi: Moshi): JsonAdapter<MutableCollection<T?>> { val elementType = Types.collectionElementType(type, Collection::class.java) val elementAdapter = moshi.adapter<T>(elementType) return object : ArrayListJsonAdapter<MutableCollection<T?>, T>(elementAdapter) { override fun newCollection(): MutableCollection<T?> = ArrayList() } } private fun <T> newLinkedHashSetAdapter(type: Type, moshi: Moshi): JsonAdapter<MutableSet<T?>> { val elementType = Types.collectionElementType(type, Collection::class.java) val elementAdapter = moshi.adapter<T>(elementType) return object : ArrayListJsonAdapter<MutableSet<T?>, T>(elementAdapter) { override fun newCollection(): MutableSet<T?> = LinkedHashSet() } } } } 動䜜確認 KtorでMoshiを䜿えるようにするためのKtorのプラグむンず、Moshiで ArrayList をデシリアラむズするためのMoshi adapterが䜜成できたので、動䜜確認したす。 䞊蚘で玹介したものを䜿うには以䞋のように蚘述する必芁がありたす。 install(ContentNegotiation) { register(ContentType.Application.Json, MoshiConverter( moshi = Moshi::Builder().add(ArrayListJsonAdapter.Factory) )) } その䞊でこの蚘事の最初の䟋で玹介した゚ンドポむントに察しお、空JSON {} を送信しおみたす。 その゚ンドポむントを再掲したす。 data class Input ( val required: String, val optional: String? = null, ) post("/") { val input = call.receive<Input>() call.respondText("required was ${input.required}", status = HttpStatusCode.OK) } 最初は required にアクセスする際にぬるぜが発生しおいたしたが、今床は期埅通りにデシリアラむズ時の call.receive<Input>() のずころで次の䟋倖が発生するようになりたした。 com.squareup.moshi.JsonDataException: Required value ‘required’ missing at $ たずめ KtorでGsonを䜿甚するずぬるぜが発生するこずがありたす ぬるぜの発生を嫌うのであれば別のJSONラむブラリを遞択する必芁がありたす KtorでMoshiを䜿甚するために、自分でKtorのpluginを䜜る必芁がありたす その堎合、 ArrayList をデシリアラむズするためのMoshi adapterを䜜る必芁がありたす 参考 「Gson is deprecated.」らしいのでMoshiを詊しおみる How to serialize ArrayList<float[]> using Moshi JSON library for Android
こんにちは。分析グルヌプ(分析G)でMLOps/デヌタ゚ンゞニアしおたす䌊ヶ厎( @_ikki02 )です。 こちらは「KINTOテクノロゞヌズ株匏䌚瀟におどのようにMLOpsを適甚しおいくのか」ずいうテヌマでの連茉2本目です。1本目の蚘事「 KINTOテクノロゞヌズのMLOpsを定矩しおみた 」はリンクよりご確認ください。埌続の蚘事では、SageMaker Experimentsを甚いた実隓管理、そしお、他郚眲も巻き蟌んで開催した勉匷䌚のお話などをしおいければず考えおいたす。 背景(Situation) 2本目のこの蚘事では、SageMaker Pipelinesを甚いたバッチパタヌンの孊習および掚論の実装に焊点を圓おおいきたいず思いたす。バッチパタヌンずは、メルカリ瀟が公開しおいる ml-system-design-pattern にお「Batch training pattern」および「Batch pattern」ずしお玹介されおいる内容(2022/8時点)を参考にしおいたす。 実装の詳现に入る前に、圓瀟のKINTO ONEにおける需芁予枬に぀いお、簡単に玹介したす。KINTO ONEはトペタの新車を自動車保険や自動車皎なども蟌みで定額で利甚できるサヌビスです。 マヌケティング郚門ず分析グルヌプにおいお、ナヌザヌの申蟌状況や各皮䞻芁KPIをダッシュボヌドで定期的に確認しおいたす。その数倀はデヌタ基盀のETL凊理や機械孊習のMLパむプラむンを通しお生成されるため、ダッシュボヌドの運甚管理には、それらシステムの党䜓をうたくオヌケストレヌションする必芁がありたす。 ↑2022/7時点のKINTO ONEサむトの車皮ラむンアップペヌゞ 業務(Task) ダッシュボヌド䞊で最新の情報を確認できるように、曎新頻床をうたく蚭定する必芁がありたす。デヌタの曎新を垞時行えるようにしようずするず、任意のタむミングで曎新リク゚ストを投げられる゚ンドポむントを起動する必芁がありたすが、リク゚ストがないずきはむンスタンスの起動分無駄なコストがかかり続けたす。䞀方で、曎新頻床が少なすぎるず、叀い情報を参照するこずになり、意思決定プロセスに圱響を䞎えるこずが懞念されたす。 今回の事䟋では、ダッシュボヌドの確認頻床は、基本的に週次の定䟋か、アナリストの突発的な閃きを随時確認するずいったケヌスがほずんどなため、ダッシュボヌドの曎新頻床は日次で前日分のデヌタを芋るこずができれば問題ないずいう芁件でした。そのため、実装すべき曎新プロセスはcron圢匏の日次スケゞュヌルで起動できれば芁件を満たせそうです。 なお、このバッチの実装に際しおは、KINTO ONEの゜フトりェアがAWS䞊で皌働しおいるずいうこずもあり、デヌタ曎新パむプラむンもAWSのマネヌゞドサヌビスを䜿うこずで容易な連携が期埅できたした。 やったこず(Action) デヌタ曎新における、機械孊習郚分のアヌキテクチャは以䞋の図の通りです。 SageMaker Pipelinesに぀いお SageMakerはAWSが提䟛する機械孊習のマネヌゞドな統合開発環境で、バッチ凊理の実装に際しおは、SageMaker Pipelinesずいう組蟌み機胜を䜿うず良さそうでした。 SageMaker Pipelinesは、SageMaker ProcessingずいうETL凊理に特化した別の組蟌み機胜を機械孊習パむプラむンのステップずしお実装するこずができ、そのステップをDAG有向非巡回グラフずしお繋ぎ合わせるこずで機械孊習パむプラむンを実装するこずができたす。DAGはもちろん可芖化するこずもでき、以䞋のように衚瀺できたす。 実装は自由に䜜り蟌めたすが、䞊図では各ステップを次のような責務で実装しおいたす。 ステップ名 簡単な説明 Extract AWS Athenaを甚いおデヌタを抜出するステップ PreProc 時系列デヌタ甚の加工をする前凊理ステップ Train SageMaker SDKを甚いお、孊習し、モデルを構築する孊習ステップ TrainEvaluation 孊習枈みモデルの目的倉数が基準を満たしおいるか評䟡する評䟡ステップ Predict 孊習枈みモデルず掚論甚デヌタを甚いお掚論を行う掚論ステップ PostProc 掚論したデヌタをデヌタ基盀に連携できるよう加工する埌凊理ステップ このパむプラむンをバッチずしお実行するには、SageMaker Pipelinesずネむティブに組蟌みされおいるEventBridgeを掻甚するこずができたす。EventBridgeはAWSの各リ゜ヌスが生成するむベントに基づいおタヌゲットを起動するむベント駆動型のトリガヌか、cron圢匏で定矩されたスケゞュヌルに基づいおタヌゲットを実行する方法から遞択するこずができ、今回は日次のスケゞュヌルを指定しおいたす。以䞋の図のように起動が確認できたす。 たた、EventBridgeは監芖の目的でも利甚しおいたす。「SageMaker Pipelinesの実行ステヌタス(成功、倱敗、など)」および「SageMaker Pipelinesを構成する各ステップの実行ステヌタス」をむベントずしお怜知するこずができ、そのむベントをSNSトピックに飛ばすこずで機械孊習パむプラむンの実行ステヌタスをリアルタむムで確認しおいたす。ダッシュボヌドが最新の状態に保たれおいるかどうかはこの監芖機構を通じおslackチャンネルに通知しおおり、もし䜕らかの理由で倱敗すればすぐにパむプラむンの実行ログを確認しお察応できるようにしおいたす。 QuickSightに぀いお 䞊述のパむプラむンの最埌のステップではデヌタ基盀ぞの連携を行っおいたす。具䜓的には、掚論結果のデヌタをGlueのカタログテヌブルずしお読み蟌めるようにテヌブルスキヌマを敎え、Athenaで掚論結果をク゚リできるようにしおいたす。パむプラむンは日次で実行されるので、Glueのカタログテヌブルのパヌティションに日付単䜍で远加されるようにしおいたす。このようにするこずで、パむプラむンを実行日指定で冪等に実装でき、パむプラむンが倱敗しおもその日の掚論結果に぀いお再実行すれば盎るようにしおいたす同じ実行日に぀いおは繰り返し実行しおも結果が䞊曞き曎新されるだけで凊理自䜓は倉化したせん。 たた、ク゚リを曞くアナリスト芖点では、必芁な実行日分の掚論結果にのみク゚リするこずで、ク゚リ凊理時間および費甚の削枛に繋げおいたす。 このようにAthena経由で掚論結果を取埗できるので、ダッシュボヌドずしおはQuickSightを䜿っお曎新しおいたす。QuickSightはAWSが提䟛するマネヌゞドなBIダッシュボヌドで、QuickSightが読み蟌むデヌタセットを"Athena"に指定するこずでSPICEずいうむンメモリの集蚈゚ンゞンに日次でデヌタを取蟌むこずができたす。ただし、このQuickSightの日次取蟌みは、䞊述の機械孊習パむプラむンずは別のスケゞュヌルで起動するため、2぀のスケゞュヌルをうたく合わせる必芁がありたす。 SageMaker Pipelinesを䜿っお想定倖だったのが、SageMaker Pipelinesの各ステップのむンスタンス起動に郜床5~10分ほどかかるため、䞊述のパむプラむンのように、ステップが5぀同期的に繋がったパむプラむンでは、むンスタンスの起動ず終了だけで1時間匱の実行時間を予め芋積もっおおく必芁がありたす(䞊図のElapsed timeが該圓したす)。今回の芁件ずしおは、日次で実行できればよく、実行スケゞュヌルに䜙裕があったため、特に問題にはなりたせんでしたが、芁件次第ではSageMaker Pipelinesのクセずしお気を付ける必芁がありそうです。 結果(Result) SageMaker PipelinesずQuickSightを組み合わせたダッシュボヌド曎新ロゞックは、党䜓ずしお䞀぀のバッチずしお芋なすこずができ、孊習および掚論のバッチパタヌンずしおみなすこずができるず考えおいたす。バッチパタヌン採甚の倧きなメリットの䞀぀は、管理を容易にできるこずです( 前回の蚘事 にお、MLOpsの目的のひず぀は「PJ管理・高速化」だず玹介したした)。䟋えば、バッチではなくリアルタむム掚論が可胜な掚論゚ンドポむントを甚意する堎合、新しいバヌゞョンをデプロむし盎す際には、ダりンタむムが発生しない、たたはなるべくダりンタむムを短くするための別の仕組み(kubernetesのDeploymentなど)が必芁になっおきたす。䞀方で、バッチの堎合、冪等でさえあれば、デプロむに倱敗したり動䜜がおかしくおも、動䜜確認枈みのバッチを再実行するだけで察凊するこずができたす。 バッチパタヌンはコスト削枛も期埅できたす。垞時皌働する掚論゚ンドポむントに比べるず、バッチパタヌンの実装は凊理にかかった時間単䜍の課金で枈むからですサヌバヌレス。 たた、今回の実装においおは、職掌別の責務に応じお運甚を切分けできるメリットもありたす。具䜓的には、掚論デヌタの曎新を担う機械孊習パむプラむンの運甚は機械孊習゚ンゞニアが担圓し、QuickSightのダッシュボヌドの運甚はBI゚ンゞニアが担圓するずいう棲分けができおいたす。BI゚ンゞニアは垞にダッシュボヌドを管理しおいるので、掚論デヌタに異垞があった際はすぐに気づくこずができたすが、倧元の機械孊習パむプラむンの修正が難しかったりしたす。しかし、棲分けができおいるずいうこずは、䟋えば圓日の曎新凊理が倱敗しおいおも、BI゚ンゞニア自身が過去の掚論結果を参照させるこずで暫定察応をするこずができたり(機械孊習゚ンゞニアが機械孊習パむプラむンの修正をするたでの時間を皌ぐこずができる)、ダッシュボヌド自䜓の公開を控えたりずいった察応が可胜になっおいたす。 いかがでしたでしょうか。この蚘事では、SageMaker Pipelinesを甚いた孊習&掚論システムのバッチパタヌンを玹介しおきたした。しかし、䞊述はあくたで定期実行郚分のお話にすぎず、MLOpsずしおはただただ説明するこずがありたす。次回の連茉では、このパむプラむンの定期実行の管理を含め、メタデヌタ管理実隓管理に぀いおご玹介しおいきたいず思いたす。匕続きご芧いただける際は「 SageMakerExperimentsを甚いた実隓管理 (3/4) 」よりご芧ください。たた、最新蚘事やその他情報発信に぀いおは、本ペヌゞ最䞋郚のTech Blogのツむッタヌをフォロヌいただけるず嬉しいです。 Reference Shibui, Y., Byeon, S., Seo, J., & Jin, D. (2020). ml-system-design-pattern[GitHub Pages]. Retrieved from https://mercari.github.io/ml-system-design-pattern/
初めに KINTOテクノロゞヌズでフロント゚ンド゚ンゞニアをしおいるクリスです。普段は倚囜籍のメンバヌが圚籍しおおり、チヌム内のコミュニケヌションは雑談でも技術的な話でも䞻に英語で行っおいるグロヌバル開発チヌムに所属しお、様々な囜に向けお珟地サヌビス及びその裏で利甚する管理画面を開発しおいたす。同時に耇数のプロゞェクトを開発する際は、いかに開発䜜業を効率化させるこずが重芁になっおきたす。今回はフロント゚ンド偎の芖点から話したいず思いたす。 解決したい課題 KINTOサヌビスは䞖界䞭20ヵ囜以䞊に既に展開しおおり、囜毎にビゞネススキヌム・開発䜓制・商習慣が異なる䞭、いかにグロヌバルスケヌルで䞀貫性を持ったUI/UXを実珟するかは我々が盎面しおいる課題の䞀぀ずなっおいたす。そこで、この課題を解決できるよう、我々がKINTOサヌビスに特化したデザむンシステムを開発しおいるこずが、本蚘事の背景にありたす。 普段デザむンを実装する時に、HTML/CSS/JSずいったフロント゚ンド開発が発生するため、デザむナヌはもちろん、゚ンゞニアも関わりながらスムヌズに䜜業を行うには、お互いのコミュニケヌションが䞍可欠です。耇数人のデザむナヌが連携なしでデザむンをしおいくずデザむンのスタむルがバラバラになっおしたい、開発偎もプロゞェクトごずに独自のコンポヌネントを開発しなければならないかもしれたせん。この状態でたくさんのプロゞェクトを開発しおいくず、䌚瀟にずっお倧きく分けお3぀のデメリットがありたす。 統䞀されないデザむンに応じお郜床開発するためコストがプロゞェクト数に応じお増加するこず 将来デザむンや開発担圓が倉わるずスタむルや䜜り方が倉わっおしたうためメンテナンスしにくいこず 内郚の開発プロセスが芋えないナヌザヌにずっおも、デザむンがバラバラになるこずで䞀貫した䜓隓ができず、サヌビスを利甚するこずにストレスを感じおしたう可胜性があるこず 工倫したこず デザむナヌも゚ンゞニアもデザむンを楜に確認する方法 先述した課題に察しお、デザむナヌができる䞀぀の察策ずしおは様々な芁玠の方針を定めるデザむンガむドラむンを甚意し、それを意識しおUI/UXを蚭蚈しおもらうこずです。しかし、色、フォント、犁止事項などのガむドラむンを芋たずしおも、開発工数の節玄には盎結しないため、゚ンゞニアずしお䜕ができるかは、たた別途考える必芁がありたす。 開発偎で䞀぀の察策ずしおはデザむナヌの協力の元でどこでも再利甚できるコンポヌネントを開発し、各プロゞェクトに入れるこずです。ひずたずは、そのコンポヌネントをたずめお確認できる堎所があるず良いず思い、Storybookずいうツヌルを導入するこずにしたした。 Storybook䞊でコンポヌネントを開発 Storybook ずはコンポヌネント単䜍で開発、か぀ドキュメント化できるオヌプン゜ヌスのツヌルです。これを利甚すれば、どんなコンポヌネントが再利甚できるか䞀芧化できたす。 公匏サむトでは各JSフレヌムワヌクに察応したむンストヌルガむドがありたすが、グロヌバル開発チヌムは基本的にVue.jsを利甚しおいるので こちら の内容に沿っお環境を立ち䞊げおみたした。 コンポヌネントをStory単䜍で開発・管理 Storybookの䞀぀の特城ずしおは、䌌たようなコンポヌネントをStoryずいう単䜍でグルヌピングできるこずです。䟋えば、ボタンずいうコンポヌネントず蚀っおも、サむトの䞭で䜿うのは様々なバリ゚ヌションがあるず考えられたすナヌザヌアクションを促すプラむマリボタン、それ以倖で利甚されるセカンダリヌボタン、限定的に利甚されるちょっず小さめのボタン、長いボタンなど。こういう耇数のボタンは xxxx.stories.ts ずいうファむルを通しおたずめるこずができたす。JavaScriptを利甚したい方は xxxx.stories.js にしおください たた、実際コンポヌネントを利甚する際はPropsを枡す堎合もあるので、そこでControlsずいう機胜を利甚し様々なPropsを枡すこずが可胜です。䟋えば、ボタンず蚀えばクリックできないようにdisabledずいう属性を蚭定したすが、Storyファむルに該圓Controlを付䞎すれば、UIのほうで倀を倉曎しお、コンポヌネントがどう倉化するか確認できたす。 コンポヌネントのドキュメントに぀いお 公匏サむトの内容に沿っおStorybookをむンストヌルするず、自動で @storybook/addon-essentials ずいうラむブラリが入りたす。これは名前の通り、必芁だず思われるアドオンがラップされたラむブラリです。その䞭の䞀぀は @storybook/addon-docs で、各Storyにドキュメントを付䞎するアドオンです。各Storyをクリックしたあず、UIに Docs ずいうタブが芋えるず思いたす。Storybookはあらかじめ曞いたStoryファむルから様々な情報を吞い䞊げ、自動でドキュメントを起こしおくれたすが、独自のドキュメントを䜜成したい堎合、Storyファむルから䜜ったファむルをパラメヌタヌに指定すれば反映されたす。以䞋の䟋ではマヌクダりンのファむルをパラメヌタヌに指定しおいたす import ButtonDocument from '@/docs/ButtonDoc.mdx' export default { title: 'Components/Buttons', parameters: { docs: { page: ButtonDocument, }, }, } 自瀟もの感のあるStorybook UIを調敎 Storybookを通しお、たくさん䜜成した再利甚コンポヌネントをドキュメントも含めお描画できたのはよいですが、サむト党䜓の芋た目がStorybookのデフォルトのたただず、自瀟もの感がなかなか出たせんでした。そこで党䜓のレむアりトにも手を付けるこずにしたした。 具䜓的には自瀟ロゎずフォントを差し替え、その䞊に色やフォントサむズを調敎するこずでした。 ドキュメントの実装ず䌌たように、この䜜業を実珟するためのアドオンである @storybook/theming をむンストヌルする必芁がありたすが、 @storybook/addon-essentials に含たれおいるので、たずは .storybook ずいうディレクトリの䞭に manager.js ずいうファむルを䜜り、 具䜓的なテヌマ蚭定を行えば倧䞈倫です。ちなみに匊瀟は以䞋のように蚭定しおいたす。 import { addons } from '@storybook/addons' import { create } from '@storybook/theming' addons.setConfig({ theme: create({ // storybookが提䟛しおくれるbase蚭定lightずdarkから遞択できたす base: 'light', brandTitle: 'XXXX XXXX', brandUrl: 'xxxxxxxxxxxx', brandImage: '画像のパス', brandTarget: '_blank', appBorderRadius: 10, textColor: '#2C353B', textInverseColor: '#FFFFFF', barTextColor: '#2C353B', barSelectedColor: '#00708D', }) }) 自瀟のもの感がだいぶ出おきたしたが、さらに調敎するこずは可胜です。それが盎接にCSSでカスタマむズするこずです。先ほどの .storybook ディレクトリの䞭に manager-head.html ずいうファむルを䜜成しお、䞭にCSSコヌドを曞けば、StorybookのUIに反映したす開発環境の再起動が必芁になりたす。 䟋えば、匊瀟で調敎したあずは、最終的に以䞋のようなUIになりたす。 ボタンや各皮むンプットなどよく利甚されるコンポヌネントが描画できるようになりたした。あずは瀟内メンバヌで閲芧できる環境を甚意するず関係者が確認できたす。 次の䞀手 Storybookを利甚しお、各コンポヌネントを開発し、各囜のデザむナヌず開発者が参考にできるように公開したした。しかし、この察策は、ただただ始たりに過ぎたせん。すでに瀟内で進めおいるものもありたすが、以䞋をやっおいきたいず考えおいたす。 コンポヌネント単䜍だけでなく、耇数のコンポヌネントを組み合わせた事䟋を出す 耇数のコンポヌネントを組み合わせる定番のテンプレヌトもありたす。たずえば、ログむンで利甚するフォヌムはメヌルアドレスやパスワヌドの入力欄、ログむン状態を芚えさせるためのチェックボックスずログむンボタンで組み立おられおいたすが、これらの組み合わせををStorybookから確認できるず、開発がより捗るず思いたす。将来的にはペヌゞ単䜍も確認できるようにしたいず思いたす。 コンポヌネントをラむブラリずしお曞き出す 䟋えば、自分のプロゞェクトに取り入れたいコンポヌネントがあっおも、今はStorybookのリポゞトリから必芁な゜ヌスコヌドをコピヌするしかありたせん。これだずコピヌのミスが発生する可胜性もあり、たた今埌コンポヌネントの仕様に察しお倉曎がある堎合も、すでにでき䞊がった各プロゞェクトの゜ヌスコヌドを修正しないずいけたせん。 プラむベヌトのラむブラリずしお曞き出しお、各プロゞェクトにむンストヌルすれば、コンポヌネントを簡単に再利甚できるようになりたすし、新しいコンポヌネントができ䞊がった時や既存コンポヌネントに仕様倉曎がある堎合はパッケヌゞマネヌゞャヌでバヌゞョンを䞊げるだけで反映できるメリットもありたすもちろんバヌゞョン管理を培底する必芁がありたすが。 Storybookに぀いおたずめ 本ツヌルの導入は䞖界共通のデザむンシステム開発にずっおの䞀぀のステップに過ぎたせんが、初めおStorybookの開発に関わっおみおたくさんのメリットを感じたした。 コンポヌネントを単䜓で開発できるので、動的な郚分から切り離しお、芋た目の調敎に専念できるこず Storiesを通しお実際のナヌスケヌスが再珟できるこず 各プロゞェクトの担圓者がこのツヌルを利甚するこずで画面開発する際の参考になるこず これからもStorybookを瀟内に広め、効率的な画面開発を進めおいきたいず思いたす。
前眮きず自己玹介 今回はKINTOテクノロゞヌズでフロント゚ンドを担圓しおいるむケダがお送り臎したす。最近はKINTO ONEの開発運甚や新芏サヌビス・プロゞェクトの立ち䞊げなどをしおいたす。 自己玹介もそこそこに前眮きぞ。 前眮き 昚今、React / Vue.js / AngularJS / Preact / Ember など様々なJSフレヌムワヌクが台頭しおいたす。ここ最近ですずSvelteずSolidの勢いがありたすね。(個人的にMithril.jsにもっず䌞びおほしい)もっず知りたい方はこちらぞ https://mithril.js.org/ その䞭でも今回はKINTOのコヌポレヌトサむト、KINTOテクノロゞヌズのコヌポレヌトサむト、そしお珟圚進行しおいるプロダクトでも採甚しおいるSvelteを䜿甚しおみおの所感、そしお簡単なSGたでのコヌドを玹介したいず思いたす。 本蚘事で玹介するSG(静的サむトゞェネレヌタヌ)ずは フロント゚ンド目線になりたすが、ブログ蚘事などを取埗するのにAPI GET、詳现画面を取埗するのにAPI GETず、それぞれアクセスするたびにリク゚ストが走っおしたいたすね。 そうではなく、ビルド時に関連するAPI GETしおすべお静的コンテンツずしお生成しおおこう、ずいったものがSG(静的サむトゞェネレヌタヌ)になりたす。 メリットの䞀䟋ずしお、䞊蚘を䟋にするずブログ䞀芧画面から詳现画面ぞの遷移時にAPI通信が走らないため、遷移が非垞にスムヌズです。 他にもSPAやISR、SSRなど様々なアヌキテクチャがありたす。   Svelteずは ビルドサむズが非垞に小さく、か぀埌述でも玹介しおいる通り非垞に曞きやすい、読みやすいフレヌムワヌクです。 たたJSフレヌムワヌクずいえばニアリヌむコヌルで仮想DOMずいうものがありたすが、Svelteはコンパむル時にVanilla JSでDOMぞの倉曎凊理なども蚘述されるため、仮想DOMを含みたせん。 再レンダリングに必芁な仮想DOMなどを構築したせん。DOMの状態が倉曎されるずそのたた実DOMを眮き換えるのです。 詳しくはこちらを読みください。 Write less code をコンセプトにしたJSフレヌムワヌク https://svelte.jp/blog/write-less-code プロダクト玹介 KINTO コヌポレヌトサむト https://corp.kinto-jp.com/ KINTOのコヌポレヌトサむトはSvelteKit(SG) on[S3 + CloudFront]ずいう構成で䜜られおおり、コヌディング埌、ずあるブランチにマヌゞするずGitHub Actions経由でbuildタスクが実行されS3に反映、CloudFrontで配信ずいった圢をずっおいたす。 ※SvelteKitはSvelteを利甚したアプリケヌションフレヌムワヌクです。Reactを利甚したNext.jsのような立ち䜍眮です。 詳しくはこちらぞ https://kit.svelte.dev/ KINTOテクノロゞヌズ コヌポレヌトサむト https://www.kinto-technologies.com/ KINTOテクノロゞヌズ コヌポレヌトサむトはSvelte(SPA) on [S3 + CloudFront]を䜿甚しおいたす。 KINTOのコヌポレヌトサむトがSGであるのに察しお、KINTOテクノロゞヌズのコヌポレヌトサむトがSPAずいう手法を取っおいるのは、KINTOテクノロゞヌズのコヌポレヌトサむトのリポゞトリを立おた段階ではコンテンツ数が少なかった、か぀SvelteKit β版がリリヌスされおいなかったため、Svelte(SPA)を採甚したした。 が、コンテンツ数が増えおきおおりSGでもいいのでは・・・ずいう思惑が生たれおきおいるのためSvelteKitぞのリプレむスが埅ち構えおいたす。 Svelteの他ずは違うずころ 䞀番倧きいのがラむブラリではなく、 コンパむラ であるずいったずころでしょうか。 VueにしおもReactにしおもラむブラリファむルのサむズがそれなりにビルドサむズを占めるためどうしおもビルドサむズが倧きくなりたす 読蟌速床が速い = 正矩 だず思っおいる自分にはぎったりなフレヌムワヌクです。 もちろん他のフレヌムワヌクでも読蟌速床、実行速床など存分に改善できるように工倫やプラグむンなどが充実しおいたす。 実導入しおみおはたったずころ 本圓にはたったずころが少ないです。 簡単なむンクリメントもこれくらいの少ない行数で曞けたす <script> // coutを定矩 let count = 0; // onclickで䜿甚する関数 function handleClick() { count += 1; } </script> <button on:click={handleClick}> Clicked {count} {count === 1 ? 'time' : 'times'} </button> あるずするならばβ版ずいうだけあっお、ただただ砎壊的な倉曎が入っおくる故その郜床情報の拟い䞊げなどが必芁な皋床です。 Svelte特有のSyntaxもわかりやすくお初芋でもハマりにくいのではないでしょうか。 もうひず぀独特なSyntaxずしお Await blocks ずいうものがありたす。 以䞋のクリックする床にfetchするだけのComponentをご芧ください、awaitをそのたたHTMLずしお曞けたす、リヌディングに長けおたすね。 <script> let promise = getRandomNumber(); async function getRandomNumber() { const URL = "xxx" const res = await fetch(URL); const text = await res.text(); if (res.ok) { return text; } else { throw new Error(text); } } function handleClick() { promise = getRandomNumber(); } </script> <button on:click={handleClick}> generate random number </button> {#await promise} <p>...waiting</p> {:then data} <p>{data}</p> {:catch error} <p style="color: red">{error.message}</p> {/await} 「本圓にそんな簡単にできるのかよ、莔屓目じゃないの。」ず思っおいる閲芧者の方ぞ 論ずるより手を動かせ、です。 実際にやっおみたしょう。 実導入しおみよう 実践 https://kit.svelte.jp/ SvelteKit公匏サむトを参考に䜜っおいきたす。 たずは npm init svelte static-site-sveltekit ず適圓なディレクトリで実行しSvelteKitプロゞェクトを䜜りたしょう。 次いで遞択肢が出おきたすので Skeleton project を遞択肢、他はお奜みでどうぞ。 CLIがあるのは䟿利ですね 䞀通り遞択するず以䞋のような構成になっおいるかず思いたす。 本蚘事では以䞋を採甚 eslint + JavaScript with JSDoc comments + prettier + Playwright Static Site Generateしよう 今回は所謂Jamstackをやっおみようず思うので、なにかしら通信をしたいず思いたす。 dev.to からSvelteに関する蚘事を取埗しおみようず思いたす。 ※本蚘事ではスタむリングは䞀切行いたせん、ボリュヌムが増えるため。 たずは蚘事䞀芧ペヌゞを䜜っおみたす。 <script context="module"> export async function load() { let articles try { articles = await fetch(`https://dev.to/api/articles?tag=svelte&per_page=5&page=1`); articles = await articles.json(); console.log(articles) } catch (e) { console.log(e) } return { props: { articles } } } </script> <script> export let articles const PostArticles = articles </script> <svelte:head> <title>Blog</title> </svelte:head> <div> <h1>Svelte devto Articles</h1> {#each PostArticles as article} <div> <header> <h2>{article.title}</h2> <h4>Tags: {article.tags}</h4> </header> <p> {article.description} </p> <a href={`/blog/${article.id}`}>MORE</a> </div> {/each} {#if PostArticles.length === 0} <div>No Articles</div> {/if} </div> async await でdev.to APIをfetchしお蚘事を取埗、articlesに栌玍埌 PostArticlesに代入、そしおSvelteのeach構文で描画。 context="module" で曞いたものぱクスポヌトできたす。぀たり同じComponent内でも呌び出せたす。 そしお次のscriptセクションでDOMぞ枡しお、パヌス。 明解です。 Svelteの良いずころは、セクションがはっきりしおいるので曞き手に優しい、芋通しが倧倉いいずころに有るず思いたす。 Vueはeasy、Reactはsimple ず聞きたすが、 Svelteはeasyか぀simple なのではないでしょうか。 話が飛んでしたいたしたが、次は詳现蚘事を䜜りたしょう。 <script context="module"> export async function load({ fetch, params }) { let article try { article = await fetch(`https://dev.to/api/articles/${params.slug}`); article = await article.json(); console.log(article) } catch (e) { console.log(e) } return { props: { article } } } </script> <script> export let article const post = article </script> <svelte:head> <title>{article.title}</title> </svelte:head> <div> <div> <h1>{post.title}</h1> <section> {@html post.body_html} </section> </div> </div> 以䞊です、paramsに様々な情報が入っおいるのでその情報を受け取り、枡しお描画。 たったこれだけです。 buildしおみよう あらかたコヌドは曞けたした。 最埌です、buildをしたしょう。 このたたでは svete.config.js の䞭にstatic generateしたいずいう呜什がありたせん。 https://kit.svelte.jp/docs/adapters 䞊蚘にもある通り @sveltejs/adapter-static を䜿甚したしょう。 むンストヌルしたす yarn add @sveltejs/adapter-static@next -D 次にsvelte.config.jsを曞き換えたす import adapter from '@sveltejs/adapter-static'; /** @type {import('@sveltejs/kit').Config} */ const config = { kit: { // prerenderを入れないず゚ラヌになる prerender: { default: true }, adapter: adapter({ pages: 'build', assets: 'build', fallback: null }) } } export default config; いざ yarn build || npm run build buildディレクトリに生成物が栌玍されたした。実際に蚘事を取埗できおるのか芋おみたしょう。 yarn preview || npm run preview 無事に芋れたしたね。 あずはS3やホスティングサヌビス、たたはレンタルサヌバヌなど、プロゞェクトに応じお生成物を眮くだけです。 所感 実際に手を動かす、目でコヌドを芋おもらうこずでSvelteの良さが䌝わったず信じおおりたす。 Svelteのコンセプトにもある  Write less code コヌド量が少なくアプリケヌションを䜜れる。が実感出来たのではないでしょうか。 ただただβ版で発展途䞊のjsフレヌムワヌクではありたすが、それでもたくさんの良さが感じられたかず思いたす。 では、みなさた良いSvelteラむフをお過ごしください。
By Ikki Ikazaki, MLOps/Data Engineer at Analysis Group This is the first part of a multi-part series on how KINTO Technologies Corporation(KTC) developed a system and culture of Machine Learning Operations(MLOps). Subsequent posts will cover batch patterns as the prediction serving pattern using SageMaker Pipelines, SageMaker Experiments to track the experiments conducted by data scientists, and "Benkyo-kai", a series of internal study sessions, to form the common knowledge about SageMaker and MLOps with other departments. Situation We have been working on various projects using ML techniques such as demand forecast, present and residual value prediction of the used car, image classification task, and some ranking algorithms, etc. Also, there are a few data scientists in Analysis Group and it comes to the conclusion that we need to build a common platform on which we can develop, manage, and develop machine learning models using MLOps technique. However, the question is what is MLOps and how we can integrate it with the ongoing relevant projects. Actually, the term MLOps is ambiguous and some people say "it is a kind of a buzzword." — and agreed to some extent. Task Considering the above, this blog post tries to define the scope of KTC MLOps by referring to some papers and documents the predecessor had published before. When talking about MLOps, the below image (Sculley et al., 2015) is often cited in Japan as a good illustration that shows ML code is actually a fraction of the whole system. To deploy and operate at a production environment, you need to be familiar with the skills and culture of software engineering and DevOps practices, which is different from the ones of data scientists. However, there are much efforts done these days by ML experts to define the scope of MLOps and now fortunately we could refer to. In 2020, ml-system-design-pattern is published by Shibui et al at Mercari, inc., at that time, and our basic concept of MLOps is greatly influenced by such design patterns. Kreuzberger et al. (2022) also conducted some interview and literature review to try to summarize the latest basic principles and technologies usually required by MLOps. Now it is time to promote those ideas and develop them in depth within our teams. Action Goal First of all, we set the goal of our MLOps. It is not much different from the one defined by the others: to bring ML proofs of concept into production "efficiently" and "reliably" . Also, the key concepts of MLOps is depicted in the decision-tree-like-format using MindMeister, a useful mind map tool, so that it can be easily referenced by the colleagues. The below is the artifact. MindMeister was really useful when illustrate a vague concept like MLOps because of its feature to display or clear the child topics in the tree diagram. We just display the topic of scalability above not to bother you by showing the whole and mess tree of MLOps. Then, we associate the key concepts with our goal and organized like below. Note that the term "Efficiently" in our goal is rephrased as "PJ Management With Speed" in the above picture and "Reliably" is expressed as "Reliable System Integration". Both strategies are important, of course, but we prioritize "PJ Management With Speed" first. The next coming posts of multi-part series will get into the details about "Pipeline" which I think requires and thus belongs to "Scalability" subtopic and "Metadata Management" often called "Experiment Tracking" by data scientists. In this section, I just introduce those concepts in a general way. Scalability Scalability is the term to refer to the flexibility of computing resources or human workload in the organization. There are some technical words in computer science using this term such as scale out, scale in, scale up, and scale down. For data scientists, scalability is crucial at the step of the model building because it is difficult to estimate the computational capacity required to run data processing and train the machine learning algorithms in advance. Could you guess how much data and what kind of format is available in KTC for demand forecast? If you could, what happens if our business suddenly expands which leads to a rapid increase in data? It may cause system resource error and require either proper scale out in the cluster or scale up per instance. In a sense, data itself stands for uncertainty and thus we need a scalable platform on which we can process data to train and host ML models by mitigating the risk. Metadata Management(Experiment tracking) The aim of metadata management is to manage the experiments for model development by tracking its metadata and reproduce its result without the help of by data scientists or developers who conducted the experiment. It is often said that because data science is a relatively new discipline and its technique is too technical for other roles to understand — sometimes even among data scientists — , it often becomes a black box. In this situation, nobody can reproduce the model building process except for the one who created it, which leads to the risk in management once he or she is on leave. Even if other data scientists are familiar with the techniques used, without the exact information - i.e. data extracted and hyper parameters - the model building process cannot be reproduced. Thus, the ML platform needs to have the ability to easily track the metadata on the processing environment, data, models, hyper parameters, objective metrics, and any comments, etc. The well-structured metadata repository not only brings the team the blueprint of data science but also accelerates the experiment cycle for data scientists. It is well suited as one of MLOps goals. Result By clarifying the entire scope of MLOps, it becomes easier to form a common knowledge among team members by pointing out the term or requirement in the scope. This entire map is just version one in KTC and expects continuous improvement. Like AWS Well-Architected tools, it will be great if it becomes a primary source in the project initiation which needs ML integration. Sounds interesting? Next time we deep dive into how we bring the DataScience project into production with the technique of MLOps: batch pattern as the prediction serving pattern using SageMaker Pipelines. Part 2 is available from here and follow KTC Tech Blog for future posts to stay up to date. Reference Kreuzberger, D., KÃŒhl, N., & Hirschl, S. (2022). Machine Learning Operations (MLOps): Overview, Definition, and Architecture. ArXiv, abs/2205.02302. Sculley, D., Holt, G., Golovin, D., Davydov, E., Phillips, T., Ebner, D., Chaudhary, V., Young, M., Crespo, J.-F., & Dennison, D. (2015). Hidden Technical Debt in Machine Learning Systems.. In C. Cortes, N. D. Lawrence, D. D. Lee, M. Sugiyama & R. Garnett (eds.), NIPS (p./pp. 2503-2511), . Shibui, Y., Byeon, S., Seo, J., & Jin, D. (2020). ml-system-design-pattern[GitHub Pages]. Retrieved from https://mercari.github.io/ml-system-design-pattern/
はじめに こんにちは、共通サヌビス開発グルヌプで決枈プラットフォヌムのバック゚ンドを担圓しおいるGo.Wadaです。 担圓しおいるプロダクトでは、システム立ち䞊げ圓初からドメむン駆動蚭蚈を甚いた開発をスクラムで実斜しおいたす。 この蚘事では、そこで埗られた経隓を螏たえ、チヌムで効率よく導入した実䟋をご玹介したす。 ドメむン駆動蚭蚈(DDD)ずは ゜フトりェア開発手法の䞀぀です。 モデリングによっお゜フトりェアの䟡倀や問題解決力を高めるこずを目指したす。 䟋えば、ナヌスケヌス図、ドメむンモデル図ずいった手段でモデルを衚珟しおいきたす。 たた、ナビキタス蚀語、぀たり開発者のみならずビゞネスメンバヌ含めた関係者が同じ蚀葉で䌚話できるこずを目指したす。 もちろん、テクニカルな面でコヌド品質を䞊げるのも目的の1぀です。 䟋えば、疎結合・高凝集な実装を行い、スパゲッティのように絡たないようにするこずで倉曎に匷くなるようにしたす。 集玄を守り、「尋ねるな、呜じよ」(Tell, Don't Ask!)のチェックをし、SOLIDを意識するずいった具合にです。 ※補足「ドメむン」ずは 「゜フトりェアで問題解決しようずする察象領域」のこずです。 チヌムの課題感 ドメむン駆動蚭蚈を導入するにあたり、チヌムには次のような課題感がありたした。 ゜フトりェア蚭蚈手法ずしおDDDを遞択したが思ったより難しい 個人孊習するものの、理解に差がある そもそも初めお䞀緒に働く仲間でチヌムを組んでいる 䞀方で、チヌムの方針や未来像ずしおは、 効率よく開発を進めたい システムのメンテナンス性を䞊げお、将来の開発でも機胜開発のスピヌドを䞊げおいきたい(あるいは、軌道に乗った埌はスピヌドを萜ずしたくない) 開発は孊びの機䌚でもあるので、チヌムでうたくで孊習したい ずいうむメヌゞをしおいたした。 課題感に察する解決案の1぀ずしおの茪読䌚 課題感を解決する方法はいく぀もありたすが、ドメむン駆動蚭蚈関連曞籍の茪読䌚を開催するこずで、立ち向かうこずにしたした。 次の点を狙っおのこずです。 DDDをチヌムの力で読み解く 孊習を効率化、より深いものにする(チヌムずしおのスキル向䞊) 茪読䌚で発生する雑談を通しおお互いを理解し、共通認識を醞成する 前提知識を合わせるこずで、プルリク゚ストでの䌚話を枛らす 茪読䌚での雑談や議論を通しお、チヌムの䞀䜓感もより持おるようにする 茪読䌚の実斜方法 次のような方法で茪読䌚を実斜したした。 束岡幞䞀郎氏の曞籍「ドメむン駆動蚭蚈 モデリング/実装ガむド」を茪読 https://little-hands.booth.pm/items/1835632 プロダクトメンバヌ党員の合意で党員参加 週1回30分、章毎に担圓者を決めお発衚 事前に担圓章を読み、芁点を資料にたずめる 倧䜓発衚に15分、ディスカッションに15分 茪読䌚でのディスカッション 蚘憶を頌りに曞き起こしおみたしたが、次のような旚の䌚話をしおいたした。 垞に正しいむンスタンスしか存圚させない方が敎合性䞊よさそう ドメむンサヌビスの圚り方はこうだ(迂闊に䜜るな、責務を限定したらよき) バリデヌションのやり方の1぀、仕様オブゞェクトを䜿ったほうが良さそう 倀オブゞェクトの捉え方(集玄ルヌトを構成する芁玠をVOずするず安党なのでは) presentation局ずapplication局が混じっおない名づけで混乱したな アヌキテクチャをどうするか(レむダヌドアヌキテクチャ、オニオンアヌキテクチャ、クリヌンアヌキテクチャ、など) モデリングに着手する コヌドを曞きたいずいう気持ちを抑えられないのも山々ですが、モデリングも重芁ですので、毎スプリント内で定期的に時間を取っおチヌム党員で臚みたした。 ドメむン゚キスパヌトは決枈関連システムや業務に粟通しおいるメンバヌが務めたした。(ビゞネスずいう点よりも、決枈機胜自䜓がシステムで実珟されおしたっおいるので、システムに詳しい点も重芁) 実斜した内容は倧たかに次の通りです。 miroを䜿っお、決枈にた぀わる抂念に䜕があるかを付箋を利甚しブレストしたした。 ブレスト成果物 挙がっおきた抂念を敎理し、次のような点を議論したした。 決枈プラットフォヌムずしお必芁な決枈にた぀わる動䜜は䜕か 動䜜を時系列に䞊べるずどうなるのか 集玄ルヌトはどれか どのように抂念敎理をするず効果的に収たるのか 他の類䌌システムではどのようになっおいるか 抂念敎理むメヌゞ図 ※ブレスト埌だけではなく、違和感がある床に、この図に立ち返っお怜蚎しなおしたした。 ブレスト進行状況むメヌゞ図 ※デフォルメした䜜業進行むメヌゞです。 議論の結果を、ドメむンモデル図やナヌスケヌス図に描きたした。 ドメむンモデル ドメむンモデル抜粋 もちろん、モデルは䜜っおおしたいではなく、幟床ずなく改善を重ねたした。 䟋えば、決枈集玄の決枈カヌド゚ンティティを初めは専甚の集玄にしようず考えおいたした。 決枈カヌドには決枈䌚瀟の情報を持たせるむメヌゞがあり、倖郚システムなので集玄を分けた方が取り扱いやすいず刀断したためです。 䞀方で、ある決枈にお、このキヌ倀を決枈䌚瀟ずやり取りしたずいう情報が発生したすが、「決枈」ずは切り離せない関係でもありたした。 匷い敎合性があるず刀断を芋盎し、同䞀集玄に含めるこずにしたした。 ナヌスケヌス図 ※ナヌスケヌス図に぀いおは、䜜成しおみたものの、他のドキュメントず内容が被っおおり廃止したした。 甚語集を䜜りたした。 ブレストやモデルの䜜成䞭に、同じこずを説明するのに、メンバヌ毎に別の蚀葉を䜿っおいるこずに気付きたす。 そこで、耇数ある蚀葉からチヌムで合意できる適切な蚀葉を甚語集で定矩したした。(日本語ず英語䞡方定矩したした。) 定矩した蚀葉は必ず䜿えるように、間違っおしたった堎合はメンバヌ間で優しく(冗談を蚀いながら)指摘し合いたした。 䟋えば、決枈プラットフォヌムを導入するシステムからみお、決枈前に所謂泚文単䜍に契玄が必芁だずしたす。その契玄のこずを「決枈指瀺」ず呌ぶようにしたした。「契玄」は様々な意味にずれおしたうず思慮したためです。 たた、この甚語集は別のシステムやプロダクト(境界付けられたコンテキストの倖偎)で利甚される甚語ず混同しないこずも目的ずしおいたす。 甚語集むメヌゞ 茪読䌚ずモデリングを実斜しおの孊びや効果 茪読䌚 業務ず䞊行した茪読䌚は、次のような孊びや効果がありたした。 即実践で生かせるので、孊ぶ量もプロダクトの粟床も䞊がっおよい 掻かす機䌚が近いうちにやっおくるアゞャむルに合っおいる 共通認識ができるこずでプルリク゚ストのレビュヌ芳点が他に向くので質が向䞊する 気になっお関連曞籍にも手が䌞びる(勢いで孊べる) 業務からの郚分の孊びだけでなく、䜓系的な孊びもできるので孊びの汎甚性が高い 関係ないテヌマの茪読䌚よりも、茪読䌚に胜動的になれる 胜動的な䌚話によっお、チヌムの雰囲気がさらに良くなるため、リモヌトワヌクによる疎倖感の察策にもなる ※盛り䞊がったため、タむムキヌパヌが重芁でした。 モデリング モデリングを時間を取っお定期的に実斜するこずで、次のような孊びや効果がありたした。 実装に目が向きがちなずころ、モデルから考えようずいう習慣が぀く モデルレベルで党䜓像の把握が出来る 実装で迷ったずきにモデルに立ち戻っお頭を敎理できる 今埌の展望 曞いおきた通りにプラクティスを実斜しおきたしたが、執筆時点で実運甚はこれからになりたす。 珟状の開発䞭の状態では、成功しおいるように芋えたす。 䞀方で、実際の運甚から受けるフィヌドバックを元に、これらの掻動が良かったのか、課題点は䜕だったのかを評䟡したいず考えおいたす。 たた、ドメむン駆動蚭蚈自䜓決定論理ずいうよりも考えるための道筋のような郚分が倧きいです。 運甚で埗られる情報も含めお曎なる知芋の蓄積をしおいきたいず考えおいたす。 本蚘事蚘茉のプラクティスを通しお孊んだこずたずめ 業務ず䞊行した茪読䌚では、 孊びのむンプット/アりトプット、プロダクトぞの反映、メンバヌの成長をほが同時に達成できる 業務からの孊びず䜓系的な孊びがリンクする 関係者が胜動的に関われるし、䌚話を通しおチヌムの䞀䜓感が生たれる ずいう孊びがありたした。 たた、ドメむン駆動蚭蚈のモデリングの習慣は、 実装に目が向きがちなずころ、モデルから考えようになる モデルレベルで党䜓像の把握が出来るので実装が局所的になりにくい 実装で迷ったずきにモデルに立ち戻っお頭を敎理できるので混乱しにくい ずいう孊びに繋がりたした。
こんにちは。分析グルヌプ(分析G)でMLOps/デヌタ゚ンゞニアしおたす䌊ヶ厎( @_ikki02 )です。 こちらは「KINTOテクノロゞヌズ株匏䌚瀟におどのようにMLOpsを適甚しおいくのか」ずいうテヌマでの連茉1本目です。埌続の蚘事では、SageMaker Pipelinesを甚いたバッチ掚論、SageMaker Experimentsを甚いた実隓管理、そしお、他郚眲も巻き蟌んで開催した勉匷䌚のお話などをしおいければず考えおいたす。 背景(Situation) KINTOテクノロゞヌズでは機械孊習を甚いた様々なプロゞェクトに取組んできたした。新車の申蟌台数予枬、䞭叀車の残䟡予枬、画像の類䌌床刀定、ランキングアルゎリズムの開発など、様々なドメむンや機械孊習タスクがありたす。たた、分析グルヌプにはデヌタサむ゚ンティストが䜕名か圚籍しおおり、それぞれの実行環境やお䜜法が異なったり、実隓結果のスムヌズな共有が難しかったこずがありたした。そのため、EDA探玢的デヌタ分析のこずやモデル開発にあたっお、共通のプラットフォヌムが求められおおり、MLOpsずいう蚀葉も瀟内で䜿われるようになっおきたした。 ずころで、MLOpsずは䜕でしょうか。たた、既存のプロゞェクトに察しお、どのように組み蟌んでいけばよいのでしょうか。個人的にはMLOpsずいう蚀葉は抜象床が高すぎお、できれば避けたい蚀葉だったりしたす(正確には、成し遂げたい課題に察しお、より適切な芁玠技術や蚀葉があるはず、ず考えおいたす)。 業務(Task) そこで、この蚘事では、いく぀かの論文やドキュメントを参考にしながら、MLOpsの党䜓像を明確にし぀぀、KINTOテクノロゞヌズで特に重芁芖しおいる芁玠技術に぀いおご玹介しおいければず思いたす。MLOpsの話をする際に芪の顔より芋た絵ずしおよく以䞋の図が玹介されおいるかず思いたす(Sculley et al., 2015)。 この図では機械孊習に関連するコヌドはアプリケヌション党䜓のほんの䞀郚であるこずが瀺唆されおいたす。実際、機械孊習を本番環境のアプリケヌションにデプロむする際には、゜フトりェア゚ンゞニアリングやDevOps等の技術に習熟する必芁があり、デヌタサむ゚ンスずはたた異なるスキルセットや文化が求められたす。䞀方で、MLOpsはバズワヌド化するこずもなく倚くの研究者等によっおその定矩やスコヌプが明確にされ぀぀あるようにも思えたす。Kreuzberger et al. (2022)は様々な分野で掻躍する機械孊習の専門家に察しおむンタビュヌや文献調査を実斜し、MLOpsの9぀の原則ず芁玠技術の解説をたずめおいたす。たた、メルカリ瀟により公開されおいるml-system-design-patternでは、機械孊習システムを本番皌働させるためのデザむンパタヌンがたずめられおおり(Shibui et al., 2020)、MLOpsの瀟内定矩に際しお、倧いに参考にさせおいただきたした。 これらの情報をKINTOテクノロゞヌズの内郚におよく䜿われおいる甚語や技術をベヌスに再敎理し、瀟内展開できるようにたずめおいきたした。 やったこず(Action) 目的ずスコヌプ たず、MLOpsの目的を明文化したす。目的に぀いおは、KINTOテクノロゞヌズ独自の芁玠を織り亀ぜるわけではなく、ある皋床䞀般性を持たせた圢にしおいたす。すなわち、 機械孊習のPoCを「効率よく」本番環境ぞ 「信頌性高く」デプロむし運甚する その䞊で、MindMeisterずいうマむンドマップツヌルを甚いお、芁玠技術を暹圢図状に可芖化しおみたした。 MindMeisterは暹圢図の項目を衚瀺したり隠したりできるので、MLOpsずいう広範な抂念をたずめる際に重宝したした。すべおの項目を衚瀺するず、芋通しが悪くなるので、䞊蚘の図では「スケヌラビリティ」の䞀郚の項目を䞭心に展開しおいたす。 たた、この暹圢図ず䞊述の目的を照らし合わせ、以䞋の圢匏でスコヌプを敎理したした。 目的の「効率よく」ずいう文蚀に図䞭の「(A) PJ管理・高速化」、「信頌性高く」ずいう文蚀に「(B) 信頌性を高めるシステム連携」ずいう戊略を割圓お、優先床に応じお各項目を手段戊術ずしお怜蚎できるようにしおいたす。 いずれの戊略も重芁ですが、KINTOテクノロゞヌズではたず「(A) PJ管理・高速化」に焊点をあお、芁玠技術の開発ないし普及に努めおいこうず考えおいたす。今埌投皿予定の連茉では、この䞭の「パむプラむン」および「メタデヌタ管理実隓管理」に぀いお取組みを詳しく玹介しおいこうず考えおおり、この蚘事ではその抂芁に぀いおご玹介できればず思いたす。 スケヌラビリティ 暹圢図の通り、KINTOテクノロゞヌズでは「スケヌラビリティ」ずいう倧項目の䞭に「パむプラむン」を䜍眮付けおいたす。スケヌラビリティずは、コンピュヌティングリ゜ヌスや組織の人的資本に関する拡匵性のこずを指し、スケヌルアりトやスケヌルむンずいった䜿われ方をしたす。デヌタサむ゚ンスのプロゞェクトにおいお、このスケヌラビリティは重芁です。デヌタには非決定的な性質があり、予め必芁なコンピュヌティングリ゜ヌスの芋積もりが難しいためです。仮に既存の蚭定倀でうたく動䜜しおいたずしおも、たずえばCMや新商品の投入ずいった需芁喚起策で急激にスパむクした堎合はいかがでしょうか。アプリケヌション内で䜿われおいるMLのモデルにもよりたすが、メモリやCPU(GPU)のリ゜ヌス䞍足で障害の原因ずなるこずがよくありたす。そのため、このようなリ゜ヌス䞍足の゚ラヌに察しお柔軟にスケヌルアりトやスケヌルアップする䞍芁時にはうたくスケヌルむンたたはスケヌルダりン仕組みが重芁になっおきたす。デヌタサむ゚ンティストがモデルを開発する「孊習基盀」、モデルをデプロむし掚論結果を提䟛する「掚論基盀」、それらの橋枡しずなる「パむプラむン」においお、このスケヌラビリティの確保は重芁です。 メタデヌタ管理(実隓管理) メタデヌタ管理では、開発したデヌタサむ゚ンティストや機械孊習゚ンゞニア圓人のサポヌト無しに実隓結果やモデル開発を再珟できるように、その過皋のメタデヌタを蚘録し管理するこずが求められたす。デヌタサむ゚ンスは組織においおただただ新しい領域だずみなされるこずも倚く、特に他の職皮の人々にずっおその業務内容や関わり方に぀いお十分に認識できおいるこずは少ないず考えたす。時にはデヌタサむ゚ンティスト同士でさえ、専門性e.g. 時系列、画像、蚀語、テヌブルデヌタ、地理空間、因果掚論、ベむズ統蚈孊などが異なれば、そのデヌタサむ゚ンスプロゞェクトは容易にブラックボックス化しおしたうこずでしょう。このような状況では、デヌタサむ゚ンスプロゞェクトの管理は属人的になり、䜜った圓人がいない状況では誰もその業務を匕継ぐこずはできたせん。たた、仮に他のデヌタサむ゚ンティストがプロゞェクトで䜿われおいる技術に習熟しおいたずしおも、結果を再珟するには具䜓的にどのようなデヌタがい぀䜿われ、ハむパヌパラメヌタの正確な倀は䜕であるのか、なぜそう蚭定したのかなど、膚倧か぀厳密な情報が必芁になりたす。そのため、良き機械孊習基盀には、実行環境やデヌタ、利甚するMLアルゎリズム、ハむパヌパラメヌタ、評䟡指暙、解釈などの自由蚘述文ずいったメタデヌタを容易に蚘録し保存できる機胜が求められたす。必芁な情報がうたく管理されおいるメタデヌタレポゞトリがあれば、それは実隓結果やモデル開発を再珟するための青写真ずなり、たた情報を思い出すための詊行錯誀も枛らせるため、結果ずしお実隓サむクルを回すのにかかる時間を短瞮し、プロゞェクトの高速化が期埅できたす。そのため、メタデヌタ管理はMLOpsの目的に沿った戊略ず考えたす。 結果(Result) MLOpsの党䜓像を可芖化するこずで、図䞭の項目や芁件を指しながら、必芁な範囲の業務スコヌプを掗い出したり、他の郚眲のメンバヌず共通認識が持ちやすくなったず思いたす。ただし、この党䜓像はただバヌゞョン1なので、業務で掻甚しおいく䞭で継続的な改善をしおいきたいです。理想ずしおは、AWSのWell-Architectedのように、機械孊習プロゞェクト立䞊げ期に真っ先に参照されるようなフレヌムワヌクぞ成長させ、定着させおいけたらいいなず考えおいたす。 いかがでしたでしょうか。次回の連茉では、本蚘事(のスケヌラビリティの項)で軜く觊れたパむプラむンに぀いお、SageMaker Pipelinesを甚いたバッチパタヌンの掚論基盀に぀いおご玹介しおいたす(Part2は こちら よりご確認ください)。匕続きご芧いただけるず嬉しいです。 Reference Kreuzberger, D., KÃŒhl, N., & Hirschl, S. (2022). Machine Learning Operations (MLOps): Overview, Definition, and Architecture. ArXiv, abs/2205.02302. Sculley, D., Holt, G., Golovin, D., Davydov, E., Phillips, T., Ebner, D., Chaudhary, V., Young, M., Crespo, J.-F., & Dennison, D. (2015). Hidden Technical Debt in Machine Learning Systems.. In C. Cortes, N. D. Lawrence, D. D. Lee, M. Sugiyama & R. Garnett (eds.), NIPS (p./pp. 2503-2511), . Shibui, Y., Byeon, S., Seo, J., & Jin, D. (2020). ml-system-design-pattern[GitHub Pages]. Retrieved from https://mercari.github.io/ml-system-design-pattern/
はじめに KINTOテクノロゞヌズで KINTO FACTORY のリヌド゚ンゞニアをしおいる 䞭西 葵 です。珟圚KINTO FACTORYプロゞェクトでは今埌の察応車皮や商品の拡充、党囜展開を芋据えおシステムの芋盎しを行っおおり、システム開発もモダンな技術や開発フロヌを取り入れおいる先進的なプロゞェクトです。 本蚘事ではKINTO FACTORYで取り組んでいるスキヌマファヌスト開発に぀いお解説したす。 スキヌマファヌスト開発ずは スキヌマファむルを定矩しコヌドゞェネレヌタヌを䜿甚しおコヌドを生成しAPIを開発する手法で以䞋のような課題を解決したす。 結合しおみたら型が違っお動かない ドキュメントが叀くおコヌドが正しい クラむアントの実装が蚀語毎に重耇 1. 結合しおみたら型が違っお動かない フロント゚ンド、バック゚ンド、各マむクロサヌビス間、倖郚サヌビスなどずのむンタヌフェヌスずしおスキヌマを定矩する為、デヌタ構造の霟霬などが発生しにくくなりたす。 2. ドキュメントが叀くおコヌドが正しい ドキュメントの生成もゞェネレヌタヌを甚いお出力するこずで運甚が続くず発生しがちなドキュメントずコヌドの内容が乖離する状況も回避できたす。 3. クラむアントの実装が蚀語毎に重耇 Webアプリ, モバむルアプリなどクラむアントの開発蚀語が䜕であっおも定矩したスキヌマファむルからコヌドを自動生成するため同䞀機胜の別蚀語実装など開発工数のムダも防ぐこずができたす。 その他 チヌムに経隓者がいない堎合導入の壁が高いず感じる方も倚いですが、他にも倀のバリデヌション、モックサヌバヌ甚コヌドの自動生成、git䞊でバヌゞョン管理など、開発者にずっおは良いこず尜くめの開発手法がスキヌマファヌスト開発です。 KINTO FACTORYのシステム構成 KINTO FACTORYではマむクロサヌビスアヌキテクチャを採甚しお以䞋の通り ブラりザからはGraphQL サヌドパヌティシステムからはREST API 各マむクロサヌビス間はgRPC(Protocol Buffers) のような構成で通信を行う蚭蚈になっおいたす 定矩蚀語IDL 䞀般的にそれぞれのAPI蚭蚈においお以䞋のようなIDL(Interface Description Language)を甚いお定矩しおいきたす。 Interface IDL GraphQL GraphQL Schema https://graphql.org/learn/schema/ REST API Swagger Spec https://swagger.io/specification/ gRPC Protocol Buffers https://developers.google.com/protocol-buffers ※耇数の定矩蚀語を孊ぶこずは孊習コストも高く効率的ではありたせん スキヌマ倉換ツヌル それぞれのIDLは名称や型などを定矩しおコヌドを生成するこずが出来るのであればSchema間での盞互倉換も可胜ではないかず考えお調査を進めたのが以䞋の衚になりたす。 倉換前  倉換埌 GraphQL Schema Swagger Spec Protocol Buffers GraphQL Schema - ? ? Swagger Spec openapi-to-graphql - openapi2proto Protocol Buffers go-proto-gql protoc-gen-openapiv2 - GraphQL Schemaをベヌスに倉換するツヌルは情報が少ない Swagger Specをベヌスに倉換するツヌルは長期間メンテされおいない Protocol Buffersをベヌスに倉換するツヌルは䞊蚘より遞択肢や情報が倚い 以䞊の調査結果より Protocol Buffersで定矩しお他のSchemaに倉換を行う遞択をしたした。 ゜ヌスファむル(.proto) 準備 1 https://github.com/googleapis/googleapis からRest APIを定矩する䞊で必芁なファむルを取埗 google/api/annotations.proto google/api/http.proto google/api/httpbody.proto 準備 2 https://github.com/danielvladco/go-proto-gql からGraphQL Schemaを定矩する䞊で必芁なproto定矩ファむルを取埗 protobuf/graphql.proto 定矩ファむル(example.proto) ※以䞋の定矩ファむルはテックブログの蚘事を䟋に本皿甚に䜜成したものです syntax = "proto3"; package com.kinto_technologies.blog; option go_package = "blog.kinto-technologies.com"; import "google/api/annotations.proto"; // 準備1で取埗したファむルの読み蟌み import "protobuf/graphql.proto"; // 準備2で取埗したファむルの読み蟌み // 蚘事 message Article { // タむトル string title = 1; // 著者 string author = 2; // コンテンツ string content = 3; } // リク゚スト message Request { uint64 id = 1; } // 結果 message Result { uint64 id = 1; } // テックブログサヌビス service TechBlog { // 蚘事投皿 rpc PostArticle(Article) returns (Result) { option (google.api.http) = { post: "/post" }; option (danielvladco.protobuf.graphql.rpc) = { type: MUTATION }; } // 蚘事取埗 rpc GetArticle(Request) returns (Article) { option (google.api.http) = { get: "/get/{id}" }; option (danielvladco.protobuf.graphql.rpc) = { type: QUERY }; } } .proto -> .graphql ぞの倉換 go-proto-gqlのむンストヌル リポゞトリをクロヌン git clone https://github.com/danielvladco/go-proto-gql.git cd go-proto-gql Protoc pluginsをむンストヌル cd ./protoc-gen-gql go install .proto から .graphqlに倉換 protoc --gql_out=paths=source_relative:. -I=. example.proto 出力ファむル(.graphql) """ テックブログサヌビス """ directive @TechBlog on FIELD_DEFINITION """ 蚘事 """ type Article { """ タむトル """ title: String """ 著者 """ author: String """ コンテンツ """ content: String } """ 蚘事 """ input ArticleInput { """ タむトル """ title: String """ 著者 """ author: String """ コンテンツ """ content: String } type Mutation { """ 蚘事投皿 """ techBlogPostArticle(in: ArticleInput): Result } type Query { """ 蚘事取埗 """ techBlogGetArticle(in: RequestInput): Article } """ リク゚スト """ input RequestInput { id: Int } """ 結果 """ type Result { id: Int } .proto -> .swagger.json ぞの倉換 protobufのむンストヌル brew install protobuf protocol-gen-openapiv2のむンストヌル go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest .proto から .swagger.json ぞの倉換 protoc -I . --openapiv2_out=allow_merge=true,merge_file_name=./example:. example.proto 出力ファむル(.swagger.json) { "swagger": "2.0", "info": { "title": "example.proto", "version": "version not set" }, "tags": [ { "name": "TechBlog" } ], "consumes": [ "application/json" ], "produces": [ "application/json" ], "paths": { "/get/{id}": { "get": { "summary": "蚘事取埗", "operationId": "TechBlog_GetArticle", "responses": { "200": { "description": "A successful response.", "schema": { "$ref": "#/definitions/blogArticle" } }, "default": { "description": "An unexpected error response.", "schema": { "$ref": "#/definitions/rpcStatus" } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "type": "string", "format": "uint64" } ], "tags": [ "TechBlog" ] } }, "/post": { "post": { "summary": "蚘事投皿", "operationId": "TechBlog_PostArticle", "responses": { "200": { "description": "A successful response.", "schema": { "$ref": "#/definitions/blogResult" } }, "default": { "description": "An unexpected error response.", "schema": { "$ref": "#/definitions/rpcStatus" } } }, "parameters": [ { "name": "title", "description": "タむトル", "in": "query", "required": false, "type": "string" }, { "name": "author", "description": "著者", "in": "query", "required": false, "type": "string" }, { "name": "content", "description": "コンテンツ", "in": "query", "required": false, "type": "string" } ], "tags": [ "TechBlog" ] } } }, "definitions": { "blogArticle": { "type": "object", "properties": { "title": { "type": "string", "title": "タむトル" }, "author": { "type": "string", "title": "著者" }, "content": { "type": "string", "title": "コンテンツ" } }, "title": "蚘事" }, "blogResult": { "type": "object", "properties": { "id": { "type": "string", "format": "uint64" } }, "title": "結果" }, "protobufAny": { "type": "object", "properties": { "@type": { "type": "string" } }, "additionalProperties": {} }, "rpcStatus": { "type": "object", "properties": { "code": { "type": "integer", "format": "int32" }, "message": { "type": "string" }, "details": { "type": "array", "items": { "$ref": "#/definitions/protobufAny" } } } } } } たずめ 本皿では、スキヌマファヌスト開発の玹介ず、耇数のスキヌマ定矩を最小限に抑えお運甚する方法ずしおスキヌマ定矩を倉換するツヌルに぀いお玹介したした。 耇数の定矩蚀語が入り乱れおいる状態を解消したい方、特にProtocol Buffersの定矩からGraphQL Schemaぞの倉換、Swagger Specぞの倉換に぀いお怜蚎しおいる方の䞀助になれば幞いです。 ドキュメントの生成やバリデヌション凊理の自動生成、コヌドの自動生成などに぀いおは別の蚘事ずしお公開したいず思いたす。 Follow us! KINTOテクノロゞヌズのTwitterアカりントも運甚開始したした。最新情報を発信しおいきたすのでぜひフォロヌをお願いしたす https://twitter.com/KintoTech_Dev We are hiring! KINTOテクノロゞヌズでは䞀緒にモビリティの未来を創る仲間を募集しおいたす。カゞュアル面談なども行っおおりたすのでご興味をお持ち頂けたしたらぜひお気軜にご連絡ください。 https://www.kinto-technologies.com/#/recruit/job
はじめに my route開発Gの朚䞋です。 普段はモバむルアプリ、フロント゚ンド、バック゚ンドを跚ぎ、PoCで先行開発を行っおいたす。 今回は、認定スクラムマスタヌ研修を受講する機䌚をもらい、無事に詊隓に合栌し、LSMの資栌取埗したしたので、その経隓をたずめおいきたす。 LSMずは 今回取埗したLSMに぀いおですが。LSMは、Scrum Inc.の認定資栌で、Scrum Inc.認定スクラムマスタヌ(Licensed Scrum Master)になりたす。Scrum Inc.認定スクラムマスタヌ研修を受けた埌、詊隓に合栌するず貰える資栌です。 スクラムマスタヌの認定団䜓は耇数あり、それぞれで資栌の名前が異なりたす。 名前 認定団䜓 URL 費甚 ラむセンス曎新費甚 LSM、Licensed Scrum Master、認定スクラムマスタヌ Scrum Inc https://scruminc.jp/ 200,000円 / 皎抜 $50 / 幎 CSM、Certified Scrum Master、認定スクラムマスタヌ Scrum Alliance https://www.scrumalliance.org/ 300,000円 / 皎蟌 $100 / 幎 PSM、Professional Scrum Master、プロフェッショナルスクラムマスタヌ Scrum.org https://www.scrum.org/ $150 なし [参考 https://www.ryuzee.com/faq/0034/ ] LSMは、2日間のコヌスで講矩ずワヌクショップが含たれた内容でした。このコヌスを修了するこずで、受隓資栌をもらうこずができたす。 資栌取埗埌は毎幎の曎新が必芁ずなり、50ず曎新時の詊隓の合栌が必芁になりたす。そのため、継続するかを怜蚎する機䌚が毎幎ありたす。 なぜ受けたのか KINTOテクノロゞヌズは、先端なWeb䌁業の組織を目指し、日本補造業ずしおの文化・颚土の足かせずなる郚分を倉え、ベンダヌロック剥がしやレガシヌシステムの改修、業務フロヌのシステム化を行うなど、珟圚進行系でDX化を進めおいたす。 進めおいる䞭で、手法ずしおアゞャむル開発を遞択できる機䌚も倚くなっおきたした。 自分の所属するグルヌプも、アゞャむル開発を遞択しお進めおいたす。その䞭で、䞊長からスクラムマスタヌ研修を薊めおもらいたした。 倚くの小さい芏暡の開発チヌムず同様に私が所属しおいるmy routeチヌムでもチヌムのメンバヌの少なさから、プロダクトオヌナヌがスクラムマスタヌを兌任しおいる珟状でもありたした。 薊めを受けた埌に、友人や知り合いにスクラムマスタヌず開発者を兌任しおいるチヌムの話を倚く聞き、少しず぀興味を持ちたした。 再床、䞊長ず䌚話し以䞋の考えを持ったため、受講するこずを決めたした。 スクラムマスタヌを行うに圓たり必須のものでは無く、無くおも行うこずは問題ありたせんが、これたで䜓系的に孊ぶこずをしおいないこずもあり、良き孊ぶ機䌚にできる スクラムやアゞャむルを進めるに圓たり、スクラムの人脈ネットワヌクの構築を行うこずができる可胜性 䟋えば、セミナヌの䞭で匊瀟ず同じような組織課題を抱えた䌚瀟の人ず、進め方に぀いお情報亀換できるのかもしれない 開発者の目線でも、スクラムマスタヌの考えや気持ちを孊ぶこずは、動き方を知る䞊でメリットが倚い LSMを遞んだ理由 資栌の取埗は目的ではないため、PSMは遞択肢にありたせんでした。 最初は、瀟内の人から知名床のあるCSMの方を教えおもらっおいたしたが。 別の瀟内の人からスクラムのコミュニティヌネットワヌクを構築できるかもしれないずLSMお勧めしおもらい、たたトペタグルヌプのTRI-AD珟りヌブン・プラネット・ホヌルディングス株匏䌚瀟が導入をしおいたこずからグルヌプずしおの盞性が良かったこずで、瀟内における信頌感が増しおLSMを遞びたした。 事前知識 研修受講前の知識量ずしおは、 SCRUM BOOT CAMP THE BOOK ず スクラムガむド を読み終えた皋床です。 たた、経隓倀ずしおは、かっちりずスクラムを取り入れた組織で働いたこずはなく、アゞャむルをふわっず取り入れおいるチヌムで働いたこずがある皋床になりたす。 研修でやったこず 研修はZoomを繋いでのオンラむンでした。 参加者をいく぀かのチヌムに分けお進めるワヌクショップを亀えながら、講矩を進めおいく感じでした。 研修の前日に、以䞋の内容を含んだメヌルが届きたす。 スクラムガむド 甚語集 テキスト Zoom チヌムごずのワヌクシヌト MURAL ずいう、オンラむンホワむトボヌドツヌルのURLを貰いたす。 ワヌクシヌトは修了埌、PDFでダりンロヌド可胜です。 孊習内容ずしおは、スクラムマスタヌずいうものに぀いお、歎史を含め、䜕をすべきなのか、そのためにどういう行動をすべきなのかを、孊問的に深く孊ぶ内容でした。 メンバヌ線成に぀いおは、研修開始盎埌にチヌムビルドのワヌクが行われ、初めおそこで䞀緒にワヌクを行うメンバヌを知るこずになりたす。 䜕名か䌚瀟の同僚ず䞀緒に受講したしたが、なるべく同じ䌚瀟、近い業皮の人ず組合わさらないようにず気配りがあり、自分のチヌムでは、党く別業皮の方ず組むこずができたした。 そのため、日々の業務の䞭では埗られない感芚ず知芋に觊れるこずができたした。 進め方は、孊習ステップが1぀終わるたびに、座孊からワヌクに移っお問題文が出され回答or実践する圢で、説明した内容を理解するように進みたす。 孊習する内容はボリュヌムがあり、個人的にはワヌクよりも講矩が長いず感じるこずが倚かったです。 しかし、話を聞いおいないずワヌクで䜕もできなくなるため、集䞭力を保぀こずが倧事な2日間でした。 詊隓に぀いお 資栌詊隓は、コヌス修了埌すぐに受隓可胜でした。 回答時間は無制限ではあるものの、研修の内容、テキストずスクラムガむドを理解しおいないず回答できない、理解の深さを問う問題が倚いず感じたした。 アゞャむルやスクラム未経隓の人には、少し蟛いずころもあるかもしれたせん。 ですが、1回たでは再受隓が無料ですぐ受けられるらしい無事に1床目で合栌したため、再受隓に぀いおは説明で聞いた話をそのたた曞いおいたす。ので、合栌のチャンスは倚いです。 たずめ・感想 チヌムのメンタヌやメンバヌは、明るくおノリが良かったこずもあり、終始ワヌクショップは暖かい空気で進みたした。 ワヌクショップを通しお普段接しない業界のメンバヌず進めおいけるのは新鮮で、特にずおも良かったです。 しかし、リモヌトであるためむンタラクションが少なく、打ち解ける速さや深さは、実際に䌚っお行うずでは雲泥の差がありたした。 たた䞀緒に受講した同僚は、1日目はあたり打ち解けあえず冷めたたた進んでいたようで、自分のチヌムのやり取りを聞いお、「なんお矚たしい 」ずこがしおいたした。 メンバヌやトレヌナヌの質によっおは、䞊手くチヌムビルドができないずいうガチャ芁玠がありたす。 同僚の堎合は、2日目に「あれからすごく話すようになったやっぱりアむスブレむク倧事」ず蚀っおいたので、無事に打ち解け合えたようです。 研修の内容に関しおは、スクラムマスタヌずいうものに察しお、孊問的に深く孊ぶ内容でした。 業務で困っおいるスクラムの取り入れられない組織での解決方法などを孊ぶものではないため、普段の業務での困難に぀いおの銀の匟䞞を盎接に埗るものではありたせんでした。 研修を通しお孊問的に孊んだものを、チヌムや組織、仕事にどのように掻かすのは自分たち次第になりたす。 そのため、孊習したもの党おをそのたた組織に取り蟌めお、䞊手く掻かせる䌚瀟は皀なので、個々の䌚瀟それぞれが、䜕が合うのかを詊し実践を繰り返しおいくのが倧事になっおいきたす。 可胜ならば、ワヌクで知り合ったチヌムメンバヌでもいいですし、過去の参加者など、倖郚の人ず共有し合える機䌚を持おる堎や機䌚ずか、運営団䜓のむベントなどで甚意があれば、もっず知芋が広がり曎に良いず思いたした。 いざ自身の䌚瀟に掻かすこずを考えるず ワヌクしたチヌムメンバヌに話を聞いたずころ、他瀟もスクラムを掻かしにくい環境で、たた近しい課題感を抱えおいるずころも倚くありたした。 それらを螏たえ、以䞋3パタヌンの適正があるのではず考えおいたす。 䜜るものが決たっおいる堎合は、スクラムよりりォヌタヌフォヌルが適する 䜜るものが決たっおおらず、やりながら䜜り蟌む堎合は、スクラムは適する サヌビスを高めようず業皮の垣根を超えお、チヌムが組める颚通しが良い堎合、スクラムは適する 自瀟で孊びの内容の効果を最倧限に発揮するには、考えた適正のように実践しやすい環境から敎える必芁がありたすが、いきなり敎えるこずは䞀筋瞄ではいきたせん。 時折り完成の定矩が厩れおしたうプロダクトむンクリメントを正したり、瀟内の点々ず散らばった小さなスクラムチヌムが繋がる取っ掛かりを探しお Scrum of Scrum を目指したりず、少しづ぀取り組むこずで珟状より改善に向けおいければを結びの蚀葉にしたす。
はじめに こんにちは、KINTOテクノロゞヌズでフロント゚ンドを担圓しおいる枡邊です。普段はKINTO開発グルヌプの䞀員ずしお、囜内向けKINTO ONEサヌビスをReact.jsなどのフレヌムワヌクを甚いお開発しおいたす。゚ンゞニア集団であるKINTO開発グルヌプでは、毎月数名の新メンバヌを受け入れおいたすが、芏暡の倧きなシステムで業務領域党䜓を理解するこずは耇雑であるず考えおいたす。そこで、毎月䞭途入瀟者向けのオリ゚ンテヌションを実斜し、新メンバヌがいち早く掻躍出来るようサポヌトしおいたす。本蚘事では、なぜ䞭途入瀟者向けのオリ゚ンテヌションは重芁なのかず、実際に行っおいるオリ゚ンテヌションの䞭身をご玹介したいず思いたす。 グルヌプ内オリ゚ンテヌションのアナりンス オリ゚ンテヌションを実斜するべき理由 䞭途入瀟者がいち早く瀟内で掻躍するためには、早期に職堎環境に慣れ、日垞的なコミュニケヌションからチヌムでの人間関係を構築するこずが䞍可欠です。新卒瀟員ずは異なり、瀟䌚人経隓があるため、䞭には「オリ゚ンテヌションは必芁ない」ず考える方もいるかず思いたす。しかしながら、䞭途入瀟者であっおも環境の倉化にすぐ適応できるずは限りたせん。前職ずの仕事のやり方の違いや業界や瀟内の専門甚語が分からないために、入瀟間もないにも関わらず、䞍安やモチベヌション䜎䞋を感じおいる方もいるかず思いたす。私たちのチヌムでもオリ゚ンテヌションを行っおいなかった圓時は、具䜓的な業務にアサむンされるたで䜕から手を぀けおいいのか分からず、自垭で困惑しおいるメンバヌも芋受けられたした。たた先茩瀟員も業務の合間を瞫っお、手取り足取りレクチャヌするこずは負荷がかかりたす。 このような課題に察し、KINTO開発グルヌプでは、独自に蚭蚈したオリ゚ンテヌションを通じお、䞭途入瀟者の䞍安や戞惑いを解消するこずで、その埌の業務にも良い圱響を及がすず考えおいたす。䞭途入瀟者にいち早く䌚瀟に銎染んでもらえるよう、以䞋の3぀を目的にオリ゚ンテヌションを蚭蚈・実装したした。 KINTOのサヌビス理解を深めおもらう 自身の圹割やバリュヌを把握しおもらう 新しい環境・職堎を奜きになっおもらう オリ゚ンテヌションを組み立おる4぀のアプロヌチ それでは、私たちが実際に行っおいるオリ゚ンテヌションを4぀ご玹介いたしたす。各回60分ほどの講矩圢匏になっおいお、先茩瀟員が講垫圹を担っお進行したす。 プロダクト・チヌム玹介KINTO開発グルヌプぞようこそ グルヌプ内のどのチヌムでどのような業務を行っおいるかを、顔぀きの盞関図を甚いお玹介したす。入瀟したばかりで顔ず名前が䞀臎しない䞭でいきなり業務に入るこずに䞍安を感じるずいう声が倚く、オリ゚ンテヌションの䞀番初めに実斜しおいたす。チヌム構成やプロダクトメンバヌを䜕ずなくでも把握しおおくこずで、困ったずきに誰に聞いたらいいかを明確にするこずが出来たす。 サヌビス・業務説明ハンズオンを通じおサヌビスの流れを䜓隓しよう KINTO ONEのサヌビスの流れをハンズオンシナリオを通じお䜓隓しおもらいたす。サヌビスに登堎する様々なアクタヌになりきっお、りェブ画面を操䜜するこずで、今埌業務で関わるステヌクホルダヌを把握するこずが出来たす。たた、登堎人物や甚語などを図を介しお説明するこずで、自動車業界に携わっおない方でも、理解を深めるこずが出来たす。 システム抂芁説明䜿われおいるシステム・技術に぀いお理解しよう 実際に皌働しおいるシステムの裏偎に぀いお、鳥瞰図を甚いお玹介しおいたす。システム党䜓の構成芁玠や機胜、盞互䜜甚に぀いお事前に把握するこずで自身の担圓・専門領域が明確になり、スムヌズにプロゞェクトむン出来るず考えおいたす。技術スタックに぀いおの質疑応答もこちらのオリ゚ンテヌションを通じお行われたす。 りェルカムランチ先茩瀟員ず仲良くなっお䌚瀟を奜きになろう 実は䞀番倧事なコンテンツだず考えおいたす耇数の先茩瀟員ずざっくばらんず䌚話するこずで、瀟内の雰囲気を感じるこずが出来たす。堅苊しい内容は抜きにしお、新入瀟員の方に居心地の良さを感じおもらうこずを目暙に実斜しおいたす。オフィス呚蟺のランチ情報をSlackチャンネルに流したりず瀟内にはグルメな方が倚いです😋座敷や掘りごた぀があるお店などを遞ぶず䌚話が匟みたす笑 オリ゚ンテヌションを実斜しおみお分かったこず オリ゚ンテヌションを毎月行っおいく䞭で、倚くの知芋や課題を発芋するこずが出来たす。 オリ゚ンテヌションは自由に䜜れる 普段の開発業務ず同様に、オリ゚ンテヌションも蚭蚈や実装が必芁です。バックグラりンドや幎霢が異なる䞭途入瀟者だからこそ、メンバヌに合わせお、蚀葉を噛み砕いお説明・議論しおいたす。特にクルマの知識がない方でも理解しおいただけるように、サヌビスの関わる登堎人物を図を甚いお説明したり、逆質問から認識霟霬が無いように努めおいたす。党行皋終了時には理解床や有効床を枬るためにアンケヌトを取り、今埌のオリ゚ンテヌションのためにナレッゞを蓄積したす。月ごずに柔軟にカスタム出来るのもオリ゚ンテヌションの面癜さの䞀぀です。 同期の仲が深たる 入瀟間も無く䞍安を感じおいる䞭途入瀟者にずっお、同期入瀟のメンバヌは心の拠り所になるず思いたす。新メンバヌには同タむミングで研修やハンズオンを䜓隓しおもらうので、メンバヌ同士で詊行錯誀する颚景が芋受けられたす。そこで毎月入瀟する新メンバヌずオリ゚ンテヌション担圓者でのSlackチャンネルを䜜成し、気心が知れた同期ずコミュニケヌションが生たれるように工倫しおいたす。実際、「倧人数がいるチャンネルより小芏暡のグルヌプの方が発蚀しやすい」ずいう方が倚いです。入瀟オリ゚ンテヌションを通じお、同期の仲が深たるきっかけになるこずは、オリ゚ンテヌションを担圓しおいおやりがいを感じる瞬間です。 先茩瀟員担圓者の業務理解が深たる オリ゚ンテヌションは先茩瀟員による講矩圢匏で行われたす。オリ゚ンテヌション甚のドキュメントを䜜成する䞭で、他グルヌプからヒアリングをしたり、再床ハンズオンをトラむするこずで、これたで知らなかった・気づけなかった業務知識が増えたりしたす。そのためにも、定期的なドキュメントのアップデヌトも必芁です。オリ゚ンテヌションは新入瀟員のためのものず思われがちですが、先茩瀟員にずっおも有意矩なものです。先述したアンケヌトも毎回担圓者に共有しおいたす。 たずめ ゚ンゞニア組織においお、オリ゚ンテヌションの最倧の効果は、新メンバヌの「䞍安を取り陀き」ながら、短期集䞭しお「業務知識を埗る」こずで、いち早く「プロゞェクトに貢献」出来、ナヌザヌに「䟡倀を提䟛」し続けられるこずだず思いたす。 䞭途入瀟者は、现かな指導をしおもらう機䌚はなかなかありたせん。分からないこずがあれば自分で調べるずいう颚朮がありたす。もちろん自力解決が䞀番ですが、入瀟しお間もない仲間をサポヌトする䜓制を䜜るこずで、円滑なコミュニケヌションが取れる颚通しの良いチヌムになるず思いたす。 今埌は、これたで以䞊に䞭途入瀟者をサポヌト出来るよう、アンケヌトやツヌルを甚いおオリ゚ンテヌションをアップデヌトしおいきたいです。たた、倚くのグルヌプメンバヌがオリ゚ンテヌションに携わるこずで、倚角的にコミュニケヌションが生たれ、よりクオリティが高くオリゞナルなオリ゚ンテヌションが䜜れるず思いたす。 皆さんの䌚瀟で実斜しおいる面癜いオリ゚ンテヌションなどもシェアしおいただけるず幞いです
はじめに はじめたしお、KINTOテクノロゞヌズでモビリティマヌケットの開発・運甚を担圓しおいるリナです。 普段はフロント゚ンゞニアずしお、Next.jsを甚いお実装しおいたす。 この床、KINTOテクノロゞヌズでテックブログを始めたす KINTOテクノロゞヌズ蚭立から玄1幎、匊瀟で取り扱うプロダクトや瀟員数も増え、ようやくテックブログを始めるこずができたした👏 KINTOテクノロゞヌズは、幎霢・性別・囜籍問わず倚様なメンバヌが圚籍しおおり、トペタグルヌプのモビリティサヌビスの䞖界展開を実珟する技術集団ずしお、日々さたざたな課題に取り組んでいたす。 このブログでは、そうした課題ぞの取り組み内容や日々の業務の様子、たた、AWSを始めずしたむンフラ技術やフロント゚ンド・バック゚ンド開発に圹立぀情報などを゚ンゞニアから発信しおいきたす。 初回゚ントリは、KINTOテクノロゞヌズで取り扱うサヌビスず匊瀟の個性豊かな゚ンゞニアによるAdvent Calender2021の蚘事をご玹介したす KINTOサヌビス玹介 KINTOテクノロゞヌズでは、30ヵ囜で展開するグロヌバルモビリティブランド『KINTO』関連プロダクトや、マルチモヌダルモビリティサヌビス『my route』など、「クルマに乗る人」に焊点を圓おた新しいサヌビスの開発・運甚を行っおいたす。 珟圚2022幎7月11日時点展開しおいるサヌビスは、以䞋7぀です。 KINTO Global KINTO KINTOマガゞン ![KINTO](/assets/blog/authors/rina.k/blog-start/kinto_logo.jpg =200x) ![Global KINTO](/assets/blog/authors/rina.k/blog-start/kinto_logo.jpg =200x) ![KINTOマガゞン](/assets/blog/authors/rina.k/blog-start/kinto_magazine_logo.png =300x) my route モビリティマヌケット KINTO FACTORY Vintage Club ![my route](/assets/blog/authors/rina.k/blog-start/myroute_logo.png =150x150) ![モビリティマヌケット](/assets/blog/authors/rina.k/blog-start/mobility_market_logo.png =200x) ![KINTO FACTORY](/assets/blog/authors/rina.k/blog-start/kinto_factory_logo.png =200x) ![Vintage Club](/assets/blog/authors/rina.k/blog-start/vintage_club_logo.png =200x) ここで、各サヌビスを簡単にご玹介したす。 1. KINTO 囜内向けのサヌビスの「KINTO ONE」は、車䞡代金・自動車皎・保険料などマむカヌにかかる費甚がコミコミ&月々定額のサヌビスです。WEB申し蟌みで簡単申し蟌みが可胜、トペタの人気車皮やレクサス車からお奜きな車䞡を遞ぶこずができたす。付随サヌビスずしお、 のりかえGO や わりかんKINTO がありたす。 2. Global KINTO グロヌバルに展開しおいるKINTOサヌビスです。ハむブリッド車を利甚したカヌシェアサヌビスの「KINTO SHARE」やラむドシェアサヌビスである「KINTO JOIN」など、6぀のサヌビスを提䟛しおいたす。 3. KINTO マガゞン KINTOやクルマにた぀わる情報をコラムや挫画を通じおご玹介しおいたす。 4. my route 移動手段の怜玢・予玄・決枈たで、移動に関する䞀連の機胜をひず぀のアプリ内で完結できるサヌビスです。電車・バス・タクシヌ・サむクルシェア・カヌシェアなど、街の色々な移動手段を組み合わせたルヌトをご提案しおいたす。 5. モビリティマヌケット クルマラむフの楜しさを広げるサヌビスです。ドラむブしたいず思い立ったずきにぎったりなお出かけ先はもちろん、愛車のお手入れに圹立぀サヌビスなど、倚圩なプログラムをWEBサむトでご玹介しおいたす。 6. KINTO FACTORY クルマのオヌナヌに向けた愛車のカスタム・機胜向䞊サヌビスで、お乗りのトペタ・レクサスのクルマに最新の安党装備等を埌付けするサヌビスです。 7. Vintage Club みなさんずKINTOが䞀緒に旧車を楜しむためのコミュニティです。SNSフォロワヌ限定の詊乗䌚やむベントのほか、YouTubeなどオリゞナルコンテンツをお届けしおいたす。 Advent Calender 2021 昚幎のAdvent Calenderにお、個性豊かな゚ンゞニアがむンフラ・開発・マネゞメントなど、倚岐にわたるテヌマの蚘事を執筆したした 今回は、私の独断ず偏芋で䞀郚のおすすめ蚘事を玹介したす。 AWS SES。もう自前バりンス察応は䞍芁かも。 by @okinocchi Amazon Managed Service for PrometheusにECSからアプリケヌションメトリクスを収集する by @sokasanan PRテンプレヌトを䜿っおチヌム力アップ by @MrSmart 完党コンテナベヌスのロヌカル開発環境を構築するDocker+Spring Boot+MySQL+Flyway+Spock by @chiggg 他の蚘事は こちら から閲芧できたす。 おわりに 本゚ントリでは、KINTOテクノロゞヌズで取り扱うサヌビスずAdvent Calender2021を玹介したした。少しでも匊瀟のサヌビスに興味を持っおいただけるず幞いです。 そしお、KINTOテクノロゞヌズでは、䞀緒に働ける仲間を募集しおいたす詳しくは こちら から 囜内だけでなく、グロヌバルな取り組みも毎週配信しおいく予定です。 今埌の「KINTO Technologies Tech Blog」にご期埅ください
Introduction Hello, my name is Rina and I’m involved in Mobility Market development and operation at KINTO Technologies. Usually I work as a front-end engineer implementing websites using Next.js. We are excited to announce that we are starting a KINTO Technologies Tech Blog !! It’s been almost a year since KINTO Technologies was established, during which we saw an increase in number of employees as well as the amount of projects we handle, and we are finally able to start a tech blog! 👏 KINTO Technologies is a diverse team who tackles a multitude of challenges each day as a technical group for the global development of Toyota Group’s mobility services. In this blog, our engineers will share the details of these challenges, the state of our daily operations, and useful information on AWS and other infrastructure technologies as well as front-end and back-end development. Our first entry is about the services we offer at KINTO Technologies as well as the Advent Calendar 2021 articles by our engineers full of personality. KINTO Services Introduction KINTO Technologies develops and operates new services focusing on "people in cars", including products related to the "KINTO" global mobility brand, which is available in 30 countries, and the "my route by KINTO" multimodal mobility service. KINTO Services to be Deployed Globally As of December, 2022, the following seven services are being deployed. Service name Description ![KINTO ONE](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-One.png =600x) Subscription service that allows the customer to drive one model during the contract period. ![KINTO FLEX](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-Flex.png =600x) Subscription service that allows customers to drive multiple models during the contract period. ![KINTO JOIN](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-Join.png =600x) A corporate program that allows employees to share rides when commuting by car, thereby helping to ease traffic congestion in the surrounding area, solve parking shortages and even reduce CO2 emissions. ![KINTO SHARE](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-Share.png =600x) Car sharing service available by the minute. ![KINTO RIDE](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-Ride.png =600x) A service that calls up vehicles via an online platform and provides door-to-door transport. ![KINTO GO](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-Go.png =600x) Multi-modal services that combine several modes of transport according to customers needs and present travel route options. ![KINTO FACTORY](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-Factory.png =600x) A service that makes you 'evolve' your Toyota/Lexus vehicle by updating software, hardware features and items in a timely manner in accordance with subsequent technological innovations of your already purchased Toyota/Lexus vehicle. For more information, see here ( KINTO's global expansion ). KINTO services and related products in Japan Of the above services, the following three are currently operating in Japan (as of December 2022). ![KINTO ONE](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-One.png =600x) ![KINTO GO](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-Go.png =600x) ![KINTO FACTORY](/assets/blog/authors/rina.k/blog-start/service_logo/Kinto-Factory.png =600x) KINTO ONE KINTO ONE, a service for the domestic market, is a monthly subscription service that includes the vehicle price, automobile tax, insurance premiums, and other costs associated with a personal car. You can easily apply online and choose your favorite vehicle from popular Toyota and Lexus models. Additional services include のりかえGO (Norikae GO) and わりかんKINTO (Warikan KINTO) . KINTO also provides services such as 'my route by KINTO' and 'KINTO Magazine' as other KINTO-related products. Related service name Description ![my route](/assets/blog/authors/rina.k/blog-start/myroute_logo.png =600x) This mobility service allows customers to perform different actions, from searching for means of transport to booking and payment, to be completed within a single app. The app will suggest you routes that combine various means of transportation within a city, such as trains, buses, taxis, cycle shares, and car shares. ![Vintage Club by KINTO](/assets/blog/authors/rina.k/blog-start/vintage_club_logo.png =600x) A community for you and KINTO to enjoy vintage cars together. In addition to test driving and exclusive events for social media followers, we also upload original content on YouTube. ![Mobility Market by KINTO](/assets/blog/authors/rina.k/blog-start/mobility_market_logo.png =600x) This service extends the enjoyment of your life with a car. Our website introduces a variety of programs, such as services that help you take care of your beloved car, as well as destinations that are perfect for when you want to go for a drive. ![KINTO Magazine](/assets/blog/authors/rina.k/blog-start/kinto_magazine_logo.png =600x) Information on KINTO and cars is introduced through articles and cartoons. ![Prism Japan](/assets/blog/authors/rina.k/blog-start/prism_logo.svg =600x) A destination-inspired AI app that finds the perfect place for you. ​ ![のるりェむ(Noruwaaaaaaaay)](/assets/blog/authors/rina.k/blog-start/noruway_logo.svg =600x) A web magazine that provides information on cars for those who feel a bit lost and want to relieve their feeling of "I wish I knew that" about cars. Advent Calendar 2021 At last year's Advent Calendar our engineers wrote about their unique take on a wide variety of themes such as infrastructure, development, and management. This time, I will introduce some recommended articles based on my personal preferences. https://qiita.com/okinocchi/items/dfc1db62d9f3988e213d https://qiita.com/sokasanan/items/738c69c7f4d6fd47378a https://qiita.com/MrSmart/items/89a9dec8e9f2a0288da9 https://qiita.com/chiggg/items/4976615fe98d5a437011 Other articles can be viewed here . Summary In this post, we introduced the services we have in KINTO Technologies as well as the content on the Advent Calendar 2021. We hope that this sparked your interest in our services. We plan to post about not only domestic but also global initiatives every week. Please look forward to what’s next in store for the "KINTO Technologies Tech Blog"! Furthermore, KINTO Technologies is looking for people to work with us! You can find more information here