TECH PLAY

株式会社メルカリ

株式会社メルカリ の技術ブログ

261

こんにちは。メルカリのBackendエンジニアの @osari.k です。 この記事は、 Mercari Advent Calendar 2023 の9日目の記事です。 一般に大きなプルリクエストはレビューが大変で、マージまでに時間がかかります。一方で複数の小さいプルリクエストに分割するとコードレビュー待ちの間、関連する開発がブロックされることがあります。今回は機能の開発時間を短くするために、チームで試したGitのブランチ戦略の1つであるStacking手法をケーススタディを交えて紹介します。 大きなプルリクエストがもたらす問題点 大きなプルリクエストがもたらす問題とは何でしょうか? コードレビューで読むサイズが増える コードレビュー中の修正回数が増える(可能性が増える) コードレビューで必要な知識の範囲が広がる(可能性が増える) 変更箇所が多いのでリリースのリスクが増加する プルリクエストが大きいということは、含まれる変更箇所が多いということです。それはつまり、コードレビューで読むサイズが増え、レビューの観点も増え、レビューにあわせて行われる修正も多くなるでしょう。 モノリシックなレポジトリの場合コード全体に精通しているエンジニアは少なく、一般に複数のドメインにまたがる変更の場合、複数のチームからレビューの承認を貰わなければなりません。 大きな変更を一度にリリースすると、障害が発生する可能性が増加し、障害が発生したときに原因の特定も難しくなります。 一方で、関連する変更を複数の小さいプルリクエストに分割すると、コードレビューの間関連する次の作業が進められないという課題もあります。 Stacking手法による小さいプルリクエストの推進 本記事ではこれまでに述べた問題を改善するために私達のチームが試してみたStacking手法について得られた知見を共有したいと思います。 Stacking手法は以下のBlogで紹介されています。 Stacked Diffs (and why you should know about them) 関連する部分を要約すると、Stacking手法は、1つの大きな変更を分割して管理できるようにするプロセスです。ある変更が別の変更に依存している場合、それらは変更差分のスタックとして組み立てられ、正確な順序でマージされます。プルリクエストに対してさらに機能を追加するプルリクエストを作る様をスタックと例えています。これにより、変更をレビューしやすくなります。 合わせて、Stacking手法は複数の作業を並行して行うのに役立つという利点もあります。各段階で作業を終了させることができるため、時間を節約できます。以上のように、Stacking手法はコードの変更の複雑さを管理するための強力な手段であり、上手く実装した場合、生産性と効率性を高めることができます。 本来は上記のBlogで紹介されているスタック間の差分を見やすくするツール( ReviewStack  など)と組み合わせて使うのがいいと思います。 この手法はチームメンバーがSlackで共有してくれて、一度チームで試してみようということでGitHubのプルリクエスト機能のみを使い試しました。 Stacking手法の目的 なぜこの手法を試すのか、それはコードレビューで開発者の他の開発をブロックしないためです。 例えばある機能を実装するときにそれを部分タスク PR1,PR2,PR3に分割し、PR2がPR1に依存、PR3がPR2に依存といった依存関係があるとしましょう。 図1: プルリクエストの依存関係 通常のプルリクエストの作り方の場合、PR1のマージが終わるまでPR2, PR3の開発はブロックされます。 ※実際には開発者はローカルでの開発は可能ですし、PR1がマージされる前にPR2のコードレビューを依頼することもできます。GitHubのプルリクエスト機能のみで試す場合に重要なのはチームで認識を揃えることだと思います。Stacking手法を使うことを共有しておくことで、混乱なくコードレビューがスムーズになります。 この方法は1人の開発者が自分のプルリクエストに依存した開発をコードレビューにブロックされずに行うためのものなので、複数人で関連機能を開発する場合には向きません。 というのも、Stacking手法は定期的にRebaseが発生します。自分だけなら、Rebaseの影響範囲や、影響が出るタイミングをコントロールできますが、複数人の場合頻繁なRebaseは開発効率を落とします。 モノリシックなレポジトリに実装されているマーケティングシステムの改善での実例 今回Stacking手法を試した一連の機能変更について紹介します。 今回はマーケティングシステムのスケーラビリティ改善に対してStacking手法を適用しました。今回改善を行うマーケティングシステムはモノリシックなレポジトリに実装されています。 ディスカウントを適用する前に商品のいくつかのデータをチェックします。そのうちの一つは別のマイクロサービス(Validation MS)の持つデータを用います。 Validation MSへのクライアント機能、その結果を使いやすいように変換する関数がモノリシックなレポジトリに実装されています。 MSごとに別々のチームがメンテナンスしており、意図した変更を達成するにはマーケティングシステムとは異なるValidation MSのドメイン知識が必要になります。 マーケティングシステムは定期的に実行されるCronjobとWorkerがQueueで接続されています。処理すべきデータは複数あり、Cronjobから処理すべき商品のIDをQueueに送り、Workerで個別にValidation MSのAPIを利用して処理を行います(図2)。 図2:改善前のシステム構成 Validation MSのAPIはBatch呼び出しもサポートしているので、Cronjob側でBatch APIを用いて事前処理をし、Worker側ではValidation MSへのアクセスをしない形にすることでスケーラビリティの改善を試みました(図3)。 図3: 改善後のシステム構成 簡易検証を行った後に、プルリクエストを作成しました。 Stacking手法で作成したプルリクエストは6つです 不要な変数の削除 不要なロジックの削除 不要なメソッドの削除 Validation MS関連機能のユニットテストの改善 Validation MSのBatch エンドポイントの結果変換メソッドの修正 WorkerからCronjobにValidatio MSの呼び出しとチェック機能の移動 プルリクエスト1~3では4以降で安全に変更するために、不要なコードを削除をして全体の見通しを良くしています。不要な変数を削除(プルリクエスト1)すると、不要なロジックが削除(プルリクエスト2)できて、不要なメソッドの削除(プルリクエスト3)に辿り着くという依存関係があります。 プルリクエスト4と5はValidation MSの開発チームと協力して実装・コードレビューをしてもらいました。メソッドのシグネチャが定まれば、マーケティングシステムチーム内で並行してプルリクエスト6を実装・コードレビューをしてもらうことができます。 図4: Stacking手法を用いた場合の開発フロー 上述のように各プルリクエストは自分より小さい番号のプルリクエストに依存しています。 そのため、Stacking手法でない場合、開発者は毎回コードレビューでブロックされてしまいます。 Stacking手法を用いた開発タイムライン Stacking手法で実際に開発がどうなったかをイメージしやすいように、今回の事例について一連の変更のデータをGitHubとSlackから取得しタイムラインとしてまとめました(図5)。 開発フェーズを以下の3つに分類しました 準備:コーディング前に情報収集や実装方針を議論する期間 コーディング:コードを書き始めてからレビューを依頼するまでの期間 今回は最初のCommitをコーディング開始時刻としました。 コードレビュー:Slackでコードレビューを依頼してからGitHub上でApproveされるまでの期間 図5の開発タイムラインのように、開発がコードレビューにブロックされていないことと、並行してプルリクエストのレビューをしてもらった様子がわかります。 今回の開発ではPoCにより大枠の方針を定めた後に実際の開発を進めており、結果として各プルリクエストのコーディングフェーズが短くなっています。 図5: Stacking手法を用いた開発タイムライン Stacking手法の評価 この一連の変更でStacking手法を使ったことで、得られたメリットは以下になります。 1: プルリクエストのサイズを小さく保てた 評価のために、プルリクエストを分割しなかった場合のプルリクエストサイズとStacking手法の各プルリクエストのサイズを比較してみます(表1)。ここでは以下の定義で比較します Diff: 追加行数と削除行数 プルリクエストサイズ: 追加行数と削除行数の合計値 比較すると、一番大きなPR4で40%のサイズになっており、他は13%〜22%のサイズになりました。 Stacking手法ではプルリクエストのレビューに後続の開発がブロックされないため、待ち時間の増加を気にせず、適切な粒度でプルリクエストを作成できました。 特に顕著なのがプルリクエスト1,2,3の分割だと思います。不要なコードの削除を1つのプルリクエストにまとめず、レビュアーにも理解がしやすい形で作成できました。 また、分割した各プルリクエストサイズの合計についても分割しなかった場合と比較して102%のサイズで、わずかに増加していますが分割のメリットを考慮すると許容範囲でしょう。 表1: Stacking手法各プルリクエストサイズの比較 プルリクエスト Diff追加行数 Diff削除行数 プルリクエストサイズ 分割無しと比較したプルリクエストサイズ 分割無し +615 -837 1452 — PR1 +2 -5 7 0.5% PR2 +48 -268 316 22% PR3 +0 -186 186 13% PR4 +318 -269 587 40% PR5 +114 -72 186 13% PR6 +149 -53 202 14% PR1〜6の合計 +631 -853 1484 102% 2: レビュー依頼開始からApproveをもらうまでの時間を短く保てた Validation MSのBatch エンドポイントの結果変換メソッドの修正を行うPR5はValidation MSのドメイン知識が必要だったため、今回はSlack上で大枠の説明をしてもらったあとに、プルリクエストレビューを通じてドメイン知識の獲得を行う方法で進めました。そのためPR5のレビューには時間がかかっています。 それ以外のプルリクエストはレビュー依頼の翌日にはレビューが完了してマージできたため、効率よく開発を進められました。 3: コードレビュー中に開発を並行して進めることができた 図5の開発タイムラインを見るとレビュー中に最初のcommitを行っていることがわかります。 実際には最初のCommit前から開発をしているため、コードレビューにブロックされることなく後続の開発を進められていることが確認できます。 コーディングと同様にコードレビューも並行して行われていることがわかります。 通常の分割手法を行った場合はレビューが完了するまで後続の開発を行わないため、コードレビューも並列で行われません。そこで、各プルリクエストのレビュー時間の合計を通常の分割手法の場合のレビュー時間と仮定します。 Stacking手法によるレビュー時間をPR1のレビュー依頼からPR6のApproveとして比較すると、Stacking手法によりレビュー時間を7%削減できたことになります。 実際には並列でコードレビューを行わないことで、各プルリクエストのコードレビュー時間が短くなる可能性もありますが、プルリクエストはGitHub上のコメントによる非同期なコミュニケーションが主であることから、相手からの返信を待つ時間が支配的となるため複数のプルリクエストを並列で行うメリットは大きいと考えられます。 4: コードレビューを専門性のある別々のチームに依頼できる Validation MSドメインにフォーカスした小さいプルリクエスト(PR4, PR5)はマーケティングシステムの詳細を知らないValidation MSチームがレビューしやすくなっています。結果としてValidation MSチームの複数名の開発者がレビューに参加してくれて、コードの質が向上しました。 具体的には、当初はマーケティングシステムに実装されていたValidation MSのSingle IDエンドポイントの変換メソッドとBatchエンドポイントの変換メソッドの詳細が異なっており、マーケティングシステムの挙動を変えないために、Single IDエンドポイントと同じ変換を行う新規Batchエンドポイントの変換メソッドの作成を考えていました。それがValidation MSチームとSlack上で議論していく中で、この実装の詳細の差分は、既存のBatchエンドポイントの変換メソッドの修正を行うことで安全に解消できました。 5: 小さいプルリクエストは開発者自身も思い出しやすい プルリクエストのサイズが小さくなることで、レビュアーがレビューしやすくなるだけではなく、開発者自身にもメリットがありました。マーケティングシステム開発の他に別の機能の開発や、メンバーのコードレビュー、ミーティングへ参加をしていると、開発した際の記憶が薄れていて、レビューコメントに対応するために再度思い出す作業が必要になります。プルリクエストが小さいことで思い出しやすく、コンテキストスイッチが多い中でもレビューコメントに対応しやすかったです。またメリット2で述べたレビュー時間が短くなったこともあり記憶が薄れずに対応できた割合も多かったです。 結論 本記事ではGitのブランチ戦略の1つであるStacking手法をチームで試した結果を整理しました。レビュー待ちの課題を解消することで、プルリクエストの分割を推進し各プルリクエストのサイズを13%〜40%と小さくすることができました。また並行して開発し、レビュー依頼をすることでレビュー時間を7%削減できました。このようにコードレビューにブロックされることなく開発ができるメリットを得ることができました。 機能開発をする中でコードベースへの理解が深まり、小さい改善点を見つけることがよくあります。そうした場合に、改善を後回しにせず、小さいプルリクエストとして分割してレビュー依頼できる点も開発者体験が上がったと感じました。 また想定外の恩恵として専門ドメインで閉じたプルリクエストを作り、専門チームにレビューをしてもらうことで、コードレビューでフォーカスする点が明確になり、最終的なコードの質が上がりました。この点はStacking手法を使わない場合でも継続して意識していきたいと思います。 明日の記事は reyさんです。引き続きお楽しみください。
アバター
この記事は、 Merpay Advent Calendar 2023 の9日目の記事です。 こんにちは。今年の春に新卒でメルペイに入社し、Credit Platform Team でバックエンドエンジニアをしている @champon です。Credit Platform Team では主に ML(いわゆるAI与信) を用いた与信枠の算出を行っていますが、その中でも自分はワークフローエンジンである Airflow を用いたデータパイプラインの開発・運用を行っています。 今回は、業務中に Airflow のバグを見つけてからその原因を調査し、実際にコントリビュートするまでの過程をお話したいと思います。 Airflow とは まず簡単に、Airflow について説明します。 Airflow とは、ワークフローエンジンの一種であり、Apache Software Foundation が管理する OSS です。 DAG と呼ばれる有向非巡回グラフの形式でワークフローを定義し、それぞれのノードは Task と呼ばれるワークフロー処理の構成要素となっています。 Task には、Airflow から提供されている様々な Operator を使用することができ、例えば BashOperator や PythonOperator などがあり、それぞれ Bash コマンドや Python プログラムを実行できます。 また、Amazon Web Service (AWS) や Google Cloud Platform (GCP) のサービス・プロバイダも公開されているため、クラウドサービス上のデータを容易に扱うことができます。 自分のチームでは、GCP 上の Cloud Composer で Airflow 環境を構築し、BigQuery や Dataflow と連携しながらデータパイプラインとしてメルペイの与信枠計算の一部を管理しています。 予期せぬエラーの発生 QA Engineer によるテスト実施中に、Dataflow を使っている Task で以下のエラーが発生しはじめました。 Exception: Google Cloud Dataflow job <xxx> is in an unexpected terminal state: JOB_STATE_DONE, expected terminal state: JOB_STATE_DONE 直訳すると、「予期していた終着状態は JOB_STATE_DONE でしたが、Google Cloud Dataflow job が予期せぬ終着状態 JOB_STATE_DONE となりました」でしょうか。 明らかに筋が通っていないこちらの1文を読んで、もしかしたら Airflow 側に何かバグがあるかもなと思い、Airflow のソースコードを探ることにしました。 エラーの原因調査 こういうときはまず、該当箇所の直近 commit を見ることにします。 スタックトレースもエラーメッセージと一緒に出力されていたため、それを頼りに該当ファイルにたどり着きました。 このファイルの最新 commit を見てみると、 PR #34217 が merge されていることがわかりました。 さらに深掘ってみると、どうやら apache-airflow-providers-google==10.9.0 のリリースに入った変更で、expected_terminal_state という引数を DataflowHook に加える対応のようです。 この expected_terminal_state というのは、 こちら で議論されており、Dataflow job が完了したとみなすステートをユーザーが設定できるというものです。 (Airflow には Dataflow job のステートがいくつか定義されており (※1)、どれを job 完了状態とみなすか、といったもの) 話を戻しますが、この PR #34217 の変更を見てみると、ちょうどエラー発生箇所に変更が加えられていました。 また、念のため Cloud Composer の package 一覧を確認したところ、該当環境の apache-airflow-providers-google のバージョンが 10.9.0 となっていたので、原因はこちらで間違いなさそうです。 gcloud composer environments list-packages <your environment> –project <your project> –location <your location> 原因はわかったので、対症療法としてバージョンを 10.8.0 に落とせばエラーをなくすことができますが、せっかくなので自分で直すことにしました。 (※1) https://github.com/apache/airflow/blob/providers-google/10.9.0/airflow/providers/google/cloud/hooks/dataflow.py#L130-L141 Issue, PR の作成 とりあえず Issue を出しました。 Issue テンプレートの下部に “Are you willing to submit PR?” という文とともにチェックボックスが添えてあったので、チェックをして PR 作成に取り掛かります。 修正箇所は前述の通り、expected_terminal_state の挙動によるものと思われます(正確には、DataflowJobsController の check_dataflow_job_state メソッド (※2))。 特に、expected_terminal_state = None (デフォルト値) のときに考慮漏れがありました。 expected_terminal_state がデフォルトのときに関係するコードを次に抜き出します(今回は Dataflow のバッチ処理なのでストリーミング処理に関係するコードは省きます)。 AWAITING_STATES = { JOB_STATE_RUNNING, JOB_STATE_PENDING, JOB_STATE_QUEUED, JOB_STATE_CANCELLING, JOB_STATE_DRAINING, JOB_STATE_STOPPED, } def _check_dataflow_job_state(self, job) -> bool: current_state = job["currentState"] if self._expected_terminal_state is None: self._expected_terminal_state = DataflowJobStatus.JOB_STATE_DONE if not self._wait_until_finished and current_state == self._expected_terminal_state: return True if current_state in DataflowJobStatus.AWAITING_STATES: return self._wait_until_finished is False raise Exception( f"Google Cloud Dataflow job {job['name']} is in an unexpected terminal state: {current_state}, " f"expected terminal state: {self._expected_terminal_state}" ) ここで、wait_until_finished という要素が新たに登場します。 このパラメータは expected_terminal_state が導入される以前から存在したもので、簡単に言うと “Dataflow job が終了するまで処理を待機するかどうか” のフラグです。 これを踏まえて上記のコードを解釈すると、例えば次の全てを満たす状態のときに Exception が返ってしまうことがわかります。 wait_until_finished = True current_state = DataflowJobStatus.JOB_STATE_DONE expected_terminal_state = DataflowJobStatus.JOB_STATE_DONE ここでようやく、今回のエラー発生時の状態にたどり着きました。 後は修正するだけです。 if not self._wait_until_finished and current_state == self._expected_terminal_state の分岐処理を以下のように変更します。 if current_state == self._expected_terminal_state: if self._expected_terminal_state == DataflowJobStatus.JOB_STATE_RUNNING: return not self._wait_until_finished return True wait_until_finished の条件が悪さをしていたので、expected_terminal_state が DataflowJobStatus.JOB_STATE_RUNNING のときの分岐を増やし、それ以外の場合は current_state == self._expected_terminal_state であれば True となるようにしました。 詳細は 修正 PR を御覧ください。 (※2) Helper method to check the state of one job in dataflow for this task if job failed raise exception: https://github.com/apache/airflow/blob/providers-google/10.9.0/airflow/providers/google/cloud/hooks/dataflow.py#L389-L433 余談: このような実装になった原因 このようなエラーが引き起こされた原因として、wait_until_finished と expected_terminal_state という似たようなパラメータが共存することが大いに関係あると考えられます。 どちらも Dataflow job の完了状態を考慮する必要があるため、完了判定条件がより複雑になってしまったことが考えられます。 また、wait_until_finished = True は、expected_terminal_state = DataflowJobStatus.JOB_STATE_DONE と実質同じ意味なのかなと考えており、将来的には wait_until_finished を廃止することでより簡潔な実装になるのかなと思いました(一応 PR 内のコメントで提案しておきました (※3))。 (※3) https://github.com/apache/airflow/pull/34785#discussion_r1348054361 まとめ 今回は、Airflow におけるバグ発見から PR を作成するまでの課程を、自分の思考を振り返りながら記事にしました。 その後、無事 apache-airflow-providers-google==10.12.0 にてリリースされたので、今後は同様のエラーが起こることはないはずです。 普段は OSS 等へコントリビュートはあまりしない(バグ見つけたら Issue 書くか、時間があったら PR 出すくらい)ですが、久々に結構楽しめたので、今後もちょくちょく Issue 見つつ手伝えそうであればコントリビュートしていこうかなと思いました。 明日の記事は @ryuyama さんです。引き続きお楽しみください。
アバター
 こんにちは!横浜国立大学理工学部情報工学EP3年の @shion1305 です。今年の10月から株式会社メルペイ Settlementチームにてバックエンジニアのインターンを始め、12月初めでちょうど2ヶ月となります。  この記事は、 Merpay Advent Calendar 2023 の8日目の記事です。  今回は、自分のインターンの振り返りも含めて以下について書きたいと思います。 インターン2ヶ月の振り返り 働く環境 メルカリグループのインターンの特徴 インターン2ヶ月の振り返り(自分の中での主なイベントまとめ) 入社オリエンテーション  インターン生は、同月入社の新入社員と一緒にオリエンテーションを受講します。メルカリでは働くにあたってカルチャーやバリューを共有することをとても大切にしていて、最初の1週間はメルカリとしてのカルチャーやバリューに対する考え方についての社内の学習教材に取り組んだり、他の新入社員とディスカッションをしたりしていました。 入社日翌日にはウェルカムランチがあり、そこで新入社員やメンターの方と交流を深めました。(ランチについては後述) 所属チームでのインターン  入社オリエンテーションが終わると本格的にチームのタスクに入っていくことになります。決済システムにはたくさんのドメイン知識が必要になるため、最初は決済システムのコンテクストの薄いタスクを行いながら、過去の資料を参照して決済システムならではの必要知識の理解や現在のレポジトリの状況の把握を行っていました。  11月に入り、ある程度慣れてからは、本格的に決済に直接関連するタスクを任されました。これまで以下のようなタスクに取り組みました。 Go言語のLinter golangci-lint の設定見直し 検証環境で発生しているトラブルの原因調査 Go言語のエラーハンドリングライブラリ pkg/errors の置き換え APIサーバーが稼働するPodの設定調整 PodDisruptionBudget / HorizontalPodAutoscaler / Resources (cpu limits) の設定値見直し Kustomizeのリファクタリング マイクロサービスの改修 改修範囲の特定と修正 テストケースの修正・改良 protoファイルの更新 リファクタリング Office Week  メルカリグループでは普段リモートで働いている人が多いのですが、メルペイ・メルコインではだいたい半期に1度Office Weekがあります。11月中旬にメルペイ・メルコインにてOffice Weekが実施され、基本社員全員が六本木オフィスに出社しました。  11月のOffice Weekは3日間で、初日からイベントやLT大会が盛りだくさんでした。自分は大学の都合上初日のみの参加でしたが、メルペイ全社が集まるキックオフイベントに参加したり、十数のLTの発表を聞いたりしました。LT会では、メルペイの他のチームではどのようなことをしているのかを知ることができたり、自分が普段あまり触れていない技術についての知見を深めることができました。普段オンラインのみでしか会っていない方やメンターランチで交流したインターン生と話したりと、対面ならではの体験がたくさんできました。 Office Weekの様子はこちらから!👇 Fintech Tech Talk at Office Week を開催したよ! | メルカリエンジニアリング インシデントを起こしてしまった  11月後半、インターンのタスクの一つとしてデータベースのマイグレーションの見直しに取り組んでいました。その作業中にコマンド1つを誤ってしまい、ステージング環境のデータベースを消去してしまったことがありました。本番環境ではなかったものの、メルペイにて関連するマイクロサービスが多くあり、社内で他のチームに影響が出てしまいました。  失敗してしまった時はとても不安と後悔でいっぱいで気が気でありませんでした。しかしさまざまな方に支えられたことによって、非常に前向きに乗り越えることができました。このインシデントは、対策の不備とオペレーションミスが重なった結果でしたが、失敗に対する自分やチームとしての向き合い方、そしてオペレーションに対するリスク管理など、エンジニアの一人として得た学びがたくさんありました。貴重な苦い経験として今後のエンジニアリング人生の教訓としていきたいです。 12月・Advent Calendar ← 現在地  Office WeekにてAdvent Calendarの存在を知り、インターン生としてAdvent Calendarに急遽参加させていただくことになりました。合計2つ枠を頂き、息を切らしながらも頑張って執筆しています ✏️ この記事は2本目で、1本目は以下です! 動作例からKubernetes PDBの挙動を理解する | メルカリエンジニアリング 働く環境  メルカリグループでは、 YOUR CHOICE というワークスタイルを採用していて、「バリュー発揮がもっとも高まるワークスタイルを、自ら選択して決めることができる」というポリシーのもと、完全フレックス制で働く環境を選んだり時間を調整できたりします。インターン生の中でも働き方はさまざまなようで、基本オンラインで働いている方もいます。  私はオフィス出社が好きなので、週1回六本木オフィスに出社しています。オフィスの居心地はなかなか快適だと思います。メルカリグループのオフィスは基本的にフリーアドレスなので、時々場所を変えたり必要に応じて個室を利用したりと、自由にスペースを利用させてもらっています。  自分は大のコーヒー好きなのですが、社内にカフェがあり本格的でさまざまなブレンドコーヒーを低価格で飲むことができるので、私のコーヒー欲求は簡単に満たすことができます。社内の自動販売機は無料で利用できるので基本飲み物には困らないはずです。 メルカリ本社オフィスがアップデート! Mercari Base Tokyoに潜入!新しい時代のオフィスの形とは? メルカリグループでのインターンの特徴 プロフェッショナル性が求められる  メルカリバリューの一つに「Be a Pro」というものがあり、インターン生も例外なくプロ意識を持って自ら考え、適切な判断を下すことが求められます。原則ある程度の知識やスキルがある状態で自分の知識を活かしてタスクに取り組むことが求められるため、かなり緊張感を持って取り組むことができます。  メルカリバリューには他に「Go Bold」「All for One」があり、社員と同様これらを意識してインターンに取り組むことが求められます。 多様なコミュニケーションの機会  メルカリグループでは社内のコミュニケーションの場を非常に大切にしていて、そのためのイベントや制度が多く存在します。基本的にインターン生は社員と同じように活動でき、社内のさまざまなイベントに参加したり制度を利用したりすることができます。社員のコミュニケーションを促進するための制度が多くあるため、インターン生にとっては非常に貴重な機会だと思います。  制度の一つに、食事代を会社が補助する制度があります。インターン生は以下の制度が利用できます。 メンターランチ 新入社員やインターン生がメンターと一緒に社内の色々なチームの人とランチ。 ウェルカムランチ 入社日直後に実施されるランチ会。 インターン生ランチ会 インターン生のみで毎月4名程度でランチ会が開催されます。メルカリグループのインターン生の人数はかなり多いので、インターン生同士で情報交換をする機会に恵まれています。 チームビルティング 自分の所属するチームでは毎月1回、所属するチームで食事会があり、他のチームの人を招くこともあります。  また、部活動というものがあります。部活動は趣味を通じてさまざまな人と良い関係性を築くことを目的としたもので、誰もが設立したり参加したりすることができます。自分はつい先日CTF(capture the flagというセキュリティコンテスト)のグループに参加していて、早速社員の方と12月中旬にCTFに参加することになり、とてもワクワクしています!  その他にも社内ではさまざまなイベントが存在します。 英語でのコミュニケーションに挑戦できる  メルカリグループのエンジニアリング組織の約半分は外国籍です。チームによって英語を使ったり日本語を使ったりさまざまです。自分のチームは日本人が多いですが、週替わりでEnglish Weekという英語を推奨する期間を設けています。  特に、英語でSlackで返信を打つ時や開発でPull Requestを出す時などは、どのように表現したら相手に伝わりやすいかを必死に考えるので英語を鍛える良い機会になると思います。他にも英語でディスカッションすることができたり、一部の会議では同時通訳を聞くことができたり、などなど、なかなか経験することのできない機会が盛りだくさんです。 大規模かつ運用年数のあるシステム開発ならではの経験  メルカリグループのインターンでは、フルスクラッチで何かを開発することは少ないかもしれません。私のチームでは、運用されてから数年が経過したマイクロサービスを扱い、過去の歴史的経緯による技術的負債に多く直面しました。割り振られたタスクでは、その負債の影響を正しく理解し、最適な解決策を見つけることが求められます。  私が初期に担当したタスクの一つでは、技術的負債が絡む部分があり、それに対して関連する箇所を全て洗い出し根本から修正する方針で進めました。その結果、変更箇所が大きくなりすぎてタスクの収拾がつかない状況になったことがありました。技術的負債が存在する場合でも、一気にすべて解消しようとすると、レビューが困難になったり、変更ミスが生じるリスクがあります。メンターからのアドバイスを受けたことで適切に選択を行い、解決策を提案することができました。  また、メルペイのマイクロサービスはかなり大規模なので、仕様を変更する時は、各マイクロサービスの担当チーム間で適切なコミュニケーションを取り連携していく必要があります。大きな組織の中で複数のチームをまたいでのコミュニケーションを実践できる機会があるのも魅力だと思います。 終わりに  改めてメルカリグループでのインターンは自分次第でたくさんの挑戦ができる、最高の機会だと思います。技術的なノウハウのみならず、コミュニケーションや仕事に対する考え方など、一人前のエンジニアとしての成長を促す多様な経験が得られます。  あと1ヶ月弱期間が残っていますが、今回のAdvent Calendarでの振り返りを元に残りの期間で、チームメンバーの一員としてプロ意識を持って積極的に貢献するとともに、最大限機会を活用してメルペイでのインターンを楽しみたいと思います。  今回のこの記事がメルカリグループのインターンを検討している方の参考になれば幸いです。  現在、インターンを通年募集していますので、興味を持たれた方はぜひ以下からぜひ申し込んでみてください! Students | 採用情報 明日の記事は champon さんです。引き続きお楽しみください。
