セプテーニ・オリジナルさん主催でEventStormingワークショップを行いました。

マーベリック株式会社、技術広報のリチャード 伊真岡です。11月16日土曜日にセプテーニ・オリジナルさん主催でEvent Stormingワークショップを行いました。私はそこでファシリテーター役を務めたので、当日の様子を私から見てブログに記します。ディスカッション慣れしていた参加者の皆さんに助けられ、実りの多いワークショップになりました。

readeffectiveakka.connpass.com

Event Stormingとは複数人で行うワークショップの一形態です。英語の公式サイトに情報が載っていますし、日本語の情報だとyoskhdiaさんのブログ記事に解説が載っています。

f:id:maverick-techblog:20191120013742g:plain

このGIF画像のように、ふせんをたくさん使って議論と整理を進めていきます。段々とカラフルなふせんが増えて途中を仕切る線も加えられているのがわかるでしょうか?ふせんを並べ替えたり追加したり、ふせんの集まりを区切ったりしながら、皆で議論して業務手順の理解を深めます。

今回行ったワークショップはEvent Stormingの中でもBig Pictureワークショップと呼ばれる方式で、Big Pictureという名の通り特定のビジネスの全体、業務手順どうしのつながりに対して理解を深めるためのワークショップです。その他のにはUI(ユーザインターフェイス)デザインのためのEvent Stormingワークショップや、よりソースコードでの実装を意識したワークショップがEvent Storming公式サイトで紹介されています。

今回のワークショップの題材

ワークショップではより参加者になじみがあるビジネスであろう居酒屋を題材に、具体性をもって議論ができるように以下の設定をしました。

今回の分析対象: 客席数150人~200人規模の居酒屋

やや大きめの居酒屋です。居酒屋だとメニューの豊富さやコースの有無、予約やクーポン、団体客など程よく複雑性があり、分析しがいがありそうです。

さて今回は店の注文・配膳および会計など飲食店の業務全体を支えるシステムを導入することにしました。システムとしてはこちらが参考になるかもしれません。もちろん導入すべきシステムが私達の要望を全て満たしてくれるかわからないので業務分析を行ってシステム導入のための要求を洗い出しましょう。

店の規模:
カウンター席、テーブル席、大小様々な個室があります。全部で150人〜200
人収容できます。

厨房:
厨房と接客フロアは別れています。厨房の人員が直接注文をうけることはありません。

接客:
フロアの接客担当が注文を伝票に記入していました。会計時にはフロア担当が店入り口のレジで会計します。大人数の団体客には席での会計を受け付けていました。

システム導入の目的:
店舗での業務の効率が悪く、またミスが多く高い廃棄率にもつながっていたためシステムによって業務をサポートする判断がなされました。また外国人従業員の採用も考え、できるだけ簡単に業務が覚えられることが望ましいです。

ワークショップで行った分析を紹介

まずは全体の手順、来客から精算までの全体的な業務手順をあらいだし、だんだんと部分的な手順からより詳細な手順を洗い出していきました。それらの詳細な部分的手順の例の一つとして「団体客の1stドリンク受注」を切り出してみましょう。居酒屋で客が来店したあと、一番最初に全員分のドリンクを注文するあの手順です。「ユーザーストーリー」という言葉に馴染みがあれば、これはひとつのユーザーストーリと言えそうです。

写真だと少し見づらいので改めて描画ソフトで図にしたのがこちら。私達ワークショップ参加メンバー渾身の分析結果です。

f:id:maverick-techblog:20191120014320p:plain

最初は「ドリンク注文はメニューを客に渡して、注文を受け付けるくらいじゃないのか?」と思っていました。しかし詳細にストーリーを検討すると「飲み放題コースがランク別に分かれている可能性」「遅れてくる客がいてなかなか全員揃わない」「客がドリンク注文を決めるまでやたらに時間がかかる」「ドリンクが売り切れる」など様々な場合分けでの対応が必要なことがわかり、参加者みな団体客のドリンク注文処理の複雑さに改めて感じ入っていたようでした。

そしてこれは「初回のドリンク注文受付」のみであり、ドリンクを配膳するところは別のユーザーストーリーとなりますし、2回め以降のドリンク注文、食べ物の注文や調理、配膳もそれぞれ別のユーザーストーリーです。「居酒屋へのシステム導入」という設定でワークショップを行いましたが、現実の業務手順はソフトウェアで表現できるよりはるかに複雑で高度な処理を多数行っていることがわかりました。

