注目しているサーバレスサービス

佃松三郎氏(以下、佃):次ですね。「今注目しているサーバレスのサービスがあれば教えてください」。

丹羽一智氏(以下、丹羽):サーバレスのサービスというと定義が難しいですけど。「サーバレスで開発されたサービス」なのか「サーバレス開発で使えるサービス」なのかというところで定義が難しいですが、そもそも世の中にフルサーバレスで動いているアプリケーションはほとんどないのが現状なので、「開発で便利なもの」という意味だと、何回か推しているんですが、Datadogがすごくおすすめです。

普通のアプリケーション開発をしていてもそうだと思いますが、「ログの扱いをどうしよう?」ということがずっと課題になっていて、Fluentdで集めてS3に置くということを、みんながんばってやっています。

DatadogにはLogsというサービスがあって、特定のポートにあるサービス、IP・ポートにアクセスして、そこにログデータをひたすら投げ込むと、それがどんどん蓄積されていくというサービスがあるんですね。

なにがうれしいかというと、どのコンテナで動いているかは一切関係なく、どんどんDatadogにログがたまっていくわけです。

しかも、そのログにはいろいろなタグ付けができるので、「このマイクロサービスのログです」とか「プロダクション環境です」「テスト環境です」みたいなタグをつけて、Datadog Logsではそれを使って検索ができて、しかも絞り込みもめちゃくちゃ速いです。

なので、マイクロサービスで作っていたりしたら、「このアクセスはどう取ってたんだっけ?」みたいなものも追いかけられるようになっていますし、どのコンテナで動くかわからないサーバレスやマイクロサービス的なものも、いろんな用途でDatadog Logsが使えると思っています。これは非常におすすめですね。

私もサーバレスで開発を始めてもう2〜3年経ちますが、CircleCIのビルドコンテナに対してしかSSHしていなくて、もうそれ以外の用途で一切SSHしていないんですね。

だいたい、SSHする時は障害対応かログを見たいときなんですが、そもそもサーバレスでやっていると障害対応も関係ないし、ログを見たい時もこうやってDatadogで流しておけば、Datadogに行ってログを見るみたいなかたちになっているので、すごくいいサービスだと思いますね。

サーバレスを始めようと思ったきっかけ

:それでは次です。「DDD、サーバレス、『これでやろう!』と思ったきっかけや経緯を教えてください」。

「丹羽さんといえば」「増田さんといえば」というところで、おそらくそれに特化してやろうと思われていると思います。そうした「これでやろう」と思ったきっかけについての質問だと思いますが、「これに賭けてみよう」というか、そういったきっかけや経緯を教えてください。

丹羽:私がサーバレスでいこうと思った理由はたった1つで、もうサーバ側が落ちただなんだとか、一切考えたくないんですね。「誰かががんばってくれるならがんばってほしい」という、この一択でした。

「私はコードを書いてデプロイしておくから、あとはいいように動かしていね」ということができるのが、ほぼFunction as a Serviceのみだった。スケールしたいときはなにも考えなくても勝手にスケールするし、自分はアプリのコードを書くことに専念できるということで、サーバレスが自分の欲望を満たしてくれたという点です。

あとは、先ほど言ったように、汎用的なゲームサーバをみんなに提供したいとずっと思っていましたが、コスト面で難しいと考えていました。それが、実行時間課金やリクエストI/O課金といったコンポーネントが増えてきて、これを組み合わせることで、非常にリーズナブルというか、「使っていないときには費用が発生しない」という料金モデルで動かせるということで、「これはサーバレスでいくしかない」となりました。

:自分の思うソリューションとか、嫌なところを解決してくれる。「だから、これはこの先絶対に伸びるぞ」という感覚ですよね。

丹羽:そうですね。Function as a Serviceに関しては、コンテナにすごく押されている分野だとは思います。

:押されてますね(笑)。

丹羽:ですが、私自身はすごくハッピーなんです。障害対応も一切していないけど、ちゃんとサービスが動き続けているし、SSHもしなくてよくなったし、すごく素直にコードを書くことに専念できているという意味でハッピーなので、いずれみんなもそれに気づくといいなとは思いますね。

増田亨氏(以下、増田):俺、実は5年前からサーバレスだね。