アバター
この記事は、 Mercari Advent Calendar 2023 の7日目の記事です。 こんにちは!メルカリの Search Middleware チームで Software Engineer をしている @otter です。 ご存じの方も多いとは思いますが、メルカリのエンジニア組織ではグローバル化が進んでおり、チームにもよりますがコミュニケーションやドキュメントではほぼ英語が必須な環境になっています。 そのような環境のメルカリに英語がほとんど話せない私が入社してから4年が過ぎました。会社の環境も私自身も変わってきており、そこで得られたものや感じたものを紹介していきたいと思います。 どんな人にこの記事を読んでほしいか? 英語を使った環境で仕事をしてみたい人 仕事で英語を使っているがコミュニケーション方法の参考にしたい人 組織のグローバル化を検討している人 入社前のモチベーション 前職では某IT企業でゲームプラットフォームの開発をしていました。コミュニケーションは全て日本語で、技術関連の英語のドキュメントを読むことはよくあるのですが、ドキュメント作成もほとんどが日本語でした。 ただ、エンジニアとして成長するには英語は必要だし、英語を使う環境で働きたいなと考え始め、元同僚からのお誘いもあり転職を決めました。 今考えると、全然話せもしないのに転職しようとした自分は少し無鉄砲だったと思いますが、当時はグローバル化推進への転換時期だったので日本語面接で採用されました。 また、転職を考え始めたタイミングでオンライン英会話を始め、有給消化期間中にニュージーランドのクライストチャーチで3週間だけ語学学校に通いました。 入社直後どうやって切り抜けたか 直前の語学学校やオンライン英会話はあまり役に立ちませんでした。 まず、入社当日のオリエンテーションや全体向けの会議にはありがたいことに GOT (Global Operations Team、メルカリの翻訳および通訳を行うチーム) の同時通訳が入っており、日本語で説明を聞くことができました。また、配属先のマネージャーとメンターが日本人だったので個別に相談するときは日本語を使っていました。 ただ、入社当日のウェルカムランチでは多様な出身のメンバー同士の会話が、それぞれの訛りもあり、早すぎてついていけず本当に面食らいました。当たり前ですがオンライン英会話の先生のように話す人なんて現場にはいません。近年はインド人の同僚と一緒に仕事することが多いので、Indian English には慣れていますが、最初の頃は全く聞き取ることができませんでした。 では、どうすればいいのか?一朝一夕でリスニング力をあげることはできません。私はツールに頼りました。Google Meet には英語字幕を付ける機能があるので、会議中は字幕をひたすら読みます。最近は自動翻訳機能も追加されましたが、そちらはまだ精度が高くないのでおすすめできません。 またオンライン会議ではなく対面のオフライン会議の場合でも、とりあえず自分のPCで Google Meet を開いておけばマイクが周りの会話を拾ってくれるので字幕を参考にしながら会議に参加することができます。目の前に人がいるのに画面ばかり見るのは難しいので、おすすめ度は低いですが参考までに。 メルカリの言語学習サポート メルカリでは公用語を英語と決められている訳ではありません。そのため言語学習は強制されるものではなく業務上必要と判断されたメンバーが受けられるサポートという位置づけです。また、日本語を学びたいメンバーが受けられる日本語学習サポートも同様にあります。 「やさしい日本語」や「やさしい英語」といったカルチャーもメルカリならではで、全員の言語スキルを上げさせるのではなく言語ギャップをお互い埋めていこうという方針があります。 私が今まで英語学習に関して受けた恩恵は下記です。 オンライン英会話の費用全負担 MECT (Mercari English Communication Test) コミュニケーションスキルレベルを知るための独自のスピーキングテスト 独自の英語学習プログラム 専任の先生とメルカリでの仕事に合わせた教材でレッスン English Chat Lunch ネイティブスピーカーのチームリーダー1名と学習者3名で毎週ランチ エンジニアのための英語・日本語ボキャブラリーリスト 社内ミーティングの会話から抽出されたエンジニアがよく使う語彙のリスト 日本語学習者にも最適な学習ツール 各サポートは都度内容見直され更新されているので現在と異なるものもあり、私が受けたことがないものもあります。 (参考) 言語学習プログラム コミュニケーション力をどうやってあげていくか あえて英語力ではなくコミュニケーション力と書きました。私はUSで働いている訳でも外資系企業で働いている訳でもありません。本当にネイティブな英語話者は少なく、ほとんどのメンバーが英語を第二言語としている人たちばかりです。なのであまり難しい単語やフレーズを覚える必要はなく、実際に周りが使っている言葉を真似していく方が近道です。とくに仕事で使う内容は限られているので、各種学習サポートはあるのですが、実際に仕事で積極的に使って行く方がコミュニケーション力は上がると思います。 おすすめは少人数のミーティングに頻繁に参加することです。以前、インド人の新卒メンバーと毎日ミーティングの時間を作って、話しながら一緒に仕事をしていました。1対1だと「やさしい英語」で話してもらえるし、自分の発言するタイミングが増えるので、話す練習にもなります。 また大事なのは、説明が難しい内容のときは必ずドキュメントを作って挑むということです。 これは英語に限らずだと思いますが、たとえば、他チームに複雑なシステムの説明を1からするときは、予め詳細なドキュメントを準備してから説明します。そして上手く説明できなかったところは後から Slack で補足したり、こう話せばよかったという反省は次回への文章づくりに活かしたりします。 前述のようにコミュニケーションは口頭の会話だけではありません。Slack や PullRequest 上でも、周りから学ぶことが多々あります。入社してすぐ驚いたのは飛び交っている Acronyms (頭字語、イニシャルを並べた略語の一種) の多さです。初めて見るものばかりだったので、ググってはリスト化していました。その一部を紹介します。 【頻出 Acronyms in メルカリ】 OOO = out of office (Slack名やステータスで使う、例: @otter – Dec 7th OoO) PTAL = please take a look (このPullRequestを見て!というときに) BTW = by the way (話を切り替えたいときに) IMHO = In my humble opinion (私の率直な意見では) TIL = today I learned (それ初めて知った、というときに) TBH = to be honest (正直なところ) TBD = to be determined (仕様書や設計書の未定義の箇所に使う) BRB = be right back (会議の途中で一時的に抜けるときに) AFAIK = as far as I know (私の知る限りは) IIUC = if I understand correctly (私の理解が正しければ) IIRC = if I remember correctly (私の記憶が正しければ) SSIA = subject says it all (タイトルだけで説明が不要な小さなPullRequestのDescriptionに使う) これ以外にも略語ではないのですがよく使う言葉としては NIT/NITS (PullRequest上で些細な指摘をするときに使う) などがあり、思っていたよりたくさんの新しい用語を覚える必要がありました。 そして現在は この4年間で直属のマネージャーは日本人→スペイン人→フランス人→スウェーデン人と変遷し、日本語が飛び交っていたチームも9人中6人がグローバルメンバーになりチーム会議も100%英語となりました。未だに私の英語はお世辞でも上手とは言えませんが、コミュニケーションの工夫と周りの温かいサポートのおかげで今ではそのグローバルなチームのTL(Tech Lead)もしています。 また英語を使う機会が増えるとともに人脈も仕事の種類も増えてきました。言語の壁があると他のチームとコラボレーションにも支障が出るし、新規プロジェクトからの声もかかりづらくなります。私の観測した限りでは両言語とも流暢に話せてコミュニケーション力が高いエンジニアは各所から引く手あまたです。私も現在全社規模のプロジェクトに参加しており、今まで自分の領域である検索機能まわりを中心に仕事をしていましたが、違う領域のチームに参加したり、別事業のヘルプに呼ばれることもあり、充実した働き方ができています。 メルカリ全体としても英語だけをサポートするわけではなく、言語のギャップをなくそうという取り組みがさらに進んでいる実感があります。以前は広範囲にアナウンスされる内容が日本語だけだったり、英語だけだったりということがよくありましたが、今では両言語でアナウンスされることが徹底されており、片方の言語だけだったとしても瞬時にbotが自動翻訳してくれる仕組みがあります。 さらに私事ですが、昨年はイタリア人のエンジニアと結婚し長男を出産しました。なので家でも基本は「やさしい英語」です。業務では絶対に使わないだろうという単語を頻繁に使うことになるので、それはそれで面白いです。息子もそろそろ言葉を覚えていく時期なので一緒に学んでいこうと思いますが、きっとあっという間に追い抜かされるでしょう。今から楽しみです。 最後になりますが、この4年の間に私が感じた、これから英語を扱う環境に飛び込んでいこうとする方たちの英語学習に関して重要だと思った点をあげておきます。 入社前のオンライン英会話は業務の英語にはあまり役に立たない 聞き取れないときはツールに頼ろう (Google Meet の英語字幕機能) 難しい英単語やフレーズを覚える必要はない 実際に周りが使っている言葉を真似していく方が近道 言語のギャップをなくそうという取り組みが大事 それでは最後まで読んでいただきありがとうございました!何かひとつでも参考になれば幸いです。 明日の記事は @wills さんです。引き続きお楽しみください!
アバター
はじめに メルカリ Engineering Office マネージャーのhiroiです。 我々のチームでは「Establish a Resilient Engineering Organization」というミッションを元に、エンジニアリングにおける、組織横断課題の解決を目指しています。 組織横断というと、Platformチームや、インフラ周りのチームを想像する方も多いと思いますが、我々のチームでは、 プロダクト開発における技術的な課題を除く 、組織課題や横断的な取り組みを推進しています。 具体的には、各技術領域ごとの研修プログラムの構築、エンジニア向けのイベント企画運営、技術広報(このEngineering Websiteも我々の活動の一つです)、ナレッジマネジメント、エンジニア文化の言語化や醸成、技術戦略策定、果てはインド開発支部の立ち上げのプロマネなどをしています。 この記事ではそんな我々の主な活動の内容、目的の紹介をします。 開発や技術力の高い組織を目指すために、その裏でどんな技術外の仕事や工夫を、メルカリではしているのか、そんなちょっとニッチな領域における話を書いてみます。 こんな人におすすめ エンジニア組織の技術以外の課題に取り組んでいる方はもちろん、そういった取り組みに興味があるマネジメント職の方におすすめです。特に上記に記載したような仕事(研修、イベント企画、技術広報、ナレッジマネジメントなどなど)のワードが気になる方、是非ご一読ください。 規模が一定以上の組織固有で発生する課題もありますが、どんな組織にも共通している取り組みも含まれています。特に規模が近い会社の方におすすめですが、どのサイズの組織でも、「その課題わかる!その仕事あるよね!」とある程度共感いただける内容を目指します。 6つの重点領域 Engineering Officeの仕事は、大きく以下の6つの領域にカテゴライズされています Tech Branding Internal Communication Onboarding Career Development Knowledge Management Strategy メンバーはジェネラリストですが、それぞれの領域に対して専門性をもって取り組んでいます。各領域ごとに3~5年の中長期計画があり、その達成を目指して日々の仕事を進めるというやり方をとっています。今回は領域ごとのミッション、主な仕事の2点を説明していきます Tech Branding Mercari Gears – Youtube。 手前味噌で恐縮ですが、本当に良いコンテンツを発信しています ミッション 技術広報です。技術発信や、カンファレンスやOSSのスポンサーもこの領域です。主に以下の3つを目的としています。 ・採用のためのブランディング ・技術コミュニティへの貢献 ・エンジニアのキャリアアップ 1点目、一番わかりやすいゴールですが、採用のためのブランディングがあげられます。採用候補者となるエンジニアにメルカリが使っている技術や、エンジニア文化に興味・関心をもってもらい、「技術力が高いエンジニア組織だ」「こういった文化のところで働きたい」といった認知を獲得することを目的としています。 2点目は技術コミュニティへの貢献です。エンジニアという業界の発展のスピードの大元には、そのコミュニティの強さ、知識や成果物の共有文化があります。実際、メルカリのアウトプットは、過去のエンジニアの経験や知見やOSSといった、技術コミュニティが築いてきた資産の上に成り立っています。私たちの経験や知見も同様に、誰かのアウトプットに繋げることで、コミュニティの発展に貢献、恩返しが出来ます。そのため、コミュニティへの貢献を2つ目の重要な目的としています。 最後に、エンジニアのキャリアアップです。エンジニアは、技術発信をする中で、思考の整理が行われ、学びを深めることができます。また、発信したものはそのエンジニアの社外へのアウトプットとなり、社内外の自身のブランディングに繋がります。社内においても、外部へのアウトプットは明確に評価の対象物になりうるため、キャリアに繋がります。これを3つ目の目的としています。 以上3点を中心に、メルカリでは、技術発信によって会社、発信者、コミュニティの三方良しの状態を目指しています。 主な仕事 ・技術発信の媒体運営、管理(Engineering Website、Gears Youtubeチャンネル、Twitterを始めとするSNSアカウントなど) ・結果の見える化とPDCA(来訪者数、チャンネル登録者数、国別アクセス、etc…) ・Engineering Blogのレビューの仕組み化 ・技術発信に対する広告運用 ・OSSや技術コミュニティ、カンファレンスへのスポンサーシップ ・発信内容の企画、制作 技術発信はメルカリにおいて仕事として認められますが、もちろん強制するわけではないですし、何を書くかといったのも個々のエンジニアの裁量です。Engineering Officeは、エンジニアが発信しやすい環境、そしてエンジニアの発信の価値が最大化されるような環境作りを行っています。 また、スポンサーシップとして、メルカリがお世話になっている 技術カンファレンスへの協賛 はもちろん、 PHP FoundationやPython Foundaitionといった団体へのスポンサー などに関しても、我々の方で提案、実施を進めています。 ちなみに写真にある Mercari Gears – Youtube はYouTube Channelですが、最近登録者数が7万人を超えました。国内のテックカンパニーが運営している技術チャンネルの中では最大規模です。豪華なコンテンツが盛りだくさんなので、見たことがない方は是非。 Internal Communication 技術の祭典であるHack Fest。毎回デザイナーさんが素敵な扉絵を作ってくれています ミッション サイロ化の防止、チーム間のコラボレーションの増加、強固な文化形成による、全体最適をミッションとしています。組織を見渡した際、チーム間での協力がスムーズに行われ、ナレッジのシェア、同じ文化の形成が出来ている状態が理想です。 一定以上の規模の組織になると、サイズが大きくなればなるほど、個別最適が発生しやすくなります。カルチャーや考え方も、チーム間で少しづつズレが生まれやすくなります。チームの一員という誇りは重要ですが、隣のチームが同じ目標、ミッションのために働いている仲間だという意識も同じく重要です。 これに対する一番の解決策はコミュニケーションだと考えています。チーム間、もしくはレイヤー間で発生する課題は、見えているものや、抱えている背景が違うことに起因することが多く、多くの場合、丁寧なコミュニケーションによる相互理解を進めることで、解消可能です。 Engineering Officeでは、普段接点を持ちづらい人同士の対話、コミュニケーションや、リーダーからの発信が進んでいく仕掛け作りをしています。 主な仕事 ・Engineering All Hands(全エンジニアが参加するMeeting)の企画運営 ・グループ横断の技術会議の企画運営 ・EM向けオフサイトの企画運営 ・Hack Festの企画運営 ・Ask Me Anything(トップエンジニアとのOpen Discussion)の企画運営 さまざまな会議の企画運営に加え、全エンジニアが開発を止め、自身のアイデアを元に好きなものを作る、 技術の祭典、Hack Festの運営 。社内のDistinguished Engineerをはじめとする、トップ層のエンジニアと、カジュアルに技術についてDiscussionを行う場の提供などをしています。技術に関して横断的に話す場だけでなく、リーダー達の考え方、思いを直接聞ける、話せる場を作るというのが重要です。 Onboarding メルカリのOnboardingの主な区分け。詳しくは こちら ミッション 入社後の戦力化までの時間の最短化、共通化やクオリティの向上による学習コンテンツの価値向上と効率化、ガバナンスの強化に加え、入社時に最高の従業員体験を提供することを目的としています。 特定のドメインナレッジ等、チーム特有で学ばなければいけないことはもちろんありますが、開発環境の作り方、コーディングのお作法、リリースサイクル、QAの考え方、インシデントマネジメントなど、チームを超えて共通する内容も多く、横断チームによる管理運営が適しています。コンテンツの集約により、重複や再作成の防止に加え、クオリティの向上が見込めます。 また、エンジニアという比較的転職サイクルが早い職種においては、いかに早く戦力化するか、という重要性が他の職種と比べ高いと考えています。一般的にOnboardingは3ヶ月〜6ヶ月かかると言われています。この最長と最短の差分である3ヶ月の差について、もし社員が3年勤続する場合、Onboarding終了後の実働が33ヶ月と30ヶ月になり、誤差がなんと10%程もあります。勤続年数が短い傾向にあるエンジニアにとって、Onboardingの速度は大きなインパクトがあります。 また、ガバナンスの強化においてもOnboardingは重要です。特に中途採用を行う際は、過去の組織の働き方から新しい組織の働き方へと移行するためのアンラーニングをきちんと行わないと、複数のお作法が意図せずして組織に定着し、さまざまな弊害を生む原因となります。出社自由といった制度などもそうですが、メルカリは自由度が高い会社なので、多くを厳格に標準化するわけではないですが、一定の標準化は必要です。入社してすぐは、比較的フレッシュなマインドで新しいことを受け入れ、過去の組織のやり方から脱却しやすい時期です。標準化が必要なものに関しては、この時期にきちんと学習できるプログラムを提供できることを目指しています。 最後に、第一印象、つまり入社時の体験はとてもとても重要です。メルカリに入社した全てのエンジニアが、入って良かった、歓迎されている、誇りをもてる、そういった気持ちになれるようなプログラムを目指しています。 主な仕事 ・全エンジニア向けオンボーディングプログラム作成 ・各技術領域(Backend、iOS、Androidなど)ごとのオンボーディングプログラム作成 ・EMのオンボーディングプログラム作成 ・オンボーディングプログラムの社外発信 基本的には技術、職種ごとに必要なOnboardingの集約、プログラムの作成、提供を行っています。それぞれの技術ごとにコミッティーを形成し、様々なチームのエンジニアが協力してコンテンツの作成を担当しています。多くのコンテンツはメルカリでないエンジニアが見ても面白いものになっています。そのため、一部のConfidentialな情報をのぞいた上で、出来る限り社外にオープンにしていくというチャレンジを最近では推し進めています。コンテンツ作成に協力してくれているエンジニアにとっても、社外のオーディエンスが増えるのはプラスになるので、この取り組みは今後も強化していきます。 Career Development エンジニアの成長段階を Engineering Ladder によって言語化をすすめています ミッション エンジニアのキャリアの可視化や、キャリアアップのための環境整備を進めている領域です。 エンジニアは自分で積極的に学習する人が非常に多いため、学習を我々が推し進めるのではなく、その学習のサポートとなるような環境、制度を提供しています。また、キャリアアップも同じく、推し進めるというよりは、キャリアアップを目指す人たちをどのようにサポートできるか、という観点から、環境の整備を行っています。 主な仕事 ・ Engineering Ladder の作成・保守 ・ Continuous Feedback の仕組み化、推進 ・職種(EMなど)の定義、言語化 ・オンライン学習コンテンツの提供 ・社外カンファレンス参加の推進、ポリシー作成 グレードや職種の言語化に加え、外部のエンジニア向け学習サービスの管理、社外カンファレンス参加におけるポリシー作成などを行っています。特にマーケットプレイスのエンジニアは、海外国籍のエンジニアが半分を超えているため、海外カンファレンスの参加も多く、費用もそれなりに高額になりやすいため、各カンファレンスの参加人数の上限を設ける、カンファレンス参加後にナレッジをシェアしてもらう、といったポリシーを定めています。 社内のキャリアアップに関しては、一番重要なのは現在地を正しく知ることだと考えています。今の自分に何が足りないのか、次のグレードにはどんなスキル、行動が求められるのかを知ることで、どんな学習、チャレンジが必要なのかというアクションを考えられます。そのため、キャリアの言語化、可視化に加え、Continuous Feedbackのような、マネージャーから適切なフィードバックを得られやすいようにするための仕組み作りを目指しています。 Knowledge Management エンジニア用の社内辞書。多くのエンジニアがコントリビュートしてくれています ミッション 社内におけるナレッジの最大化をミッションとする領域です。Engineering Officeは多くのメンバーがジェネラリストですが、この領域に関しては、Technical Writerという職種のメンバーが専属で推し進めてくれています。 メルカリではオンライン中心で働くエンジニアが非常に多いため、以前のような「隣の人にちょっと聞く」というコミュニケーションから「社内のWikiで調べる」といった行動が増えており、ナレッジをドキュメント化し、蓄積する重要性が高まっています。 また、プロダクトも10年目ということもあり、一目ソースコードを見ただけではわからないような、いわゆる歴史的経緯などが多く存在します。ナレッジは言語化を進める事で、特定の人に依存する状態から、社内のナレッジへと変わります。社内のナレッジが必要な時に、必要な人のもとに届く状態を目指しています。 主な仕事 ・社内のエンジニア向けポータルの管理 ・ポータルの利用、コントリビューションの可視化と最大化 ・ナレッジの収集、発信 ・ポータルのポリシーの仕組み作り、運用 一番メインとなっている活動が、社内におけるエンジニア向けのポータルの管理です。そこに価値のあるナレッジを収集し、必要としている多くのエンジニアに届けられる状態を作っています。例えば社内のエンジニア向けの辞書であったり、Onboardingコンテンツ、キャリアアップのために有用な情報や、エンジニア採用のプロセスやノウハウなどが整理されています。 もちろん、Knowledge Managementの担当者だけが全てのコンテンツを作ったり、アップデートしたりするのは不可能なため、一定のポリシーやルールを作り、運用するというのも大きな活動の一つです。どれくらいのエンジニアが見て、どれくらいのエンジニアがコンテンツにコントリビューションをしてくれているのか、というのを重要な指標としており、エンジニアが自然に日々の業務の中で、ナレッジをシェア、ドキュメント化しようと思えるような文化、環境を作ろうとしています。 Strategy ミッション エンジニアリングにおける戦略の言語化をすすめ、外部に発信したり、他部署に理解してもらえる状態を目指しています。Engineering Officeにおいて一番新しい取り組みです。 ビジネスは数年単位の戦略が存在するように、エンジニアリングにおいても、年単位の投資が必要な活動が多く存在します。過去の例でいうと、MobileとWebのリファクタリングプロジェクトや、ビジネスの共通基盤ドメインの大幅アップデートである RFS などがそれにあたります。こういった開発は、売上にすぐに繋がるような、緊急性の高いものではありませんが、将来の開発速度や、メンテナンスコストなどを踏まえると、非常に重要です。 これらの開発が考える重要な投資をエンジニア以外の方が理解しやすいような形で言語化し、エンジニア戦略として発信を行っています。それにより、他部署やプロダクトマネージャーにその重要性を理解を得て、売上をあげるような新規開発と、中長期を見据えた機能を直接増やすわけではない開発の適切なバランスが取れている状態を目指しています。 主な仕事 ・技術課題における中長期計画作成のサポート・発信・運用 ・Engineering Principlesの作成のサポート、発信 ・Engineering OKRの作成のサポート・運用 もちろんこういった計画の中身自体はCTOをはじめとしたエンジニア部門のリーダーが中心となって考えますが、ボトムアップで必要な情報を集めたり、更新サイクルの作成、適切な発信を行っていくためのサポートをEngineering Officeでは行っています。 今回紹介した6つの領域はそれぞれ強く結びついています。例えばOnboardingで作成したコンテンツはTech Brandingを通して外部に発信されます。Strategyで決められた方向性やカルチャーは、Internal Communicationを通してEMやエンジニアに発信され、Onboardingを介して新しく入社するエンジニアに届けられます。また、新しい目指すべきカルチャーに沿って評価の定義が微調整され、Engineering Ladderによって、その見える化が進み、そのドキュメントはKnowledge Managementの元、管理、更新が徹底されます。メルカリにおけるEngineering Officeの強みは、これらの活動のシナジーを意図的に生み出せるところにあるかなと思っています。 課題と展望 以上がEngineering Officeがメルカリエンジニアリング組織横断で行っている仕事です。 どの活動もまだまだ道半ばで、やれること、やらなければいけないことが非常に多いです。特にオンラインとオフラインが入り混じるハイブリッド環境下でのコミュニケーションの促進、改善はいまだ試行錯誤しており、いまだに新しいチャレンジを繰り返しています。 また、Knowledge Managementの最適化は十分なスピードで行えておらず、コンテンツが過去のまま更新されずに利用されていたり、どこにドキュメントを書けばいいかわからないといった問い合わせがあったり、場合によってはフロー情報であるはずのSlackが、Wiki代わりに使われてしまって、誤った過去の情報を元に仕事が進められてしまったり、ということも発生しています。 プロダクトも大きくなり、フィンテック領域が黒字化し、会社としても少しづつステージや雰囲気が変わってきたなと内部からも感じることが増えています。今後も既存プロダクト、新規プロダクト開発での新しい技術的チャレンジは増えていきます。少しでも価値が早く提供できるように、それまでの道のりがエンジニアにとって良い体験になるように、今後も足元の課題解決を進めていければと思います。 長文になりましたが、読んでいただきありがとうございます。読者の方にとって、少しでも何かプラスになれば幸いです。メルカリ編と書きましたが、こういった話は中々表に出てこない領域でもあるので、他社の方で同じような取り組みをしている方がいれば是非書いてみてください!
アバター
この記事は、 Merpay Advent Calendar 2023 の6日目の記事です。 はじめに こんにちは、MerpayでBackend Engineerをしている @panorama と申します。 今年(2023年)の4月に新卒として入社しました。 今回は「メルペイに新卒入社して1年目にやったこと」という内容で、入社後から現在にかけてどのようなことをしてきたかご紹介したいと思います。 今後入社される方やメルペイ新卒エンジニアの1年目の動きに興味がある方の参考になればと思います。 (一部プロジェクトは社外秘で内容は伏せています🙏) それでは早速始めていきます。 4月~6月 研修期間 4月~5月の頭にかけてはメルカリグループの新卒研修である「DevDojo(※1)」を受けていました。 DevDojoでは特定の分野に限らず Backend、 Frontend、 セキュリティ、 アーキテクチャ、 Spanner 、・・・ などさまざまな技術について学びます。 また今年は新しい試みとしてマナー研修もありました。 「人生に1度きりの新卒研修なのでマナーについて学んでおこう」というものです。 名刺の渡し方や席の座り方(※2)、社内の人間の呼称など基本的なマナーを勉強しました。 今年のDevDojoは取材も入っていて、上記のマナー研修の様子もYouTubeに上がっているのでご興味があればぜひ見てみてください。 業務開始 DevDojoが終わってからは本格的に業務に入っていきました。 そのとき進んでいたプロジェクトとして「メルカード審査完了後に即座にカード番号を利用できるようにする」というものがあり、その機能の一部の実装を担当しました。 今まではカードを利用するためにカードの到着を待つ必要があったのですが、上記のプロジェクトによってオンラインでの決済であれば審査後すぐにご利用いただけるようになりました。 審査完了後すぐカード番号が利用可能に そのプロジェクトが終了してからは他の機能も実装しつつ、少し大きめの改善系のタスクなども実施していました。 これに関しては以前記事(※3)を書いたため、気になる方はそちらをご覧ください。 また上記の期間を通してドメイン知識のキャッチアップや運用の理解、QA環境の用意の仕方やリリース手順などBackendが関わる基本的な作業についても学んでいました。 ※1 技術トレーニングDevDojoで実際に使用されている学習コンテンツを公開しています。 こちら をご参照ください。 ※2 ちなみに余談ですが、筆者のpanoramaはこのマナー研修後にExec(役員)と新卒のランチ会に30分遅刻(😇)し、なぜか上座が空けられていたので座ったという体験をしています。そしてなぜか誰もそれを気にしていませんでした。(補足すると遅刻の理由は寝坊ではなく直前のMTGの終了時刻がランチの開始時刻であったことと、ヒルズを出た後迷子になったというダブルパンチによるものです。) ※3 Cloud Tasksで外部APIへの流量制御をするときに考えたこと 7月~9月 7月からは業務の幅を広げて、お問い合わせの調査なども積極的に拾うようになりました。 私のチームでは、お客さまからのお問い合わせは基本的にはCS(カスタマーサポート)チームが対応するのですが、サポートツール上からはわからない事象だった場合はBackendが調査を行う体制になっています。 また8月からはオンコールのシフトにも入るようになりました。 オンコールとは「サービスのパフォーマンスが悪化したり、停止が疑われたりする場合に備えて担当者が常時対応できるようにしておく仕組み」です。 メルカリグループではPagerDutyを使用してオンコールシフトを管理しており、PagerDutyに紐づけられた特定のDatadog Monitorが閾値を超えた場合、自動で担当者を呼び出す仕組みになっています。 5月~6月にかけて知識のキャッチアップや運用の理解を進めてきたため、(難なくとは言いませんが)お問い合わせやオンコールに対応できるようになりました。 (※またオンコールは万が一手に負えない場合、エスカレーションする仕組みがあります。) オンコールで使用しているツール (左: Datadog, 右: PagerDuty) (Datadog 画像 出典: https://www.datadoghq.com/ja/about/resources/) (PagerDuty 画像 出典: https://www.pagerduty.com/brand/) DatadogのロゴになっているワンちゃんはBitsという名前みたいです 合わせて8月1日から入ってこられたインターン生(※4)のメンターにもなりました。 メンターの主な役割はインターン生のサポートですが、メルカリグループでは新しくチームに入られた方に対してメンターランチ(※5)やチービルランチ(※6)を行う文化があるためそういったサポートも実施しました。 インターン生の方はみなさんとても優秀ですが、社内の知識に関しては初めてのことばかりなので、メンターとしてタスクを適切に分割してお渡ししたり、実装に必要な知識をお伝えしたり、場合によっては巻き取って進められるように自分もタスクを追ったりしていました。 8月中旬以降は新しいプロジェクトに参加しました。 そのプロジェクトは今までに経験したことのない別のチームと連携して行うもので、かつ延期が難しいハードスケジュールのものでした。 自分のチームから担当としてアサインいただいたのですが、開発終盤で別のチームとの依存関係を見落としている箇所があることが発覚し、ギリギリで実装を追加することで乗り切りました。 (他の開発チームと特にQAの方にご協力をいただいてなんとか無事故・不具合なしで期日内にリリースできました。) この経験以来、他チームとの調整がある場合にはなるべく早い段階で変更箇所を確認し、定期的にsyncしていく必要があることを意識するようになりました。 上記はプロジェクトの内容を伏せてしまっていますが、他にはFIDOの対応などもやっていました。 FIDO認証画面 ※4 参考: mercari careers / Students ※5 メンターランチ: メンターとメンティー(新入社員・インターン生)とのランチ。チームメンバーや他チームを紹介がてら行います。 ※6 チービルランチ: 目的はメンターランチと同じでrelationship buildingですが、関係性はメンターとメンティーに限りません。 10月~現在 10月の中頃でメンティーだった方のインターン期間が終了しました。 そして新しく動き始めたプロジェクトにBackendの担当としてアサインされました。 このプロジェクトではまず機能自体の調査とそれを実現するための調査が必要でした。 機能に関する資料と調査結果をチーム内で読み合わせ、ある程度固まったら関連するチームも巻き込んで共有会を行いました。 担当のBackendとしてこの調査や会議のリードを任せていただき、現在は設計に入っています。 ありがたきUnipos (社内投げ銭サービス(※7)) 今まではタスクがアサインされた時点でやることが決まっていることが多かったのですが、今回は「何をどこまでやるのか」「どうすれば実現可能か」という段階からPMと一緒に関わらせていただいているので非常に新鮮に感じています。 先述の通りまだ設計中で、その後にbreakdownして実装に入るので、引き続きプロジェクト達成に向けて努力していく所存です。 また上記のプロジェクト以外だとBe a Pro Days(※8)と呼ばれる取り組みで自動化のためのBotを作ったり、キャンペーン施策のBackendの実装をいくつかやったりしました。 ※7 参考: メルカリのピアボーナス制度「メルチップ」、メッセージ累計数が100万を突破しました〜!#メルカリな日々 ※8 参考: 「自分自身が発揮できる価値」に向き合う──1人ひとりがオーナーシップを持って課題解決を取り組むために導入した「CD Be a Pro Days」 まとめ 今回は私が新卒入社後にどのようなことをしていたか、(振り返りの意味も込めて)記事化してみました。 入社前には自分が1年目でインターン生のメンターになったり、一部のプロジェクトのリードを任せてもらえるとは思っていなかったため本当に「Go Bold」の考え方が実践される素晴らしい環境だと感じました。 また多少の修羅場(?)やさまざまなチームの方とのコミュニケーションの機会を通じて、技術一辺倒だった学生時代よりも色々なスキルを身につけた気がします。 内容としては個人ブログのような部分も多かったかもしれませんが、社内レビューを通っているので”公認”で社内の話についていろいろ言及できた気がします。 メルペイ(メルカリグループ)の新卒入社後について気になっている方がいて、具体例として参考になっていれば幸いです。 それでは、ありがとうございました。 明日の記事は @Malli さん, @ben.hsieh さんです。引き続きお楽しみください。
アバター
こんにちは。メルペイ Engineering Engagement チームの mikichin です。 この記事は、 Merpay Advent Calendar 2023 の5日目の記事です。 11月のOffice Weekで「Fintech Tech Talk at Office Week」を開催したので、その様子をお届けします。 Fintech Tech Talk at Office Week について Office Week とは? メルカリグループでは、「YOUR CHOICE」という制度があり、約90%以上のメンバーがリモートワークで働いています。 関係性が薄くならないようにメルカリグループのFintech領域では「Office Week」というイベントをだいたい半期に1度開催し、なるべく出社し集まることでチーム内・他部署・経営とのコミュニケーション機会の創出、関係強化を図っています。 メルカリ、多様な働き方を尊重した 「メルカリ・ニューノーマル・ワークスタイル “YOUR CHOICE”」の活用状況を公開 Fintech Tech Talk とは? エンジニアリング組織全体で得た知見を共有するLT大会です。 発表時間は5分、話すテーマは技術的な話はもちろん、趣味の話など何でもOKというゆるいルールです。 リモートワークが中心となった今、オフラインで全体に知見を共有する機会も少なくなりました。そこで、他チームのメンバーや取り組みを知り、交流のきっかけになればと考えて運営しています。 当日の様子について どんなLTがあったのか 内容は業務にとどまらず、興味のある領域も対象です。キーボードの話や直近チームで取り組んだプロジェクトについての話、メルカリグループの部活として行っている 技術書典 の話など、さまざまなテーマのLTがありました。 △メルペイVPoEのkeigowさんが「Introduction of Competitive Programming」の発表をしている様子 メルペイ Frontendエンジニアの @yutaro さんは、以前 社外イベント で発表した「内製UIコンポーネントのアクセシビリティテストを支えるOSS」を社内用にアレンジして発表をしました。社外イベントの資料は公開していますので、興味がある方はぜひこちらをご確認ください。 メルペイ Backendエンジニアの @Liu さんが発表した「LINE 公式アカウントPJ」については、下記記事をご確認ください。 Flow Control Challenges in Mercari’s LINE Integration 参加者の反応について イベントには、メルペイ新CEO @Takeshiさんをはじめエンジニアリング組織以外のメンバーも含め、100名以上が参加しました。 現在のメルカリグループは、約50カ国のメンバーで構成されています。本イベントに全員が参加できるよう、Global Operation Team(GOT)※ の同時通訳を入れ、登壇者の言語にあわせた言語で司会進行しました。 ※:社内の通訳・翻訳を担当する専門チーム GOTの取り組みはぜひ、メルカン記事「 言語を活用してメルカリのビジネスやD&Iをサポート!──Global Operations Teamが提供する通訳・翻訳業務以上の価値 」をご確認ください。 イベント中、Slackには「アクセシビリティ、大事だよねぇ」「全然知らない内容でおもしろい」といった内容についての反応や「日本語だけではなく、英語のLTもあってよかった」「おもしろかった」といったイベント全体への感想が投稿されていました。 Office Weekにあわせて出社した社員はもちろん、Fintech Tech Talkはオンラインでの参加者もたくさんいました(Google Meetで社内向けに配信していました)。 おわりに 社内向けLT大会は、参加者が発表をきいて何かを得ることも大事ですが、それよりもわいわいみんなで楽しむことができること、気軽に発表をするという経験をすること、が大事かなと思っています。 今回、イベント当日の朝に飛び込みで登壇が決まったLTがありました。プレゼン資料はなく、完成したばかりのシステムの画面を使ってアップデート箇所を紹介するLTだったのですが、このLTもとても盛り上がっていました。こういうふうに気軽に発表でき、みんなで盛り上がる場所を今後もつくっていきたいなと思います。 明日の記事は panoramaさんです。引き続きお楽しみください。
アバター
 こんにちは!横浜国立大学理工学部情報工学EP3年の @shion1305 です。今年の10月から株式会社メルペイ Settlementチームにてバックエンドエンジニアのインターンとして所属しています。 この記事は、 Merpay Advent Calendar 2023 の4日目の記事です。 Settlementチームでは、メルペイ加盟店で発生した売上金を加盟店に振り込む際に、指示を出したりデータの管理を行ったりするマイクロサービスの開発を行っています。Settlementのマイクロサービスについては こちらの記事 でも紹介されています。 私がJoinして早々担当したタスクの一つが、Settlementサービスに対するKubernetesのPod Distruption Budget(PDB)設定の見直しでした。Kubernetesについてはこれまで個人開発で少し調べたことがある程度でした。今回PDB見直しを行う中で仕様についてリサーチをしていたのですが、多くの記事がある中で実際の挙動について自分が思うような記事があまり見つかりませんでした。今回のAdvent Calendarを機に、自分なりにわかりやすくまとめてみることにしました。 本記事では、特に以下にフォーカスします。 PDBの挙動 パーセント指定を用いた場合のPDBの動き minAvailable maxUnavailable それぞれのポイント Pod Disruption Budgetの概要  PDB(Pod Disruption Budget)は、 Voluntary Disruptions(システムの計画的な中断) からアプリケーションの可用性を保護するKubernetesの機能です。 Voluntary Disruption の具体例としては以下が挙げられます。 kubectl drain でのNodeからのPod退避 Nodeスケールダウン時のPod退避 Node間のPodの移動 (NodeからPodを他のNodeに退避させる操作を、以降Drain操作と表記します。)  例えば、以下のように記述すると、 Voluntary Disruptions において、使用できないPodの割合を33%までとなるように指定できます。 apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: pdb-sample namespace: namespace-sample spec: maxUnavailable: 33% selector: matchLabels: app: pdb-tester  PDBの設定においては、 minAvailable または maxUnavailable のいずれか一方を指定することが可能です。 minAvailable では、指定したPod群の中で常に稼働していなければならない最小限のPodの数または割合を指定でき、 maxUnavailable は、一度に中断または利用不可となっても良いPodの最大数または割合を指定できます。 自動スケールによってPod数が変動する場合において固定値を設定するのみではPod数に応じたPDBの挙動を設定することができないため、パーセント指定が用いられることがあります。実際、メルカリグループのマイクロサービスで設定されているPDBの多くでは、パーセント指定が用いられています。  しかし、パーセント指定を行う場合、PDBがどのような挙動をとるのか、分かりにくくなってしまいがちです。 パーセント指定におけるPDBの挙動 公式ドキュメントでの記載 公式ドキュメントには以下のように、パーセント指定で中途半端な数になった時には数が繰り上げられることが明記されています。 When you specify the value as a percentage, it may not map to an exact number of Pods. (中略..) Kubernetes rounds up to the nearest integer, so in this case, 4 Pods must be available. When you specify the value maxUnavailable as a percentage, Kubernetes rounds up the number of Pods that may be disrupted. Thereby a disruption can exceed your defined maxUnavailable percentage. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget 対応するソースコードを見てみる  中途半端な数になった際の繰り上げの振る舞いについて、実際のソースコードを確認してみます。 minAvailable と maxUnavailable の読み取りに対応する部分は以下のようになっています。 /pkg/controller/disruption/disruption.go L797-L800 (2023/12/1時点) maxUnavailable, err = intstr.GetScaledValueFromIntOrPercent(pdb.Spec.MaxUnavailable, int(expectedCount), true) if err != nil { return } minAvailable, err = intstr.GetScaledValueFromIntOrPercent(pdb.Spec.MinAvailable, int(expectedCount), true) if err != nil { return } ここで用いられている GetScaledValueFromIntOrPercent の中身の実装はこのようになっていて、上記では パラメータとして roundUp: true が指定されているため、繰り上げ処理がされていることが確認できます。 func GetScaledValueFromIntOrPercent(intOrPercent *IntOrString, total int, roundUp bool) (int, error) { (中略...) if isPercent { if roundUp { value = int(math.Ceil(float64(value) * (float64(total)) / 100)) } else { value = int(math.Floor(float64(value) * (float64(total)) / 100)) } } return value, nil } PDB設定時の動作例 前述で繰り上げ処理が行われることはわかりましたが、受け付けた値に対してPDBがどのような動作をするのかについて、いくつかケースを想定して検証しました。 今回想定した流れは以下の通りです。 Nodeが2つ存在している 片方にPodが入っていて、PDBが設定されている Podが存在しているNodeに対して kubectl drain が実行され、Podの退避処理が実行される ケース1: Pod数:2, maxUnavailable:50% maxUnavailableのPod数は1Podとして計算されます。その結果、図のように可用性を担保した状態で Drain操作ができることが確認できました。 ケース2: Pod数:1, maxUnavailable:50%  maxUnavailableのPod数は1となります。そのためDrain操作が可能となりますが、退避するPodの中断処理と新しいPodの起動処理は同時に実行されるため、Drain操作中に利用可能なPod数が0となる可能性があります。  このようにmaxUnavailableを用いる場合、最小pod数を考慮する必要が出てきます。(Pod数が1の時にあえてDrainできないようにする手段もあるようです。 公式ドキュメント ) ケース3: Pod数:2, maxUnavailable: 80%  maxUnavailableのPod数は2となります。そのため2Podに対して同時に退避処理が実行されます。そのため、drain操作中に利用可能なPod数が0となる可能性があり、可用性に問題が出る可能性があります。 ケース4: Pod数:1, minAvailable: 50%  minAvailableのPod数は1となります。PDBはdrain操作のためにPod数の調節を行うことはしないため、PDBの条件を満たすDrain操作ができず、Drain操作は止まったままの状態となります。  このように、minAvailableを用いる場合でも最小pod数を意識する必要が出てきます。 minAvailableとmaxUnavailableの整理  これまで具体的なケースにおけるPDBの影響を確認しました。  PDBではminAvailableとmaxUnavailableどちらかのみしか設定することができません。それぞれを採用することによるメリット、考慮すべき点について以下にまとめます。 minAvailable メリット 0より大きい数を指定しておけば、Drain操作時において必ず1Pod以上動作させて可用性を持たせることができる。 考慮が必要な点 (パーセント指定ではなくPod数で指定した場合) スケールアップして多くのPodがPDBの管理対象となっている場合、Drain操作で一度に多くのPodが利用できない状態となり、パフォーマンスに影響が出る可能性がある。 適切に値を設定しないとDrain操作ができなくなってしまう。(特に管理対象のPodが少数である場合は注意が必要) Drain操作ができなくなる条件 パーセント指定の場合、現存のPod数に対して計算を行い繰り上げ処理が行われた結果、minAvailableのPod数がPDBが対象とするPod数と同数になる時。 Pod数指定の場合、minAvailableのPod数がPDBが対象とするPod数より多くなってしまう場合。 maxUnavailable メリット Drain操作ができなくなる状態は基本発生しない。 考慮が必要な点 適切に数値を設定しないとDrain操作中に全てのPodが中断してしまう可能性がある。 Drain操作ができなくなる条件 maxUnavailableを0に設定する。 Pod数が1の状態のままでは可用性を持ってDrain操作をすることができないため、あえて maxUnavailable: 0 を設定して警告を出すために設定する方法もあるようです。 公式ドキュメント まとめ  PDBの設定に関しては、minAvailable と maxUnavailable のどちらが良いという一般的な答えは存在しません。システムによって要件は異なるのでPodの最小稼働数や中断許容範囲を理解し、それに基づいて適切な設定をすることが重要です。今回の記事が、皆さんのPDBに関する理解を深め、より効果的なKubernetesの運用に役立つ一助となれば幸いです。 明日の記事はmikichinさんです。引き続きお楽しみください!
アバター
はじめに こんにちは。メルペイVPoEの @keigow です。 この記事は、 Merpay Advent Calendar 2023 の2日目の記事です。 今年の3月まではソウゾウでHead of Engineeringとして働いていましたが、4月にメルペイに2年ぶりに戻ってきました。本日はメルペイのProduct組織の改善とProgram組織への移行の取り組みについてご紹介します。 以前のProject Matrix型組織 2022年9月までは、Microservicesの単位をベースとして構成されたFunctionチーム(Growth、Platform、与信領域など)から、3ヶ月ごとに決めているProject(新機能開発、他社連携など)に各メンバーをアサインしていくという形でProduct開発を推進していました。 会社のOKRとして合意した目標に沿って、Productチーム内でProjectの優先度を決めて左から順に並べ、Project毎にProject LeaderとTechnical Project Manager(Engineeringのカウンターパート)を置くことで、以下のような良い点があったと考えています。 事業としてフォーカスされている点が理解しやすい 優先順位が明確なためアサインの判断がしやすい 結果として、会社として重要なProject(チーム横断な動きが必要なものであっても)をスピード感を持って推進できる 一方で以下のような課題感もありました。 組織の成長と人員増加に伴い、優先順位の調整コストが高まってきた 3ヶ月単位でProjectの見直しがあり、アサインの変更も随時行っていたため、チームビルディングのコストが高い 今後の運用や改善までを想定した中長期の計画づくりが難しくなっていた これらの課題感を踏まえて、2022年10月より新しいProgram型組織への移行を開始しました。 Program型組織の導入 特定のドメインごとに組織を分けて、より小さな単位で意思決定をできるようにしたチームをProgramと呼んでいます。現在メルペイには6つのProgramがあり、その役割ごとに大きくProduct / Foundation / Enablingという3つの領域に分けています。 Product: 支払いや与信、還元の仕組みなどお客さま体験のコアとなる部分の提供を担う。 Foundation: 各Product領域のProgramに対して汎用的に利用可能なPlatform機能を提供する。決済の中心となるマイクロサービスや、KYC(本人確認)、ポイント付与の仕組みなど。 Enabling: ArchitectやSRE、Data Platformなど、横断的な技術課題の解決や生産性向上など開発全体を支援する。 各ProgramにはProduct HeadとEngineering Headを置いています。Product Headは施策の優先順位の決定や、戦略・ロードマップの策定とその推進に責任を持ち、Engineering Headは中長期を見据えた技術的な戦略や方針の策定と推進に責任を持っています。 基本的にはOKRなど会社方針をベースにProgram内で意思決定が出来るようにしていますが、3ヶ月ごとにProgram HeadメンバーとCPO/CTO/VPsを交えたStrategy Reviewを行うことで、Program組織の戦略と経営の戦略の方向性を揃えられるようにしています。 Engineering組織のアップデート ドメイン毎のProgram組織を作ることで、Program内のアサインに柔軟性が生まれ、運用や改善も踏まえた、中長期の戦略への投資がしやすい環境になりました。一方でEngineering組織のレポートラインは職種別となっており、Backend、Frontend、iOS、Androidなど各職種別にEngineering Manager(EM)、Manager of Managers(MoM、EMのManager)が居るという体制になっていました。その結果として一部のEMやMoMが各Programにフォーカスすることが難しいという課題が有りました。 この問題を解決するため、今年の10月からProgram組織に合わせたレポートラインに変更し、それぞれのEMやMoMが自身の担当するProgramにフォーカスできるような体制変更を行いました。 振り返りと今後 Program組織にトライし始めたのは1年ほど前ですが、Engineering組織のアップデートも含め、細かい改善を積み重ねることで、少しずつ動きやすい状況が作れてきたと思います。とはいえ、まだまだ課題も多いため、1つずつ課題と向き合って解決していきたいと思っています。 余談になりますが、今回のような組織体制はメルペイとしては初めてではなく、Project Matrixをベースとした体制に移る前には、(当然今と違う部分はありますが)Program組織に近い体制を取っていた時期もありました。 組織変更はコストが高いので、頻繁に変えすぎるのは良くないと思っていますが、一定のタイミングでその時の状況やニーズに合わせて、変化をしていくこと自体は必要だし、やっていきたいと思っています。どのような組織もPros/Consがあるものだと思うので、ある意味自然な姿だとも感じます。 おわりに 明日の記事はkeigoandさんの「Merging teams for a Growth Platform」です。引き続きお楽しみください。
アバター
この記事は、 Merpay Advent Calendar 2023 の1日目の記事です。 hello hello hallo how high? メルペイで5月からVPoE の @nu2 です。 はじめに 2023年6月、メルペイはエンジニアリング組織の新体制を発表しました。 https://mercan.mercari.com/articles/39414/ (新体制になったメルカリグループのFintechのエンジニアリング。新CTOとVPたちが語る、グループLTV最大化のためにFintech事業が果たすべき役割) 今年の Merpay Advent Calendar はエンジニアリング組織新体制の元、オープナーとしてメルペイのこの1年を淡々と振り返ってみたいと思います。 特に私は5月に入社しましたので新鮮な視点をお伝えできればよいなと考えています。 https://engineering.mercari.com/blog/entry/20230704-merpay-techasset-first-impression/ (New Member として見たMerpay Tech Asset First Impression) LLM 入社日当日にLLM を活用した「ぐげん会議」を開催するからVP としてチームのスポンサーになってくれと言われました。全く前知識とコンテキストがないまま、これまでの経験から障害報告書を障害の状況から規定の形式に自動生成して書記をするAI を開発するチームをスポンサードする事に決めました。 https://mercan.mercari.com/articles/39144/ (LLMを活用してなにがつくれるか?——「ぐげん会議」開催から見えてきた、AI活用の新たな可能性) 私がスポンサードしたチームは見事にCTO 賞を受賞しました。 また、MVPを受賞した返済相談チャットシミュレーターを開発したチームはその品質の高さとともに、会社の決算資料にも報告を開始したクレジットサービスの債権残高 / 回収率にとても大きなインパクトを残しそうなポテンシャルを感じるAI プロダクトでした。 メルカード 2022年12月から提供を開始したメルカードの発行枚数が200万枚を突破しました。 https://jp.merpay.com/news/2023/11/2million/ (「メルカード」、すべてのお客さまへの提供開始から1年足らず(約11か月)で発行枚数200万枚突破) 提供開始からわずか半年で機能をアップデート、その約3ヶ月後に更にアップデートをしています。 https://jp.merpay.com/news/2023/06/20230627seisan/ (メルペイ、清算機能のアップデートで清算後すぐに「あと払い利用枠」が回復する機能を追加) https://jp.merpay.com/news/2023/10/20231016seisan/ (メルペイ、清算機能のアップデートで清算後すぐにポイントが付与される機能を追加) このような体験向上をデザイン面、エンジニアリング面から支えた結果がグッドデザイン賞を受賞した事につながっているのではないかと思います。 エンジニアリングとしてこのように短期間でアップデートをかけられる決済機能をこれまで日本国内で見た事はありません。 なぜこのような事が可能なのか?という事はMerpay & Mercoin Tech Fest 2023 の こちらのセッション にて発表されています。 グッドデザイン賞 https://about.mercari.com/press/news/articles/20231005_gdesign/ (メルカリグループのサービス、「メルカード」と「ビットコイン取引サービス」が2023年度グッドデザイン賞をW受賞) Merpay & Mercoin Tech Fest 2023 そしてエンジニアリング組織の新体制後初のTech Fest を開催しました。 Fintech 領域の業務経験やドメイン知識が不十分な状態で入社しましたので 個人的にもこのTech Fest は自分のインプットを増やす上で非常に有用でした。 https://mercan.mercari.com/articles/39180/ (8月22日より3日間にわたって開催!Fintech CTOと2名の新VPoEに聞く、「Merpay & Mercoin Tech Fest 2023」の見どころと意気込み) https://engineering.mercari.com/blog/entry/20231023-mmtf2023-day1-2/ (【書き起こし】How to Unleash Fintech – Shunya Kimura / Keigo Watanabe / Noriaki Utsunomiya 【Merpay & Mercoin Tech Fest 2023】) 現在配信したセッションの動画を全てテキストに書き起こしてくれているので予習、復習に最適です。 https://engineering.mercari.com/blog/entry/20231023-mmtf2023-list/ (Merpay & Mercoin Tech Fest 2023 セッション書き起こしまとめ) 求人プラットフォーム「メルカリ ハロ」 そしてTech Fest のトークセッションで「まだ言えない事がある」とCTO が言及していたのがこのスポットワーク事業に参入する話です。 https://about.mercari.com/press/news/articles/20231113_mercarihallo/ (メルカリ、2024年初春にスポットワーク事業に参入、本日より求人募集パートナーの先行受付を開始) “メルペイを通じて、給与デジタル払いを実現し、「メルカリ ハロ」をご利用いただいた際、「メルペイ」で給与を受け取れる体験を提供することを目指します。” プレスリリースから引用した文章のとおり、この体験の提供を実現するため現在急ピッチかつ慎重にプロジェクトを進行しています。 貸金業務取扱主任者制度 貸金業務取扱主任者制度 とは貸金業法で定められている国家試験です。 我々は貸金業を営んでいますので、所属する社員は誰でも会社の経費で受験する事ができます。ドメイン知識を習得する絶好の機会なので受験してきました。 毎年試験にチャレンジするエンジニアはかなりおり、試験前後は試験対策用に立てられたSlack チャンネルがとても盛り上がってました。 なぜこのような法律ができて、貸金業を事業とする事業者は資格の保有を義務付けられるのか?というこれまでの歴史的背景から学ぶ事も多くあり私は既に来年の試験に向けて毎日少しずつ学習を繰り返そうと考えています。 経済安全保障推進法 株式会社メルペイは経済安全保障推進法の特定社会基盤事業者として指定されました。 給与デジタル払いを実現するためにも必要なことであります。 https://www.fsa.go.jp/news/r5/economicsecurity/231117infrastructure.html (金融分野における経済安全保障対策) “経済安全保障推進法第50条第1項及び第2項の規定に基づき、特定社会基盤事業者を令和5年11月16日に指定し、同年11月17日に公示しましたので、別添をご確認ください。” https://www.fsa.go.jp/news/r5/economicsecurity/tokuteishakaikiban.pdf (特定社会基盤事業者として指定した者) 私が入社後ちょうど半年を経過したタイミングで国から社会インフラの一部として指定され、入社後丸一年経過する日までに法令に準拠する体制を構築しなければなりません。 私個人の経歴としてもインターネットポータル、検索、通信とICT の社会インフラ企業で経験を積んできましたので運命めいたものを感じてしまいました。 「守り」あってこその「攻め」を来年は実践していく所存です。 おわりに 2023年のメルペイは前年にリリースをした大きな機能を磨き上げる年になったと個人的に感じました。またその大きな機能に対してさまざまな反響をいただきました。 今後もお客さまの安心・安全を維持しながら新たな価値をお届けすることを、エンジニアリングで達成していきたいと思います。 明日の記事は VPoE のkeigowさんです。引き続きお楽しみください。 おまけ 今年無事。 所属する会社が変わってもこのフレーズをAdvent Calendar に投稿する事は私の恒例行事なので、 今年もILL-BOSSTINO のこの言葉を捧げます。 特に我々の業界は月跨ぎ、年跨ぎのタイミングでインシデントが発生しやすいです。 皆さま良いお年をお迎えください。 (THA BLUE HERB “今年無事” @ 東京 contact – 2019.12.29)
アバター
こんにちは。メルペイ Engineering Engagement チームの mikichin です。 早いもので来週から12月ということで、Advent Calendarの季節がやってきます!今年も、メルカリとメルペイ2社で Advent Calendar を実施します! ▶ Mercari Advent Calendar 2023 はこちら Merpay Advent Calendar とは? Advent Calendar の習慣にもとづいて、12月1日から25日までの期間毎日ブログ記事を投稿する、というブログ公開型イベントです。 メルペイ・メルコインのエンジニアがプロダクトや会社で利用している技術、興味のある技術分野やちょっとしたテクニックなど知見をアウトプットしていきます。このAdvent Calendarを通じてクリスマスまでの毎日を楽しく過ごしていただければと思っています。 2022年のMercari / Merpay Advent Calendar はこちら Mercari Advent Calendar 2022 Merpay Advent Calendar 2022 公開予定表 (こちらは、後日、各記事へのリンク集になります) Date Theme / Title Author 12/1 メルペイ VPoE による2023年の振り返り @nu2 12/2 メルペイのProgram型組織への移行 @keigow 12/3 Merging teams for a Growth Platform @keigoand 12/4 動作例からKubernetes PDBの挙動を理解する @Shion (Intern) 12/5 Fintech Tech Talk at Office Week を開催したよ! @mikichin 12/6 メルペイに新卒入社して1年目にやったこと @panorama 12/7 Enhancing Collaboration and Reliability: The Journey of Version History in our Page Editor Tool @Malli , ben.hsieh 12/8 メルペイでのインターンを2ヶ月経験してみて @Shion (Intern) 12/9 新卒エンジニアが Airflow のバグを発見してからコントリビュートするまで @champon 12/10 加盟店精算のインボイス対応 @ryuyama 12/11 Cypress + Gmail APIでメール+SMSの2FA認証をテスト自動化する(気合&パワー) @fukutomi 12/12 Flow Control Challenges in Mercari’s LINE Integration @Liu 12/13 多国籍メンバーで構成されたメルペイ決済基盤チームが言語の壁を突破するために取り組んだこと @abcdefuji 12/14 TnS Platform Team, past, present, and future @ntk 12/15 Merpay Frontend のこれまでとこれから: 2023年版 @tokuda109 12/16 品質要件が厳しいLLMアプリケーションのトライアル評価を通じて得た知見 @gucci 12/17 2023 GopherCon Review @tenlingp 12/18 (JA) Merpay Enabling Client チームが目指すこと (EN) What the Merpay Enabling Client Team aims for @masamichi 12/19 モダリティを考慮したiOSアプリのナビゲーションの再設計 @kenmaz 12/20 決済基盤の Observability を向上するための Datadog Dashboard の進化 @komatsu 12/21 AWS Transfer Family で SFTPサーバーを作ってみたら便利だった話 @myoshida 12/22 お手軽な検索API構築 その2 ~マルチコア・ベクトル・分散検索 @orfeon 12/23 メルコインにおけるGitHub Actions活用術 @iwata 12/24 Offsitesのワークショップでの4つの工夫 @pooh 12/25 メルカリEngineering Roadmapの作成とその必要性 @kimuras Merpay Advent Calendar 2023 の1日目は、 VPoE の @nu2 が執筆予定です。 ひとつでも気になる記事がある方は、この記事をブックマークしておくか、 エンジニア向け公式X(旧Twitter) をフォロー&チェックしてくださいね!
アバター
こんにちは。メルカリ Engineering Officeの yasu_shiwaku です。 またまたこの季節がやってきましたね!来週から12月ということで、Advent Calendarがはじまります。今年もメルカリとメルペイ・メルコインで2本のAdvent Calendarを実施します! ▶ Merpay Advent Calendar 2023 はこちら Mercari Advent Calendar とは? Advent Calendar の習慣にもとづいて、12月1日から25日までの期間毎日ブログ記事を投稿する、というブログ公開型イベントです。 メルカリグループのエンジニアがプロダクトや会社で利用している技術、興味のある技術分野やちょっとしたテクニックなど知見をアウトプットしていきます。このAdvent Calendarを通じてクリスマスまでの毎日を楽しく過ごしていただければと思っています。 2022年のMercari / Merpay / メルカリ Shops Advent Calendar Mercari Advent Calendar 2022 Merpay Advent Calendar 2022 メルカリShops [フライング]アドベントカレンダー2022 公開予定表 (こちらは、後日、各記事へのリンク集になります) Date Theme / Title Author 12/1 The Bitter Lesson about Engineers in a ChatGPT World @darren 12/2 How We Saved 75% of our Server Costs @pratik 12/3 How we reduced response latency by over 80% @rclarey 12/4 Performance monitoring in Mercari mobile apps @fp 12/5 The Spirit of Giving: A Year-End Roundup of Our Open Source Contributions @adbutterfield 12/6 強いエンジニア組織に必要な、6つの技術以外のこと – メルカリ編 — @thiroi 12/7 英語が苦手なエンジニアがメルカリに入ってどうなったか @otter 12/8 t9n, i18n, l10n, g11n ?! @wills 12/9 Gitブランチ戦略 Stacking手法のケーススタディ @osari.k 12/10 In search of a knowledge management silver bullet @rey 12/11 チームワークと効率向上のカギ!メルカリが成功する大人数iOS開発のための手法とは? @sae 12/12 The art of streamlining mobile app releases @fp 12/13 Leading a team of lead engineers @fp 12/14 Current Microservices Status, Challenges, and the Golden Path @ayman 12/15 BigQuery Unleashed: A Guide to Performance, Data Management and Cost Optimization @sathiya 12/16 Closing the visual testing gap on Android with screenshot tests @lukas 12/17 The new Mercari Master API @cafxx 12/18 ① The Frontend Infrastructure Monorepo @jon 12/18 ② Onboarding施策を成功させるポイント @aisaka 12/19 Leveraging LLMs in Production: Looking Back, Going Forward @andre 12/20 GCSのリソース最適化の取り組みで得た知見 @ayaneko 12/21 iOSDC2023で発表した「メルカリ10年間のiOS開発の歩み」のトークスクリプトを公開 @motokiee 12/22① Making of "Your Mercari History" @manoj 12/22② 言語モデルを用いたQuery Categorization ( EN ) @pakio 12/23① メルカリの中長期技術投資 プロジェクトRFS: 約2年の振り返り @mtsuka 12/23② Fine-Tuned CLIP: Better Listing Experience and 80% More Budget-Friendly @andy971022 12/24 Renovate Web E2E tests with Playwright Runner @jye 12/25 メルカリEngineering Roadmapの作成とその必要性 @kimuras Mercari Advent Calendar 2023 の1日目は、 Data Engineeringチームのdarren が執筆予定です。 ひとつでも気になる記事がある方は、この記事をブックマークしておくか、 エンジニア向け公式Twitter をフォロー&チェックしてくださいね!
アバター
はじめに こんにちは、mercari.go スタッフの hiroebe です。 11月1日にメルカリ主催の Go 勉強会 mercari.go #24 を YouTube でのオンライン配信にて開催しました。 今回は GopherCon 2023 に焦点を当てた特別回として、サンディエゴで開催された GopherCon 2023 に実際に現地参加したメルカリエンジニアが、セッション内容を要約して発表しました。この記事では、当日の各発表を簡単に紹介します。動画もアップロードされていますので、こちらもぜひご覧ください。 GopherCon 2023 Recap 1つめのセッションは nsega さんによる「GopherCon 2023 Recap」です。 発表資料: GopherCon 2023 Recap at mercari.go#24 このセッションでは、はじめに GopherCon の概要と今年の GopherCon 2023 の様子について紹介し、後半のパートでは GopherCon 2023 から「The Future of JSON」というセッションについて振り返りを行いました。 Go の encoding/json パッケージは、長年使われてきた中で機能の不足やインターフェースの欠陥、パフォーマンスの制約といった問題を抱えていることがわかっていて、これを解決するために新たなメジャーバージョンである encoding/json/v2 パッケージが提案されています。セッションでは、これまでに挙げられた問題点が encoding/json/v2 パッケージによってどのように解決されるかについて詳細に説明されていました。 json と jsontext の2つのパッケージを用意する話など、個人的にもとても興味深かったです。 またセッションの最後には、このような大きな変更を伴う開発をどのように進めていくか、という点についても触れられていました。オープンに議論をしながら合意形成をしたり、パフォーマンスに関してはベンチマークを取りながら進めるといった手法は、nsega さん自身も今後開発を行っていく上で参考にしたいと仰っていました。 Concurrent Data Structures and CPU Caching with Go 2つめのセッションは derrick さんによる「Concurrent Data Structures and CPU Caching with Go」です。 発表資料: Concurrent Data Structures and CPU Cache with Go セッションの前半は、GopherCon 2023 の中から「Building A Highly Concurrent Cache in Go」というセッションの振り返りを行いました。このセッションでは Reddit でのキャッシュの活用事例について話されていて、Redis でのキャッシュとは別にローカルなキャッシュを導入することでコスト削減に成功した事例や、キャッシュのための独自のデータ構造を作成した事例などが紹介されていました。データ構造はシンプルなものから始めること、それを変更する際には都度プロファイルやベンチマークをとることといったノウハウが詰まった発表でした。 セッションの後半では、前半のセッションで言及のあった Cache Line について掘り下げて解説を行いました。サードパーティの xsync.Map は標準パッケージの sync.Map と比べても高いパフォーマンスを見せていて、その理由は Cache Line を考慮したデータ構造にあるそうです。Cache Line を理解するための前提知識として CPU のキャッシュについてもわかりやすく説明されていて、個人的にもとても勉強になりました。 Recap: Automatically Instrument Your Go Source Code with Orchestrion 3つめのセッションは komatsu さんによる「Recap: Automatically Instrument Your Go Source Code with Orchestrion」です。 発表資料: Recap: Automatically Instrument Your Go Source Code with Orchestrion このセッションでは Datadog 社が開発している orchestrion という CLI ツールについて紹介されました。orchestrion は Datadog で APM を計測するための Go のコードを自動計装 (code instrumentation) するためのツールです。Go は Java でいうアノテーションや Python でいうデコレータのような構文を持ちませんが、一方で文法がシンプルで AST のパースが簡単という特徴があり、それを踏まえたアプローチになっているそうです。また AST の解析には標準パッケージの go/ast ではなく dave/dst を使っているそうで、その理由についても触れられていました。シンプルなツールであるため導入が簡単である一方、大規模なリポジトリに導入するにはまだいくつかの課題があると komatsu さんは考えているそうで、今後のさらなる開発に期待したいです。 GopherCon 2023 Overview 4つめのセッションは tenling さんによる「GopherCon 2023 Overview」です。 セッションの前半では、GopherCon 2023 で行われた CTF について紹介しました。GopherCon で CTF が行われたのは今年が初めてで、セキュリティやコードに関してだけでなく、以前の GopherCon で発表されたテーマに関する出題もあったそうです。このセッションでは、CTF で出題された中から tenling さんがお気に入りの問題を2つ紹介しています。CTF は来年も実施を予定しているそうなので、今回の発表で興味を持った方はぜひチェックしておきましょう。 セッションの後半では、GopherCon 2023 から「From Zero to Hero: Launch Your Own Game in 45 Minutes」というセッションについて紹介しました。 feed-the-gopher というゲームを開発した事例の紹介で、 Momento というサービスを利用することで素早い開発を実現しているとのことでした。また、ゲーム開発では Unity などを利用するのが一般的になっていますが、Go でゲーム開発をする人がもっと増えてほしいという思いもこのセッションには込められているそうです。 Navigating the Seas of Data: A Migration Journey 5つめのセッションは mann さんによる「Navigating the Seas of Data: A Migration Journey」です。 発表資料: GopherCon 2023 Bitly _ Migrating 80 billion records from MySQL to Bigtable このセッションでは、Bitly がセルフマネージドな MySQL から Google Cloud の Bigtable へマイグレーションを行った事例が紹介されました。Key-Value 形式の膨大なデータを持つ Bitly 社では、従来の MySQL を利用した仕組みにおいてスケーラビリティやバックアップに関する課題を抱えていたそうです。それらの課題を解決するために Bigtable へのマイグレーションが実施され、結果として高いスケーラビリティや強固なバックアップが実現されました。セッションではマイグレーションの手順について順を追って説明されていて、中でも古いレコードのバックフィルなどを行うマイグレーションスクリプトが Go で記述されているそうです。マイグレーションは手順だけ見るとシンプルですが、これを膨大なデータを抱えるプロダクションサービスで実際にやりきったという事例はとても参考になると思います。 GOOOPs – Talking about Go and OOPs 6つめのセッションは amit-kumar さんによる「GOOOPs – Talking about Go and OOPs」です。 このセッションでは Go と OOP (オブジェクト指向プログラミング) の関係について説明しました。開発者の多くは Go に触れる以前に C++ や Java といった他のオブジェクト指向のプログラミング言語を扱った経験があるかもしれませんが、それらの言語におけるオブジェクト指向の考え方をそのまま Go に適用するべきではありません。そのような誤った方法で Go に OOP が適用された状態をこのセッションでは GOOOP (= GO + OOP) と呼び、GOOOP を疑うべき兆候としてどのようなものがあるか、具体例とともに紹介されています。またセッションの後半では、OOP とセットで語られることの多い SOLID 原則についても紹介しました。SOLID の各原則が Go ではどのように実現されるかについて、1つずつ順番に説明されています。従来の OOP の考え方をそのまま適用するのではなく、その背景にある原則を正しく理解し Go らしい書き方で実現することが重要であると結論づけていて、個人的にもとても勉強になるセッションでした。 おわりに 今回は GopherCon 2023 の活動報告会として、実際に現地参加したエンジニアからセッションの振り返りの発表をお送りしました。GopherCon 2023 に参加できなかった方も、イベントの雰囲気を感じていただけたのではないでしょうか? ライブで視聴いただいた方も録画を観ていただけた方も本当にありがとうございました! 次回の開催もお楽しみに! イベント開催案内を受け取りたい方は、connpassグループのメンバーになってくださいね! メルカリconnpassグループページ
アバター
Merpay & Mercoin Tech Fest 2023 は、事業との関わりから技術への興味を深め、プロダクトやサービスを支えるエンジニアリングを知ることができるお祭りで、2023年8月22日(火)からの3日間、開催しました。セッションでは、事業を支える組織・技術・課題などへの試行錯誤やアプローチを紹介していきました。 今回、より多くの方に知ってもらい役立ててもらうため、Merpay & Mercoin Tech Fest 2023の全セッションを書き起こした記事を用意しました。セッションがたくさんあるので、その記事リンクまとめを作成したのが本記事です。お役に立てば幸いです。 ▼Merpay & Mercoin Tech Fest 2023 書き起こし一覧 ※各記事にYoutubeのセッション動画が埋め込まれています。 .author_icon{width:50px; height:auto; margin:1px; border-radius:20px} .day1{ border: 2px solid #ff0211 !important} .day2{ border: 2px solid #4dc9ff !important} .day3{ border: 2px solid #00c1aa !important} Author Session Title Keynote Shunya Kimura How to Unleash Fintech Shunya Kimura , Keigo Watanabe , Noriaki Utsunomiya 1週間リリースを支えるAndroid自動テスト運用のその後 Kenta Takahashi , Shintaro Miyabe Merpay iOSのGroundUp Appへの移行 kenmaz Merpay iOSにおけるSwift Concurrency対応の挫折と今後 Takeshi Sato SwiftUIでビットコインの価格チャートを改善・再実装した話 andooown フロントエンドチームのスキルテスト評価システム改善の取り組み tokuda109 WYSIWYGウェブページビルダーを支える技術的マジックの裏側 Hal Amano , Arvin Huang , Ben Hsieh , Jas Chen メルカリのカスタマージャーニーにおける不正防止の取り組み codechaitu 日本におけるお客さま本人確認と今後の技術的課題 Tim Tosi , Manpreet Kaur , Christophe Labonne メルカリへのFIDO導入の経緯とこれからの展望、課題から得た学び koi , kokukuma , daichiro , hidey メルペイのあと払いとスマートマネーを支える返済基盤マイクロサービスの進化 Peichong Cui 拡張性を備えたソフトウェア設計 Rupesh Agrawal 発行枚数100万枚を支えたメルカードGrowth施策の裏側 Kazuya Kawashima , Soichiro Kashima , Mikael メルカードの常時ポイント還元開発の裏側 keitaj メルペイ加盟店売上精算の仕組み Takumi Shibazaki GoによるSQLクエリテストの取り組み Yuki Mukasa 発生可能な取引の属性データを用いた素早い不正検知 Liu , Li メルペイMLにおける機械学習の品質保証とリスク管理 shuuk , Haruki Kaneko , Yuki Saito Merpay & MercoinにおけるLLM活用の取り組み Yuki Ishikawa , Daisuke Torigoe , Noriaki Utsunomiya , hmj BigQueryのデータ監視社内サービスを作った話 Hirobumi Takahashi 社内用GitHub Actionsのセキュリティガイドラインを作成した話 Toshiki Kawamura BigQueryのコンピューティングリソース管理の取り組み Go Kojima fake clock microservice -時刻をハックしてテストする方法- vvakame , Hiraku Nakano , Hiroyuki Tanaka メルコインのインフラ設計・構築と、信頼性のあるサービスをリリースするためのSREの取り組み Masaki Iino , Takaaki Yuhara メルコインにおけるシステム間のデータ分離を実現するための通信アーキテクチャ Kohei Noda Building a Global environment at Merpay: India & Japan Robert Jerovsek , Keigo Andrade , Sumil Panicker なめらかなFintech QAを実現するためにテストケースフォーマットを標準化した話 Yuki Sakamoto , Masatoshi Sato メルコイン決済基盤の実践話 Junwei Liang メルコイン決済マイクロサービスのトランザクション管理を支える技術 Shota Suzuki Merpay Engineering Career Talk Keigo Watanabe , Osamu Tonomori , Katsuhiro Ogawa gRPC Federation を利用した巨大なBFFサービスに対するリアーキテクチャの試み goccy Enabling ProgramのEngineering Headをちょっとやってみている Masahiro Sano Merpay & Mercoin Tech Fest 2023 プレイリスト Merpay & Mercoin Tech Fest 2023 の各セッションごとの動画と、各DayごとのLiveアーカイブ動画をまとめたプレイリストです。気になる動画や、一気に視聴する場合などにお役立てください。 再生リスト: Merpay & Mercoin Tech Fest 2023 – YouTube
アバター
Merpay & Mercoin Tech Fest 2023 は、事業との関わりから技術への興味を深め、プロダクトやサービスを支えるエンジニアリングを知ることができるお祭りで、2023年8月22日(火)からの3日間、開催しました。セッションでは、事業を支える組織・技術・課題などへの試行錯誤やアプローチを紹介していきました。 この記事は、「 社内用GitHub Actionsのセキュリティガイドラインを作成した話 」の書き起こしです。 @goro:今回、「社内用GitHub Actionsのセキュリティガイドラインを作成した話」というタイトルで発表させていただきます。株式会社メルコインで、バックエンドエンジニアをしております。Toshiki Kawamuraと申します。よろしくお願いします。 私は株式会社メルコインに、2022年の6月に入社しました。メルコインでは主にビットコイン取引サービスの立ち上げに参画して、バックエンドエンジニアとして開発運用を担当しております。 今回発表の題材になった、GitHub Actionsのセキュリティガイドラインの作成などの取り組みも関わっております。 まず発表の最初として、今回テーマに置いているGitHub Actionsのセキュリティガイドラインについて説明させていただきます。 GitHub Actionsセキュリティガイドラインとは、社内でのGitHub Actionsの利用の広がりに合わせて、社内有志によって検討策定された。セキュリティのガイドラインになっております。 GitHub Actionsを使うにあたり、どういった点に留意すれば、最低限の安全性を確保できるか学習してもらいたい、定期的に本ドキュメントを見返してもらい、自分たちのリポジトリが安全な状態になっているかを点検する際に役立ててもらいたいという想いに基づいて作成されているガイドラインになります。 ガイドラインは、合計4人のチームで作成しました。 まずは株式会社メルカリのSolutions Teamに所属している@vvakameさん、株式会社メルカリのバックエンドエンジニアをしている Motonori Iwataさん、株式会社メルコインのエンジニアリングマネージャーをしている sadahさん、僕の4人の有志メンバーで、このガイドラインを作成していきました。 それでは、本発表の流れを事前に紹介します。まず最初にガイドラインの中身を一部紹介いたします。その後に、ガイドラインの社内での活用状況について紹介した後に、最後にガイドライン策定の裏話ができればと思います。 それでは発表に入っていきます。まずはガイドラインの中身を一部紹介します。 ガイドラインを策定する上で、まずはチーム目標を決めました。 まず一つ目に「常に達成したいこと」として決めたのは、「外部の攻撃者からの攻撃を防ぐこと」。二つ目に、「可能であれば考慮したいこと」として、「内部と同等の権限を持つ攻撃者からの攻撃を防ぐ」。この二つを大きな目標に置いて、ガイドラインを作成していきました。 ガイドラインの構成は3部になっています。 まずはどのような脅威があるのかを知ってもらうという意図を込めて、第1部では、脅威を知るというテーマで、GitHub Actionsを利用するにあたって、起こりうるセキュリティ上の脅威を紹介しました。 2部では、1部で紹介した脅威に対して、どのような対策が取れるのかを紹介しました。 最後の3部では、主に2部の内容をベースに、どのような項目を満たすと、実際にセキュリティの対策ができるのかがわかりやすくなるように、チェックリスト形式で行って、ほしい対策について、具体的な設定方法を含め、記載しました。このような内容でガイドラインは構成されています。 それでは1部から紹介していきます。 脅威として紹介したのは、「権限設定の不備を突く攻撃」になります。プルリクエストを契機に起動するトリガーは攻撃者が何かを仕掛ける余地が大きく、不注意にワークフローを構築すると、シークレットを外部に送信されて攻撃を受ける可能性があります。 補足情報として、GitHub Actionsのトリガーにはどのようなものがあるかを紹介していきたいと思います。 例えば、ワークフローのリポジトリで発生したイベントです。例えば、リポジトリのDefault Branchにプッシュが行われたときや、リリースが作成されたとき、あるいはIssueがオープンされたとき。 プルリクエストが作成されたときなどに、ワークフローを実行するように設定することが可能です。 他にも、GitHubの外部で発生し、GitHubでリポジトリディスパッチイベントを発生させるイベントですとか、時間指定での自動実行など、さまざまなトリガーがあります。 そのようなワークフローの権限設定において不備があると、例えばシークレットが外部に送信されるなどの危険性があります。 ここで、外部に送信される方法として考えられるものをいくつか記載しました。例えば、ビルドスクリプトに細工をする、依存関係にあるライブラリを悪意のあるものに差し替える、自動実行の仕組みに相乗りされる(例えばnpmのpreinstallやpostinstall)。 また、過去にも実際に人気のライブラリでローカルファイルをスキャンする事例がありました。このような方法でシークレットが外部に送信される危険性があります。 それ以外にも、権限設定の不備があると、攻撃が行われるような影響が考えられます。 例えば、攻撃者に悪意のあるActionsや、侵害されたActionsによってGitHub Actionsの計算リソースを不正に利用される可能性が考えられます。 他にも、侵害された または 悪意のあるActionsによって、リポジトリの自動ワークフローが中断される可能性もあります。他にもDeployment Keyやアクセストークンなどの、シークレットへの読み取りアクセスは攻撃者が他のリソースを侵害するために利用される可能性があります。以上が権限設定不備があった場合に、起こりうる事象の紹介です。 次に紹介したいのは、インジェクションによる攻撃です。一見安全に見えるワークフローにおいても、コードやコマンドインジェクションを引き起こす可能性があります。 事例を二つ紹介します。まず、事例の一つ目になります。スライドのコードを見てください。 このコードにはインジェクションの脆弱性があります。コメントを二重括弧で囲っている箇所がありますが、ここに1+1のようなものを入れると、Actionsは内部で二重括弧のあたりを補完するためにlodashを使っているため、Node.jsのコードが実行され、出力が2になります。 二つ目の事例です。ワークフローのインラインスクリプトに直接インジェクションを配置するシナリオも考えられます。また、ブランチ名やメールアドレスへのコマンドインジェクションも可能です。 ここで具体的に紹介するのは、こちらのコードです。 内部の式の二重括弧が評価され、結果の値に置き換えられるため、コマンドインジェクションに対して脆弱になる可能性があります。ここではプルリクエストのタイトルが二重括弧に囲まれています。 攻撃者が実際にどのようなことができるかというと、「a”;ls $ GITHUB_WORKSPACE*」というタイトルのPRを作成する可能性があります。これを利用して、ステートメントを中断し、ランナーでコマンドを実行できるようになっています。実行すると、lsコマンドが確認できます。 インジェクションが起こると、どのような影響があるかを紹介します。インジェクションをされると、攻撃者は任意のコマンドを実行できるため、外部のサーバーにシークレットを送信するHTTPリクエストを行うことが可能になります。 リポジトリへのアクセストークンを取得しても、ワークフローが完了すると失効するので、攻撃自体は簡単ではありません。しかし、攻撃者が自動化し、管理するサーバーにトークンを呼び出してコンマ数秒で攻撃を実行することが可能です。 その場合、GitHub APIを利用してリリースを含むリポジトリのコンテンツを変更するなどの影響も考えられます。 なので攻撃者は悪意のあるコンテンツをGitHub Context経由で追加できるので、潜在的に信頼できない入力として扱う必要があります。以上が第1部「GitHub Actionsでの脅威を知る」の紹介でした。 第2部は「対策を考える」です。 まず対策の一つとして紹介したいのは、「最小権限の原則に従う」ということです。最小権限の原則は、ソフトウェアがタスクを達成するために必要な最小限の権限セットで実行されるべきであるという原則です。 ワークフローで利用可能なシークレットの権限と、ワークフロートリガーの種類に基づいて自動的に提供される一時的なリポジトリトークンの両方に当てはまります。 この原則に従うと、GITHUB_TOKENの権限のデフォルト設定は、読み取りと書き込み権限から読み取り専用に変更した方がいいと思います。 実際にこの設定をやろうとすると、リポジトリのSettings > Actions > Generalから変更できるので、ぜひ変更してみてください。 また、GitHub Actionsの権限はジョブ単位で設定を行うことで、権限を最小化できますのでなるべく権限は細分化して設定することが推奨されます。 シークレットの利用についても、いくつか対策があります。例えば、Long=lived tokenを使用しない、Workload identity federationを用いたSecret Managerの利用を検討する、JSONなどの構造化データをシークレットにしないことがあげられます。 3つ目については、なぜかというと、GitHub Actionsは、全文をマスクデータとして扱ってくれますが、部分マスクはされないためです。 ワークフロー内で使用される全てのシークレットマスクをマスクするように登録することも、対策として考えられます。シークレットに保存されたアクセストークンの利用状況を観察することも必要です。 他にもスコープが最小限のクレデンシャルを使用する、登録されたシークレット監査およびローテーションする、シークレットへのアクセスについてレビューを要求する。こういった対策が考えられます。 次は、イベントトリガーの対策です。 利用すべきイベントトリガーとして、リポジトリへのwriteはできないように制限されているので、プルリクエストの処理にはpull_requestイベントを使った方がいいです。 少し制限を緩めたものとして、pull_request_targetがあります。Github Actionsのワークフロー自体は、pull_request_targetだと、Default Branchのものが使われます。ワークフローのyamlに直接記載する場合は、攻撃者によって上書きされることはありません。チェックアウトしたコードに含まれるComposite Actionを使う場合は注意が必要となります。 ここで、Composite Actionについて補足させてください。Composite ActionはカスタムActionの一つであって、使用することで、ワークフローの複数Stepを組み合わせて一つのActionsにできます。 例えば、複数のrunコマンドを一つのActionにまとめて、そのActionsを一つのStepとしてワークフローから呼び出して実行することが可能になってきます。 なのでpull_request_targetをイベントトリガーとして使う場合、Composite Actionは、攻撃者によって上書きされる可能性があるので、注意が必要です。 シークレットの内容を露出する際、可能な限り単位を狭くする方がいいです。Job単位よりStep単位の方がより良いと考えられます。Step間のファイルによるデータのやり取りは、全ステップから可視であると考えてください。 Jobは処理によって分けることも一つの対策になります。例えば、テスト/ビルド/デプロイはそれぞれJobを分けた方がいいです。これはなぜかというと、必要なGithub ActionsのPermissionやクラウドプロバイダーの権限を制御できるためです。 次に紹介したいのが、Dependabot / Renovateを利用したGithub Actionsでの更新になります。Actionsはバグの修正や新機能によって、頻繁に更新されます。Dependabot / RenovateでGitHub Actionsの依存関係を最新に保つことができるため、設定しておくとより良いと考えます。 次はサードパーティのActionsを利用する際の注意点です。サードパーティのActionsを利用する場合、基本的にFull Changeset Hashに固定するのがいいと考えています。 サードパーティのActionsの書き方は、四つあります。 まず一つ目がFull Changeset Hash。これは基本的には衝突が困難になっています。次にあるのがShort Changeset Hash。これも衝突がしにくいですが、脆弱となっています。次に、よく使われるTag / Releaseです。この場合、タグを後で変更されて意図しない変更が混入してしまう可能性があるので、注意が必要です。Branch Nameの場合意図しない変更が混入してしまう可能性もありますし、将来壊れる可能性があるので、なるべくFull Changeset Hashで指定するのがいいと考えています。 Full Changeset Hashで記入すると、このバージョンを使っているのかがいまいちわからないなっていうのがあるので、その場合はバージョンコメントを記載するのがわかりやすくておすすめです。 同じくサードパーティActionsを利用する際の注意点でもありますが、Actionsのソースコードをしっかり観察して、サードパーティのホストにシークレット送信するなどの疑わしいことがないか確認することが必要です。 ワークフロー内で利用しているサードパーティActionsのAction permissionsの設定をセキュリティ観点で見直すことも推奨されます。この設定に関しては同じくリポジトリのSettingsで可能になっています。不要なワークフローやJobは削除した方がいいです。不要なものは削除して、なるべく依存を減らすのが良いです。 先ほども触れたインジェクションについてですが、これを防ぐためには信頼されない式の入力値を中間環境変数に設定することが、対策として考えられます。 例ではこのようにenvに中間環境変数を入れていますが、この方式は、スクリプトの生成に影響するのではなく、メモリに保存されて変数として使用されます。このように、信頼されない式の入力値を中間環境変数に設定するのも有効です。 他にも、シェル変数をダブルクォートして単語の分割を避ける。これはシェルスクリプトの一般的な水槽事項でもあります。 GitHubのカスタムアクションやワークフローを書くときは、信頼できない入力に対して書き込み権限でコードを実行することがあることを考慮した方がいいです。外部Actionsとなりますが actionlist を使用することで対策できるので、導入を検討したり、GitHub Security Labの開発する CodeQL queries を利用したりすることも対策として考えられます。 それでも完全に攻撃を防ぐことは不可能と考えて、問題が発生したときに受ける影響を最小限に抑える必要があります。 例えば、プロダクション環境に影響を及ぼす(サービス停止など)ことが最悪のケースなので、対策が必要です。もう一つ、GitHub Action がPRを作成またはオーナーとして承認しないようにすることも対策の一つです。 最後に、第3部の「セルフチェックリスト」です。 セルフチェックリストは、定期的にチェックすることで、GitHub Actionsの安全な利用に繋げるという目的があり、ガイドラインで学習した内容が本チェックリストでカバーすることを目指して作成されています。 第2部の内容をベースに、講じてほしい具体的なセキュリティ対策を設定方法含め、チェックリスト形式で記載しています。 ここでは一例を紹介します。例えばCODEOWNERSの設定を見直すことが一つチェックリストにあります。CODEOWNERSというファイルが.githubディレクトリにあるのですが、そこで適切にコードのオーナーが設定されることが必要になってきます。 Protected Branchの設定で、Default BranchへのPull RequestがCODEOWNERSによる承認が必須になっていることも、チェックする必要があります。 続いて、ワークフロートリガーを見直すこと。コードプッシュをトリガーとする場合、pull_requestか、それが難しければ、pull_request_targetを使うことを考えた方がいいです。 on: psuhをpull_request用に使っていたら見直す必要があります。 このように、具体的な対策をチェックリスト形式で書いています。 さらに詳しい内容はブログに公開しておりまして、そちらを見ていただきますと、今回発表したガイドラインの内容が更に詳しくなっておりますので、ぜひご覧いただければありがたいです。 参照 社内用GitHub Actionsのセキュリティガイドラインを公開します 次は、ガイドラインが実際に社内でどのように活用できているかを紹介します。 一つ目の活用状況として紹介したいのが、Developer Documentationの追加です。これは主に、メルカリ、メルペイ、メルコインのバックエンドエンジニアがよく参照する社内プラットフォームの使い方がまとまった社内ポータルです。そこにGitHub Actionsのセキュリティガイドラインを掲載していただきました。 次はSecure Coding Guidelinesの掲載です。このガイドラインはSecurity Teamがメンテナンスする社内基準のセキュリティルールを満たすためのガイドラインです。ここにもGitHub Actionsのガイドラインを掲載しました。 他にも各チームでのガイドライン提供やサポートなどを行っており、プロジェクトメンバーに自チームに関するリポジトリに対して、今回作成したガイドラインの内容を適用させたり、他のチームがガイドラインを適用する際のサポートや質問を受け付けるような体制となりました。 最後に、「ガイドライン策定の裏話」をします。 まず、このガイドラインをどのように作ったかについて紹介します。まず最初に、作成する上で行ったことは、GitHub Actionsのセキュリティに関する文献記事をチームメンバーで読んでいくことです。記事には複数の記事がリンクされているので、それらも読んでいきました。 そこで得たインプットをもとにガイドガイドラインのアウトラインをまとめて、3部構成を作りました。参考文献の設定を試したりしながら、ガイドラインを変えていくフェーズに入り、その後に自分たちでガイドラインをレビューして、あとSecurity Teamにもレビューしていただきました。レビューをいただいた内容を修正して、英訳して公開しました。 ちょうど1年前ぐらいから始まったプロジェクトで、2022年の7月から9月の間にメンバーを招集して、アウトライン・執筆を開始していきました。その後、10月から12月の間にレビューを実施したり、リファクタリングをした後に、2023年に入ってから最終レビューが完了して、正式版を公開しました。4月から6月の間に、エンジニアリングブログでの社外公開なども行いました。 ガイドラインを作成していく中で、気をつけた点についても、4点ほど紹介させてください。 まず一つ目は「小さく始める、無理をしない」ということ。これはボランティアメンバーで、それぞれのメンバーが別のプロジェクトを持ちながら進めていったので、なるべく無理をしない形で、進めていきました。 二つ目が、「絶対完成させるという強い意志を持つ」。こういう有志の取り組みを長期的に継続していくのは難しいかなと思うのですが、でも絶対完成させるという強い思いをみんなで持って、完成させました。 三つ目が、「適切な量のフィードバックをもらえるように意識する」。これはちゃんと外部の意見を取り入れながらリファクタリングできるようにという名目でもありますし、大量にフィードバックが降ってくると修正も大変なので、適切な量になるようにコントロールしてもらいました。 四つ目が、「正式版を公開してから育てていく」。GitHub Actionsやセキュリティなどに関連する技術は、今後も日々アップデートしていくので、正式版を公開したから終わりではなく、今後も育てていくようにしていきたいです。 GitHub Actionsのセキュリティガイドラインは、今後も適切に更新していき、よりスムーズで安全な開発をサポートできるように努めていきたいと思っています。また更新した際には外部向けにも発信していこうと考えておりますので、ぜひご覧いただけるとありがたいです。 以上です。ご清聴ありがとうございました。
アバター
Merpay & Mercoin Tech Fest 2023 は、事業との関わりから技術への興味を深め、プロダクトやサービスを支えるエンジニアリングを知ることができるお祭りで、2023年8月22日(火)からの3日間、開催しました。セッションでは、事業を支える組織・技術・課題などへの試行錯誤やアプローチを紹介していきました。 この記事は、「 Keynote 」の書き起こしです。 @kimuras:メルカリFintech領域のCTOを担当しているKimuraです。本日はMerpay & Mercoin Tech Fest 2023をご視聴いただき、誠にありがとうございます。 メルペイが2017年に設立してから、2023年になって決済や与信、クレジットカード、暗号資産など、多くの金融サービスを提供してまいりました。今回は、多くの成功を支えてきた技術をふんだんにまとめ、Merpay & Mercoin Tech Fest 2023を実施することになりました。 また、これら金融サービスを伝える技術的な土台をいかして、これからもFintechサービスを成長させ、「世界をなめらかにする」というミッションを実現していくことを目指し、次世代のFintechサービスを作るためのアイディアやヒントになるような、気づきとなるものをご提供できたら幸いです。 私はKimuraと申します。メルペイ・メルコインのCTOを担当しています。 もともと機械学習領域を担当していましたが、2017年より株式会社メルカリに入社し、研究開発組織R4Dの立ち上げを行い、AIを中心とした幅広い研究領域のリサーチを担当しました。その後、AIと検索エンジン領域のエンジニア組織を設立してDirectorとしてメルカリのAI導入をリードしました。 2022年7月より、社内のプラットフォーム開発を統括するVP of Platform Engineeringを担当し、CTOとして4月から働いています。 まず、メルカリグループのFintech事業を振り返ります。 2023年2月にメルカリグループは10周年を迎え、「あらゆる価値を循環させ、あらゆる人の可能性を広げる」というミッションを新しくしました。 メルペイはフリマアプリ「メルカリ」での売る・買うの取引を通じて信用情報を可視化し、新しい信用の形を生み出して、それに基づいてお金を自由に使える世界を作ることを目指しています。 メルコインはモノ・お金だけではなくて、暗号資産、NFTなど、あらゆる価値をめぐらせて新しい経済を作ることを目指しています。世界中のモノやコト、人には見出されていない価値がたくさんあり、その価値を必要としている人もまた世界中で数多く存在していると思っております。 メルカリグループはテクノロジーの力で世界中の人々をつないで、有形・無形に限らずあらゆる価値が循環するエコシステムを作ることを通じてその人の可能性を広げる存在でありたいと考えています。 メルペイは2019年2月にサービスを開始しました。iD決済・コード決済といった決済領域から始まり、あと払いサービスであるメルペイスマート払いで、与信領域を本格的にスタートさせました。 その後、バーチャルカードやメルペイスマートマネー、メルカリの利用実績等で限度額が決まってアプリで利用と管理が完結できるメルカードをローンチするなど、サービスを拡充しました。 メルカードは提供開始から 約半年で発行枚数100万枚を突破 して、国内で今トップレベルとなっております。そして2023年3月からメルカリアプリ内でビットコインが売買できるようになりました。この開発を担うのがメルコインとなります。 金融機関からチャージした残高はもちろん、メルカリで不用品を売って得た売上金やポイントを活用して、1円という少額から安心して始めることができます。こちらも提供開始から 3ヶ月強で利用者数50万人を突破 しています。 これらのように2019年からサービスの提供を開始して、Fintech領域では1,571万人ものお客さまにご利用いただくまでに成長しました。 メルカリグループで構築する「循環型金融」ということで、ここからこれらのサービスを支える技術について触れていきたいなと思います。 多くのサービスを開発し、約1,500万人ものお客さまに金融サービスを提供してきた成長の背景には どのようなものがあるのかをお話しします。 金融サービスはセキュリティ的な要件が非常に高く、技術的には妥協が許されない領域です。 そしてメルペイの特徴でもある「なめらかな社会を実現する」ため、簡単で便利なUIを提供するという攻めの姿勢と、セキュリティを高めるための守りの姿勢は、基本的に相反する関係にあります。 UIを簡易的にすればするほど、セキュリティは甘くなってしまいますし、セキュリティを厳しくすればするほど、簡易なUIを提供することは難しくなってしまいます。 我々はこの攻めと守りのバランスを保つことで、大きな障害を避けつつも便利なUIを提供することでお客さまの支持をいただいてきたと考えています。 攻めと守りを実現するために、人材投資にもバランスを保ってきているのが、我々を支えてきた源泉だと考えています。 大きく組織を説明しますと、メルペイのエンジニア組織は大きく分けて、プロダクト開発をメインで行っているProduct Engineeringと、Foundationやプラットフォームの開発を行っているPlatform Engineeringの二つの組織があります。 メルペイは設立当初から現在までProduct EngineeringとPlatform Engineeringに対して、バランスよく人材投資を続けており、人数はおおむね同じ割合となっております。 なめらかなUI提供をするためにProduct Engineeringは重要ですし、堅牢なFoundation Platformを構築するPlatform Engineeringと同じ割合で投資することで、複雑なシステムであってもSecurityやAvailabilityを担保し続けているという背景があります。 Fintechの成長を支えてきたテクノロジー投資についても説明します。多くのFoundationへの投資の中でも、今回は不正対策、セキュリティ、リアーキテクチャ、独自の与信モデルについてご紹介したいなと思っております。 基本的に不正対策はルールベースのものもありますが、機械学習をメインに活用し、Vertex AI Pipelinesを導入してモデルのトレーニングやデプロイを共通化しています。また特徴量を共有化することによるコスト削減はFeature StoreとしてFEASTを導入しています。これにより保守性担保やコスト削減だけじゃなくて結果としてエンジニアがモデル開発の改善に、より時間を費やすことができるようになり、生産性向上や品質改善にもつながりました。 メルペイの不正対策に活用しているのが、グラフ理論というものです。節点と呼ばれるノードの集合と、辺と呼ばれるリンクの集合で構成されるグラフに関する数学の理論を活用しています。メルカリ・メルペイには非常に多種多様なデータがあります。お客さまのアカウントの情報や出品、決済、購入といった情報をグラフとして表現し、類似度を計算するといったことができます。 【書き起こし】グラフ理論と不正対策 つながりをデータから解き明かしたい – hmj 【Merpay Tech Fest 2022】 不正対策・不正検知については、今年もセッションを用意していますので別セッションで詳細をご覧ください。 【書き起こし】メルカリのカスタマージャーニーにおける不正防止の取り組み – codechaitu【Merpay & Mercoin Tech Fest 2023】 【書き起こし】発生可能な取引の属性データを用いた素早い不正検知 – Liu / Li【Merpay & Mercoin Tech Fest 2023】 続いて、セキュリティについてです。セキュリティでは3DセキュアやFIDO、パスキーの導入を行ってきました。 3Dセキュアの導入は不正利用を未然に防ぐための対策です。2021年12月に比べて、不正利用数は10分の1まで抑えることができました。図は1年前の状態を示しています。直近でもこの低水準の状態を継続できています。 本件に関しても、去年のセッションやブログで紹介しています。今年も進化した部分であると、2022年11月に、 FIDOアライアンスに加盟 して、メルカリの各種サービスにFIDO認証の実装を進めています。2023年3月にリリースをしたメルコインにFIDOあるいはパスキーを導入しています。 【書き起こし】Credit Card Payment Security: adding 3D Secure SDK for Merpay iOS – Mikael LE GOFF 【Merpay Tech Fest 2022】 【書き起こし】メルカリグループの認証基盤における理想と現状、今後の取り組み – kokukuma 【Merpay Tech Fest 2022】 約2年半かけて、iOS Androidアプリケーションでも同じく、スクラッチから作ったアプリケーションに移行するプロジェクトを進めました。 今はすでにこの新しいバージョンを全てお客さまに提供できておりまして、コードベースもモダンかつコンパクトな状態です。今後は生産性が改善によって上がり、よりよい機能をより早くお客さまに提供できるようになっています。 リアーキテクチャした背景として、メルカリのアプリリリースから約10年近くの月日が経っております。アプリのアーキテクチャの潮流やUI/UXのフレームワーク、OSが提供する機能など、何もかもが大きく変わっています。 またメルカリはこの間に大小さまざまな機能がリリースされており、コードベースも膨大になってビルドやメンテナンスに大きなコストがかかっていました。モダンなフレームワークの導入や新たなデザインシステムの採用などに取り組んできましたし、最終的には生産性の観点からAndroidでもコード量を約半分の程度に減らすことができたということで、大きなメリットを得ることができました。 ほかにもさまざまなチャレンジをしていますので、詳細は他セッションをご覧ください。 【書き起こし】Merpay iOSのGroundUp Appへの移行 – kenmaz【Merpay & Mercoin Tech Fest 2023】 【書き起こし】Merpay iOSにおけるSwift Concurrency対応の挫折と今後 – Takeshi Sato【Merpay & Mercoin Tech Fest 2023】 技術的な観点では、独自の与信モデルも欠かせません。メルペイでは包括信用購入あっせん業者の認定を日本で初めて取得し、勤続年数や年収など、一般的な属性情報だけじゃなく、メルカリが持っているデータ、あるいはメルカリの行動実績に基づいて、信用を判断することができます。独自与信モデルはメルペイスマート払いやメルペイスマートマネー、メルカードなどのサービスで活用されています。 機械学習は不正対策だけではなく、このような独自与信モデルも使っています。詳細は、こちらのセッションをご覧ください。ITエンジニアとITリスクマネジメントのメンバーが密にコミュニケーションをとり、AIの危険性やリスク管理にどのように対応するかを解説します。 【書き起こし】メルペイMLにおける機械学習の品質保証とリスク管理 – shuuk / Haruki Kaneko / Yuki Saito【Merpay & Mercoin Tech Fest 2023】 ここからは、これからの技術的な挑戦について簡単に説明します。 これまで説明したように、Fintech領域でおおむね土台となるサービスを実現してきました。「なめらかな社会を実現する」という意味では、大きな土台が出来上がりました。 大きく分けると、簡単で安全に利用できる決済システムや、メルカリでの行動に基づいたAI与信、簡単に本人確認ができるeKYCサービス、簡単に暗号資産を購入できるメルコイン、アプリで利用と管理が完結するクレジットカードサービスのメルカードなどがリリースされました。 しかし、これでFintechのテクノロジーが終わりではありません。今後もよりなめらかな世界を実現するためには、Fintechサービス外からでも活用できるようにプラットフォームの強化をしていく必要があります。 今後Fintechを解き放ち、より世界をなめらかにしていくためには、三つのポイントが重要だと考えています。一つ目はこれまで培ってきたFintechサービスを生かして、プラットフォームとしてFintech外でも活用されること。 Fintechは単体でも価値のあるものですが、同時にメルカリグループ内でも重要なプラットフォームになっています。今後はよりグループシナジーの強化につながるプラットフォームとしての機能強化や、APIの整備に力を入れる予定です。 二つ目はデータ基盤整備です。Fintech領域では、日々、膨大な決済情報が蓄積され、よりメルカリグループでのサービスのデータ連携を強化することで、お客さまにより価値が提供できると考えています。 しかし、データ量は増えていくと同時に、データをうまく活用するためにはデータの基盤の改善・変革が必要となってきます。情報のAccessibilityとMaintainabilityをより改善していき、安全なサービス開発、そしてグループ間でのデータ連携を実現していきたいです。 最後に、LLMの活用強化も重要です。これまでメルペイでは、不正検知やAI与信でLLMの活用を本格的に行ってきましたが、LLMの実用化によって、Fintech領域でのAIの活用はさらに進化を遂げると考えています。より安全かつ便利で、金融領域に詳しくないお客さまへの洗練されたサポートを実現し、よりなめらかな社会構築に貢献できるのではないかなと思っております。 グループシナジーの強化について簡単にご説明します。メルペイやメルコインでは、決済、与信、信用情報、暗号資産など会社にとって重要な機能や情報を持っています。 これらの機能や情報は、すでにメルカリグループ内で活用は進んでいます。しかし、より今後お客さまに便利でお得にサービスをご利用いただくためにも、メルカードのポイント還元であるロイヤルティプログラムでデータ活用をより促進していくためのデータ連携やAPI強化は重要になってきます。また、メルカリ内で行っているサービスなどにあわせた決算基盤を提供するとか、そういったことがグループ会社として今後重要になってきます。 メルカリではさまざまな新規事業も展開しておりまして、新規事業を実現する上でも、決済機能や与信機能、セキュリティ機能などを提供することによって、新規事業のサービス提供スピードがより向上して価値のあるサービス提供が可能になり、グループシナジーの強化につながると思っています。 また、具体的にはまだ進められていませんが、将来的にメルカリ外にも機能提供する基盤が整備されることによって、メルカリの金融サービスとしての価値向上や、世界の金融サービスの利便性向上にも貢献できるのではないかと考えています。 メルペイではメルカードをご利用いただいてるお客さまに、よりお得にサービスをご活用いただくためにポイント還元をするロイヤルティプログラムを提供しています。 これがデータ基盤にとても関わっており、現在もこのサービス自体は提供しています。提供を続けるには、日々お客さまの売買データを効率的に分析できるように基盤を整備していかなければいけません。 メルカリとのデータ連携を強化するためにも、中間データの整備やデータ構造自体の整備が今後重要になってきます。AIのためのトレーニングデータを作成し、包括的に管理する仕組みが重要になってきますし、特にLLMでは多くのテキスト情報とメタデータの付与が重要になるのでAIに特化したデータ構造や、データパイプラインの構築が今後重要になってきます。 同様にデータ利活用が進めば進むほど、データベースのインフラコストは増大します。 今後 AI活用が強化されている中で、世界中でもインフラコストの最適化は重要なトピックになっています。我々もサービス改善を目的として日々データの量は増加しているので、攻めと守りの姿勢を継続してインフラコスト最適化を進めていきたいです。 最後にLLM活用なんですけども、こちらもセッションが別にございますので、ぜひこちらで議論を見ていただけたら幸いです。 【書き起こし】Merpay & MercoinにおけるLLM活用の取り組み – Yuki Ishikawa / Daisuke Torigoe / Noriaki Utsunomiya / hmj【Merpay & Mercoin Tech Fest 2023】 今回のイベントは、「Unleash Fintech」というテーマで、これからも世の中を便利にしてなめらかな社会を作り、多様な価値をめぐる新しい経済を作り、そして人々の可能性をより解き放つために、テクノロジーの力でまだまだできることがあるという強い気持ちを持って開催させていただくことになりました。 我々がこれまで培ってきたテクノロジーを公開することで、少しでも世界のFintechの進化に貢献できたら、とても嬉しく思います。 そして、これからも技術に謙虚な反省を忘れず、時には大胆に、時には冷静に世の中をよくするために自信を持った技術を使っていきたいという気持ちがあります。 以上です。ご清聴ありがとうございました。
アバター
Merpay & Mercoin Tech Fest 2023 は、事業との関わりから技術への興味を深め、プロダクトやサービスを支えるエンジニアリングを知ることができるお祭りで、2023年8月22日(火)からの3日間、開催しました。セッションでは、事業を支える組織・技術・課題などへの試行錯誤やアプローチを紹介していきました。 この記事は、「 Merpay iOSのGroundUP Appへの移行 」の書き起こしです。 @kenmaz:今回は、「Merpay iOSのGroundUP Appへの移行」というタイトルで、iOSチームの@kenmazが発表します。 こちらが私の自己紹介です。 今回のメインテーマであるMercari iOSのGroundUP App(GU App)とは何かについて説明します。 GU Appは、メルカリ本体のコードをフルスクラッチで書き換え、さらにBazelによる高速・高信頼のビルド環境に置き換え、メルカリをイチから作り直すプロジェクトです。 メルカリの開発が始まってから10年以上経って、技術的負債がかなりたまってきている状態になったので、フルスクラッチで書き換えるのが本プロジェクトの目的です。 このプロジェクトではiOSではSwiftUI、AndoirdではJetpack Composeといった最新のUIフレームワーク、さらにDesign System v3.0という社内のUIライブラリを最新版に置き換えることが盛り込まれたプロジェクトです。 フルスクラッチで書き換えるプロジェクトなので、再構築期間中は新規機能開発を凍結し、フルスクラッチでのリライトに集中する流れで進みました。 参考記事 メルカリアプリのコードベースを置き換える GroundUP App プロジェクトの話 メルカリiOSアプリのBazelを使った高速・高信頼性ビルド メルカリアプリの上にはメルペイの機能が載っています。メルペイにおいてのGU Appへの移行について説明します。 メルカリ本体のコードと比べるとメルペイのコードは、比較的技術的負債が少ない状況でした。開発が開始してから、当時で2〜3年ほどしか経っておらず、比較的クリーンなUIKit + Design System 1.5を使っていました。そのため、メルペイのコードについては、フルスクラッチで書き換えるよりも、最小限の変更でそのままGU Appに載せ替える方針を決めました。 さらにGU Appの裏で、メルペイでは新規機能開発の必要性があり、メルペイ自体の開発を止めるわけにはいきませんでした。移行期間中でもメルペイの新規開発は極力止めずにそのまま載せ替えることを目的としました。 こちらがプロジェクト全体の概要です。上の段の「Production」が実際にお客さまに届けるアプリの状況で、下の段の「Development」が社内で開発しているコード群です。 GU Appのプロジェクト自体は2020年4月頃に始まりました。最初はメルカリのコア部分のみをSwiftUIで書き換え、アーキテクチャや全体の構成などを固める作業からスタートしました。 その後2021年10月に全ての準備が完了して、本格的にリライトのプロジェクトが開始されました。この段階は、メルカリ側の機能群の開発を凍結し、全ての開発メンバーはメルカリのリライトに注力する期間でした。この期間が2022年8月まで続くことになります。 一方メルペイについては裏で重要なプロジェクトが動いていたので、機能群自体は変更せず、メルカリ側とメルペイ側のコードを Integrationするため、 IntegrationLayerと呼ばれる中間Layerのみを書き換えることで、メルペイの機能群のコードを変更せずに新しいアプリと古いアプリ両方で同じメルペイのコードが動作するように対応する必要がありました。 そこで IntegrationLayerの開発にメルペイチームが参加しました。このGroundUP Appのプロジェクトが始まった同時期に、社内では重要なプロジェクトがいくつか進みました。 メルペイのトップ画面をリニューアルするプロジェクトや、メルカードというメルカリのクレジットカードを開発するプロジェクト、メルコインというビットコイン関係のプロジェクトなど、いろいろなプロジェクトが走っている中で行われたのがGU Appです。 このメルカリと Integrationの実装が完了し、2022年8月に、Phase1としてGroundUP Appがリリースされました。この時点で、メルカリ側は全てSwiftUIにリライトされ、メルペイ側は今まで通りUIKitで動いています。 その後、2022年10月にメルペイ側でSwift UIで書き換えられたものがリリースされ、残りのメルペイの機能やメルカードの機能はまだUIKitで作られていました。2022年11月にメルカードの機能、翌年にメルコインの機能がリリースされました。 フェース3は進行中ですが、今残っている古いUIKitで作られてる部分を最終的には全部書き換え、最終的には100%Swift UIのアプリにする動きが続いています。 それぞれのPhaseについて説明します。まずはPhase1のMerpay SDK GU App Integrationです。 Merpay自体はSDKという形で開発されていて、比較的メルカリと疎結合の状態で設計されていました。 これにはいろいろな背景がありますが、一つは、メルカリの機能はメルカリが担当し、メルペイの支払いや決済に関する機能はメルペイで開発を担当していて、会社自体がわかれていたのでリポジトリを分けて、設計も極力結合なものにした方がよいという考えで、このような構造になっています。 メルカリアプリとは別にメルペイアプリ単体のアプリを作る話もあがっていたので、かなり疎結合でポータビリティを持った設計になっていました。 参考記事: メルペイのスケーラビリティを支えるマルチモジュール開発 GU App Integrationは4つのステップにわかれています。 一つ目は、準備段階としてメルペイ関連機能のSDKへ集約することです。 Merpay SDKの中にはメルペイの必要な機能が入っていますが、いくつかの機能はメルカリ側に直接実装されているコードもあります。そこで、メルペイが管理すべきコードは一旦全部Merpay SDKに集約することにしました。例えば、本人確認機能や売上金の振り込み申請機能などはSDKに移しました。 これらはUIKit + ReactiveCocoaやObjective-Cで書かれていましたが、一旦メルペイのアーキテクチャに合わせてUIKit + MVVMに書き換えました。 これで全てのコードがMerpay SDKに入ったので、次はビルドの環境を設定変更します。旧メルカリアプリはCocoaPods/Carthage/git-submoduleを使ってビルドを行っていましたが、新しいメルカリアプリであるGU Appでは、全てBazelを使ってビルドを行うように変更されました。 したがって、Merpay SDKを含む全ての社内外のコードをBazelでビルドできるように設定する必要がありました。 merpay-ios-sdkやDesign System、Google Maps SDK、Lottie-iOS、CryptSwiftなど社内外のコードをBazelで全てインポートし、一つのメルカリアプリとしてまとめてビルドできるようにする設定変更が行われました。 次はコーディングの段階です。メルペイにはMerpayDependencyRegistryというDIコンテナのようなものがあります。これを用いることにより、メルカリ側で実装されている機能をメルペイ側に注入できます。 全ての依存関係がここに集約されているので、メルカリ側の実装をメルペイに注入する作業をひたすら行います。実際に注入したコードとしては、Feature Flagやイベントログなど、図にある通りです。 これでメルペイのコードは全てMercari GU Appの上でビルドできるようになったので、最後に画面遷移の実装を行います。 GU Appでは、基本的に全ての画面はSwift UIで作られていますが、画面遷移周りはすべてUIKitで実装されています。Wireframe Layerというものがあり、そこでSwiftUIの画面は一旦UIHostingControllerでUIKitのViewControllerとして変換され、それをUINavigationControllerが画面遷移を制御します。 メルペイの画面はすべてUIViewControllerで作られているので、DependencyRegistryを経由して、UIViewControllerをWireframeにそのまま渡します。あとはWireframe内部で細かい画面遷移の実装を行います。 以上で統合完了です。この段階で1年ぐらいかけて行われてきたGU Appのアプリがリリースされました。メルカリアプリは全てSwiftUIで書き換えられていますが、メルペイの機能が集約されている「支払い」タブに関してはまだUIKitのままの状態です。 しかし、更なる最適化の作業が残っています。 まずはGitリポジトリ統合です。GU Appが始まる前は、mercari-iosリポジトリでメルカリのコードが管理され、merpay-ios-sdk、mercari-jp-ios-coreは別リポジトリとして管理されていました。 GU Appでは、メルカリ側のコードはmercari-groundup-iosという新たなリポジトリで管理されています。メルコインのコードもすべて同じリポジトリに実装されています。しかし、メルペイの機能やメルカリのいくつか残りの機能、たとえばメルカリのToday Extensionの機能やメルペイでしか使用していないDesign Systemのコードは、依然として別のリポジトリで管理されており、Bazelによって都度インポートされる構成になっています。 しかし、この構成には開発効率の観点から二つの問題があります。 一つはリポジトリが分かれているのでメルペイの機能の開発を直接行えないという問題です。メルペイの機能を開発する際は、まずMerpay SDKのリポジトリをチェックアウトして、ソースコードを編集・プッシュして、GU Appに戻って、Bazelでリポジトリをインポートし直してビルド・動作確認、という非常に煩雑なデバッグプロセスが必要です。 また、GU Appのビルドインフラを活用できないという問題もありました。GU Appとメルペイのモジュールはそれぞれ別のビルドインフラ上でCIが実行されます。GU AppはBazelでビルドが行われているのでユニットテストも非常に高速にできます。一方、メルペイモジュール単体のビルドにはBazelは使用していないので、その恩恵を受けることができません。 Gitレポリポジトリ結合では、すべてのコードを単一のGU Appのリポジトリに移動することによって、上記の問題を解決します。 なおDesign System1.5はメルペイでしか使われてない古いUIライブラリなので、これは例外としてこのまま別リポジトリとして、コードフリーズした状態でインポートすることにします。 リポジトリ統合にはいくつか方法がありますが、一番単純なのは、ファイルコピーです。一番簡単ですが、Gitの履歴が消えるという問題がありました。 なるべく履歴を壊さずにソースコードをGU Appのリポジトリに移動する手段として、Subtree Mergingというリポジトリの結合方法があります。これによって履歴は保持されますが、リポジトリ全体をマージしてしまうので、この2〜3年間で蓄積された不要なデータまでマージされてしまいます。リポジトリのサイズが増えることで、CIの時間に影響を与えてしまう問題があります。 そこで、もう一つの解決策としてgit-subtreeコマンドを使って、リポジトリを部分的に結合する方法をとりました。必要最小限のコードのみをピックアップして結合し、かつ履歴を保持することが可能になります。必要なコードをピックアップする必要があるので少々作業が煩雑になってしまいますが、これによってリポジトリの肥大化を抑えつつレポジトリ統合を行うことができます。 参照 Subtree Merging: https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_subtree_merge git-subtree: https://git.kernel.org/pub/scm/git/git.git/plain/contrib/subtree/git-subtree.txt リポジトリに全てのファイルを移動できた後は、Bazelビルドに合わせた最適化を行います。ソースコードのレイアウトの変更や、画像アセットを最適にして無駄なデータを含めないようにすること、Bazelのビルドとビルドターゲットとするために、それぞれのモジュールをBazelのモジュールとして定義する作業などが行われました。 また移行期間中に古いコードに変更が入るとコンフリクトが発生するので、コードフリーズ宣言を行ってコードの変更を禁止することで、コンフリクトを防ぎました。 間違いで変更してしまうこともあり得るので、変更を検知するためのモニタリングの仕組みなども入れ、リポジトリ統合を進めました。 このようにおよそ2ヶ月半ぐらいかけて、26モジュールを段階的に移行し、Gitレポジトリ統合が完了しました。 もう一つの問題は、いくつかのメルカリの機能のモジュールがMerpay SDKに直接依存している点です。これによって、テストバンドルのキャッシュが肥大化してしまい、最終的にCIの実行時間やキャッシュストレージの使用量が増加してしまうことがわかりました。 この問題を解決するために、Merpay SDKのDIコンテナのインターフェースのみを抽出し、別のモジュールとして分離する設計の変更を行いました。 これはモジュールの相関関係を表す図です。「MK Feature modules」がメルカリの各機能を実装したモジュールです。いくつかのメルカリの機能はメルペイの機能に依存しているので、それらはMerpay SDKの中の「MerpayCoreKit」モジュールに依存する必要があります。 ただ、MerpayCoreKit自体はさらに、Protocol Buffersのモジュールや、Design System1.5のモジュールなどの、メルカリの機能にとっては不要なモジュールにも依存しています。それらのモジュールはサイズが大きいので、メルカリの機能モジュールをビルドしてテストしようとすると、依存関係にある全てのモジュールがビルドされ、Bazelのキャッシュとして残り続けて、最終的にCIインフラのストレージの使用量の増加を引き起こしてしまう問題がありました。 そこで設計を変更して、MerpayCoreKitが提供していたコードのインターフェース部分だけをプロトコルとして切り出し、「MerpaySDKInterface」という別のモジュールとして切り出し、メルカリの機能モジュールは軽量なインターフェースモジュールのみに依存する形式に変更しました。 これによってモジュールごとのテストバンドルのキャッシュサイズが300MBから150MBまで削減され、ストレージの使用量の問題も解決されました。 またMerpay SDKの最小限の機能のみをメルカリ側に整理・公開する設計にしたので、SDKの債務の明確化が行われ、SOLID原則に従ったSDKの設計にも貢献できたという副産物もありました。 参照: Single Responsibility Principle in SOLID 以上で、Integrationのプロジェクト自体は完了しました。GU Appリリース後、Phase2として、次はメルペイの新規開発画面をShiftUI+GUアーキテクチャで開発するプロジェクトが始まりました。 ここで、メルカリアプリ自体のアーキテクチャの変遷について振り返っていきたいと思います。 旧メルカリアプリでは、10年の間に様々な内部的なアーキテクチャの変遷がありました。最初は純粋なMVC、そこからMVVM+ReactiveCocoa、さらにMicro View Controller + Stateアーキテクチャに変遷しました。しかも全てが変遷していたわけではなく、部分的には古いMVCが残っている状況でした。 一方メルペイは独自のシンプルなMVVM Without 3rd party libsというシンプルなアーキテクチャを採用していました。このように、GU Appの前はいろいろなアーキテクチャが一つのアプリの中に共存している状態でした。 参考資料 Mercari iOSにおける きらやばArchitectureとAutomation Mercari iOSクライアント Re-Architectureのその後 / After Re-Architecture of Mercari iOS client Introducing ViewModel Inputs/Outputs: a modern approach to MVVM architecture GU Appでは、それが一新され共通アーキテクチャが策定されました。SwiftUIをベースとし、Reduxや TCA などからインスパイアされた単方向データフローの独自のアーキテクチャです。 メルカリおよびメルコインの機能は全てこのGUアーキテクチャに基づいて開発されています。メルペイもこの共通アーキテクチャに統合する方針を決定しました。 ちょうどメルペイのトップ画面のリニューアルする新規開発プロジェクトが別で計画されていたので、そこでGUアーキテクチャを試験的に先行導入することにしました。 Phase2の開発が完了しました。この段階でメルペイのトップ画面に関しては100%SwiftUIが達成できました。 メルペイのトップ画面以外の既存画面に関しては、未だにUIKitのままです。Phase3では、既存画面をすべてSwiftUIに書き換えます。これは現在進行中です。 ここで、なぜ最初に技術的負債が比較的少ないメルペイのコードを書き直す決断をしたのか、そのモチベーションについてお話します。 技術的負債負債が比較的少ないといえども、初期のコードは2018年に作られたものです。当然UIKitベースのコードなので、GUで刷新された基盤機能の恩恵は受けられせん。 SwiftUI自体ははもちろん導入できなくはないのですが、メルカリの機能で使用されているDesign System3.0を使用するには、GUアーキテクチャへの移行も必要になります。 アクセシビリティについてもGUアーキテクチャはかなり手厚くサポートされていて、新規イベントログ基盤もGUアーキテクチャにより最適化されたものになっていたなどの事情がありました。これらの事情によって、メルペイ側の既存コードも段階的にGUアーキテクチャに移植するのが良いという決断になりました。 とはいえ、メルペイの既存機能がかなりの数があるので、まず現状の仕様整理から始めました。まず、移植作業の計画を立てます。大量のメルペイの既存画面の仕様を整理・リストアップし、優先度を決めて移植作業を少しずつ始める計画を立てようと考えました。 大量の既存コード・仕様書はありましたが、ここで既存コードと仕様書の対応関係が不明瞭であったり、対応する仕様書が見つからなかったりといった問題が発生しました。仕様書によっては同じ画面に対して別の呼び方がされていることもあり、特に非日本語話者にとってはその理解が非常に困難な状況でした。 そこで既存の仕様を整理する前に、一旦全てのメルペイの画面を一意に特定する「Merpay Screen ID」を導入することにしました。 例えばここにあるように、”MP-BNK-001” はメルペイの銀行接続の1番目の画面を示します。このような採番作業を全ての画面に対して実施しました。 Screen IDをソースコード、仕様書、Figma上で横断的に記載することで、それぞれの関係を明確化しました。これによって、認識の齟齬を解消できる上、非日本語話者でも理解しやすくなりました。これは社内の開発ガイドラインにも組み込まれているので、この辺の整理が今後も進んでいくと思います。 これを導入したことによって、スクリーンに関して仕様書を探したいときにScreen IDで検索すればそれに関連する仕様書が全て出てきます。 またFigmaでUIレイアウトを確認したいときも、Figmaの検索ボックスにScreen IDを入れれば、正式なレイアウトを確認できます。 ソースコード中にこのようにScreen IDを埋め込んでおけば、ソースコードと仕様書の関係、その画面に関する実装についても発見できます。 このように、事前の準備をした上で計画を立て、現在絶賛移植作業中です。全体の77%は古いコードのままなので、今後数年かけて移植する予定です。 こちらが現在移植中の銀行接続画面の例です。 GU App Integrationの開発プロジェクトを進めることで、メルペイ自体の機能開発を止めることなく、GU AppのIntegrationが完了しました。メルペイのコードを変更することなくそのまま新しいGU Appのコードベースに移植することに成功しました。 またBazelのメリットを最大限に生かす構成に変更しました。さらにメルペイの既存画面をShiftUIで移行するにあたり、いろいろと基盤を整備しました。 以上です。ご清聴ありがとうございました。
アバター
Merpay & Mercoin Tech Fest 2023 は、事業との関わりから技術への興味を深め、プロダクトやサービスを支えるEngineeringを知ることができるお祭りで、2023年8月22日(火)からの3日間、開催しました。セッションでは、事業を支える組織・技術・課題などへの試行錯誤やアプローチを紹介していきました。 この記事は、「 Enabling ProgramのEngineering Headをちょっとやってみている 」の書き起こしです。 @kazegusuri:それでは「Enabling ProgramのEngineering Headをちょっとやってみている」というタイトルで@kazegusuriが発表します。 まずは自己紹介です。@kazegusuriという名前で、社内でも社外でも活動しています。メルカリに入社したのは約8年前で、当時はSREとして入社しました。そこから1年ほど経って、旧ソウゾウと呼ばれている会社に移動して、ID & Payment Platformチームに所属しました。 これは、現在のメルペイの基礎になったIDと、決済の仕組みを作っていたチームです。さらにまた1年経って2018年にメルペイができると同時にチームごと異動して、それを機にアーキテクトとして仕事をすることになりました。 現在もアーキテクトの仕事自体は続けていますが、今年の4月からEnabling ProgramのEngineering Headを兼務することになりました。今回はEngineering Headの仕事について紹介します。 今日話すことは三つあります。まずはProgram体制の話と、所属しているEnabling Programの説明をした後に、Engineering Headについて説明をし、自分がEnabling ProgramのEngineering Headとして何をしているかを説明します。 Program体制とは、メルペイでの開発組織の体制のことです。2023年1月からスタートしました。 Program体制は、役割に応じて大きく三つのグループにわかれます。一つ目がJourney、二つ目がFoundation、もう一つがEnablingです。 Journeyはその中に三つのプログラムが存在していて、Foundationは二つのプログラムが存在します。自分が所属しているEnabling Programは一つです。 続いて、それぞれの役割について説明します。Journeyはお客さま体験を改善するいわゆるプロダクト開発を行い、お客さまの機能を提供する組織として活動しています。 Foundationの役割は、Journeyがプロダクト開発をするにあたって共通基盤を提供する組織です。Enabling Programは、Journey、Foundationの開発を支援する組織です。 Program体制はメルペイにおける組織であって、つまりメルカリ・メルコインにおいては開発体制が異なります。 グループ全体のプロジェクト開発に対して、インフラを提供しているのが、Microservices Platformです。 次に、Engineering Headの役割について説明します。各プログラムには、Engineering HeadとProduct Headがいます。 ただし、Enabling Programには現状Product Headがいないので、Engineering Headが、Product Headの役割も兼ねている状態です。彼らはいわゆる会社で言うとCTOとCPOのようなものです。技術的な意思決定をする人やプロダクトに対する意思決定をする人というイメージです。 Enabling Program・Product Headには、People Management的な役割がないので、組織には彼らとは別にManagerを置いています。 Enabling Programに所属しているチームは、この七つです。 Backend Architectは、バックエンドの開発を支援したり、アーキテクチャを考えたりするチーム。Client Architectには、モバイルやフロントエンドに携わる人が在籍し、各プログラムのクライアント開発を支援します。Engineering Productivityは、バックエンドの開発の生産性を上げるためのチームです。 SREは、会社全体の信頼性を向上させるために、いろいろな仕組みを考えています。Data PlatformとData Managementは、会社のマイクロサービスにおける各種データやプロダクトで得られたデータを収集して、それらをプロダクト開発に生かせるようにする目的で活動しています。QA Optimizationは、各チームのQAをより良い最適化を行うために活動しています。 Enabling Programを構成するチームは、多岐にわたります。では、Enabling ProgramのEngineering Headは、何を期待されているのでしょうか。 例えば、トップダウンで、Engineering Headとして今後の戦略を考えて、各チームにその戦略を遂行するように適用していく。もしくは、各チームがボトムアップでやりたいことを考えて、それに対して意思決定をすることが考えられます。 ただし、現状自分がまだEngineering Headになってから3ヶ月であることや、Enabling Programに所属しているチームの技術エリアがすごく広いので、戦略を立てたり、意思決定をすることは、正しい精度ですることが難しいと思います。 さらに、このProgram体制ができる前から、これらのチームは存在していました。当時から各チームは自分たちが何をすべきかを考え、自分たちの責任で遂行していくことがすでにできていた自立したチームでした。今回Program体制になったからといって、短期的にいきなりその方向性を変える必要はないと、個人的には思います。 では、自分がなぜ今回Engineering Headになりたいだろうと思ったのか、目的を説明します。 Engineering課題を解決するときのプロセスをこの会社として決めたいという理由がありました。メルペイでArchitectチームとして5年以上活動した中で、いろいろなEngineering課題があって、解決するためのいろいろなプロセスをとりました。 プロセスはタイミングや課題の内容に応じて変わります。 例えば今回の課題を解決するために、いろいろな開発チームに対策・対応をお願いしないといけないとき、どうやって対応を依頼をするのか。会社全体が大きくなった今、どうやって対応するのかを考えることは難しいです。 また、Engineering課題が決まったとしても、プロダクトとの優先度をどうやって決めるのか、そのプロセスが決まっていた方がやりやすいと感じていました。 これは、Enablingチーム全員の共通の課題です。そこで、この辺りをまずは解決したいなと思いました。 さらに、裏目標として「テックカンパニーを目指したい」ということがあります。 会社としては元々「グローバルテックカンパニーを目指しています」と公言していますが、個人的にもテックカンパニーをずっと目指しています。 Enabling Programで作っている技術はよくできていて、社内でもまだ知らない人にもっとアプローチしていきたいですし、社外にももっと自慢した方がいいと思います。 現在ある仕組み・技術をもっと発展させるために、技術に対する投資をする必要があります。そのようなサイクルを回すためにはまずは、Enablingチームに所属しているチームが、どれだけ会社にとって有用性があるのかを伝えていく必要があると思います。 個人ではなく、Enabling全体として伝えていきたいなと思って、Engineering Headをやりたいと思いました。 次に、実際にEngineering Headになってやっていることを三つ説明します。 一つ目は、課題の可視化。二つ目が、会社としての課題に設定する。三つ目が成果報告。それぞれ説明していきます。 まず一つ目の「課題の可視化」についてです。プロジェクトロードマップを作っています。この目的は、Enablingプログラムのやっていることや成果を他のチームの人たちが理解できる状態にするためです。 「プロジェクトロードマップ」という名前通り、プロジェクト単位でそのプロジェクトのロードマップを作成しています。JIRAを使って可視化していこうと思っているのですが、まだやりきれていないところです。 プロジェクトとは、中長期的な施策のことを言います。メルカリでは、全体的にOKRという考え方を、短期的な目標設定と成果を計測するために使っています。 今のOKRの使い方は、短期的な目標には使いやすい一方、中長期目標には使い勝手が悪い状態です。そのため、代わりにプロジェクトという考え方を用いています。 この考え方はメルカリ・メルペイ全体で使われており、同じプロジェクトという考え方をEnabling Programでも使っていこうと思います。 次に、プロジェクトの種類です。これは、Enabling Programの中でのプロジェクトの種類を指しており、通常プロジェクトと重要プロジェクトの大きく二つに分けて考えています。 通常プロジェクトの定義は、達成することで他のチームにインパクトがあること。これを達成すると、影響がある人たち、つまりプロダクトを開発している全ての人たちに対して、行っていることやその影響を知ってもらいたいという目的があります。 重要プロジェクトの定義は、達成することで会社レベルの目標にインパクトが出るものです。カンパニーのOKRや重要な目的に対して影響があるということです。周知したい人は、VPや他のProduct/Engineering Headです。 二つ目「会社としての課題に設定する」については、Merpay Engineering Projectsを実施しています。 これはメルペイでの重要なEngineering課題です。元々メルペイでは、この会社レベルで、重要な指標としてEngineering OKRがありました。しかし、やはりOKRであると短期的な目標になってしまいがちです。一方、重要なEngineering課題は中長期的なものが多く、会社としてもプロジェクトという形をとっています。 Merpay Engineering Projectsという会社レベルのプロジェクトは、Enablingの重要プロジェクトから取り入れてもらっています。Enablingの重要プロジェクトをEngineeringプロジェクトとして採用してもらうことによって、担当のVPがアサインされて、サポートが得られます。 大きな意思決定が必要な場合や、他のプログラムの優先順位の変更が必要な場合、VPレベルで説明してもらうことが可能です。 Engineering Projectsは、2週間に1回、各プロジェクトの進捗や課題を報告して、ブロッカーを洗い出しています。場合によっては、VPなどに対して対応を求めやすい状態です。 三つ目「成果報告」についてですが、成果発表会を行っています。これは、Enabling各チームの代表者が発表してもらっていて、3ヶ月に1回、成果を発表してもらっています。 今までは各チームでOKRを設定していていましたが、OKRの成果を他のチームに知らせる機会がほとんどありませんでした。 それを改善するために、成果発表会という形でEnablingチームがやっていることを発表したいと思いました。発表会には、エンジニアだけじゃなくてPMなど、開発に関わる広い範囲の人を招待しています。 実際に前クォーターの成果発表会を開いたときは、100名もの方に参加いただきました。Enabling Programが何をしているのか、みなさんが興味を持ってくださったおかげです。 これまで自分がEnablingのEngineering Headになって、プロセスを改善するためにいろいろなことをしてきました。でも、まだ改善することが多いです。 例えば、Engineering課題が会社レベルで設置されたとしても、プロダクトの優先順位をどうするのかという問題や、出した成果をもっと投資してでも伸ばしていくべきなのか、それともすでに成果が出ているからStayでいいのかという説明をしなければなりません。 今後としては、引き続きこれらの改善をしていくと同時に、すでに行ってきたことを継続していくことも重要だと考えています。 発表は以上です。ご清聴、ありがとうございました。
アバター
Merpay & Mercoin Tech Fest 2023 は、事業との関わりから技術への興味を深め、Productやサービスを支えるエンジニアリングを知ることができるお祭りで、2023年8月22日(火)からの3日間、開催しました。セッションでは、事業を支える組織・技術・課題などへの試行錯誤やアプローチを紹介していきました。 この記事は、「 Merpay Engineering Career Talk 」の書き起こしです。 @keigow:今回のセッションは、「Merpay Engineering Career Talk」というタイトルでディスカッションを進めていきます。 @keigow:メルペイVP of Engineeringの@keigowと申します。私は、2016年にメルカリグループに入った後に、2018年のメルペイ立ち上げのタイミングから3年、メルペイに所属してました。2年ほどグループ会社のソウゾウという会社で新規事業の立ち上げに取り組んでいたんですけれども、この4月にメルペイに戻りました。 @osamingo:皆さんこんにちは、@osamingoです。@keigowさんと同じく、2016年8月にメルカリの子会社のソウゾウに入社しました。そのときのメンターは@keigowさんで、個人的には感慨深いです。 元々はバックエンドエンジニアとして入社し、プロジェクト開発に従事しました。2018年頃にメルペイへ異動し、バックエンドエンジニアをしていたのですが、約1年半後にエンジニアリングマネージャー(以下、EM)になりました。最初は、コード決済や加盟店管理/審査、加盟店精算周りに携わっていたのですが、現在は、Fintech ArchitectやEngineering Productivityという社内のデベロッパー向けのサービス開発のEMをやっています。本日はよろしくお願いします。 @fivestar:@fivestarです。本名はKatsuhiro Ogawaと申します。メルカリには2018年1月に入社し、6年目になります。最初はコーポレートエンジニアリングという、社内の評価システムや社内向けのプロダクトを開発する部門の立ち上げにジョインして、そこから1年半ぐらいメルカリ側で開発をしていまして、そのときはバックエンドアーキテクトということで、バックエンド寄りの部分も担当していました。 そこから2019年にメルペイに転籍し、ずっと与信部門に所属しています。そこでメルペイのあと払いやメルペイスマートマネーといった与信系サービスの開発を行っています。 エンジニアではありますが、組織上Engineering Headという役割を賜っていまして、チームのエンジニアリングに関する意思決定の取りまとめもしています。過去にはマネージャーや、スタートアップのCTOをしていた時期もあり、エンジニアとしてのキャリアをまた再構築している状況なので、少しでも参考になればいいなと思っております。 @keigow:では、早速ディスカッションの方に入っていきます。 @fivestar:@keigowさんがVPになったのはいつでしたっけ? @keigow:正式には今年の7月ですが、メルペイに戻ってきたのが4月なので、そこから徐々に似たような役割をしていました。 @fivestar:僕がメルペイに入って1年経たないくらいから一時期、@keigowさんにマネジメントしてもらったことがありましたが、メルペイに戻ってきたと思ったらいきなりVPになったじゃないですか。きっかけが気になりますね。 @keigow:もともとソウゾウでHead of Engineeringという形でエンジニアリング組織を見ていました。ちょうど今年の4月のタイミングでメルカリShopsの事業がメルカリ本体と事業統合し、組織が変わるタイミングで、これからどうしようか迷っていました。 その中でメルペイに戻ってきてVPの役割を担当しないかという打診がありました。メルペイ自体はすごい大きな組織で難しさもよくわかっていたので悩みましたが、こういう機会はなかなかないと思っていて、チャレンジしないのはもったいないという気持ちが最終的には勝ちました。 @fivestar:元々VPはキャリアの選択肢として考えていましたか? @keigow:元々ポジションにこだわりはありませんでした。自分のスキルが一番会社に貢献できる場所ってどこなんだろうと、ずっと考えていました。一番好きなのはプロダクト開発だったので、VPやCTOになりたいとは考えていませんでした。 でも、最初マネージャーをやったときは、マネージャーでいっぱいいっぱいでしたし、人が増えていく中で、中間管理の人が必要だと思ったタイミングで挑戦しようかなと思いました。 ただ、VPになりたいという気持ちもそこまでなくて、常に当時の上長には「たまに現場に戻りたいって思うんですよね」という話はずっとしていました。でも行動していく中で少しずつ考え方がアップデートされていきました。その結果としてVPにチャレンジをしたいと思うようになりました。。 @fivestar:どのタイミングで、マネジメントの方向に行こうと決心したのですか? @keigow:これというタイミングはなかったです。最初はプレイングマネージャーだったので、コードも書きつつマネジメントしていました。また、プロダクトマネージャーの時期も挟んだことでコードから離れてしまい、それが続いて今に至ります。そのときの状況に応じて最適だと思う選択肢を選んできました。 次に、@osamingoさんからの質問です。 @osamingo:@fivestarさんは、Credit Designという与信やあと払いを管理しているチームに異動されてからも、こだわりをもって業務をされていると思います。組織が大きくなり、サービスがリリースされていくという変化が激しい中でも、永く所属されています。この中で、エンジニアリングの責任の深さや広さはどう変化し、またどう対応してきましたか。 @fivestar:もともと前のチームでバックエンドのアーキテクトという立場で、複数のサービスを組み合わせて全体のアーキテクチャを見ていましたし、自分の一番関心のある領域は、ドメインモデルやアーキテクチャでした。そのような設計を取りまとめるという役割を考えて、ずっとキャリアを歩んできています。 だから、僕が来たときと比べると、与信サービス事業はめちゃくちゃ拡大しているのですが、キャリア的な考えで言うと、もともとメルペイにきたときからある程度広く見ていけるようにという意識はもっています。その中で、僕は20代の頃はコードを書きたいと思っていたのですが、年齢を重ねるごとに、設計をきちんとして良いプロダクトを生み出し、課題解決をやっていきたいという思いがあります。 Credit Designの与信事業にすごく興味があったので、異動の希望を出して今に至ります。でも、最初はチームの中で信頼されることが大事だと思うので、最初は本当に小さいマイクロサービスの開発チームに入って積み上げていって、大きなマイクロサービスのテックリードをやったり、あとはメルペイ立ち上げからいろいろな課題があってその解決にオーナーシップをもって取り組むことを意識しています。 確かに広さ・深さは実質的に変化していますが、現場の第一線で、際限なくいろいろな課題を解決したいという思いがあったので、マネジメントではなく現場側の役割でやらせてもらっています。 @osamingo:特にメルペイだと、自分が作ったサービスに触れる喜びはかなり強いと思うんですよね。全体を設計することに対するメンタルやモチベーションについてはいかがですか? @fivestar:チームのマネージャーとコミュニケーションをしていく中で、「もっとパフォーマンス発揮の仕方として、周りをうまく活用して」と言われたことで、少しずつ意識の変化が起こりました。 それから、今後LLMによってコードを書かなくていい世の中になるかもしれませんし、コードを書いていればお金がもらえる世界じゃなくなるかもしれません。それよりは、課題の本質に触れる方を自分の仕事にしていった方が、食いっぱぐれるリスクが少ないかなという打算的な部分もありました。 @osamingo:昔からそういう意識はあって、今このタイミングでもともと持っていたものが発揮されたイメージですかね。 @fivestar:与信事業はかなり課題が複雑で、お客さまの体験という点でいろいろな接点があります。 例えばあと払いサービスを使うところから返済して、そのお金を回収しなきゃいけなかったり、単体でひとつの事業としてPLを持つくらい複雑な事業です。法要件も複雑で、割賦販売法や貸金業法などの理解も含めて難しいドメインですが、難しい方が自分としてはチャレンジのしがいがあります。複雑なものを紐解いたときは嬉しいです。 メルペイの面白いところは、強い人が集まっていることです。特に与信チームは強いメンバーが多くて、会社からの期待値が常に高いんです。いろいろなサービスをどんどんアプリとして、事業を引っ張るプロダクト開発チームなので、会社からの期待値も含めてやればやるほど成果が出ます。そこで責任を持てて、しかも現場の中で必要に応じたマネジメントをしながら、組織を引っ張る立場にいられるのは、自分が昔から目指していた形の一つだったのでやりがいを感じます。 @osamingo:リスペクトできるメンバーと働けるのは、明文化できない福利厚生ですよね。 @fivestar:@osahimgoさんはこの会社に入ってからマネージャーになりましたよね。ICに戻りたいという葛藤はありましたか? @osamingo:ありましたよ(笑) 「Go Bold」という会社のバリューがありますから、「自分がBoldに行けるところはどこなんだろう」ということを常に探っているタイミングで、ICに戻るという選択肢を考えたこともあります。でも今のところはマネージャー業が楽しいので続けています。 @fivestar:どういうところが楽しいでしょうか? @osamingo:EMになったきっかけとして、メルカリグループに入社して2年半くらい経ったときに、自分のパフォーマンスを最大化させるときに「自分はこのままでいいんだろうか」とモヤモヤしていた時期が半年ほどありました。 当時、メルペイがリリース準備でいろいろ頑張っているタイミングでした。そのときに会社で開催されていた「Engineering Manager Philosophy Talk」のイベントに参加し、自分の気持ちが明確になりました。そのイベントは、外部の講師を招いてEngineering Managerの哲学や経験について語っていただくというものでした。そこで、タイミングよくEMに登用されました。 もともとコード決済や加盟店審査、加盟店管理などのプロダクトサイドを長く担当していて、例えば、NTTドコモさんとd払いで連携する場面や国の省庁と連携して何かをやる場面に立ち会うことが多々ありました。 それもすごく楽しかったのですが、EMの活動として、プラットフォームサイドにもチャレンジをしたいという気持ちがあって、今はArchitectやEngineering Productivityという裏方寄りのところを担当しています。 今の領域はプロダクトマネージャーの人がいなくて、エンジニアが自発的に動き、かつEMも動きもあるという、動き方やEMへの期待値が違うため、エリアによってかなり求められるマネジメントスキルが違います。そのギャップが楽しいです。 @keigow:今視聴者さんから質問が来ていますが、「キャリアを築いていく中で現場との距離から焦燥感が発生したときの向き合い方を知りたい」とのことです。 やっぱり、EMになって、自分がコードを書かないことで知識が遅れていくんじゃないかと思うこともあるのかと思いますが、どうでしたか。 @osamingo:そういう考えは、ありました。 一線で書いてないと、特にエンジニアの知識量、エッジなテックに対しての対応能力が著しく下がるし、コードを書くスピードは3分の1にまで落ちるという現象が早めに来てしまって。「俺はエンジニアとして死んでしまったんじゃないだろうか」という焦燥感に苛まれることは僕もありました。 そのとき何をやったかというと、1on1でメンバーから教えてもらうということです。マネージャーからメンバーに聞いた方が「こいつはまだテクノロジーに対してちゃんと関心を持ってるんだな」というアピールもできますし、現場から離れて焦燥感はあるのですが、チームで仕事しています。メンバーとのコミュニケーションという中で、僕はそこを埋めてきたところはあります。 @keigow:@fivestarさんにも聞きたいのですが、マネジメントではないですが、Engineering Headという立場で、コードを書く時間が減ってきているという話があったと思うのですが、似たような課題感や焦燥感はありましたか? @fivestar:正直あるのですが、押さえておかなければいけない部分はある程度押さえていると思います。また、与信領域の全てを押さえておくというよりは、ある程度責任の移譲は必要だし、必要な意思決定を自分がしていく一方で頼ることも大切だと思います。 僕の場合、周りにいるのはテックリードなど、同じような役割の人たちなので、役割分担して自分が全部抱えないようにしています。 @keigow:最後、個人的に僕が聞きたかった質問なんですけれど、@fivestarさんは組織にもかなり興味を持っていると思います。実際、マネージャーという職種には興味を持っていますか? @fivestar:1年前ぐらいまでは全然考えていなかったのですが、今のロールはいずれ他のチームメンバーにtake overしていかなきゃいけないと思います。そうなったときに、次に自分に求められるのがマネジメントの可能性もあると思っています。マネージャーは、選択肢として持ってもいいかなと思っています。自分がやりたいと思ったときは、改めて相談させてください(笑) @keigow:まだまだ聞きたいこと・話したいことがたくさんあるかと思うのですが、時間が来てしまったので、本日はこれでおしまいにしたい思っております。 ご清聴ありがとうございました。
アバター
Merpay & Mercoin Tech Fest 2023 は、事業との関わりから技術への興味を深め、プロダクトやサービスを支えるエンジニアリングを知ることができるお祭りで、2023年8月22日(火)からの3日間、開催しました。セッションでは、事業を支える組織・技術・課題などへの試行錯誤やアプローチを紹介していきました。 この記事は、「 SwiftUIでビットコインの価格チャートを改善・再実装した話 」の書き起こしです。 @andooown:「SwiftUIでビットコインの価格チャートを改善・再実装した話」というタイトルで発表します。 まずは簡単な自己紹介です。株式会社メルコインのクライアントチームで、iOSエンジニアをしている、Yoshikazu Andoと申します。GitHubやSNSでは、@andooownというIDで活動しています。2019年に新卒で株式会社MIXIに入り、ウォレットサービスのiOSアプリの開発を行っていました。 その後、2021年にメルカリグループにジョインして、ビットコイン取引サービスの立ち上げに参加し、引き続きiOSアプリ開発者として、設計やグループ内の連携も含めて担当しています。 では、改めてSwiftUIでビットコインの価格チャートを改善・再実装した話をします。 まずは、メルカリのビットコイン取引機能について説明します。ビットコイン取引は、ありがたいことに、サービス開始から3ヶ月強で口座開設数が50万人を突破しました。引き続き伸ばしていきたいと考えています。 右の画像がサービスのトップ画面です。ビットコイン取引は、メルカリアプリの機能のひとつであり、メルカリアプリにSDKとして実装されています。これによって疎結合にしつつ、グループ共通の基盤機能やコンポーネントを利用して開発されています。 アプリ内の主な動線は、マイページ。口座開設や普段の利用も、マイページからご利用いただけます。ビットコイン取引機能も含めて、メルカリアプリはSwiftUIを基本として開発されています。SwiftUIも含めたアプリ全体のリライトの話は、メルカンに掲載されておりますのでぜひご覧ください。 参考記事: メルカリの事業とエコシステムをいかにサステナブルなものにするか?かつてない大型プロジェクト「GroundUp App」の道程 また、パスワードレスの認証システムであるFIDOを使用しているので、セキュアにビットコイン取引が行えることも特徴です。こちらはメルカリサービスで最初に採用されています。 本題のビットコインの価格チャートについてです。 チャートはサービスのトップ画面にあり、一番お客さまの目に入る画面となります。チャートには、ビットコインの価格の推移を表示しており、バックエンドから配信された価格のデータをもとに点の間を補完して描画しています。また、画面を開いている間は、一定間隔でデータが更新されます。お客さまはチャートの下のボタンから閲覧する期間を変更できます。 チャートはタップでき、それによって実際の価格や時刻が表示されたり、見た目が変わったりします。 タップされている位置より右側のラインの色はグレーになり、グラデーションの塗りつぶしもなくなります。タップ後には、線の太さや補間の方法が変化し、その間はアニメーションによって連続的になっています。 初期の段階では、このチャートの実装にOSSのChartsライブラリを利用していました。おそらく一番有名な danielgindi/Charts ライブラリで、Appleプラットフォームでチャートやグラフを実装したことがある方ならご存知なのではないでしょうか? こちらの画像はGitHubのREADMEから持ってきたものですが、このようなシンプルなチャートであれば、簡単に実装できます。 グラデーションでFillする機能もあり、こちらのサービスのチャートの要件にマッチしています。また、去年のWWDCで発表されたApple公式のSwift ChartsですがこちらはiOS 16から利用可能となっており、サービスの要件にマッチしていないため、今回は採用を見送りました。 OSSのChartsは、UIKitで作られており、メルカリアプリはSwiftUIを基本として開発されています。そのため、今回はUIViewRepresentableでラップした状態でサービスに組み込みました。 また、タップしている間に表示される価格や日時のコンポーネントはSwiftUIで実装しています。ChartViewと併せてVStackに入れ、タップされてる位置などを同期する必要があるので、Stateを引きまわして実装しています。 この実装にはいくつかの課題がありました。 まず感じていたのは、Chartsライブラリの制約によって、無理やり感のある実装設計になっていたことです。例えば、サービスとして実現したインタラクションがありましたが、そのためには、ライブラリ側で用意されているデリケートメソッドだけでは足りず、自前でUIGestureRecognizerを追加していました。 また、タップした位置の左右で色を変えたり、塗りつぶしの有無を変えたりという要件がありましたが、標準の機能ではこれを実現できませんでした。悩んだ上で、二つのChartViewを生成し、それぞれタップした左側用の設定・右側用の設定で描画し、それらをクロップした上で、ZStackで重ねる方法をとっていました。 ChartsのChartViewはかなり高機能で、そのようなViewを二つ生成しているので、無駄が多かったと思います。 この部分は後になってライブラリのRendererなどをオーバーライドして自作することで、一つのChartViewで実装できるようになりましたが、それによってメンテナンスコストが上がり、どちらにしても課題が残る状態となっていました。 次の課題として、データフローが複雑になっていることがありました。 UIViewRepresentableを使った実装ではあるあるだと思いますが、StateはSwiftUI側にあり、initializerでUIViewに渡します。その上で、タップイベント等はUIKit側から発生します。チャートの上にある価格表示部分はSwiftUIであり、座標をUIKit側と同期する必要があるため、SwiftUIのStateにも反映します。 UIKit、ChartViewも高機能であるため少なからずStateは持っており、SwiftUI側にも、もちろんStateがあります。これによって、Stateやライフサイクルの同期がうまくいかないことによるバグも発生していました。 例えば、「指を離しているのに線が残る」というもので、これはChartViewのバグにより想定しているデリケートメソッドが呼ばれず、Stateがずれてしまうということが原因でした。 この話に関連して、Chartsライブラリにも課題を感じていました。実装当時、Chartsライブラリは頻繁にメンテナンスされているとは言えず、バグ修正のPRはあったものの、1年半放置されている状況でした。そのため初期のChartの実装では、ブランチのライブラリを利用していました。 発表に際して、改めて状況を確認すると、最近新しいメジャーバージョンがリリースされていて、今後は多少活発になることが予測されます。 最大の課題は、ここまでの制約によってやりたいことができないということです。初期段階では、デザイナーさんなどがいろいろな表現の案を提案してくれていましたが、制約によって「かなり無理やりなことをしないと無理そう」と断ることが度々ありました。 チャートはサービスのトップ画面にあり、一番最初に目に入る機能のため、ここにはこだわりたい気持ちがありました。しかし、他のタスクや今後のメンテナンスを考えると、断らざるを得ない状況でした。 あるときPMが、「チャートは取引所サービスの顔」と言っていることがありましたが、その通りだと思いますし、もどかしい思いをしていました。アニメーションもこうして断念した表現の一つであり、初期の実装では、アニメーションなしで見た目が切り替わっていました。 「チャートはサービスの顔だが、不完全燃焼」という状態ですが、このままリリースするのは勿体ないということで、チーム内で合意を取って、チャートをフルスクラッチで実装し直すことになりました。 我々のサービスは、暗号資産交換業ということもあって、スペックや仕様については細かく文書化されているものの、チャートの部分については最低限守るべきスペックのみを定め、iOS・Androidのプラットフォームごとにできる表現をとことん突き詰めることも、このときに同意しました。この認識をチームで共有できたことで、この後が進めやすくなったので非常によかったです。 リライトしていくにあたり、まずは設計方針を決めました。チャートのコンポーネントは二層で構成し、汎用的な部分とサービストップのビットコイン価格チャート固有のドメインを含む部分とで分けることにしました。 汎用的な部分については、X方向に位置、Y方向にビットコイン価格を取る、グラフにおいて汎用的に使うであろう数値と座標の変換ロジックや、チャートのサイズの管理などを含みます。 トップ画面のドメイン固有のレイヤーに関しては、この時点では、どの程度サービスで再利用できるかがわからなかったこともあり、非常に多くのものを含んでいます。 価格の点の間を補完するロジック、画面仕様に合わせて、各個のコンポーネントをレイアウトするロジック、実際にチャートのラインや、グラデーションを構成描画する部分も、ドメイン固有のレイヤーに含まれます。 レイアウトの描画に関しても、SwiftUIのView・Shapeで構成する方針を立てました。これとは反対に、公式のSwift ChartsのようにChartContentというprotocolと専用のResult buildersを作ってデータモデルを構成し、それをもとに内部で描画をする方法もあります。 しかし、この場合は、SwiftUIに用意された豊富なレイアウト方法や、既存の資産を使うことができないため、表現の幅を制限しないためにも、View・Shapeを使うことにしました。これらの決定は後ほど活きてくることになります。 この方針をもとに、2週間ほどでPoCを作成しました。 作ったものについて説明します。リライト後、左の赤枠の範囲のViewは、ViewBuilderを使って通常のViewのように右のコードのように記述できるようになりました。 コードは実際のものを簡略化していますが、構成は同じで、汎用的な座標計算などをしてくれるContainer ViewであるLineChartの中に、SwiftUIの LayoutコンポーネントであるVStackなどを使ってチャート構成要素をレイアウトしています。 では、具体的に見ていきます。先ほどのコードで一番外側を囲っていたのがこのLineChartです。 これ自体もSwiftUIのViewであり、initializerでChartの点の配列と実際の表示要素を返すViewBuilderのクロージャを受け取ります。 そして、受け取ったクロージャに対してChartContextというオブジェクトを渡してViewを生成します。 bodyを見るとわかるように、LineChartは渡されたクロージャーから生成できるView以外に表示要素は持ちません。 そしてChartContextは、チャートの作成に必要な情報を持っています。右側のコードのように、実際はLineChartからさまざまなものをinitializerで渡して作成されています。 entriesは引き続きチャートの点のデータの配列。sizeやtransformerについてはこの後説明いたします。LineChartはこのチャートの作成に必要な情報を管理することが責務です。 ChartContextが持つsizeプロパティは、チャート部分の大きさを表しています。 ここでいうチャート部分とは、右の画像の赤の実線の範囲です。先ほどの通り、LineChart自体は赤の点線の範囲になりますが、チャートとして数値に関連した座標系を持つ範囲は実践の範囲ですので、その部分の大きさがsizeとして保持されています。 これは座標や数値の計算、各コンポーネントをレイアウトに利用するため、Contextに保持されています。 そのsizeですが、LineChartの中でどのように取得されているかというと、このようなmarkAsChartContent()というカスタムModifierが利用されています。 ViewのbackgroundにGeometryReaderを挿入して、サイズを取得するSwiftUIではおなじみの実装です。取得したサイズはpreferenceに記録されます。 LineChart側では、左側のように、preferenceを読み取り、privateな@Stateとして保持し、それをContextに渡しています。 実際の場面では、右側のコードで赤く囲まれたところのように、LineChartのViewBuilderの中で、座標系の範囲に相当するViewにModifierがつけられています。赤枠の上のMarkerViewはタップ時に価格や時刻を表示するコンポーネントなので、座標系は持ちません。 Contextの最後はMatrixTransformerオブジェクトです。これは左下のように、チャートの数値データと画面上の座標を相互変換する機能を持っています。これも各コンポーネントをレイアウト・描画するときに必要になります。 MatrixTransformerも右の画像のようにサイズを用いて作成されます。これによって、数値と座標の相互変換ができます。 実際のChartViewでは、これらの情報が詰まったContextを使ってViewを作ります。 このコードはタップ時に表示される縦の点線の例ですが、Contextのtransformerを使ってタップされているデータから、実際の画面上のX座標を取得してレイアウトされています。価格のラインやグラデーションなども同様にContextを利用して作成されています。 もう一つこのコードからわかるのは、タップされているデータであるselectedEntryが、LineChartの外で管理されていることです。LineChartは、数値・座標の管理のみが責務です。現時点では、触って数値を見れるという機能が、今後実装されるチャートでも同じかわからないため、このような設計になっています。 ここまでは、初期の実装にあったものをただSwiftUIでリライトしただけです。発表タイトルの再実装のみが回収されました。 ここから時間を取って改善を始めました。ただ再実装しただけであれば、開発面で運用コストが減ったかもしれませんが、プロダクトとして良くなった点はありません。 今まで制約によってできなかったけど、やりたい表現を実現するために、右のスクリーンショットのようなデモアプリを作成し、手元の端末で触れる形でPMやデザイナーも含めて配布しました。デモアプリではチャートに関連するパラメータをUIから操作できるようになっていて、タップしているときといないときの線の太さ、チャートをなめらかにするための数値処理、点の間の補間方法など、さまざまなものがあります。 アニメーションもこの段階で実装し、アニメーションの長さなども調整できるようになっていました。このデモアプリがあることによって、今までは「もっと線を丸い感じで」「なめらかにしたい」など、言語化しにくかった表現が、具体的なパラメータとして共有できるようになり、改善のPDCAが加速しました。 後半では、「デザイナーさんが気に入ったパラメータ」「PMさんが気に入ったパラメータ」のように、各々が気に入ったものをプリセットとして登録して、呼び出す機能も実装しました。最終的にはチームで画面共有をしながら、お客さまに届ける際のパラメータを決定しました。 デモの実装においては、SwiftUIでリライトしたことで、宣言的UIになったことや、アーキテクチャがSingle Source of Truthになっていることが存分に活きました。大量のパラメータを1ヶ所で管理し、各コンポーネントはパラメータに応じた振る舞いを記述するのみでよくなります。 UIKitなどの命令的なUIでは、パラメータが多い場合、パラメータ自体とパラメータを利用するView、パラメータを設定するためのViewの同期を取って更新するのが難しいと思います。 また、ViewBuilderの恩恵によってViewの構造を変化させるのも容易なため、一つのViewに全てを実装するのではなく、「補間方法に応じたViewを用意する」などもやりやすかったです。 リライトしたことの別の大きな恩恵は、アニメーションが簡単に実装できたことです。シェイプ自身がAnimatable protocolに準拠しており、その仕組みのおかげで実装できました。アニメーションは、UIKitの仕組みの場合は簡単には実装できなかったと思います。 アニメーション自体は初期からアイディアはあったものの、ライブラリの制約によって断念したため、改善フェーズで実装できて本当に良かったです。 アニメーションの実装方法に少しだけ触れておきます。左は、チャート上のラインを構成するコンポーネントで、SwiftUIのシェイプになっています。Animatable protocolでは、animatableDataプロパティを通じて、アニメーションにおいて連続的に変化する値を設定します。 ここでは、通常時は0、チャートをタップしたときに1となるような数値をanimatableDataとしています。これによって、アニメーション発生時はSwiftUIによって、animatableDataが0から1の間で0.1、0.2といったように、連続的に設定された状態でViewが描画され、アニメーションが実現されます。 チャートでは、滑らかなラインから詳細な価格がわかるラインへとアニメーションさせたいので、animatableDataデータの値に合わせて、二つの価格推移データの間を取る値を計算し、補間処理についてもその強度をanimatableDataを基に計算することで、アニメーションを実現しました。 改善を終えてみた感想です。やはりSwiftUIの特徴を生かしてチームでPDCAを回し、実際にプロダクトをより良いものにできたことは非常によかったと感じています。 デモ準備したりと工数はかかってしまうものの、共通の動くものを見ながら議論・意思決定するのはやはり迅速で、かつ同じものを見ているため、認識のずれも少なかったと思います。 これによって、リモートワークの環境でも、言語化しにくいUIの部分を改善できました。そして、ありきたりですが、リライトを通じてSwiftUIの理解はかなり深まったと感じています。 普段の画面開発や趣味の小さな実装では、なかなか深い理解が難しいことも多いですが、製品レベルでチャートのようなチャレンジングな課題に取り組むと、理解が早く深いものになるなと改めて感じました。 一方で、汎用的な設計を目指しましたが、それがどこまで通用するのかは未知数だとも思っています。OSSのChartsにも言えますが、Alamofireのように、通信データに関するものや、UI系でもAuto LayoutのためのSnapKitのようなユーティリティ系とは異なり、それ自身がUIコンポーネントを提供するタイプのものは、汎用するのが難しいなと改めて感じました。表現はサービスによって十人十色であり、ライブラリを使った表現が最適なサービスばかりではないからです。これはライブラリを利用する側にも作る側にも当てはまる話だと思います。 社内レベルのコンポーネントだとしても、年月を経て、最初は小さかったものが次第に高機能になり、逆に要件を満たしづらくなることもよくあることかと思います。 そして最後に製品のクオリティのために早くサービスをリリースしたいであろう立ち上げ時期に時間を取らせてくれた、また一緒に改善に臨んでくれたチームに感謝したいと思います。今回の進め方で都度チームで合意をとっていたのが良かったなと個人的には思っていますが、裏を返せば、合意をしてくれたチームのおかげです。本当にありがとうございました。 今後は、どこかの時点でパフォーマンスチューニングをしたいと考えています。もちろん、リリース時点で実機でカクつかないことを確認していますが、チャートtの補間部分やViewの構造など、最適化の余地はたくさんあると思っています。どこかでProfileを取りながら進めていきたいと考えています。 また、デモや動画など、動くものを使った議論の効率の良さを改めて目の当たりにしたので、これは継続したい思っています。 忙しくなってくると、「進捗がわかるものを出してください」と言われているわけではないので、自発的なスクリーンキャプチャーの共有などはおろそかにしがちです。 それによって実装が全て終わった後で、認識齟齬があって手戻りしてしまうことは、あるあるではないでしょうか?今後は、「今こんな感じです」と共有する気持ちを忘れずにいきたいと思います。 発表は以上になります。メルコインのクライアントチームでは、日々和気あいあいとプロダクトの開発に取り組んでいます。ご興味がありましたらぜひご連絡ください。 Software Engineer, iOS – Mercoin また、今回ご紹介したチャートはOSSで公開をしています。 https://github.com/mercari/swiftui-chart ご清聴ありがとうございました。
アバター