f:id:maverick-techblog:20191120014442j:plain

参加者の感想

ワークショップの最後には参加者の感想を共有しました。一番皆が同意したのは「この複雑な処理を毎日何度も行う人は優秀」という人類に対する畏敬の念でした。他の感想は以下にあるとおりです。

  • ふせんのドメインイベント(公式サイトやyoskhidiaさんのブログ参照)には主語を書いたほうがわかりやすい
  • 登場人物をドメインイベントを考えると同時に貼っていかないと忘れそう
  • ふせんの整理が横軸(時系列)と縦軸(参加者のセンスに任される)だけだと難しい、もうひと軸欲しいくらい
  • 対象の業務領域の経験者がいるとドメインイベント洗い出しがはかどる
  • ワークショップの中でどこまで異常系・例外的なフローを洗い出すか
  • ドメイン・イベントは過去形の動詞を用いるというルールだがこだわらなくてもよい?
  • ドメイン・イベント主体で洗い出すと抜けもれが少なくなりそう
  • 物理のふせん紙を使うと検索ができない
  • 矢印を描きたい(今回はカベに直接ふせんを貼りました)
  • 事前に思っていたより細かい点まで分析できた、その共通認識がもてた
  • 2回目を明日やったらもっと上手に分析できそう
  • 今回は来客から精算までというスコープだったがその前後にも話が広がって収集がつかない部分もあった
  • 人数が増えると情報が増えすぎてワークショップ運営が難しくなりそう
  • 食べ物は必要、リラックスできる要因になった

Event Stormingというワークショップ形式自体がおもしろく、また参加者のみなさんが積極的に参加し鋭い指摘を次々にしてくだたおかげで様々な学びがありました。数多く挙げられた感想にそれが表れています。Event Stormingはいろいろな対象の業務分析に役立ちそうなので機会を見つけて活用していきたいです。

おまけ、ふせん紙の品質について 今回ドメイン・イベント用に使っていたふせん紙が何度もはがれおちてしまいました。ドメイン・イベントはEvent Stormingワークショップの中で最も数多く、100枚や200枚のふせん紙を使うこともめずらしくないでしょう。「最もよく使うものこそ高品質で使いやすいものを」という人生の教訓まで得られた1日でした。

参加してくださった皆さまありがとうございました!

Scala関西 Summit 2019で登壇しました!

マーベリック株式会社技術広報のリチャード 伊真岡です。

Scala関西 Summit 2019に参加してきました。2日間に渡って行われたこのカンファレンスですが、1日目の感想をブログにまとめます。公式Webサイトにあるように2トラックあった中で私は一日中ずっとトラック1の発表を聞き続けました。

2019.scala-kansai.org

トラック1ではClean Architectureに関連した発表が5本中3本ありました。弊社ではClean Architecture本やエリック・エヴァンズのドメイン駆動設計本の読書会を行っている最中ですので、実践をしている開発者たちからの知見がえられるのは嬉しかったです。

Dependent method types を利用した軽量Clean Architecture の紹介

最初のトークはがくぞさん。(スライド)

難しい抽象化の概念と捉えられがちなモナドにたよることなく、Tagless FinalやFree Monadなどで実現される利点をDependent method typeによって得ようという発表でした。

Scalaは高度な抽象化ができるからといって、モナドという理解のハードルが高いと思われがちな概念を取り入れるより、Javaに馴染みの深いエンジニアにもその延長線で理解できる技術を使うのはメリットがありそうです。

ソースコード全体に関わるかつ短期では変更しづらい方針なので、Tagless Finalを採用するかFree Monadにするか、Dependent method typeかは開発リーダーの腕が問われそうです。技術の取り入れやすさ、教育のしやすさ、メンテナンスコストなど様々なことを年単位で見通すという難しい判断になるでしょう。

Java 5.0時代の非同期処理技術から学び直すScala/Java非同期処理

次は私の発表。(スライド)

非同期処理はある程度時間をとって学ばないと何がなんだかわからない分野なので、いったんJava 5.0の時代までもどって、そこから現代の技術までたどると大きな流れが見えます。それが非同期処理理解の助けになりそうです、という発表でした。

Chatworkでリアクション機能をリリースした話

勝野さんの発表。(スライド)

