Regional Scrum Gathering Tokyo 2022に参加しました!

こんにちは、エンジニアの富田です!

2022年1月5日〜1月7日まで開催されたRegional Scrum Gathering℠ Tokyo 2022に参加してきました!

twitter #RSGT2022 #RSGT2022 hashtag on Twittertwitter.com

[Regional Scrum Gathering Tokyo 2022のスライドまとめ #RSGT2022

scrummasudar.hatenablog.com


Regional Scrum Gathering Tokyo(RSGT)とは?

「Regional Scrum Gathering Tokyo」は、日本最大級のアジャイル関連のカンファレンスです。 毎年、1月上旬に東京で開催されます。

去年はオンラインで参加したのですが、今回は会社から参加費を出してもらい、現地参加しました。

コロナ禍でオフラインの集まりにほとんど参加していなかったのですが、久しぶりに大勢の人と話すことが出来、3日間、どっぷりとアジャイルの世界に浸かることが出来ました。

また、オンラインの参加者はDiscordで活発にやりとりされていたのですが、そちらを見て感想を楽しんだり、投稿内容から知識を得ることもできました。


参加してみてどうだったか?

f:id:yuri_terao:20220205215547p:plain

一番、印象に残っているのは、プロダクト・スプリントのそれぞれのゴールの話でした。

現在、私のチームではスクラムで開発を行っているのですが、スプリントゴールがあいまいになりがちでした。

スプリントゴールは、プロダクトゴールから逆算して、直近(現在のスプリント)で実現すべきものかなと思います。

プロダクトゴールがぼやけてしまっているのが、スプリントゴールにも波及していることが理解出来、帰ってきてからプロダクトオーナーとこの点を話しました。

また、システムコーチングを体感するワークショップにも参加しました。 オフラインのワークショップも久しぶりなので、かなり緊張しましたが、楽しく実体験として学ぶことが出来ました。


参加後

参加後は、レポートを作成して社内に公開したり「共有会」を開催しました。 「共有会」はレポートを元に、1日目から順に登壇の内容や感じたことをを報告していきました。

RSGTの3日目は、毎回Open Space Technology(OST)が開催されるのですが、その動画を見ながらどんな風に開催されるのか共有しました。

社内では、まだアジャイル開発が広まっているわけではないので、上記のような活動で少しずつでもアジャイルのファンを広めていこうと企んでいます 😎

来年は、社内の他の人も巻き込んで参加出来ればと思っています!


ちなみに、参加中、東京は、歴史的な雪景色でした。

f:id:yuri_terao:20220205215450p:plain

Baseconnectではエンジニアメンバーを絶賛募集しております! もしご興味をお持ちいただけた方がいらっしゃいましたら、下記のリンクよりぜひカジュアルにお話しさせていただけましたら嬉しく思います!

meety.net

herp.careers

課金システムをマイクロサービス化したお話

はじめに

こんにちは、Baseconnectのエンジニアインターンの東野です!

20xx年某日、僕はあるプロジェクトにアサインされました。その名も「課金システムマイクロサービス化」プロジェクトです。

このプロジェクトにはもちろん社員メンバーの方と一緒に携わらせてもらったのですが、今回代表して、Musubuの課金システムをマイクロサービス化した話を執筆させていただくことになりました!

まずMusubuって?という方にはぜひこちらを見ていただけたらと思います。 (ざっくり一言で説明するなら「営業支援ツール」になります。)

もともとMusubuはモノリシックなシステムだったのですが、課金システムをマイクロサービス化しようという流れになり、プロジェクトが開始しました。

課金システムの主な機能

  • 定期課金情報の管理
  • 支払情報の管理
  • カードへの請求や請求書払いなどの支払いに関する処理です

システム構成図

まずは大まかな課金実装のシステム構成は以下の通りです。

モノリシックな状態 f:id:yuri_terao:20220217141023p:plain マイクロサービス化後の状態 f:id:yuri_terao:20220217141037p:plain

端的に言うとMusubuでカード決済代行サービスの処理を実行していたり、データベースの中に定期課金や支払いに関する処理を保持していたものを切り離しました。

課金システムのER図

次にどのようなデータがあるかについてです。以下の他にもモデルはありますが、概ねの流れを理解するのに必要な部分を抜き出したいと思います。 f:id:yuri_terao:20220217141049p:plain

クライアントデータ

クライアントデータは、課金システムからみた外部システム、つまり今回でいうとMusubuになります。Musubu以外のサービスでも利用できるようにクライアントデータという名前で抽象的な概念として情報を持っています。

顧客データ

顧客データはユーザー情報のうち請求処理に必要な情報のみを保持しています。

課金データ

ユーザーの定期課金の情報を保持しています。次の支払い時期や月額単価などの情報を保持しています。

購入データ

毎月発生する定期課金の支払いや個別での支払いの情報を保持しています。

課金登録時の処理

f:id:yuri_terao:20220217141138p:plain

  1. Musubuのユーザーが定期課金(有料プラン)登録
  2. Musubu内でアイテム(企業情報を取得することができる件数等)付与
  3. 課金に関するデータを作成
  4. カード決済代行サービスへカード情報作成と支払い処理をリクエス

この2~4の処理はすべて同一トランザクションにしています。 マイクロサービス化されているので、外部への処理の委託をトランザクションの最後に実行して、失敗した場合(レスポンスのステータスが2xx以外のとき)ロールバックするという風にすると、アトミックな処理に対して一貫性を保つことができます。

しかしリクエストの結果からさらにデータを更新する必要がある場合、トランザクションという方法で完全に一貫性を保つことはできませんので、リトライ等で対策する必要があります。

契約更新時の請求処理

f:id:yuri_terao:20220217141152p:plain

  1. スケジューラが支払い処理を開始させる
  2. 更新日に達した課金データに対して支払い取得し支払い処理を実行します
  3. 支払い処理の成否をMusubuに通知して、Musubu側でのユーザーにアイテム付与や利用停止などの処理を行います

わかったこと

マイクロサービス化で難しい点

  1. データの整合性の担保
  2. 複雑な条件での検索(データが分散しているため)
  3. 各システムの責務の切り分け方(これが実装のしやすさや安全性に大きく関わってきます)
  4. 外部システムの知識を汎用的に表現すること(責務の切り分け方が悪い場合もありますが、どうしても外部システムの知識が必要になることがあります)

データの整合性の担保

課金登録時の処理の説明のところでも出てきていますが、どうしてもアトミックな処理が複数のシステムの処理をまたがってしまい、ぶつ切りになってしまいます。そんなときはアトミックな処理をできるだけユーザーにとってストレスのない単位で切り分けて、すぐに検知して正しいデータに戻せるようにする必要があります。

複雑な条件での検索

データが複数のDBに分散しているため、それぞれのDBにしかないプロパティを組み合わせた条件などで検索するには少し工夫する必要があります。一例として片方のデータベースにメタ情報として外部のシステムのデータを保持する方法があります。ただメタ情報をもたせすぎるとマイクロサービスではなくサブシステムっぽくなってしまうので注意が必要です。

各システムの責務の切り分け方

マイクロサービスは外部システムの知識を減らすことで、他のシステムでも利用できるようになったり、コードがシンプルになるというメリットがあります。なので責務を切り分けたタイミングで、外部システムの知識が混ざるような構造になっていると、サブシステムのようになってしまい他のシステムで利用できないようになったり、実装が複雑になったりしてしまい、あまり意味がなくなってしまうこともあります。

外部システムの知識を汎用的に表現すること

どこまでしっかり責務を切り分けたとしても、やむを得ない事情で外部システムの知識を保持する必要がでてくることがあります。そんなときはできるだけ汎用的にメタ情報(外部システムの情報)を表現することが大切ですが、その結果万能モデルみたいになってしまいコードやデータが複雑になりすぎてしまうことがあるので、できるだけ利用しないように運用を工夫するなどの対策をしなければならないです。

終わりに

今回は課金サービスの実装した経験を書かせていただきました。自分でもこんなにも重要なプロジェクトに参加させていただけるとは思っておらず、大変貴重な経験となりました。皆様にとって少しでも役に立てるような記事になっていたらとても嬉しく思います。ありがとうございました!

Baseconnectではエンジニアメンバーを絶賛募集しております! もしご興味をお持ちいただけた方がいらっしゃいましたら、下記のリンクよりぜひカジュアルにお話しさせていただけましたら嬉しく思います!

meety.net herp.careers

Amazon SageMaker BYOCとAWS Step Functionsで推論エンドポイントを構成する

はじめに

この記事はAWS Summit Online 2020で登壇した内容ですが、テックブログのため再度まとめ直した記事です。

目的と課題

Baseconnectでは500万件ほどの企業情報を保持しており、その内140万件ほどをサービスで提供しております。 その中から利用者が欲しい情報を探し出すために、検索軸や検索性能を改善し続けています。 ただ、検索で探し出すのではなく、利用者自身が保持しているリストと突合させて情報を補完(名寄せ)したいという要望があり、それに応えるためにAIを補助的に入れることを目的としました。

進めるにあたり、以下のことを意識して進めました。

  • ゴールはどのような状態か
  • 精度の基準はどうするか
  • どのような手法で機械学習を行うか

取り組み

ゴールはどのような状態か

今回は既にサービスで提供している部分をAIでリプレースすることを目指しました。

これまでに、利用者の手持ちの営業先リストがアップロードされた際に140万件の企業情報との名寄せを実装済みでした。
そのため、ゴールとしては利用者としては意識すること無く、バックエンドをAIへリプレースすることで利便性の向上を目指しました。
精度の基準はどうするか

今後入力項目や名寄せ対象が増加されることも考えられましたが、まずは既存の仕組みでの精度よりも向上させることを基準としました。

※入力データの状態により異なるため、サンプルデータを用意 ※取り組み前の時点で既存の機能でサンプルデータを用いた精度は名寄せ率が55%ほど

どのような手法で機械学習を行うか

機械学習として教師あり、教師なし、強化学習とありますが、大きくはどれで(もしくはどの組み合わせで)取り組むかについて検討しました。(以下、検討の一部)

  • 教師あり
    • 名寄せ先となるデータが140万件あり、それらは日々増加や更新が行われている
    • 正解が140万件となるのは現実的では無さそう
  • 教師なし
    • クラスタリングを活用するのは一定の効果がありそう
    • if文などのロジックが増えてきたら、最初からロジックで作るのとあまり変わらない
  • 強化学習
    • 名寄せした結果が求めているデータに近いかどうか判断をすることで、名寄せ先のデータに変動があっても耐えられる仕組みに出来そう

ただ、ブレストの中で教師なし学習も今回の目的の中で活用は出来そうと話はしていました。 クラスタリングなども間に含めて多段的にAIを使うことも考えましたが、まずはシンプルに強化学習でどこまで精度が出せるのか取り組んでみました。

取り組み内容

具体的に取り組んだ内容です。

全体構成

Amazon SageMakerをコアに使うことを考え、そのフローをどうするかとして全体を設計しました。

当初推論はLambdaで構成しようとしてましたが、メモリの制限や起動に時間がかかる(プロビジョニングにすると高くなる)ため、Amazon SageMakerの利用を選択しました。 Amazon SageMakerはモデルの学習や推論エンドポイントの提供、またマルチエンドポイントで利用者毎のモデル提供など将来的に展開を考えられそうでした。

また、名寄せ先となるデータは変動が考えられるため、今回はデータベースを直接参照するという手段を取りました。 なお、学習・推論と検証する中でデータベースのパフォーマンスも負荷がかかりすぎないか監視しながら実施しました。

学習とDocker Imageの作成

Amazon SageMakerで推論エンドポイントを利用するために、そのコンテナ構造に合わせています。

◆ディレクトリ構成
project-root/
  ├ opt/
  │  └ ml/
  │      ├ code/
  │      │  ├ agent.py
  │      │  ├ environment.py
  │      │  ├ train.py
  │      │  ├ eval.py
  │      │  ├ handler.py … Amazon SageMakerの推論API用
  │      │  ├ nginx.conf … Amazon SageMakerの推論API用
  │      │  └ serve … Amazon SageMakerの推論API用
  │      │
  │      ├ failure/
  │      ├ input/
  │      │  ├ config/
  │      │  ├ data/ … 学習用データ
  │      │  └ eval/ … 評価用データ
  │      ├ model/ … 学習済みモデル
  │      └ output/ … 評価結果
  ├ build_and_push.sh
  ├ buildspec.yml
  ├ Dockerfile
  └ requirements.txt

Amazon SageMakerにもNotebookがあり、そこでもコーディングと実行は出来るのですが、今回は先に開発端末で試していたこともあり開発端末にて学習/評価を実行し、GitHubのPullRequestでAWS CodePipelineを利用してDocker Imageを作成(AWS CodeBuildでイメージを作成し、Amazon Elastic Container Repositoryへプッシュ)するようにしました。

Docker Imageの作成はサンプルを参考にしましたが、一部変更しました。

  • DockerHubの tensorflow/tensorflow:2.0.0-py3 を利用
    • その当時の新しいバージョンを利用したかったため
  • 学習済みモデルもDocker Imageに含める
    • パイプラインにAmazon SageMakerでトレーニングも含めることも出来たのですが、ひとまず開発端末でモデル作成まで行っていたため
  • Docker Image内にDBの接続情報も環境変数で定義
    • 秘匿情報を限定的に参照としたく、暫定的に進めたかったため
  • Docker Image内でもPythonライブラリをセットアップ
    • 後述のhttp serverもサンプルとは異なる方式を取ったため
  • tensorflow-model-server は利用しない
    • 深層強化学習で作成したモデルがtensorflow-model-serverでそのまま使えなかったため
    • 学習済みモデルのServingにはPythonのHTTServerを利用
Docker Imageの動作確認

まず開発端末で動作を確認したかったため、以下のコマンドでDocker Imageの作成とコンテナの起動を行いました。

$ docker build -t demo . --build-arg DB_HOST=”xxxxxx” --build-arg DB_USER=”xxxxxx” --build-arg DB_PASS=”xxxxxx”
$ docker run -p 8009:8009 -it demo serve

ECRの設定まで済んでいる場合は以下でも出来出来ます。

$ ./build_and_push.sh
$ docker run -it 8009:8009 -it {account}.dkr.ecr.{region}.amazonaws.com/demo:latest serve

動作イメージは以下のようになっています。サンプルで作成するとエンドポイントは決まるので、そこに対してPostmanなどで確認しました。

AWS Step Functions Data Science SDKの利用

Amazon SageMakerで推論エンドポイントを更新するまでを自動化するためにAWS CodeBuildからAWS Step Functionsをトリガーするようにパイプラインを構成しました。 そして、AWS Step Functionsを構成するためにAWS Step Functions Data Science SDKを利用しました。 SDKPythonで利用でき、notebook上で記述と実行を試しながら進めました。

AWS Step Functionsの構成としては以下となっています。

各ステップで気にした点は以下です。

[モデル] ・独自Docker Imageでは学習済みなのでトレーニングは行いませんでした ・データベースへの接続が必要なのでVPC内で構成する必要がありました ・上記2点を考慮して構成する場合はSDKではダメでAWS Lambdaを構成に含める必要がありました

[エンドポイント設定] ・モデルの指定 ・インスタンスタイプを ml.t2.medium(最小)で構成

[エンドポイント] ・既存のエンドポイントを新しいエンドポイント設定で更新するように構成

[その他] ・SDKではAWS Step FunctionsのCreate or Updateは出来なかったので別々に構成しました ・AWS Step FunctionsではエンドポイントのCreate or Updateは出来なかったので別々に構成しました ・SDKのドキュメントはstableだと詳細の記載が無かったのでlatestで見ていました

推論エンドポイントの確認

まず、Amazon SageMakerのエンドポイントはsig-v4で保護されており、通常のREST APIのように呼び出すためには手順が必要なため、boto3でクライアントを構成して推論エンドポイントの確認をするようにしました。 https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_runtime_InvokeEndpoint.html https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html

aws cliに同梱されているboto3で動作確認した サービスから利用する場合も各言語で提供されているaws-sdkのboto3で実装

呼び出しサンプル(Python)
import json 
import boto3 

sagemaker_runtime = boto3.client("sagemaker-runtime") 

data = dataset[start : start + SPLIT_SIZE] 
headers = { "Content-Type": "application/json" }
payload = { "mode": "bulk_linkage", "clients": data }

# 推論エンドポイントにリクエスト 
response = sagemaker_runtime.invoke_endpoint( 
                        EndpointName="demo-endpoint", 
                        Body=json.dumps(payload), 
                        ContentType="application/json", 
                        Accept="application/json" 
) 

decoded_response = response["Body"].read().decode() 
# bodyがstringになっているのでjson化 
result = json.loads(decoded_response) 

結果

評価と改善を繰り返すことで既存の名寄せ率が23%向上しました。(サンプルでの結果)  既存:55%  新方式:78%

その後一部改善などを行い、以下の精度になっています。
 名寄せ率:77%
 正解率:86% (後から確認したところ、取り組み時の正解率はおおよそ65%ほどでした)

また、リポジトリを分離でき、マネージドサービス上にDevOpsを構築できました。 既存の処理はプロダクトと同一リポジトリ内に実装されていたため、変更をリリースする際にもプロダクト全体のリリースとなっていた点が解消されています。 リリースの運用についても、分離する際にAWS Step Functionsなどを利用することで軽減した状態で構成することが出来ました。

さいごに

今回の取り組みでAmazon SageMakerを用いた本番環境までの流れを把握出来たので、次は監視やスケール、Amazon SageMaker上での学習もDevOpsに組み込んで最適化していくとさらに他の領域も展開しやすくなると考えています。

また、SageMakerのマルチエンドポイントは現在のサービスにもフィット出来そうなので、自社で作り上げる膨大なバックエンドのデータを用いてエンドユーザー毎に最適なAIを届けることも取り組んでいければさらに価値が出せるのではないかと思います。

名寄せの精度という点では、今回は深層強化学習を利用したところですが、他にも辞書の改善や多段的な推論など含めてアプローチできることはあるので、そういうところにも手を入れることによって向上出来るのではないでしょうか。

Baseconnectではエンジニアメンバーを絶賛募集しております! もしご興味をお持ちいただけた方がいらっしゃいましたら、下記のリンクよりぜひカジュアルにお話しさせていただけましたら嬉しく思います。

meety.net

herp.careers

Baseconnectプロダクトの技術スタックのご紹介

こんにちは、Baseconnectでエンジニアをしている米丸です。開発部門の組織改善や採用ロールを担当しています。この度、情報発信と業界貢献を目的にテックブログを始めることになりました。パチパチパチ!

Baseconnectでは現在、法人営業向けのクラウド型企業情報データベースサービスであるMusubuとその集客の役割を持つBaseconnect.in、協業企業向けのPartnershipAPIの3つのプロダクトを運用しています。

また、外からは見えませんが、社内向けにMusubu管理システムと企業情報登録システムといったものが存在します。一発目のテックブログということで、今日はこれらの弊社プロダクトの主要な技術スタックをご紹介したいと思います。

私自身はまだ昨年10月にBaseconnectに入社したところなので、社歴のあるエンジニアメンバーヒアリングして導入経緯なども含めまとめた内容になります。

前提として、Baseconnectでは特定の技術にとらわれずスピードや保守性を重視し、エンジニアで議論をしながら技術選定を行ってきました。バランスを見ながら責務を切り分けられるものを対象にマイクロサービス化を進め、サービスに合わせた技術を選定してきたことで、いくつかの技術をくみあわせた技術スタックとなっています。

技術スタックや利用ツールの全体像としたは以下のようになっています(Baseconnectのエンジニアリングについてまとめた Engineering Recruite Book より抜粋したものです。興味がある方はこちらもぜひご一読ください)。

f:id:yuri_terao:20220202183922p:plain f:id:yuri_terao:20220202183927p:plain

ここからいくつかピックアップしてご紹介します。

バックエンド

Ruby / Ruby on Rails

Baseconnectの各プロダクトではベースとして Ruby / Ruby on Rails の言語 / フレームワークが用いられています。創業当初、限られたリソースの中で短期間での開発を実現するため、Rubyが採用されました。

採用戦略として、京都の優秀な学生をインターンシップメンバーとして積極的に採用していて、初学者でも習得のしやすいRubyは相性の良さがありました(現在インターンシップメンバーの採用は当時より縮小しています)。その後も、エンジニアが多く採用しやすいことからメインの言語として利用しています。

ただ、Rubyしか使わないと決めているわけではなく、目的に応じて以下のサーバサイド言語も採用しています。

Go(Golang / Go言語)

コンパイラ言語のメリットを活かせる一部のシステムでGo(Golang / Go言語)を導入しています。具体的には、企業情報データベースサービスであるMusubu内で得られた企業情報は、Musubu内でメール配信やアプローチ管理を行えるだけでなく、CSVデータでダウンロードし利用することができるのですが、そのダウンロード時のデータエクスポート要求を処理するサブシステムで、Goが採用されています。

当時、メモリ使用量が大きくシステムを切り分けたかった事があり、その際にコンパイラ言語による処理速度の向上とライブラリなどが軽くなり立ち上げやすくなることを期待してGoを選択しました。また、当時Goの注目度が高かったというのも正直あったそうです笑。

Python

Pythonは、機械学習との相性を考慮し、一部のシステムで導入しています。一つは、Musubuサービスで提供しているマッチ度の算出に用いています。マッチ度は成約確率の高さを表す独自の指標で、成約先企業の特徴ベクトルのクラスタリングを行うことで算出しています。計算には scikit-learn とういう python機械学習ライブラリを使用し、Kmeans法でのクラスタリングを行っています。

もう一つ、企業情報の名寄せシステムにも用いられています。ユーザーが登録した営業先情報とMusubuが保有する企業情報を名寄せする(同じと思われるものを突き合わせる)システムがあり、SageMakerを利用し機械学習による精度向上をはかっています。

フロントエンド

TypeScript

当初はJavascriptで開発が開始されましたが、徐々に開発規模が大きくなっていく中で安全な開発を行うために、型定義を行えるTypeScriptを導入しました。Musubuの前身であるプロダクトにおいて、ビジネスロジック部分(Model、Service、Redux) のコードから段階的に移行してきており、現在はReact Component 等、ビジネスロジック以外のコードも TypeScript で書くようになっています。

React / Redux

Musubu のフロントエンドではReactを採用しています。また、状態管理のフレームワークとして Redux を利用しています。もともと画面描画は Ruby on Rails のview上で行っていましたが、メイン機能である企業情報検索画面のおいて、動的でリッチなUIを実現し検索体験の向上をはかるために導入されました。

フロントエンドはどんどん新しい技術が出てきてキャッチアップが難しい領域ではあると思いますが、2021年に積極的なリファクタリングを行ったことで、比較的モダンなシステムを取り入れることができていると感じています。いくつかピックアップすると、xstyledやRTK Query を導入しました。

xstyledは、styled-component を拡張したもので、tailwindow のようなCSS指定を props ベースで行えるようになっています。 わかりやすい恩恵としては、テーマカラーの管理がかなり楽になりました。RTK Query は、SWR や React Query の API を Redux で再現したもので、Reduxとの相性の良さを考慮して採用しました。

フロントエンドのリファクタリングの取り組みについては他にも行ってきたことがあるので、また別の記事でご紹介できれば嬉しいなと思います。

データベース

Neo4j

Musubu ではグラフデータベースであるNeo4jをメインDBとして利用しています。グラフデータベースの特徴として、一般的なリレーショナルデータベースにはない、ネットワーク上のデータ構造をもちデータ同士の繋がりを可視化する表現力があることがあげられます。

Baseconnectでは 「世界中のデータを繋げることで、ダイレクトに必要な情報にアクセスできる世界を作る」 ことをビジョンに掲げていて、将来的に企業データだけでなく人物データや与信データといった様々な情報を繋げる構想に向けて Neo4j を採用しました。

一方で、グラフデータベースには苦手なこともあるため、以下に紹介する他のデータベースを組み合わせることで弱いところを補完するようにしています。

Elasticsearch(Elastic Cloud)

企業情報検索システムにて、検索速度を上げるためにElasticsearch(Elastic Cloud)を用いています。Elasticsearchの利用にあたっては、複雑なデータ構成の中でいかにパフォーマンスを向上させるかというところを、試行錯誤しながら取り組んできました。

特に、直近行ったデザインリニューアルでは大幅な検索システムの改善を行ったのですが、その中の技術要件として複数のデータを組み合わせた複合検索を実現する必要があり、技術探索のフェーズを設け課題をクリアしてきました。

※ Elasticsearchは正確には検索エンジンですがグラフデータベースの補完として位置づけているため、このブログ上はデータベースに分類しています。

MySQL

メール配信システムや課金システムといったMusubuのサブシステムでは、MySQL を採用しています。グラフデータベースよりもRDBの方が、表形式での集計といったところがやりやすく管理しやすいという利点があり、採用しています。

データベース全体の課題として、正規化や実行計画などパフォーマンスに影響するところや特徴であるグラフデータベースの利点を意識した設計を、一人ひとりが高いレベルでできているとは言えずまだまだ道半ばというところがあります。

インフラ

AWS

細かいサービスを含めるとキリが無くなってしまうので、(乱暴だと自覚しつつ)ひと括りにまとめてしまいますが、サービス発信環境は基本的にAWSのサービス群を用いて構成されています。GCPMicrosoft Azure ではなくAWSをメインにしているのは、特に深い理由はなくスタートアップ向けのクレジットをもらえたからだそうです笑。同じ理由で当時はGCPも使っていたようですが、管理のしやすさのためAWSに集約しました。

Kubernetes

Baseconnectでは Amazon EKS(AWSマネージドのKubernetesコントローラー)を導入しています。VagrantからDockerに置き換える過程で導入されました。導入のきっかけは、当時コンテナを使わないことにリスクを感じたメンバーからの発案によるもので、Musubuのサブシステムである課金サービスから段階的に対応していきました。

BigQuery(GCP

BIエンジニア向けの分析用データウェアハウスとしてBigQueryを用いています。データウェアハウスにはBigQueryを使っていますが、データレイクにはS3を使っていて、GCPAWSのいいとこ取りのような使い方をしています。データ分析ソフトウェアとしてはTableauを使っていましたが、「データの民主化」を合言葉にBIエンジニア以外も気軽にデータが見れる環境を整えるため、最近 looker に移行しました。

Terraform

主にインフラ管理の権限移譲の課題を解決することを目的に、SRE/BIチームにより導入されました。インフラの設定変更や立ち上げを行う際に本番環境などはSREメンバーに権限が偏っていたため、SREチームがボトルネックになる課題がありました。絶賛進行中ですが、Terraform導入によりインフラのコード化を行い、SREメンバーはコードをレビューし許可を出すだけで実行に移せるようにフローを変更することで、ボトルネック解消をはかっています。BIでは分析基盤の属人化を解消するためにTerraformによるコード管理が使われています。

DataDog

プロダクトの成長にともないパフォーマンス監視の優先度も上がってきました。当初のCloudWatchからZabbixに移行し、直近ではDataDogへの入れ替えを行っているところです。Zabbix では、エスカレーション基準の設定や異常検知などの機能が弱く、また他のモニタリングツールも併用しているためツールの運用負荷が高いといった課題があり、統合監視ツールであるDataDogを導入することになりました。 DataDogを使ってみたメンバーの感想では、UIが直感的でめちゃくちゃ使いやすいとのことで、開発者体験としてもよさそうでした。


Baseconnectプロダクトを構成する主要な技術スタックをご紹介しました。ミドルウェアやライブラリといったレイヤーまで含めるとご紹介できる技術スタックは他にもありますが、長くなりすぎるのでここまでとします。今後も、新しい挑戦もしつつ不用意に手を広げすぎないよう、バランスをみた技術選定をおこなっていきたいです。

もし今後の技術選定に関わっていきたい方や、もう少し詳しい話を聞いてみたいという方、ぜひカジュアルにお話ししましょう! Baseconnectではエンジニアメンバーも絶賛募集しています!

meety.net

herp.careers