丹羽:そうなんですか?

増田:うん。プログラム書いて、ローカルで動いて、完成したって自分で思うじゃん。あとは投げると、みんなよしなに……。

丹羽:人力サーバレス(笑)。

:人力サーバレス(笑)。

増田:デプロイしてスケールアウトもしてくれて。「5年ぐらい前から、俺、そういえばサーバレス開発ばっかりやってるなぁ」って。

:でも、誰かがやってくれている……(笑)。

増田:まぁまぁ、AWSなのか属人なのかは置いておいて、私から見ると丹羽さんが言ってるサーバレスの環境の気持ちよさというのは、すごくわかるような気がする(笑)。

丹羽:(笑)。

増田:だから、人に迷惑かけたり、そこにコストをかけるんじゃなくて、環境として用意されていたらいいよなと思います。

ドメイン駆動設計を評価したきっかけ

増田:ドメイン駆動設計についてなんですが、直接のきっかけはすごくはっきりしています。

火を吹いちゃった、とんでもないプロジェクトがあって、火を吹いたあとの焼け野原みたいな状態で私が呼ばれて、「とにかく、なにしてもいいからなんとかしてくれ」ということでやったときに、ドメイン駆動設計じゃなくてリファクタリング……マーチン・ファウラーの書いてる『リファクタリング』の嫌な匂いだらけなわけですよ。どこを切っても嫌な匂いしかしない。

本当にバグだらけのシステムなので、破壊的なリファクタリングをガンガンやって、ちょっとしたテストをしただけでリリースしても怒られない状況だったんですね。そのぐらいひどかった。ビジネス的にはありえないようなバグが起きていて、仮に直してエラーが出ても、今の状態を防止できるんだったらそれでもいいみたいな、すごい状態だった時があったんですよ。

:それでリリースされていたんでしたっけ?

増田:うん、リリースしましたよ。朝、昼、晩。ものすごく簡単なことを言えば……ゲームの例え話がいいのかな。実際になにが起きてたかというと、A社さん・B社さん・C社さんでマルチクライアントで使われるASPなんですが、B社さんの機密情報がA社さんに見えちゃうという状態でした。

:恐ろしい(笑)。

増田:もう、そんなのはビジネス的にアウトになってる状態です。「なにしてもいいよ」と、「そんなのをなんでリリースしたんだ?」って話はあったんですけどね。

その時に、問題箇所から集中的にリファクタリングをやっていきました。『リファクタリング』に書かれている内容、「こんな嫌な匂いに対しては、こうやって整理していくと、こうなるよ」ということを実行して、それで相当手応えを感じていました。その時にマーチン・ファウラーの「エヴァンスって男が『ドメイン駆動設計』という本を書いていて、これは相当期待できるよ」という前振りがあって、一番最初に興味を持ったきっかけはそれですね。

『ドメイン駆動設計』を最初に読んだ時に、「オブジェクト指向のコミュニティの哲学を言語化したものです」と書いてあって、「ああ、ダメだ、こりゃ」って。僕は当時オブジェクト指向派じゃなかったので、「オブジェクト指向で現実的なプログラム、アプリケーションを作るというのはアプローチとしてどうなの?」と、非常な懐疑的な状態でした。

ところが、『ドメイン駆動設計』を何度も読んで、現場で自分たちが困っている問題に対して『ドメイン駆動設計』に書かれているようなアプローチをちょっと試してみたら、けっこういい感じで改善できたりと、味をしめることが少し増えてきました。

そうやっているうちにだんだん「これはなかなかおもしろいな」と思い、『リファクタリング』や『ドメイン駆動設計』で、どこに手応えを感じているかを整理し直してみたら、手続き的なモジュール構造ではなく、値の種類ごとにモジュールを分けて組み立てることによって柔軟性が出せるというところで、「これはすごいな」と思いました。

今までのオブジェクト指向の説明は、基本的には非常にテクニカルだったり、逆に言えば概念論だったり、実際のコードをどう作って、それが業務アプリケーションにどう活きるか、全部つながってなかったんですが、エヴァンスの本を読んでいるうちにそのピースがうまくつながってきました。あるいは、その取捨選択ができるようになってきました。