Chatworkのリアクション機能楽しいですよね!今回はリアクション機能開発で行われていた性能要件分析とそれをもとにした技術選定、さらにベンチマーキングを行って詳細を検討する話でした。

特にベンチマーキングを行って「やってみないとわからないつまづき」(ベンチマーク環境でのAWSネットワーク構成の影響など)をひとつずつ潰して解決策を発見していく過程は、実践した人にしか提供できない価値ある情報だと思いました。

大きなシステムの改変を性能要件を見極めながら設計・開発していくのは非常に難しい一方楽しそうな仕事ですね。わたしもいつかそういう仕事をやってみたいと思える発表でした。

資産運用スタートアップの開発で採用した、PlayによるClean Arcitectureでの設計・開発事例

株式会社クラウドポートの若松さん(スライド)。資産運用サービスをたった3人のエンジニアで開発しているということにおどろいたのですが、少人数で効率良い開発を行うためにClean Architectureをどう活かしているかという発表でした。

Clean Architecture本に書いてあるようなメリットをうまく生かして少人数での開発を効率化している様子が伺える発表でした。

金融サービスの実装が複雑というのはそのとおりで、私が証券会社にいたときも感じていました。関連する規制・法律や業界慣習などが多岐にわたり複雑というのが一つの理由ですが、後のFolioさんの発表でも言及されますが金融関連のサービスは複雑になりがちです。

FOLIO のマイクロサービス in Action

最後はFolioのむらみんさんの発表(スライド)。むらみんさんの発表はスライドがきれいで発表慣れもしているのか話し方がわかりやすいです。

こちらもClean Architectureを絡めた話。Clean Architectureを使って層の分離をたもつことで、DDDの知識の蒸留のサイクルを回し続けるといった内容の前半と、マイクロサービス構成をFolioではどのように実現しているかという内容の後半に分かれていました。

Folio流の実践は工夫がたくさんあり、また発表からその工夫によって改善のサイクルがうまくまわっていることがうかがえる素敵な発表でした。

2日目はアンカンファレンスでした。アンカンファレンスの内容はこちらのブログには載せませんがツイッターのハッシュタグ #scala_ksでアンカンファレンスを含むScala 関西 Summitの様子がわかると思います。

楽しいカンファレンスでした!!

Chatworkさんでステートフルなサーバーレス技術である「CloudState」紹介ビデオの上映会を開催しました

マーベリック株式会社、技術広報のリチャード 伊真岡です。

10月4日金曜日にChatworkさんのオフィスで、ステートフルなサーバーレス技術、オープンソース・プロダクトであるCloudStateの上映会を行いました。

Chatworkさんには突然の申し出にもかかわらず快く会場を提供していただき、また上映会のあとも様々な知見を共有していただきました。ありがとうございます!

youtu.be

上映会の様子

上映会ではビデオを理解するために必要な背景知識の種類や量が多く、既存のサーバーレス技術の背景や現状、KubernetesやKnative、gRPC、そしてAkkaといった分野の理解が要求される内容でした。しかし参加者の皆さんは真剣に見入っていて、上映会のあとの感想の共有でも活発な意見交換がなされました。

f:id:maverick-techblog:20191008121826j:plain

かとじゅんさんによるAkka自体の紹介もあり、それがCloudStateのUser Functionsとどう組み合わされるのか?CloudStateの謳うメリット、とくに費用対効果の高さは本当に実現できるのか?私が事前にもっていた疑問や印象もぶつけてみて、わかっている部分とこれから検証していきたい部分の境界がよりはっきりしてきたと思います。

CloudStateとステートフルなサーバーレス技術の紹介

connpass.com

さてここからは、以下は上記Connpassでのイベント説明からの引用ですがステートフルなサーバーレス技術の必要性、そしてCloudStateの紹介をします。

FaaS == サーバーレス ???

サーバーレスはサーバーの管理・運用業務に頭を悩ませることなくシステム(の一部)を構成することが出来、開発者たちからも歓迎され、未来のクラウド技術の主軸を担うとの意見もあるほど注目されています。現状はサーバーレスの主な利用例としてはFaas(Function as a Service)形式のものがあり、マネージドなFaaSの代表格としてはAmazon Lambda、Google Functions、Firebase Functions等が挙げられるでしょう。

参考資料: サーバーレスアーキテクチャ再考 - ゆううきブログ

