2019年6月27日から29日までの3日間、プログラミング言語Scalaに関するカンファレンス「ScalaMatsuri 2019 」が開催されました。
本稿では、2日目となる「カンファレンスDAY」におけるさまざまなセッションのなかから、実サービスへのScalaの応用に関する3つのセッションをピックアップして紹介します。本稿を読み、自らの携わるサービスにおけるScalaの利用に興味を持っていただけると嬉しいです。
QRコード決済サービスでのAkka Cluster利用事例
まず紹介するセッションは、根来和輝氏による「決済サービスでAkka Cluster使ってみた」です。先行リリースされた伝統的なCRUD構成のQRコード決済サービスを、Akkaをはじめとするソフトウェアスタックを使って置き換えた事例が紹介されました。
根来和輝氏
ここでポイントとなるのは、Akkaを用いたEvent Sourcing+CQRSなアーキテクチャの採用です。同氏はこの2つの用語について説明します。
まずはEvent Sourcingについて。おおざっぱに言えば、決済の開始や入金など、システムの中で起きた「イベント」を順次データストアに記録していくというものです。状態を持たず(つまりRDBMSにおけるUPDATEがなく)INSERTしか起こらないため、ロック不要で複数ノードへの分散書込みが可能という利点を持ちます。
もちろんこのようなしくみを採用することの欠点も存在します。イベントしか永続化されていないため、データの集計や一覧を作るためにコストがかかってしまうのです。QRコード決済サービスにおいては「店舗がこれまでの決済を一覧する」といったの機能も必要になってきますから、この欠点を放置しておくことはできません。
これを解決するのがCQRS(Command and Query Responsibiliry Segregation、コマンド/クエリ責務分離)というしくみです。文字通り「コマンド=書き込み」と「クエリ=読み込み」を分離するというもので、コマンドサイドのデータストア(今回で言えば、Cassandraへのイベントの書込み)からクエリサイドのデータストア(今回はMariaDBを使用)へと非同期でデータを反映し、集計や一覧が必要になった場合はクエリサイドへ問い合わせる……という形になります。
しかし、コマンドサイドからクエリサイドへのデータの反映には一定の遅延が発生するため、一時的に整合性が保たれない場合があります。結果整合性しか担保されないということです。この場合、実装しようとしているシステムが結果整合性を許容できるよう設計する必要が出てくるでしょう。
今回のプロジェクトでは、一部の場面で結果整合性を許容できない場合があったといいます。そこで登場するのがAkka Persistenceで、コマンドサイドのデータストアへのイベントの記録と同時に、遅延のない情報取得に必要な情報を持った「エンティティ」の状態を遷移させます。Akka Persistenceの持つ諸々の特長により、安全なスケールアウトが可能になり、遅延なく状態を確認できるようになりました。
以上、Event SourcingおよびCQRSのしくみについて、セッションの内容をもとに簡単に紹介しました。このあとも設計・実装にあたっての経験が述べられるなど、Akkaの活用事例として充実したセッションとなりましたので、気になる方はぜひスライドも参照してみてください。
本発表のスライド
SpotifyにおけるScioを使ったデータ処理
続いては、SpotifyのデータエンジニアであるJulien Tournay氏による「Data Processing @Spotify using Scio」というセッションを紹介します。
Julien Tournay氏
ふだんから同サービスを利用している方であればご存知のとおり、Spotifyは、新しい音楽との出会いを助けてくれる「Discover Weekly」や、よく聴くジャンルの音楽をまとめた「Daily Mix」といった、さまざまなレコメンド機能を持っています。
もちろんこうした機能の実現のためには、大量のデータをうまく扱うしくみの構築・運用が不可欠です。分析や処理をすばやく簡単に行えることはもちろん、コストも抑えなければなりませんし、GDPRへの対応などプライバシーへの配慮も必要……などなど、数多くの乗り越えるべき課題があります。同氏はこれを「データ処理は難しく、そして高価である」とまとめました。
そして、こうした課題を解決するためにSpotifyで開発されたのがScioです。Google Cloud Platformのデータ処理基盤であるCloud DataflowのScala APIといった位置付けのソフトウェアで、OSSとして公開されています。
同氏はScioのゴールとして「充実したドキュメント」「 予測性」「 パフォーマンス」「 生産性」 、そしてScalaならではの特長として「型安全性」を挙げました。Spotifyではこれらのゴールを達成するために、意欲的にScioをアップデートしつづけているのです。
セッションの後半では、Scioの最近のアップデートのなかから、シリアライズの効率化および型安全性の向上や、巨大なデータセットどうしのJOINの効率化、より使いやすく型安全なクエリ機能などを紹介しました。
月間アクティブユーザが2億人を超えるような、世界中の人たちが利用するサービスの運用において、Scalaがその特長を活かしながら積極的に活用されていることがわかるセッションとなったのではないでしょうか。
AWS LambdaでScalaをサクサク動かす
本稿で最後に紹介するのは、田所駿佑氏によるセッション「AWS LambdaでScalaをサクサク動かす」です。セッションタイトルのとおり、Amazon Web Servicesの提供するFaaS「AWS Lambda」において使い慣れたScalaを動かしたいという話なのですが……実はScalaのようなJVM系の言語とLambdaとは、( すくなくとも現在のところ)ちょっと相性が悪いのです。
というのも、Lambdaの「関数」の初回実行時(コールドスタート時)には実行環境の初期化処理が必要なのですが、JVMはほかの言語ランタイムに比べ、この起動までの時間がかかりがちであるからです。もちろん一度起動してしまえばそこはJVM、十分な処理速度が出るのですが、ひとつのリクエストをひとつのLambdaコンテナが担当するという原則から、複数同時リクエストなど実行可能なコンテナに空きがない場合にはやはりコールドスタートしなければなりません。
では、これを解決しLambdaでScalaを「サクサク動かす」ためにはどうしたらよいのでしょうか? 同氏は「Scala.jsを利用する」「 ScalaNativeを利用する」「 GraalVMを利用する」という3つの方法を紹介しました。
田所駿佑氏
まずはScala.jsの利用です。おおざっぱに言えば、Scalaで書いたコードをJavaScriptのコードに変換し、これをLambdaのNodeランタイムで動かすという形になります。次にScalaNativeの利用です。Scalaで書いたコードから(JVMのクラスファイルではなく)実行可能バイナリを生成することができるため、これをLambdaのCustom Runtimeで実行するという形になります。JVMを介する必要がないため、初期化が比較的高速に行えることになります。最後はGraalVMの利用です。GraalVMはOracleが開発した汎用仮想マシンで、Javaプログラムをコンパイルし実行可能なバイナリを生成するコンポーネントであるSubstrateVMが含まれています。これにより、ScalaNativeを使った方法と同様にCustom Runtimeにて実行できるというわけです。
そして同氏は、これら3種の方法を実際にいくつかの例で試してみた結果、いずれの方法でも大幅に高速化されたことを示しました。
しかし、もちろんそれぞれに欠点がないわけではありません。Scala.jsはコードサイズが小さく、JavaScript用のSDKが使えるためAWSサービスとの連携がしやすい一方で、NodeをScalaから扱うためのボイラープレート的なコードが必要だったり、Nodeの知識が要求されるという問題があります。また、ScalaNativeの場合は使えるライブラリに制限があったり、ビルドが非常に複雑になってしまう問題があります。GraalVMの場合も(ScalaNativeほどではないものの)ビルドが複雑になりがちなほか、パッケージサイズの削減効果がほかの方法より薄いといった難点があるようです。
同氏は実際に趣味のプロダクトにおいて、トレードオフを勘案しつつこれらの複数の方法を使い分けており、Scalaの持つパワフルさや型安全性の恩恵を受けている一方、それでもLambdaでScalaを使うのは現状では簡単なことではないとも述べました。
まだ課題が多くプロダクションへの採用は踏み込みづらい応用分野ではあるものの、起動を高速化するためのJVMの進化などにも触れられており、今後のScalaやJVMの発展にも期待が持てそうだとも感じました。特にGraal / GraalVM については最近注目が集まっているようで、同日のFlavio Brasil氏のセッション(TwitterでのGraalの活用事例の紹介!)や、アンカンファレンスでのAmitpal Singh氏のセッション(Singh氏はGraalVMの本家OracleのGraalVMエヴァンジェリストです!)など、今年のScalaMatsuriでのホットなトピックのひとつであったといえるでしょう。
このように、単なるお試しにとどまらない、懐の深いセッションだったのではないでしょうか。詳しいベンチマーク結果などについては、ぜひスライドを確認してみてください。
本発表のスライド
以上、本稿では3つのセッションを紹介しました。このほかにも、Scala言語そのものに関する深い知識を得られるセッションはもちろん、1日目のワークショップDAY、3日目のアンカンファレンスDAYも盛況であったScalaMatsuri。公式サイト では、カンファレンスおよびアンカンファレンスのセッションのうち、スライドが公開されているものもありますから、気になる方は訪れてみてください。
(写真提供=ScalaMatsuri準備委員会)