実際にやってきた中で手応えがあったので、それを続けてきたということですね。そういう意味では、本を読んだ時には「これだ!」とは思いませんでした。むしろ逆です。

:ですから、そういった技術とか、次のなにかを感じさせるものがあったというお話ですよね。すばらしいです。みなさんも、ぜひそういうものに出会えると……私はまだ出会っていません。

(一同笑)

サーバレスとコンテナについて

:では、次の質問。「コンテナは嫌いですか」。

増田:おお〜。

:これは悪意ある質問ですよね。

丹羽:(笑)。いや、別に私、コンテナは嫌いじゃないです。

:嫌いじゃない?

丹羽:なぜなら、サーバレスはコンテナに支えられているからですね。

:といいますと?

丹羽:なぜかというと、仮想サーバじゃLambdaは作れないんですよ。コンテナの起動がめちゃくちゃ速いという特性によってFunction as a Serviceは成り立っています。なので、コンテナの次のステップに存在するものがFunction as a Serviceだと考えるのがいいと思います。

ただ、いわゆるJ-ALERT的なものかもしれませんが、Kubernetes的なアプローチは、私はあまり好きではありません。なぜかというと、クラスタを自分で組んでその上でノードを動かすという考え方は、結局自分でVM Wareをオンプレミスに入れて、その上で仮想サーバを動かして……みたいなことをやっているのにすごく近いと思っていて。

その頃となにが違うかというと、今までは「インフラ担当者とアプリケーション開発担当者という2つのロールがあったときに、「MySQLを入れるのはインフラ担当者なのか? でも、アプリケーションの都合でMySQLって必要になってるよね?」みたいなところで、境界がすごく曖昧でした。それが、コンテナの登場によって、「インフラの担当はKubernetesでクラスタを作るところまでです。あとはコンテナの中にMySQLとかを入れたければ入れて、アプリケーション開発者がイメージを作ってね」と、分業がすごくきれいに分かれるようになったので、コンテナのメリットが見えているのかなと思っています。本質的な「サーバ運用って大変だよね。しんどいよね」ということが解消できたかというと、クラスタの運用がある以上、なくなってはいないので。

私はコンテナで幸せになる人がすごくいっぱいいるのは確かだと思います。とくにインフラチームとアプリケーションチームでロールが分かれている組織では、有効な解決手段の1つだったと思います。ですが、そもそもインフラチームというものがなく「アプリケーション開発者が書いたコードをバッと運用に乗せていきたい」みたいなときには、サーバレスなのかなと思っています。

好きとか嫌いとかいう話ではなくて、その組織のニーズに合っているかというところがあると思っています。

私は、(インフラは、その運用を)任せられるところとしてAmazonやGoogleなど、すごく大きい会社があるわけで、しかも24時間365日の監視体制や復旧体制を自分で敷くよりも、AmazonやGoogleにやってもらったほうが絶対に品質は高いので、そういうところに任せて、自分たちはアプリケーションを書くことに専念したほうが価値を出せるんじゃないかと思っているだけですね。

:なるほど。では、「嫌いではない」と。

丹羽:そうですね、必要な技術だとは思います。使い方がどうかなという感じですね。

:ありがとうございます。

DDDを使いたいが上司が承認してくれない

:次の質問ですね。「ドメイン駆動設計を取り入れたいが、上司がなかなか納得してくれません。どう説得すればいいですか?」。これは「がんばれ」としか言いようがないのかな。そういうわけではないですかね?

増田:いや、上司に何の了解を得なきゃいけないのかな? それがわからないな。

:なるほど。逆に、この人は何が障害なんでしょうね?

増田:ちょっとわからないので、相当な推測で、大外しなのかもしれませんが、形にこだわりすぎてるんじゃないですかね。

僕は、エンジニアがコードの設計に責任を持つことに対して、上司になにかおうかがいを立てなきゃいけないとか、設計に関して上司がいいジャッジ・サジェスチョンをしてくれるなんて環境は、むしろほとんどないんだろうなと思っているから、自分の裁量範囲で設計すれば……自分というか自分たちですよね。コードに責任を持つ人間の間だけで話をして「こうしよう、ああしよう」を決めればいいだけで。