FaaSを例に取るとその主なメリットは:

  • 費用対効果が高い
  • 従量課金制である
  • 様々な自動化が容易である
  • 開発者体験(DX)を向上させる仕組みに富む
  • シンプルな構成でシステム開発時間を短縮できる

などが挙げられます。メリットだけをみるとまるで夢の技術のようですが、FaaSにはもちろん弱点もあります。それは:

一般用途のアプリケーションを構築するには制限が強すぎる

ということです。FaaSではFaaSに向いたシステムしか構築することが出来ず、そしてFaaSに向いたシステムとは思ったよりも範囲が狭いものであるということです。例えば、Webサービスを展開している多くの企業にとってそのバックエンドを全てFaaSに移すことは現実的ではないかもしれません。それを阻む主な要因としては:

  • Functionの寿命が短い
  • システム内部データの取得のために毎回データストアに問い合わせなくてはならない

などがあります。 多くの開発者は「サーバーレスはそういうもの」として受け入れていたのではないでしょうか。しかし、もしこれらの制限にとらわれないサーバーレス技術が利用可能だとしたらどうでしょう?つまりFaaSとは異なる制限をもつ別の種類のサーバーレス技術があるとしたらどうでしょう?

CloudState.io

CloudStateはLightbendが2019年8月に立ち上げた新しいオープンソース・プロジェクトです。 その目的はまさに上記で上げた問題点の解決、「クラウドの未来」であるサーバーレスの可能性を広げるためのプロジェクトです。

CloudStateという名のとおり、このプロジェクトではサーバーレス・システムでの分散ステートを扱います。AakkaのCluster、Event SourcingやCRDT、Kubernetes、 Knative、gRPCなどの技術を利用しサーバーレス・システム上での分散ステート管理に対する解決策を提供します。

感想

あらためて、参加者の皆さんのご協力で楽しく有意義な上映会になりました。上映会を終えてからもこのCloudStateという技術、そしてステートフルなサーバーレス技術という領域は非常に面白い分野なので、私は追いかけていくつもりです。

社内ドメインモデリング・ワークショップを開催しました

マーベリック技術広報のリチャード伊真岡です。8月26日月曜日に弊社内でドメインモデリング・ワークショップを行いました!当日の様子を紹介します。

f:id:maverick-techblog:20190903131621p:plain

題材

今回は映画館の券売・発券システムを題材に以下のような架空の設定を元にワークショップを進めました。

https://github.com/richardimaoka/ddd_hanson

ある映画館ウェブサイト https://cinemacity.co.jp/ の券売システムと、映画館においてある券売機システムを統合することになりました。我々はその統合システムの分析・開発をするプロジェクトを任されました。チケットの購入から発券にまつわるルールと業務フローを分析・モデリングしましょう。

準備段階当初はツイッター上で盛り上がった #チケット料金モデリング を参考にワークショップを行うつもりでした。しかし私個人の好みもあり、今回に限ってはチケット料金モデリングだけを扱うよりは、券売システム全体を考えるほうがドメインモデリングの醍醐味を味わえるのではないかと考え、上記のような題材を設定しました。

ユーザーストーリー分析

いきなりドメインモデリングに入る前にチケット販売・発券の業務フローを理解するためユーザーストーリー分析を行いました。理解が深まった後にドメインモデリングを行った方が議論がスムーズになるだろうと考えたからです。

こちらはユーザーストーリー分析で貼った付箋のすべてです。

f:id:maverick-techblog:20190903131654p:plain

  • 見たい映画を決める(スタート)
  • シアターの席に座る(ゴール)

という2つの時点を定め、それらをつなぐ動作(水色の付箋)を洗いだす事から始めていきました。

手法の詳細は省略しますがオライリーの「ユーザーストーリー・マッピング」という本に載っている印象的な言葉を紹介します。

  • ストーリーを使う目的は、良いストーリーを書くことではない
  • ストーリーを作る本当の目的は、共通理解をつかむことだ

以下の画像は書籍「ユーザーストーリー・マッピング」から引用したものです。左上にあるようにみんなが「合意できた」と思ったことも、よくよく話してみるとそれぞれが違ったことを考えていたということがあります。そういった認識の齟齬を防ぐため、話し合いを通してほんとうに共通した理解を得られるようにすることが重要だということが書籍では語られています。

f:id:maverick-techblog:20190903131915p:plain

私リチャードはすっかりこの考えに感化されてしまい、ワークショップでも10回以上共通理解、共通理解と繰り返す人になっていました。若干めんどくさい人ですね。

ドメインモデリング

ワークショップの後半はいよいよ本題であるドメインモデリングにみんなで取り組みました。ユーザーストーリー分析から「オブジェクト」を抜き出し、どの属性がどのオブジェクトに属するか議論をしていきました。

https://cinemacity.co.jp/ticket/ を見ていただくと料金体系だけでもなかなか複雑であることがわかるかと思います。今回の題材はチケット料金の計算ロジックをコードに落とし込めばよいというわけではないので「チケット料金計算に必要な属性を全部パラメタとして突っ込んで力技で金額を返すメソッド」を実装すればよいわけではありません。券売システム全体を考えどのオブジェクトがどの属性をもつか設計しなくてはなりませんでした。

ドメインモデリングを始めると議論は盛り上がり、以下のような点をはじめとしていい意味で意見が割れ、議論を深めるに連れ券売システムというドメインにたいして理解が深まっていきました:

  • 映画を見る場所をなんと呼ぶ?シアター?スクリーン?
  • 映画館オブジェクトはチケット販売システムには不要なんじゃない?
  • 18歳未満は見られない映画がある
    • R18指定の映画がある
    • 東京都の条例により、18歳未満の方は、終映時刻が23:00を過ぎる回は、保護者同伴の場合でも入場はできない
  • 料金はメソッドの戻り値として計算されるべきじゃないか?
    • いや計算された値は固定されないと支払い後料金が変わるのはおかしい
  • チケットの「予約オブジェクト」をつくろう
    • 「予約オブジェクト」は「チケット」と同一なのではないか?
    • いや、一回の予約で一人が友人の分もまとめてチケットを予約するかも

議論が白熱する中、何度か洞察の鋭い意見を出していた参加者の一人がチケットの券面のスクリーンショットをみつけました。項目が多い…!

f:id:maverick-techblog:20190903132047p:plain

これらすべてを「チケットオブジェクト」に結びつけてしまうと大変な巨大オブジェクトが出来上がってしまうので、できるだけきれいにしようとしたのがこちら。

f:id:maverick-techblog:20190903132416p:plain

オレンジの付箋はオブジェクト名、水色の付箋はオブジェクトの属性、黄色はメソッド(時間がなくて網羅できませんでした)、そしてピンクの付箋は疑問点やモデリングが複雑そうな項目を忘れないようにメモとして残したものです。

感想

複数人で議論を深めながら「映画チケット発券」に対する共通理解を育てていくというのが体験を伴って学べたのが何よりの収穫でした。

今回はユーザーストーリー分析とドメインモデリング含めて3時間だったので、ドメインモデリングが完了するところまでは想定しておらず、またソースコードに起こす時間もとっていませんでした。個人的にはあとでソースコードを書く時間をとって考察を深めてみるつもりです。

実際の業務のなかでドメインモデリングを活かすにはソースコード、ドメインモデル、さらにはユーザーストーリーも含めてなんども行ったり来たりしながら議論を深めて共通理解を育てていくのが良いのかなと思います。

参加者からも好評だったようで第2回社内ドメインモデリング・ワークショップをいま計画中です!

atWareさんで出張Akkaワークショップを行ってきました

マーベリックの技術広報リチャード伊真岡です。

今回横浜にあるatWareさんのオフィスでAkkaワークショップで行ってきました。atWareさんはScalaMatsuriのスポンサーやScala先駆者インタビューなど様々な活動を行い会社としてScalaコミュニティ、その他技術コミュニティの発展に貢献されています。またかとじゅんさんを講師として招いてドメインモデリングワークショップAkkaハンズオンも開催するなど社内での技術教育・啓蒙にも力を入れています。

今回はatWareさんに私の知り合いがいたことから実現したワークショップ。私が以前にOSS貢献をしていたころの経験談と、それから私の得意分野であるAkkaについてお話しさせていただきました。

さてこちらはatWareさんのオフィス。WeWorkオーシャンゲートみなとみらい内にあり、とてもキレイなオフィスでした。

f:id:maverick-techblog:20190828123819p:plain