もちろん、マネジメントからしてみたら「いつまでにこれくらいの品質のものを、このぐらいアウトプットしてくれるんだよね」というコミットは要求してくるので、そのコミットに関しては応えるようにがんばるべきだけど、中身の設計をどうこうするというのは、「別に上司に話さなくていいんじゃないの?」という気はしますけどね。

:ちょっと質問者の方の環境がわかりませんが、プログラムを作るというのがアウトプットだとすると、そのアプローチについておうかがいを立てるようなものではないというお話ですね。

増田:私はそういうレベルでやればいいんだと思ってますけどね。お客さんにも「ドメイン駆動設計でやります」なんて言ったことはないですよ。

:確かにそうですね。というか、「それでなにがよくなるの?」という……。

増田:逆に説明しなきゃいけないことが増えるだけだから。

:そうですよね。

増田:「ソフトウェア作ります。以上、終了。中身は任せてください」ですね。

:丹羽さんはこれについて、なにかありますか? 「がんばれ」ですか?

丹羽:「がんばれ」ですね。

(一同笑)

たぶん環境が悪いんじゃないかと思うので、辞めたほうがいいと思います。

増田:うん、それは匂いとしては感じるね。

丹羽:(笑)。

:こういう組織からは抜けたほうがいいんじゃないかと(笑)。なるほど。ありがとうございます。

クラウドサービスの選定基準

:次です。「今使われているのはAWSだと思うのですが、GCPなどほかの環境に乗り換えてやるんですか?」。

丹羽:これは完全に誤解ですね。

:誤解ですか?

丹羽:はい。私は最初から、AWSとGCPのハイブリッドで作っています。なんでそんなことをしているかというと、別にDisaster Recoveryだとか言うつもりはまったくないです。

AWSが提供しているフルマネージドサービス、GCPが提供しているフルマネージドサービスと、いろいろありますが、わかりやすい例で言うと、AWSにはDynamoDBというデータベースがあって、GCPにはCloud Datastoreというデータベースがあります。DynamoDBとCloud Datastoreでは、特性がずいぶん違うんですね。

作っているものに対して、当然機能要件や性能要件みたいなものがあって。わかりやすい例で言うと、去年の11月の「re:Invent」で、DynamoDBに追加されたトランザクション機能の有無というのがちょっと前まではありました。DynamoDBにはトランザクション機能がなくて、Cloud Datastoreにはあると。

そうなってくると、例えば、課金周りや購入履歴のレシートと残高の増加と減少をアトミックに書き込まないといけないとき、DynamoDBではやりにくかったんですね。ということで、そういうところではCloud Datastoreを使いましょうと。

その作っているアプリケーションの要件に合わせて、2つのクラウドのフルマネージドサービスのいいところ取りをしています。

乗り換える予定があるかという観点で言うと、別のクラウドベンダーが増える可能性はあります。より魅力的なフルマネージドサービスを持つベンダーであれば、そちらも追加していくというスタンスですね。

:逆に、今はAzureなんかがありますが、それらの新たなベンダーにはまだ乗り換えないという感じですかね?

丹羽:そういう意味では、設計の哲学が出ていると思います。Amazonが現在トップランナーで走っていて、それをいろいろなベンダーさんが追いかけている状態だと思います。

よくS3で話を聞く人もいると思いますが、「S3互換のAPIのストレージサーバです」などもしばしばあります。でも、私からするとそれって「いや、S3を使ったらいいんじゃん?」みたいな感じになっちゃうんですよ。世の中の後追いの人たちって「互換性があるから、ちょっとうちに来てくださいよ」みたいな考え方で後追いをしているベンダーがけっこうあります。

それに対して、Googleは「自分が考えるクラウドのシステムはこうだ」みたいな思想をちゃんと反映したプロダクトが出てくるので、AWSと特性が違うものが出てくるんですよね。なので、使い分けのしがいがあるというか、使い分ける余地があるんです。でも、それ以外のベンダーのものだと「あえて使わなくてもAWSを使っていればいいかな?」というものが多いというだけですね。

:ありがとうございます。また新たに尖ったベンダーが出てくるのを待つところですね。

丹羽:そうですね。はい。

DDDにおける悩み

:おそらくこれが最後の質問になりますが、「ドメイン駆動設計をしていると、設計しているよりも悩んでいる時間が非常に多いように感じます」ということで、「だからなに?」という話なのかもしれませんが(笑)。