前半はOSS活動について。私リチャードはakkaというJava/ScalaのOSSに100件ほどコントリビュートしたことがあるので、その時の経験をもとにOSS活動に対して私が持っている心構えを紹介しました。私自身の考えをお話しましたが、とはいえOSS活動というのは人それぞれの形があるので、GitHubにpull requestを送らなくてもOSSの普及や発展に少しでも間接的であっても貢献できればそれは立派なOSS活動だと私は思います。atWareの皆さんにはOSSにすでに貢献したことがある方もいましたし、今後のOSS活動に意欲的な方がいたようなのでそれぞれのみなさんが満足のいくOSS貢献の形を見つけていただければ嬉しいです。

f:id:maverick-techblog:20190828123926p:plain

後半はAkkaについて。よくある「Akka入門」という話に終始せず、より踏み込んだ中級者向けの内容になるように意識しました。

akkaはすでにモジュールの数が多く「なぜこんなに沢山あるのか…」と感じてしまうかもしれませんが、akkaの発展の歴史を振り返ればそれぞれのモジュールが当時その時点で課題となったことを解決するために作られたことがわかります。その歴史を把握することで各モジュールの関係性が明確になるのではと考え今回の内容に組み込みました。

それから私見とLightbend社のFast Data Platform構想を交えて「Akkaを導入するにはどういうパターンがあるか?」という点にまつわる話もしました。Akkaは学習負荷が小さくはないツールなので、Akkaの全てのツールを取り入れてシステムを作るのは苦労する面があるとおもいます。そこで最初からAkkaを最大限活かす方向性の導入方法と、部分的・あるいは段階的にAkkaを取り入れるパターンについて紹介しました。

とはいえせっかくAkkaに興味をもってくれたなら、やはりその良さを最大限活かすAkka actor + persistence + cluster-sharding を使ったフルパワー(?)構成で使うAkkaの力を知ってほしいと思っています。そこでいずれAkka Clusteringハンズオンをやりたい、そこで練習をとおしてAkkaの真の実力を体感してほしいというお話をしました。

勉強会の後は懇親会を開いていただきました。VimConfスタッフをしているasanoさんと話してカンファレンス・技術コミュニティ話で盛り上がったのですが、atWareさんは2017年から継続的にVimConfのスポンサーをしていて2018年は唯一のプラチナスポンサーだった会社です!Vimユーザの皆さんにはとても頼もしい会社ですね!

vimconf.org

今回の勉強会について楽しく振り返ることができ、また今後私が技術広報として企画していきたいことについても相談に乗っていただき非常に有意義でたのしい一日でした。atWareさんとマーベリックの絆も深まったことでお互い技術コミュニティに今後一層貢献していきたいと思います。

マーベリックのDSPプロダクトSphereのバックエンド技術構成

マーベリック技術広報担当のリチャード伊真岡です。

今回は弊社のDSP(Demand Side Platform)プロダクトであるSphereバックエンドの技術構成を紹介いたします。Sphereも弊社のもう一つのプロダクトであるCirquaと同様、バックエンドはScalaで書かれています。

採用技術: Scala, Finagle, PlayFramework, ScalikeJDBC, MariaDB, Redis, Kafka, Spark, HDFS, 等

DSPとは

DSPとはDemand Side Platformの省略で、広告枠を「要求する・買う」側つまり広告主のためのサービスです。DSPと対になるサービスがSSP、Supply Side Platformと呼ばれこちらは広告枠を「供給する・売る」側、つまりWebサイトやアプリを運用するメディア側向けのサービスです。

どちらがDemandでどちらがSupplyかわかりづらいかもしれませんが、アドテクノロジーの世界では商品としての広告枠に対してのDemandとSupplyという意味でDSPとSSPという呼び方になっています。

DSPとSSPは別の会社が運営する全く別のサービスの場合もありますが、中には一つの会社がDSPとSSP両方のサービスを運営していることもあります。

さて、DSPとSSPがどう連携しているかをお見せするためにこちらをご覧いただきたいと思います。弊社デザイナ坂東とエンジニアが協力して作成しScalaMatsuri期間中に公開した「あなたのブラウザに広告がでる仕組み」です。この記事では簡単のためADNW(アドネットワーク)に関しては説明しませんが、DSPとSSPが連携することによって広告主の出向した広告がメディアの広告枠に表示される様子を見て取れるかと思います。(今回はアニメーションで表現していますが実際にはLEDデバイスを経路に沿ってひからせるIoTデバイスとして制作しました。)

f:id:maverick-techblog:20190819120115g:plain

Sphereの処理の流れ