増田:いや、そうじゃなくて(笑)。「設計しているより悩んでいる」というのは、よくわからないな。

:何に悩んでいるんでしょうね。設計から実装への橋渡しとか、そういう話ですかね。

増田:でも、コードを書くこともドメイン駆動設計の重要な活動です。いい設計やいいコードが一発じゃ見つからないから、小さな実験をしながら少しずつよくしていこうという活動なので、悩んでいるというのは非常に好意的に受け止めていいことなんだと思いますけどね。「思考停止していなくて、いろいろ考えているんだよね」という。

「時間は迫ってくるけれど、一発でいい答えは見つからないわ」というのは、ある意味ではソフトウェア設計の非常にまっとうな状態なので、その限られた時間の中で「今回はここまでやってみよう」とか「今回はこれはこうしてみよう」みたいなことを積み重ねていけばいいのかなという気はします。考えている時間が多いとか、「A案、B案、両方あるんだよな」みたいなことを考えるのは、むしろ非常にいいことだと思いますけどね。

:なるほど。悩んでいる時間が多いのは、それだけ……。

増田:私は考えているってことだと思うけど。

テクロスが直面した悩み

丹羽:私は増田さんの話を聞いて頭を悩ませたほうなので、何に悩んだかという話をしたいと思います。

増田:(笑)。

丹羽:増田さんの話を聞くまでは、当然ながら、データベースのテーブルの定義と1:1のオブジェクト……クラス定義が存在すると考えていたわけですね。

ですが「それは違う」とわりと早い段階で言われて。「今作ろうとしているものが何なのかを分解していって、その結果保存することになるんだから、DBに保存するデータはいろいろなオブジェクトが持っているはずだ」みたいな話をされて、そこで「え〜っ!」となったんですけど(笑)。

増田:ああ、そっか、それは……。

丹羽:「でも、バラバラになったデータをどう集めてpersistするの?」みたいなことは、ずっと考えました。でも、全然いい答えが出てこなくて、「どうしよう?」というので、かなり悩みましたね。

:その答えは出たんですか?

丹羽:答えが出たかというと、結局「複数のオブジェクトを渡してpersistする」みたいな流れになったはずですね。

増田:たぶんそういう意味では悩んでいる人がすごく多くて、相談を受けることも多いところなんですけど、すっごく簡単な話なんです。

アプリケーションには、計算する部分と入出力をする部分があるんですね。必ずこうなるわけですよ。「計算の部分はオブジェクトにする」というふうにして、計算するためのオブジェクトは入出力を一切考えいないからこそ、計算するモデルや実装をシンプルですっきりできます。

「でも、これって実際にはデータを記録しておかないと次に使えませんよね?」という話が出てきて、記録するときに、いま丹羽さんからもあったように、テーブルにどう持たせるかはオブジェクトの都合だけでなく、テーブル設計としてあるべきというか、定石があるので、それが一致しないんです。

一致しないんだけど、テーブルは事実の記録のためにいい設計をして、オブジェクトは計算のためにいい設計をしてと。両方ともいい設計なら、ちょっとマッピングに手間がかかるかもしれないけど、「マッピングすればいいじゃん?」と思えたら、その部分の問題は解消します。

そう思えずに、「いや、そこは自動化できないか?」とか「可能なかぎり一致したら作業が楽になるんじゃないか?」という思いに囚われていると、いつまでたっても幸せにはなれないと思いますね(笑)。そこは、それほど面倒な話じゃないですよ。

:わかりました。ありがとうございます。

データオブジェクトの扱いについて

丹羽:もう1つ悩まされたことがありまして、マスターデータと言われるものです。あらゆるオブジェクトに対して固定のデータみたいなものが、ファイルストレージかどこかにあって。

でも、それと、利用者によって変わるデータが1つのオブジェクトの中に混在するんですが、そのあたりが最初はまったくわからなくて、「どうやったらこのオブジェクトに不変の部分と可変の部分を持たせられるんだろう?」みたいなことで、すごく悩まされました。こういうことが、たぶん質問のスタートラインなのかなと思います。

増田:悩んでいる時間。なるほどね(笑)。

それも、計算モデルを作るために、一式の計算ができるように、ありとあらゆるデータを書き集めてきて、まずはオブジェクトのネットワークを作ってしまって、できあがったら、もう一声かければありとあらゆる計算結果を返してくれるみたいな状態……手続き計算をしながらまたマスターを見にいくのではなく、必要なデータを全部持っちゃって、計算用に必要な状況を用意してあげる。

そうは言っても、計算結果によって取らなきゃいけないマスターが変わるという現実もあるので、それは計算フェーズを大きく分けて、各計算フェーズで、まずはとにかく計算用オブジェクトを作ってしまう。作れば仕事は終わったも同然で、その結果をもってもう1回次のフェーズ用のオブジェクトを、キーなんかで渡してあげて作ってあげる。

その入出力と計算は、そういうかたちで常に分けるということをしたほうが、コードはすごくわかりやすくなると思います。手続き的なプログラミングやアプリケーションは、入出力の手続きの中にIF文や計算式が埋まっているんだというスタイルが大前提になってしまっていると、やっぱり大変だとは思います。

:ありがとうございます。

マルチクラウドのコストについて

:そうしましたら、時間となりましたので終わりたいと思います。

司会者:せっかくなので、みなさんの中からもご質問を受け付けたいと思います。ご質問がある方はいらっしゃいますか?

質問者1:貴重なお話をありがとうございます。丹羽さんにお聞きしたいんですが、先ほどAWSとGCPでマルチクラウドにして、というお話でした。AWSとGCPの間の通信の遅延の問題だったり、あるいはAWSのIAMのパーミッションの管理などとGCPのパーミッションの管理がぜんぜん合わなかったりとかすると思います。

「そのあたりのコストが問題になったことはないのか?」あるいは「問題になったとしても、それを乗り越えるだけの価値があってマルチクラウドをやってるのか?」みたいなところをお聞きしたいです。

丹羽:そういう意味では、先ほどのトランザクションの話がすごくわかりやすいですが、なかったら成立しないんです。だから、やるしかないという前提で「どうやるか?」という話になります。

まず計測したのは、「AWSからGCPへのコンポーネントを触ったときにどれぐらい遅延があるんだろう?」というところですね。実際にやってみると、両方とも東京リージョンでやると、だいたい往復30ミリ~40ミリぐらいで返ってくるんですね。

Lambdaは特性上、そのコンテナが起動して実行して返すというところのレイテンシーが、どうがんばっても300ミリはかかります。そう考えると30ミリ~40ミリの実行時間が伸びても許せるかなと。そこは割り切ったという側面があります。

次に権限管理ですが、当然、LambdaからGoogleのコンポーネントを触るには、Google側の権限をLambdaが抱え込む必要があります。そこは割り切ってクレデンシャルを組み込んでいます。これも組み込み方は環境変数で渡すとか、いろいろ方法はあるので、やりようがあるところだとは思います。

サーバレスにおける注目ツール

司会者:ありがとうございます。ほかにご質問がある方はいらっしゃいますか?

質問者2:ありがとうございます。丹羽さんに質問なんですけど、「TECH × GAME COLLEGE」の第2回以降、もしサーバレス界隈で増えたメンツというか……例えばLambdaのLayer・Customだったり、AWSのTimestreamなど、そのあたりで新しく出てきたサービスについて、注目しているものや、便利に使っているものがあれば教えていただきたいです。

丹羽:一番重要だと思ったのが、DynamoDBのOn-Demandですね。これがなにかというと、今までDynamoDBは、1秒間にどれだけ読み込みするか・書き込みするかを予約しないといけませんでした。使っていようが使ってまいが、予約した分だけお金がかかっていたんですよ。

これが、私が最初に言った「使ってないときは費用はかからない」というサーバレスの思想に反している唯一のコンポーネントだったんですが、「DynamoDB On-Demand」というサービスが出てきて、リクエスト課金で使えるようになったのが、私の中で大きな変化があったものの1つですね。

それ以外にre:Inventでいろいろ発表されたんですけど……私が震えたのは、そのOn-Demandかなと思います。

増田:(笑)。

司会者:ありがとうございます。それでは、あらためて、お三方、ありがとうございました。

増田:ありがとうございました。

(会場拍手)