DSPとSSPが連携して広告表示する場合、メディアの運営するWebページの広告枠に対してオークションが行われて表示される広告が決定されます。そのオークションに関わる処理の流れをSphereの視点から詳しく見ていきましょう。

f:id:maverick-techblog:20190819121252p:plain

まず、訪問者がメディアの運営するWebサイトを閲覧すると、SSPに対して広告要求が送られます。Sphereは入札サーバを通してSSPから入札要求を受け取り、入札要求に付属するデータに基づいて入札に参加するかどうかを自動で判断します。そして参加する場合入札サーバはSSPに対して入札を送信します。

f:id:maverick-techblog:20190819121334p:plain

ここでSSPはSphereにだけ入札要求を送るのではなくオークションを行うため複数のDSPサービスに対して入札要求を送っています。各DSPサービスはSphereと同様に入札参加すると判断した場合に入札をSSPに対して返します。

f:id:maverick-techblog:20190819121359p:plain

Sphereが広告枠を落札できたときはSphereから送信された広告が表示されます。ただし広告の画像は入札データの中に含まれるのではなく、Sphere内の別の画像配信サーバーから読み込まれます。 アドテクノロジーの世界では広告が表示されたことを「インプレッション」とよび計測の対象としています。Sphereの場合広告に含まれるタグによってトラッキングサーバにインプレッションのデータを送り、さらに訪問者が広告をクリックしてリンク先の広告主のページに遷移したら「広告クリック」を計測します。インプレッションや広告クリックなどの広告効果測定のためのデータはすべてトラッキングサーバからKafkaに送られ、その後HDFSに保存されます。 この記事では詳しく説明しませんが、Sphereの機械学習システムはこのHDFS上のデータに対してSparkジョブを走らせることが出来、その結果が広告配信の最適化などに利用されています。

Sphereの技術構成

ここからはSphereの技術構成を紹介します。

f:id:maverick-techblog:20190819121449p:plain

入札・トラッキングサーバはScalaで実装されていて、そのバックエンドにはRedis、さらにScalikeJDBCを通してアクセスするMariaDBがあります。また先程述べたように、トラッキングサーバーからは広告効果測定のためのデータがKafkaへ送られています。機械学習システムについてはこの記事では大まかにしか触れませんが、いずれ別の形で詳しく紹介するつもりです。

f:id:maverick-techblog:20190819121532p:plain

入札サーバはおよそ60インスタンス、トラッキングサーバはおよそ30インスタンスが同時に走っています。これらSphereのサーバー群はほぼ全てオンプレミスのデータセンタ内に配置されていて、機械学習用のインスタンスなどを含めると全体でのサーバーの数は約270台にもなり、そのサーバー郡の監視にはZabbixを利用しています。

実際にはこの記事で紹介する以外にも様々な処理が行われており、機械学習システムがバッチ処理の結果をMariaDBに書き込むケースも有ります。複雑なビジネスの要求に答えるため年月をかけて注意深く実装されたシステムがSphereの面白いところだと思います。

バックエンドはScala!インフィード広告プロダクトCirquaのバックエンド技術構成を紹介します

マーベリック技術広報のリチャード伊真岡です。

今回は弊社のインフィード広告プロダクトCirquaの技術構成及び技術的課題の一部を紹介したいと思います。CirquaのバックエンドはScala、フロントエンドはTypeScriptで書かれており、今回の記事ではバックエンドの紹介をします。

採用技術: Scala, Finagle, PlayFramework, ScalikeJDBC, Amazon RDS(MariaDB), Amazon ElastiCache(Redis), Fluentd, Amazon S3, Amazon Athena 等

Cirquaの仕組み紹介

Cirquaはインフィード広告と呼ばれる種類の広告を主に扱うプロダクトです。

f:id:maverick-techblog:20190801145339p:plain

インフィード広告とはSNSのニュースフィードに代表されるようなタイムライン状に表示されるコンテンツの中に表示される広告を指していて、「フィード」の「中」に表示されるので「インフィード広告」と呼ばれています。

技術構成の紹介の前に、まずCirquaの仕組みを簡単に紹介したいと思います。以下では訪問者がCirquaを導入しているメディアのWebサイトを閲覧したときの動作を簡略化して説明します。

f:id:maverick-techblog:20190801145324p:plain

訪問者がWebページを閲覧すると、ページのHTMLに埋め込まれたCirquaのScriptタグが読み込まれます。そのScriptタグによってマーベリック側のネットワークにある広告配信サーバから広告を取得しWebページ内にインフィード広告が表示されます。

f:id:maverick-techblog:20190801145345p:plain

インフィード広告が表示された時点で訪問者が広告を表示したことがカウントされ、それをアドテクの世界では「インプレッション」とよんで計測しています。インプレッションの発生はトラッキングサーバに送信され、更に訪問者がその広告をクリックして広告主のウェブサイトへ遷移した場合その「クリック」をトラッキングサーバに送信しそれも計測しています。

またトラッキングサーバ側は集計処理も行うので以下のデータ集計用のフローにもつながっています。 計測、集計したデータは機械学習チームにも渡され、広告配信の配信ロジックに利用されます。

f:id:maverick-techblog:20190801145343p:plain

Cirquaのバックエンドで採用している技術スタックを以下のように図示してみました。Webページから送信されたインプレッションとクリックのデータはfluentdを介してAmazon S3に送られ、バッチ処理が定期的に走ってAmazon Athenaを用いて集計しています。Amazon Athenaを使うとS3にため込むデータの形式さえ整えれば集計処理が手軽にできるので運用はとても楽です。

Cirquaバックエンドの技術スタックを以下のように図示してみました。

f:id:maverick-techblog:20190801145352p:plain

広告配信サーバはScalaで書かれており、非同期処理部分はFinagleを用いて実装しています。HTTPのRequest/Responseのパラダイムに従って素直に非同期処理が書ける点がCirquaチームがFinagleに感じる魅力です。トラッキングサーバはPlayFrameworkを使っています。このFinagleとPlayFrameworkの使い分けはチームの両フレームワークに対する慣れや過去のプロダクト開発における知見の積み重ねなどから総合的に判断して使い分けをしています。バックエンドのデータベースはRDS(MariaDB)を使っていてScala側からはScalikeJDBCを使って接続しています。ScalikeJDBCはSQLを素直に書けるところが使いやすいライブラリだと感じています。

バッチ処理については先進的な試みとして一部でScala ZIOを取り入れています。Scala ZIOは関数型を活かしつつもオブジェクト志向プログラマにも馴染みがあるDependency Injectionを取り入れており新たに学ぶ概念が少なくわかりやすいとされています。非同期処理がきれいに書けるところがとても良いと感じています。バッチ処理は広告配信サーバとトラッキングサーバ本体とは切り離されているのでScala ZIOの導入がしやすく、まずはバッチ処理から取り入れてみることにしました。

開発チームの構成

Cirqua開発チームの構成は:

  • バックエンドエンジニア2人
  • フロントエンドエンジニア3人
  • プロダクトオーナー1人

となっており、これ以外にインフラエンジニアとCirquaを含む複数プロダクトのサーバーやネットワークを管理し、Quality Assuranceチームが同じように複数プロダクトを担当しています。

Ciruquaチームでは毎週のリリースをdevelop環境は木曜、production環境は月曜日にリリースを行っています。 develop環境のリリース後はQuality Assuranceチームを交え全員で画面を触り、新機能のチェックを行います。 こうすることで常にチーム全員がプロダクトの新機能、いつどの機能が入ったかなどを把握できる状況を作っています。

リリースはslack botから実行できるよう自動化されています。少人数チームではContinuous Deliveryの仕組みは必須ですね。

今取り組んでいる技術的課題

現在CirquaのインフラについてはAmazon EC2上でそのままプロセスを走らせる形からKubernetesを使った運用に移せないか検証を行っている最中です。もちろん導入が上手くいけばKubernetesエコシステムを活かしたインフラ運用、そしてアプリケーションエンジニアがインフラ運用の一部を担当できるというメリットを狙ってのものですが、なによりKubernetesを触るのはエンジニアとして楽しいですよね!Kubernetesに伴う負担を可能な限り軽減しつつ、楽しさを存分に活かせる導入方法を現在模索中です。

さらにCirquaシステムは一部リファクタリングを行っており、Domain Driven Design的な設計手法を取り入れてアプリケーションのコア部分を書き直しています。scala言語の表現力の高さを活かし、コアドメインを宣言的かつ表現力豊かに再定義することができています。チームメンバは社内で開催されているDomain Driven Design読書会にも参加し、Domain Driven Designに対する理解を深める努力を行っています。