RedisサーバのCPU負荷対策パターン

Redisは多彩なデータ構造をもつ1インメモリDBであり、昨今のWebアプリケーションのデータストアの一つとして、広く利用されている。 しかし、一方で、性能改善のための手法を体系的にまとめた資料が見当たらないと感じていた。 実際、最初にCPU負荷が問題になったときにどうしたものかと悩み、調査と試行錯誤を繰り返した。 そこで、この記事では、自分の経験を基に、RedisサーバのCPU負荷対策を「CPU負荷削減」「スケールアップ」「スケールアウト」に分類し、パターンとしてまとめる。

背景

Redisのハードウェアリソース使用の観点で重要なことは、Redisサーバはシングルスレッドで動作する(厳密には他にもスレッドあるがクエリ処理をするスレッドは1つ)ことと、Redisサーバ上のデータをメモリ容量を超えて保持できないことだ。 前者については、シングルスレッドで動作するということは、マルチコアスケールしないということであり、特定CPUコアのCPU使用率がボトルネックになりやすい。 後者については、Redisはディスクにデータを永続化2できるとはいっても、MySQLやPostgreSQLのようなメモリ上のバッファプールにデータがなければ、ディスク上のデータを参照するといったアーキテクチャではないため、基本的に全てのデータをメモリ容量以下に収めなければならない。

設定やクラスタ構成によっては、ディスクI/OやネットワークI/Oがボトルネックとなることもある。 例えば、Redisのデータの永続化方式[^2]としてRDBを利用していると、Redisサーバのメモリ使用量が大きいほど、ディスクにフラッシュするタイミングで、ディスクIOPSを消費する。 また、マスター・スレーブ構成をとる場合、スレーブのマスター昇格時の再同期処理でネットワーク帯域の使用がバーストすることがある。 さらに、Redisは低レイテンシで応答するため、1台あたりのスループットを高くしやすく、ホスト1台あたりのネットワーク帯域が大きくなることもある。

これらの中でも、特にCPU利用率と戦ってきた経験があり、Mackerelというサービスでは、以下のように、なぜか毎年CPU利用率と戦っていた。

f:id:y_uuki:20170910003050p:plainf:id:y_uuki:20170910003102p:plainf:id:y_uuki:20170910003054p:plain
issue

RedisのCPU負荷対策パターン

以下の図は、CPU負荷対策パターンをカテゴリごとにまとめたものになる。

RedisのCPU負荷対策のカテゴリとして、CPU負荷削減、スケールアップ、スケールアウトがある。 CPU負荷削減は、Redisサーバが実行する処理そのものを減らし、スケールアップはハードウェア性能そのものを向上させ、スケールアウトは複数のCPUコアやサーバに処理を分散させる。 実際には、各カテゴリの対策を組み合わせることが多いだろう。

CPU負荷削減

CPU負荷削減のためのテクニックとして、「multiコマンド」「Redisパイプライン」「Luaスクリプティング」「Redisモジュール」がある。

multiコマンド

MGETMSETMSETNXなどの複数のキーに対して操作するコマンドを使うことで、余分なCPU処理をせずにすむ。 これは、multiコマンドを使わずに複数回コマンドを発行することに比べて、リクエスト/レスポンスの往復回数が減り、Redisサーバ側でリクエスト受信とレスポンス送信のためのオーバヘッドを削減できるためだ。

Redisパイプライニング

Redisパイプライニング3は、クライアントがレスポンスを待たずにリクエストを投入しつづけることで、ラウンドトリップタイムを削減する。 ドキュメント[^4]には、ラウンドトリップタイムだけでなく、Redisサーバ上でのトータルでの処理量を削減できると書かれている。

ただし、全てのコマンド発行パターンにおいてパイプライニングが有効なわけではない。 Read After WriteとWrite after Readのような、レスポンスに含まれる結果を利用して次のコマンドを発行する場合には、レスポンスを待たないパイプライニングは有効ではない。 パイプライニングにおいて、クライアント側のコマンド実行順序は保証されるため、Write after Writeのパターンでは有効だ。 Read After WriteとWrite after Readのパターンで処理効率を向上させたい場合、後述するLuaスクリプティングを使うとよい。

一部のRedisクライアントは、pipelineという名前がついたインタフェースであっても、Redisプロトコルレベルでのパイプライニングではないことがある。 Redisプロトコルレベルでのパイプライニングを真のRedisパイプライニングと同僚と呼びあっている。 真のRedisパイプライニングかどうかは、tcpdumpでコマンド発行の度に同期的にQUEUD応答が返ってくるかどうかで確認できる。

パイプライニング自体は伝統的な技術であり、CPUプロセッサの命令パイプラインが有名だ。 ネットワークプロトコルの中では、例えばHTTPパイプライン4がある。Redisのドキュメント[^4]には、多くのPOP3実装でパイプライニングをサポートしていると書かれている。

Luaスクリプティング

Luaスクリプティング5は、Redisサーバに対してLuaコードを送り込んで実行できる機能だ。 具体的には、クライアントとサーバ間でコマンド発行と応答を往復させなければ一連の処理を、Luaで記述することでRedisサーバ上で処理を完結できる。

Redisパイプライニングのドキュメント[^4]の「Pipelining VS Scripting」の項を読むと、パイプライニングを利用できるような多くのユースケースにおいて、より効率的に処理を実行できると書かれている。 さらに、Redisパイプライニングでは対応できないコマンドパターンにおいて、ラウンドトリップタイムを改善できる。 Luaスクリプティングにより、例えば、HASH型に対するmultiコマンドは実装されていませんが、Luaで複数キーに対応したHMSET(MHMSET)のような処理をする関数を実装できる。

しかし、Luaコードの処理内容によっては、もともとクライアント側で計算していた処理をRedisサーバ側で実行するため、RedisサーバのCPU利用率が増加する可能性がある。

Redisモジュール(夢)

これまで、Redisのデータ構造として使えるのは、LIST、SET、HSET、ZSETなどの汎用のデータ構造だけだった。 しかし、Redis 4.0からRedisモジュール6が追加され、独自のコマンドとデータ構造をC拡張により追加できるようになった。 これを使えば、アプリケーションに最適なコマンドを実装することで、CPU利用率に限らず、その他の性能も大幅に向上させることが理屈上は可能である。

自分では使ったことも作ったこともないが、Redis Modules Hubには検索エンジンやJSONフォーマットをサポートするような拡張が公開されている。

スケールアップ

スケールアップは、CPUをのクロック周波数を高いもに変更するか、CPUアーキテクチャの世代を新しいものにするかといった選択肢がある。 経験上、CPUのクロック周波数に対してほぼ線形にRedisサーバのCPU使用率が変化する。

前述のようにRedisサーバはシングルスレッドで動作するため、CPUのコア数が大きいものを選んでも意味はあまりない。 ただし、ディスクの永続化方式にRDBを選択している場合、Redisサーバプロセスからforkされた子プロセスが、メモリ上のデータをディスクに書き出す処理をバックグラウンドで実行するため、最低でも2コアにしておくと安心だと思う。

ただし、EC2を利用する場合、EC2インスタンスのCPUコアは論理コアなので、RDB利用の場合、4コアのインスタンスを選ぶことをすすめる。7 物理CPUコア数は論理コア数(vCPU数)を2で割った値になる。 例えば、c4.2xlargeは表記上のコア数は8だが、物理コア数は4となる。

スケールアウト

Redisのスケールアウトのための手法として、「参照用スレーブ」「垂直分割」、「水平分割」、「Redis Clusterによる水平分割」がある。 「参照用スレーブ」「垂直分割」、「水平分割」は、Redisに限らずMySQLなどのRDBMSにおいても、一般的なスケールアウト手法として知られている。8 参照用スレーブは名前の通り、参照クエリのみ分散できる。 更新クエリを分散するならば、「垂直分割」または「水平分割」が必要になる。 垂直分割と水平分割は、CPU負荷の分散以外に、メモリ使用の分散にも利用できる。

参照用スレーブ

Redisはレプリケーションによりマスター・スレーブ構成のクラスタを作成できる。 はてなでは、主にスタンバイサーバの作成に利用しており、KeepalivedによりVIPベースで冗長化している。

スレーブは他にも用途があり、参照用スレーブは、アプリケーションから参照クエリを向けるためのスレーブだ。 スレーブに読み込みクエリを投げることにより、マスターの負荷をスレーブへ分散できる。

以下の図のように、クライアントから複数のスレーブに向けて参照クエリを投げます。複数のスレーブに向けてロードバランシングするための手段はいろいろあるが、TCPロードバランサを挟むか、DNSラウンドロビンによるロードバランシングが一般的だ。

|-------------------------------------|
|              |----> redis (slave)   |
|        read  |                      |
| client ------|----> redis (slave)   |
|        |     |                      |
|        |     |----> redis (slave)   |
|        |                            |
|        |----------> redis (master)  |
|        read/write                   |
|-------------------------------------|

何も考えずに、すべての参照クエリを参照用スレーブに向けるのは危険だ。 Redisのレプリケーションは基本的に非同期であり、レプリケーション遅延があるため、クライアントからは結果整合性をもつデータストアとして扱う必要がある。 具体的には、マスターにデータを書き込んだときにスレーブにデータが転送され書き込まれるのを待たずにクライアントへ応答を返す。 したがって、応答がクライアントへ返った後に、書き込んだキーの参照をスレーブへ向けても、該当データが書き込まれている保証がない。 参照用スレーブを使う場合は、アプリケーションロジックがデータの一貫性を要求しないものかをよく確認しておく必要がある。

垂直分割

垂直分割は、データの種類ごとに複数のRedisサーバを使い分ける手法だ。 下記の図のように、データの種類A、B、Cに必要なデータを異なるRedisサーバに書き込むことで、参照と更新クエリを機能ごとに分散できる。

|------------------------------------|
|              |----> redis (種類A)  |
|              |                     |
| client ------|----> redis (種類B)  |
|              |                     |
|              |----> redis (種類C)  |
|------------------------------------|

可用性のために、各Redisサーバは冗長化されている必要があり、1つのクラスタで処理を捌くより、無駄なサーバが増えやすいというデメリットがある。 また、特定種類のデータに対するクエリの負荷が大部分を占める場合、その種類のデータを別のRedisサーバに移しても、結局分散先のRedisサーバのCPU負荷が問題になることがある。

水平分割

水平分割は、ある特定の種類のデータをレコードごとに分割し、それぞれのレコードを別のRedisノードへ配置する手法だ。 水平分割のことをシャーディングやパーティショニングと呼ぶこともある。

レコード分割の手法は様々であり、後述するRedis Clusterのようなミドルウェア側で分割する機構がないもしくは利用しない場合は、データの性質を利用する。 例えば、RedisにユーザIDに紐付いたデータを格納するとして、ユーザのIDをノード数で割った剰余の値により、配置するノードをマッピングするといった方法がある。 下記の図はノード数が3の場合を示している。 他にはユーザ名の頭文字がaの場合はノード1、bの場合はノード2といった分割の方法もある。

|------------------------------------------|
|              |----> redis (id % 3 == 0)  |
|              |                           |
| client ------|----> redis (id % 3 == 1)  |
|              |                           |
|              |----> redis (id % 3 == 2)  |
|------------------------------------------|

水平分割は、垂直分割同様に、CPU負荷の分散以外に、メモリ使用の分散にも利用できる。

この手法のデメリットとして、ノードの負荷の偏りと、リシャーディングの困難さの2つがある。

ノードの負荷の偏りは、特定のユーザ(もしくはブログIDや記事IDなど)に関するコマンドは必ずマッピング先のノードに向けて発行されるため、特定のユーザの活動が非常に活発な場合、負荷が特定のノードに偏ってしまうという問題がある。

リシャーディングの困難さは、ノード数を増減させるオペレーション(リシャーディング)に非常に手間がかかることだ。 マッピングの手法にもよりますが、上記のような剰余ベースでマッピングしていると、リシャーディング時に既存のマッピングが変更される。 既存のマッピングが変更されると、すでに書き込み済みのデータを新しいマッピング先のノードに移動する必要がある。 最もナイーブな方法で移動するなら、新旧のマッピングで配置が変更されるレコードを抽出し、新マッピングにしたがってデータを移動するバッチスクリプトを実行するといった手段がある。 バッチスクリプトを流す時間だけサービス停止できればよいが、これをオンラインでやろうとすると大変だ。 例えば、新旧のマッピングを意識したアプリケーションに改修しつつ、裏で新マッピングへの移動スクリプトを流すといった泥臭い運用が待っている。

さらに、ノードの負荷の偏りを平滑化する(リバランス)となるとさらに困難なことになる。 このリシャーディングとリバランスの難しさから、できるだけ水平分割を選択しないようにしている。

しかし、Redisをキャッシュとして用いる場合は、リシャーディングはもうすこし簡単になる。 レコードにTTLを設定しておき、マッピングが変更された後に、たとえキャッシュミスしたとしても、キャッシュ元のなんらかのデータソースからデータを引く実装になっていれば、アプリケーションの動作としては問題ない。TTLにより、旧マッピングのデータがずっと残っているということもない。 キャッシュミスをできるだけ抑えたい場合は、consitent hashingを使うと、リシャーディング時にマッピングの変更を少なく抑えられる。

Redis Clusterによる水平分割

Redis Cluster9は、複数のRedisサーバに対してデータを「自動で」水平分割する。 前述の水平分割の場合は、アプリケーション開発者がレコードを分散する処理を書き、リシャーディング運用をしなければなかった。 Redis Clusterを使うと、自動でキーとノードのマッピングを作成され、アプリケーションからのコマンドは自動で分散される。 さらに、redis-tribというRedisが提供しているオペレーションスクリプトを使ってリシャーディングとリバランスができる。

しかし、Redis Clusterにはdatabaseと複数キーのコマンドの扱いに制限がある。

まずdatabaseについて、複数のdatabaseを使えない制限がある。databaseはRedisのキー空間を分ける機能で、キーの重複を考えなくてすむため、データの種類ごとにdatabaseを分割するといった使い方をする。すでにアプリケーションが複数のdatabaseを使っている場合、途中からRedis Clusterに移行するには手間が発生する。

次に複数キーコマンドについて、複数キーにまたがるコマンドは、全てのキーが同じノード上になければならないという制約がある。 そこで、hash tagsを使うと、キー文字列の中の部分文字列を中括弧で囲うことで、同じ部分文字列をもつキーであれば、同じノードにマッピングするようになる。 したがって、hash tagsにより、キーとノードのマッピングをある程度開発者がコントロールできる。 パイプライニングやLuaスクリプティングについても、基本的に操作対象の全てのキーが同じノード上にある必要がある。 ただし、一部のクライアント10では、同じノード上にキーがなくても、複数のノードにクエリを投げてマージするといった実装が入っていることがあるようだ。

これらの制限に加えて注意する点は、水平分割の項で説明したノードの負荷の偏りを、Redis Clusterを使ったからといって防げるわけではないということだ。 システムのワークロードによって、よくアクセスされるキーが存在すると、特定ノードへ負荷が偏ることは避けられない。 ただし、slotを別のノードへ移動させるコマンドにより、負荷の高いslotを移動させてマニュアルで負荷の偏りをある程度均すことは一応可能だ。

ちなみに、Redis Clusterは、Mackerelの時系列データベース11で利用している。 まだ投入して間もないため、運用ノウハウを積んでいくのはまだまだこれからというところだ。

その他

上記カテゴリのいずれにも該当しないチューニング例として、RPS12とCPU Affinityによるネットワーク割り込み負荷をRedisプロセスが処理するCPUコアとは別のコアへ分散がある。 この手法は、はてなのLinuxネットワークスタックパフォーマンス改善事例13の後半で紹介している。

スライド資料

あとがき

発表から少し時間が空いてしまいましたが、この記事の内容は、Kyoto.なんか #3での発表を加筆修正したものになります。

これらの内容は一人でやったものではなく、自分は主にアーキテクチャや作戦を考える係で、アプリケーションの実装は主に同僚のid:mechairoiさんとid:itchynyさんによるものです。 真のRedisパイプライニングについては、同じく同僚の id:ichirin2501 さんに教えてもらいました。

Redisは好きなミドルウェアで、[^11]でもお世話になっています。 オンディスクDBは、RDBMSならMySQLやPostgreSQL、分散データストアならHBase、Cassandra、Riak、Elasticsearchなどさまざまな選択肢がありますが、インメモリDBはウェブ業界の中では実績や使いやすさを考えるとRedis以外の選択肢をあまり思い付きません。

しかし、Redisがこれほど利用されているにもかかわらず、議論の土台となる運用をまとめた資料がないと感じていました。これは、単に自分が発見できていないだけかもしれません。 以前から、Webの技術を自分の中で体系化することに興味があり、過去の試みには 2015年Webサーバアーキテクチャ序論 - ゆううきブログWebシステムにおけるデータベース接続アーキテクチャ概論 - ゆううきブログ といった記事があります。 そこで、今回は、RedisのCPU負荷対策についてまとめまてみました。メモリやネットワークI/O全般について書ければよかったのですが、まだ知見が及ばないところも多いので、一旦CPUの部分のみにスコープを絞りました。

ところで、今年のはてなサマーインターン2017の大規模システムコースでは、Serfで使われているGossipプロトコルベースの自律分散監視や、グラフDBのNeo4jを用いた分散トレーシングといったとてもおもしろい成果がでています。

参考資料

時系列データベースという概念をクラウドの技で再構築する

サーバ監視サービスMackerelにおいて開発中の、高解像度・長期間のサーバメトリック収集を実現するための新しい時系列データベースDiamondを紹介します。具体的には、Amazon ElastiCache、Amazon DynamoDB、Amazon S3を組み合わせ、Amazon Kinesis StreamsとAWS Lambdaによりコンポーネント間を接続した、階層構造のデータストアアーキテクチャの設計と実装を解説します。

はじめに

先日開催されたAWS Summit Tokyo 2017にて、「時系列データベースという概念をクラウドの技で再構築する」というタイトルで登壇しました。 この記事では、講演した内容に加えて、時間の限られた講演では触れられなかった内容を併せて議論します。

タイトルに時系列データベースとあるので、時系列データベースの話をもちろん書きます。しかし、AWS Summitでの発表ベースの記事なので、「AWS」を用いたシステム設計という切り口で話を進めます。 具体的には、Write-Intensive Application(書き込み要求が支配的となるアプリケーション)をAWS上で設計するための議論の土台になればと考えています。 時系列データベースは比較的単純なデータモデルを扱うため、よいモデルケースになるのではないかと思います。 時系列データベースとしての機能比較や実装の詳細についてはまた別の機会に紹介します。

背景

Mackerelでは、成長しつづけるサービスのスケーラビリティの確保と、データ量とI/Oがひと桁またはふた桁増加するような機能実現が求められています。

Mackerelの重要な機能のひとつに、メトリックのグラフ化機能があります。 開発中の新時系列データベースは、このグラフ化機能について、より高解像度でより長期間のメトリック収集と保持を実現しようとしています。 さらに、1つのグラフに1000以上のメトリックが含まれている状況でも高速に表示できるようにするなどの性能向上や、それ以外に、メトリックの異常検知など将来的な機能追加に対するワークロードに対して対応できるようにしたいと考えています。

Mackerelにおけるメトリックの収集とグラフ化の仕組みの概要は、以下の図のようになっており、前述の機能要求にとって、時系列データベースというコンポーネントが重要になってきます。

時系列データベースとはそもそも何でしょうか。時系列データベースとは、時系列データを扱うことに特化したデータベースであり、サーバモニタリングやIoTの文脈でのセンサーデータの収集のために使われます。有名な実装として、OpenTSDBInfluxDBGraphite などがあります。地味にみえて、多くの実装が存在し、学術研究論文になっているものもあります。id:rrreeeyyy さんの 時系列データベースに関する基礎知識と時系列データの符号化方式について - クックパッド開発者ブログ [3]が詳しいので、一読することを薦めます。

Mackerelで運用している時系列データベースについては、Mackerelを支える時系列データベース技術 - ゆううきブログ [4]の記事にまとめています。2年前の記事ですが、現状でも概ねこの通りの構成で運用しています。1台あたりピーク時で150k write IOPSを叩き出しており、サーバモニタリング向け時系列データベースの探究 / The study of time-series database for server monitoring // Speaker Deck [5]で紹介したようにパッチをあててパフォーマンスを改善してきました。

ところが、MackerelのGraphite運用には、以下の4つの問題を抱えています。

まず、スケールアウトのための運用コストが大きいという問題です。書き込みI/Oのスケールアウト手法として、水平分割(sharding)が一般的です。Graphite自体にはconsistent-hashingにより、水平分割する仕組みがあります。しかし、シャードの増減により、ハッシュキーとノードのマッピングが変更されたときに、データを再配置するための仕組みはGraphite本体には実装されていないため、運用でカバーする必要があります。

次の問題は、データ保持期間を増やすと金銭的なコストが激増するというものです。前述したようにスケールアウトのための運用コストが大きいことから、書き込みI/Oをスケールアップするために、NANDフラッシュメモリを利用しています。非常に性能が高い一方で高価なハードウェアなので、容量単価が大きいという特徴があります。 したがって、データ保持期間を増やすと、ディスク上のデータ量が増加し、安価なハードウェアにのせることに比べてお金がかかることになります。 一般の解決策は、圧縮してディスクに格納するか、既に書き込まれたデータを低速で容量単価の小さいストレージに移動するような仕組みにすることです。 前者の圧縮については、[3]で紹介されている差分符号化やXOR符号化のテクニックをGraphiteに実装すれば、実現できそうではあります。しかし、これらのエンコーディングにより、ランダムアクセスできなくなるため、Graphiteのラウンドロビンデータベース構造とうまく噛み合うかがわからないところです。圧縮は基本的に、CPU負荷とトレードオフになるため、CPU負荷がボトルネックとなる可能性もあります。 後者のデータ移動については、Graphiteのラウンドロビンデータベースの、古いデータを新しいデータで上書きしていくという性質のため、別のストレージに効率よくデータを移動させることが難しく、データ構造を大きく変更する必要があります。

3つ目の問題は、データロスト耐性が低く、フル同期のための運用コストが大きいことです。アプリケーションから書き込みすると、Graphiteのメモリ上のキューにデータが非同期に書き込まれるため、サーバダウンによりキューの中身をロストしてしまいます。デュアルライトにより、別のサーバには書き込まれているので、そちらからデータを同期するなど、運用でカバーしなければなりません。これを解決するには、GraphiteにWAL(Write Ahead Log)を実装するなど、大きな変更を強いられます。

最後に、新規にメトリックが投稿されたときに、未来の領域をファイル作成時に確保するので、ディスク使用効率が低いという問題があります。これは2つめの問題と関連します。なぜこのようなデータ構造になっているかは http://graphite.readthedocs.io/en/latest/whisper.html?highlight=rollup#disk-space-efficiency に書かれています。このデータ構造は、コンテナのようなImmutable Infrastructureの概念と相性が悪く、非効率です。

これらの4つの現状の問題点と、冒頭に書いたような新しい機能要求を考慮すると、根本的なアーキテクチャの刷新が必要だと考えました。

既存の時系列データベース

まず、既存の時系列データベースの調査から始めました。Andreas Baderらのサーベイ論文[1]やOpen Source Time Series DB Comparison[2]にオープンソースの時系列データベース実装がまとめられています。

時系列データベースの概念

前述のサーベイ論文[^1]では、時系列データベースの定義は、以下のような性質を満たすDBMSのこととされています。

  • タイムスタンプ、値、属性(メトリック名など)で構成されるデータの行を格納できる
  • 時系列としてグループ化された複数の行を格納できる
  • データ行に対してクエリを発行できる
  • タイムスタンプまたは時間範囲をクエリに含められる

この定義を満たすものを実装するのはさほど難しくありません。しかし、実際には、分散/クラスタリング、Function、Rollup Aggregation(自動丸め)、タグ、複数のデータ解像度、クエリ言語などの時系列データベースにまつわる機能要求があります。 特に、今回のようなスケーラビリティを確保する目的であれば、分散/クラスタリングが重要になってきます。

時系列データベースの分類

時系列データベースのOSS実装は大きく2つの分類があると考えています。それは、他の汎用DBMS上に実装されたもの(TSDB on DBMS)と、時系列データベースに最適化したストレージエンジンをもつもの(TSDB standalone)です。 前者にあたるものは、例えば、OpenTSDBやKairosDBなどがあります。一方、後者にあたるものは、GraphiteやInfluxDB、Prometheusなどがあります。 前者のDBMSとして、HBase、Cassandra、Riak、ElasticsearchなどのいわゆるNoSQLが使用されます。もちろん、TimescaleDBのようにRDBMSであるPostgreSQLをベースにした実装も存在します。前述の時系列データベースとしての定義を満たすだけなら、ACID保証が必要ないので、NoSQLを利用するケースが多いようです。

時系列データベースを実装する側の視点でみると、TSDB on DBMSは、分散/クラスタリング機構を自前で実装せずにすむため、実装が楽というメリットがあります。一方で、TSDB standalineは分散/クラスタリング機構も実装しなければならないというデメリットがありますが、TSDB on DBMSと比較して時系列データベースに最適化できるというメリットがあります。

時系列データベースを運用する側の視点でみると、たいていのTSDB on DBMSはCassandraなどの分散システムとしての運用コストが高いといわれるDBMSを利用しており、一方で、TSDB standaloneは分散システムとしての信頼性を測るための実績が少ないといえます。実際には、製品ごとに細かくメリット・デメリットがありますが、大雑把にこのように認識しています。

さらに、Mackerelで採用するという視点でみると、既存の時系列データベースをそのまま採用するデメリットとして、Rollup Aggregationに対応していないものや、インタフェースが大きく変わるので変更コストがある、Mackerelの現在または将来のワークロードに対してスケールしない可能性があります。

新時系列データベースDiamondのアーキテクチャ

方針

調査の内容を踏まえて、既存の時系列データベースを採用せずに、Amazon DynamoDBなどのAWSマネージドサービスを採用し、マネージドサービス上に独自の時系列データベースアプリケーションを実装するという方針にしました。 マネージドサービスを採用したのは、時系列データベースの分散/クラスタリング機構に必ずついてまわるデータベースの検証・運用コストを削減するためです。はてなでは、特定ベンダーのロックインをなるべく避けるという技術選択方針がありますが、今回は、Mackerelの成長速度や将来の機能要求を考慮して、ある程度のロックインを受け入れることにしました。 独自に、TSDB on DBMSにあたるものを開発することにしたのは、ひとえにMackerelの要求を満たす実装がないか、要求を満たすかどうかの検証に時間がかかるためです。AWSマネージドサービス採用によりデータベースの検証/運用コストを削減できるので、その代わりの開発工数を確保できると考えました。

この大方針に沿って、Graphite運用の4つの問題点を解決できるか考えます。

まず、負荷分散の運用コストの解決です。前述したようにDynamoDBなどのフルマネージドサービスの利用により、運用コストを削減できます。水平分割のためのキーの設計を間違えなければ、お金を払った分だけI/Oスループットがスケールするので、検証も比較的楽になります。 ところが、DynamoDBのI/O課金が高いため、今のMackerelのI/Oを工夫せずにDynamoDBに向けるとインフラコストが大きく増加します。 したがって、個々のデータポイントを別々に書き込むのではなくまとめて書き込み、I/Oコストを下げる必要があります。 最終的には、前段にElastiCache(Redis)を配置し、ライトバックキャッシュ(講演ではバッファと呼んだ)として利用することにしました。

次に、データ保持期間についての解決です。DynamoDBのディスク容量課金は感覚的には安く感じましたが、1分解像度のデータを年単位で保持しようとすると、そこそこのコストがかかります。 S3のコストはスタンダードストレージでもDynamoDBの1/10程度に収まるので、ここでコストを浮かせておけば、他の機能拡充にコストをあてられるため、なるべくS3を使いたいと考えました。 とはいえ、S3のレイテンシはDynamoDBに比べて1桁以上大きいかつ、DynamoDBよりも内部的なパーティションあたりのスループットが低い可能性があります(要確認 リクエスト率およびリクエストパフォーマンスに関する留意事項 - Amazon Simple Storage Service)。 Mackerelの場合、古い高解像度データはほとんど参照されないという参照局所性があるので、参照回数が小さいデータの表示は多少遅くてもよいという性質があります。 そこで、この性質を利用し、ホットデータをDynamoDB、コールドデータをS3に配置することでコスト最適化することを考えました。

この時点で既に、階層型データストアアーキテクチャになることが決定しています。

3つ目に、データロスト耐性の向上です。これは簡単で、メモリ上のキューではなく、ディスク書き込みするメッセージキューを採用することです。OSSなら、KafkaやRabbitMQなどがこれにあたり、AWSでは、Amazon Kinesis Streamsになります。内部的な実装としてはキューではないと思いますが、キューのように利用できます。Kinesis Streamsは直近の24時間分のレコードをディスクに保存し、投稿したレコードをLambda functionの引数に渡すことも簡単です。Kafkaほどレイテンシが低いわけではないそうですが、どのみちMackerelのデータポイントはインターネットごしに投稿されるので、もともとユーザに反映されるまのでレイテンシが大きいので、無視できる程度のレイテンシの差だと考えました。キューというよりは、Using logs to build a solid data infrastructure (or: why dual writes are a bad idea) - Confluentに書かれているように、アプリケーションレベルのWAL(Write Ahead Log)を前段に配置していると捉えてもよいかもしれません。

最後に、ディスク使用効率の向上です。容量問題はS3の利用で解決できるので、ラウンドロビンデータベース構造にする必要がなく、未来の領域を確保することはしません。 圧縮や符号化については、RedisやDynamoDB上でレコード単位で圧縮しようとすると、レコードに対するデータポイントの更新時に、レコード内のデータを全て読み込んでからデータポイントを更新し、レコードの内容を差し替えるということをしなければならないため、余分なread I/Oとネットワーク帯域を圧迫する可能性があります。OSのファイルのようなseekできるストレージであれば、必要な分だけ読み出せるので、効率が良いと考えます。(しかし、これを書きながら、データサイズが小さくなっているのだから、ネットワーク帯域はさほど気にならない可能性もあるということに思いあたりました。)

さらに、時系列データを読み出すコンポーネントをMicroservicesとして開発しています。Graphite互換のインタフェースを実装し、新システム移行時のインタフェース変更コストを小さくしています。1つのクエリに1000以上のメトリックが含まれることがあるため、各メトリックのタスクを並行処理できるように、軽量スレッドでI/O多重化できるGo言語を実装言語として選択しました。

設計

前節の方針を元に、新時系列データベースのアーキテクチャの設計の概要を以下にまとめます。

  • 金銭コスト最適化のために参照局所性を利用する。データ参照頻度に応じて適切なデータストアへデータを移動させる
    • ホットデータをDynamoDB、コールドデータをS3に配置
    • ライトバックキャッシュのストレージとしてElastiCache(Redis)を利用
    • DynamoDBのTTL機能によりシームレスにデータ移動
  • Kinesis Streamsに対して先行ログ書き込みし、データロスト耐性と耐障害性の向上させる
  • Graphite互換インタフェースにより、各ストレージからデータ取得するWebアプリケーションを実装する

アーキテクチャ図を以下に示します。

このように複数のデータストアを組み合わせる場合、データをシンプルな手法で移動させるためのアイデアが必要です。 2017年2月にDynamoDBがTTLサポートされました。 TTLがexpireしたレコードをDynamoDB Triggers経由でLambda functionに渡すことができるため、簡単に古いデータをS3へ配置することができます。

この機能がリリースされたとき、ちょうどデータ移動の仕組みに困難さを感じていたところでした。当時は、タイムウィンドウごとにDynamoDBのテーブルを用意して、古いタイムウィンドウテーブルをテーブルごとDataPipelineによりS3にエクスポートすることを考えていました。いわゆる、MySQLで日時カラムに対してパーティションを切り、古いパーティションをパーティションごとDROPするという手法に近いと思います。 テーブルファイルがS3に配置されても、巨大なテーブルファイルに対してクエリするのは現実的ではないため、テーブルファイルをレコード単位に分割してS3に保存し直すような手間のかかる処理が必要でした。 テーブル単位による管理を強いられるため、アイテム単位で細かくデータ配置を制御したくなったときに、どうしようもなくなるという問題もありました。

古くなったデータを別のストレージに移動したいというのは一般的な要求なので、データベースのTTLとイベント通知というサーバーレスアーキテクチャらしい仕組みは、汎用的に利用できるアーキテクチャだと考えています。

実装

実装についての詳細は、スライドを参照してください。時系列データベース固有の話になります。Redis/DynamoDB上のスキーマ設計、Redisによるライトバックキャッシュ、Graphite互換アプリケーションのI/O多重化について簡単に紹介しています。

考察

Write-Intensive Applicationとして、例えばログ収集や、チャットメッセージングなどがあります。ログやチャットメッセージと違い、メトリックのデータポイントは固定長のデータなので、データ構造を最適化しやすいという特徴があります。したがって、可変なデータを書き込むアプリケーションの場合、時系列データベースでは考えなくてよかったようなデータ構造の工夫が必要かもしれません。

サービスの仕様変更により、データ構造を変更したくなったとき、3箇所にデータを保持していると、それぞれ変更を加えなければいけないというデメリットがあります。これについては、場合によっては、今あるデータ構造に追加の変更をするよりは、前段のKinesis Streamsから別のストレージに最適な構造で書き込むことも考えられます。

3層構造のデータストアアーキテクチャを提案しましたが、必ずしも3層にする必要はないと思います。ディスク使用が少なければElastiCacheとDynamoDB、書き込みI/Oが少なければ、DynamoDBとS3、readレイテンシを気にしなければ、RedisとS3というように、2層で対応できることもあるでしょう。 ちょうど手元のマシンでRAM+SSD+外部ストレージで大抵のことが事足りるように、3層あれば多くの状況でコスト最適化できると考えています。

DynamoDBにはDAXというライトスルーキャッシュが最近実装されました。もし、DAXにライトバックキャッシュが実装されれば、DiamondアーキテクチャのうちRedisの層は不要になるかもしれません。

その他、運用の観点で、スナップショットバックアップについては、ElastiCache自体にバックアップ機構があり、DynamoDBでは前述のDataPipelineによるS3への定期バックアップが可能であり、S3上のファイルは一旦作成されたら基本的に更新しないので、スナップショットバックアップはそれほど必要ないと考えています。

さらに、Lambda functionの実装にバグがあるとデータロストの危険性がないかについては、前段のKinesis Streamsに24時間(追加コストで1週間)データ保持されるので、原理上はそこからリカバリできるはずです。functionの実行がエラーになるケースでは、functionの実行がリトライされます。ただしこれには、functionの実行がべき等である必要があります。Diamondの場合、RedisとDynamoDBのデータ構造がタイムスタンプをキーとしたハッシュマップになっているので、データポイントの書き込みはべき等になっています。

Diamondアーキテクチャのデメリットとして、構成要素が多いことが挙げられます。Kinesis streamsもあわせると、4つのデータストアを併用することになります。一般に構成要素の数が増加すると運用コストも増加しますが、マネージドサービスの利用やCloudFormationのようなInfrastructure As Codeの利用により、運用・管理コストを抑えられると考えています。 しかし、Diamond自体のモニタリングは複雑になるため、モニタリング手法もあわせて提案する必要があると考えています。

資料

プレゼンテーション資料

参考資料

あとがき

「時系列データベースという概念をクラウドの技で再構築する」というタイトルは、少年ジャンプで連載中の食戟のソーマの第115話で、主人公 幸平創真の「親子丼という概念をフレンチの技で再構築する」という台詞から拝借したものです。 主人公は定食屋のせがれで、定食屋としての技術の限界を超えるため、フランス料理の技術を学び、日本の庶民の料理である親子丼を抽象化して、フレンチの技を用いて再構成するというお話になっています。 自分では、この話をとても気に入っていて、今回、ちょうど同じように、時系列データベースの構成要素を取り出し、マネージドサービスやサーバレスアーキテクチャなどのクラウドならではの技術を用いて再構築していると感じ、このタイトルをつけました。

今回話をしたかったのは、単に使っているOSSを列挙するようなものや込み入った実装の話ではなく、アーキテクチャの話です。 最近、アーキテクチャと実装の違いについて考えているのですが、まだあまりよい答えをもっていません。少なくともいえるのは、アーキテクチャには汎用性があり、実装するソフトウェアだけでなく他のソフトウェアにも通用するなにかがあるということです。 アーキテクチャの観点では、Webアプリケーションは参照局所性にあわせて複数のデータストアを併用するのは昨今では当たり前なので、今回のようなTTL + Lambda Functionのようにそこにもっとサーバレスというかイベント駆動な考え方を持ち込み、体系化できないかということを考えていたりします。

Mackerelでは、時系列データベース以外にも、おもしろいソフトウェアアーキテクチャを実現できるチャンスがまだまだたくさんあります。僕の場合は、最近は機械学習を支える効率のよいシステムやグラフDBのアーキテクチャに興味があります。 はてなでは、アーキテクチャを設計・実装し、本番投入し、運用まで持っていくことに興味があるエンジニアを募集しています。

また、今年のはてなインターンでは、Mackerelやはてなのインフラストラクチャを支えるシステムを開発できる、「大規模システムコース」と「クラウドサーバ管理システムコース」があります。 はてなサマーインターン2017 - Hatena Developer Blog

matsumotoryさんの博士学位論文公聴会に参加し、見て聞いて考えたこと

先日、京都大学で開かれた id:matsumoto_r さんの博士学位論文公聴会に参加してきた。

博士学位論文公聴会というものを、そもそも僕はあまりよく知らなかった。とりあえず、博士の学位を取得するための最後のステップと認識している。厳密には、この後にもいろいろあるらしいのだが、その日のうちに学位取得の合否が決定され、晴れてmatsumotoryさんが合格された様子をその場でみることができた。本当におめでとうございます。

発表内容について

博士論文や当日の発表スライドはそのうちmatsumotoryさんが公開されると思う。発表内容自体は、当たり前だけど、以下の予備審査のスライドとほぼ同等のものだった。

Webサーバの高集積マルチテナントアーキテクチャに関する研究 / Studies on Highly Integrated Multi-Tenant Architecture for Web Servers // Speaker Deck

matsumotoryさんの研究内容のストーリー全体を俯瞰する発表を聴くのは、今回が初めてだった。 これまで、個々の要素、例えば、mod_mruby/ngx_mrubyやmod_process_securityなどは多少理解していたつもりだったものの、その背景には大きなストーリーがあり、それぞれの要素がどのように配置されているのかといった論理構造が浮かび上がってくるようだった。 同じITシステムの運用にたずさわっていても異なるコンテキストをもつ僕が、自然と論理構成を理解できて、その後の質疑応答の内容もほぼすべて理解できた。これは大きなことだと思う。

発表の冒頭にもあるように、対象となるシステムは、事業者がアプリケーションを制御できない状況設定におけるアーキテクチャの提案となっている。僕が普段相手にしているシステムは、事業者がアプリケーションを制御するのが当たり前になっている。自社で開発しているサービスをデプロイし、運用する事業形態だ。

これは僕にとって発表を聴く直接のメリットがないようにみえるが、その逆で、適応領域が異なるほうが、むしろ抽象的なアーキテクチャを議論するヒントになりやすい。 実際、これのおかげで、この前のIPSJ-ONEにおける発表では、matsumotoryさんが提唱されているなめらかなシステムとの対比から様々なヒントを掴み、自分の思考の枠組みを一歩超えるような体験ができた。

さらに、matsumotoryさんの貢献の一つである「Webサーバの高集積マルチテナント方式の基本概念と課題を体系的に整理」をみて、ITシステムの運用というのは、そもそも体系からつくらないといけない分野であることを再認識できた。 そして、自分が過去に書いた以下の記事では、事業者が制御可能な前提でのシステム運用の体系を作りたかったのではないかと思うようになってきた。

僕がこのようなことを考えていることそれ自体が、matsumotoryさんの貢献でもある気がする。

質疑応答について

質疑応答は1時間弱くらい続いていたかもしれない。あのmatsumotoryさんが若干怯えた様子で、応答されていたのをみて、博士課程の予備審査にいってきました - 人間とウェブの未来 に書かれていることを思い出した。

入学資格審査や中間発表では、研究の突っ込んだ話は当然のこと、「アカデミックはどこにあるのか」「普遍的な学術的貢献はなんなのか」「工夫なのかアイデアなのか」といったように非常に抽象度が高く、汎用性・一般性に基づいた質疑が飛び交います。

博士課程の予備審査にいってきました - 人間とウェブの未来

特にセキュリティの観点で、厳しい質問があった。それ以外にも、高集積というアイデアはWebホスティング以外にも適用できないか、これからのLinuxに必要な機能はなにかといった、抽象的な質問が飛び交っていた。

参加するからにはどうにか自分もそのレベルで、なにか今後のmatsumotoryさんの研究活動に貢献できるような質問をしようと久々に発表を聴きながら頭をひねって、以下のような質問をした。

  • 第2章と第3章で提案されているアーキテクチャについて、chroot以外にLinux Namespacesを用いてよりセキュアなシステムにすることは可能か
  • Linuxのアーキテクチャに依存したアーキテクチャならば、Linux自体のアーキテクチャの限界に引きずられた結果、提案されている高集積マルチテナントアーキテクチャの息が短くなることはないか。他のOS前提でのアーキテクチャのほうが、高集積マルチテナントに有利になることはないか。

これらの質問は、実装よりアーキテクチャで解決するという最近の自分の関心事から端を発している。 また、最近社内で輪読している詳解システム・パフォーマンスにて、Solarisが登場する場面が多く、普段さわっている実装がどこまでLinux依存なのかといったことを考えていたためである。

この文脈では、スレッド単位での制御がOSレベルで可能なアーキテクチャであればよくて、カーネル内部でのプロセス表現として知られているtask_struct構造体は、実体としてはスレッドを表現しているはず(要確認)なので、Linuxのアーキテクチャの限界にはおそらくあたらないのではということを軽くあとで会話した。この話はちょうど、輪読会でも議論した。詳解システム・パフォーマンス 3章「オペレーティングシステム」メモ - ゆううきメモ

ところで、その日のmatsumotoryさんのツイートによると僕が強烈な質問をしたことになっていて、おもしろかった。優しく見守った結果のはずなんですよ。

アウトプットについて

エンジニアのアウトプットとは何なのかということを最近というかずっと考えていて、今回、公聴会に参加して、一つの考えがまとまった。

普段からウェブエンジニアのブログ、プレゼン、OSSをみる機会は非常に多いのだけれど、「知識」と「経験」に関するアウトプットに恵まれている一方で、「思考」に基づいたアウトプットが少ないのではないかと感じている。つまり、「知ったこと」と「やったこと」そのもののブログやプレゼンは多いのだけど、自分で問いを立てて「考えたこと」を表現することがあまり重視されない傾向にあるのかもしれない。これは単に数あるアウトプットから僕がその人の考えを読み取れていないだけという可能性もある。

問いを立てて思考した結果は、なんらかの新規性を持っているように思う。 例えば自分の身の回りだと、mizzyさんのServerspecや、同僚であるitchynyさんのsjsp Mackerelにおけるフロントエンドのパフォーマンス改善の取り組み - Hatena Developer Blog であったり、はてなで採用されている実装のないフレームワーク ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011 であったりする。 これらに比べればずっと小さな成果だけれども、自分の場合だと Dockerとchrootを組み合わせたシンプルなコンテナデプロイツール - ゆううきブログ がこれに該当する。

今回の公聴会では、知識と経験をベースに思考を重ねたアウトプットをストーリーとしてみることができた。 そして、このようなアウトプットこそがエンジニアを大きく成長させるようなアウトプットだと確信するようになった。

自分で考えたことというのは、後ろ盾がない状態なので、人にみせるには勇気がいる。 しかし、小さな成果でもよいから、それを乗り越えて、その人らしいアウトプットをみれるとうれしくなる。 これから、自分もこういったアウトプットを志していきたい。

あとがき

matsumotoryさんのことは、自分のブクマを振り返ってみると、5年ほど前から存じ上げていたようだった。 5年前というのはちょうど、人間とウェブの未来 - Linuxエンジニアを辞めて大学院に入学しました の記事にあるように、大きな挑戦をされた年だった。

一方そのころの僕は、はてなでアルバイトし始め、ほそぼそとブログを書き始めた年で、その年の振り返りに

最後のやつ,いつも読んでるブログの,"人間とウェブの未来"の中の人にブクマしてもらえて,おおー ってなった. 忘年した2012年の記憶を掘り起こして忘年意味ないみたいな感じになった - ゆううきブログ

というようなことを書いて喜んでいたようだった。

その翌年は、大学院を中退し、そのままはてなに入社したのだけれども、そのときも、以下のような言葉をかけていただいたのをよく覚えている。

大学院の修了に失敗し、新卒入社にも失敗しました - ゆううきブログ

こんなに怒られるような寛容でない場所は辞めても良いと思う。ブログを見る限りこの方を必要とする企業は沢山あると思うので頑張って欲しい。

2013/11/21 14:05
(しかし、この記事は雑すぎて、新卒入社(4月入社)には失敗しただけではてなには入社しているということを伝える気のない書き方だった。このときは、会社の印象が悪化するのを気にして、はてなっていう単語を出さないように勝手に気遣った記憶がある。)

そこから気づけば、レンサバの常識を覆す「なめらかなシステム」に挑む──運用技術を学術研究して実際のサービスへ適用 - はてなニュース のように一緒にインタビューを受けたり、IPSJ-ONEでバトンを渡していただいたりした 高度に発達したシステムの異常は神の怒りと見分けがつかない - IPSJ-ONE2017 - ゆううきブログ

振り返ってみると、同じ組織に属したことはないし、直接お会いした機会はこれまでせいぜい6,7回程度しかない。 親炙と私淑という言葉を最近知ったのだけど、もともと私淑していたところを徐々に親炙するようになった、よい意味でインターネット的な関係といえるかもしれない。

以上のような背景のもとに、matsumotoryさんの一つの挑戦の集大成をみることができて、なんだかうれしくなってこの日記を書いた。

高度に発達したシステムの異常は神の怒りと見分けがつかない - IPSJ-ONE2017

名古屋大学で開催されたIPSJ-ONE2017 で登壇しました。 IPSJ-ONEというのは、情報処理学会の各研究会から選ばれた日本の若手トップ研究者17人が集まり、自身の研究を高校生でもわかるように発表するイベントです。 1000人ぐらい入る講堂で、しかもニコニコ生放送で配信されるというとても大掛かりなイベントです。

ちなみに、昨年は、同じ研究会からの推薦で、 id:matsumoto_r (matsumotory) さんが登壇されています。 IPSJ-ONE 2016で登壇してきた - 確実に時代は変わってきている #ipsjone - 人間とウェブの未来

発表

「高度に発達したシステムの異常は神の怒りと見分けがつかない」という、一見何の話かわからないやばそうな話なんですが、大真面目に話してきました。

スライドを以下に公開しています。ただ、スライドだと何の話をしているかおそらくわからないので、ニコ生のタイムシフト試聴でたぶん一週間くらいは動画をみれるようです。 http://live.nicovideo.jp/watch/lv289955409#6:40:12 (その後におそらくアーカイブされるはず?)

IPSJ-ONEの趣旨として、登壇者個人の成果や考えを表に出すことを求められており、実際には会社やチームでやっていることの中で、僕個人がやっていることについて話をしたつもりです。

5分の発表なので、10秒レベルで無駄を削って、エッセンスのみを抽出しました。特に、一般の方がわかるような内容であることに最重視しており、専門用語を使わないように徹底しました。

内容と補足

補足を追加した内容を以下に書き留めておきます。

インターネットのシステムは、24時間365日動き続けることが求められている一方で、人手による運用でカバーしている部分がたくさんあります。 これをどうにかしたいと思って、全自動化へ向けて頑張るんですが、全然うまくいきません。 なぜうまくいかないのか。それは、自動化に対する恐れがあると考えています。 実際に現場では、このオペレーションを自動化したいけど、本番にいれるのはかなり検証つまないと怖いよね、というような話を頻繁にしています。 もちろん、開発工数がとれないとか別の次元の話もありますが、怖さを取り除くまでに手間がかかると言い換えることもできます。

なぜそんなに恐れるのか。今のインターネットのシステムは、極めて高度に発達しており、生物/自然を連想するような複雑な系をなしています。 この自然は普段はおとなしいですが、時として天災のような異常となって我々人間に襲いかかってきます。 情報システムの場合は、システム障害ですね。 このような異常が発生するために、人は未知に対する恐れを抱いてしまいます。 これに似た構造があり、古来より人々は、例えば神話のような世界で、未知の異常を神の怒りと表現していました。 実際には、雷や地震といった災害になるかと思いますが、今ではこれらの現象が神様の仕業だと考えることは少ないように思います。 そのギャップを埋めたものは何かと考えたときに、思い浮かんだのが、「観測」でした。

「観測」することで、わからないものがわかるようになった事例はたくさんあります。 情報システムの世界では、「観測」にあたるものを監視と呼びます。 監視というのは、人間でいうところの健康診断に似ていて、人間の場合は、体重とか血圧とかその他もっと細かいメトリックを計測しチェックします。 ウェブサービスのような情報システムの場合は、CPU利用率とかメモリ使用量とかそういったものになります。 これらの情報をなるべく頻繁に大量に集めるためには、専用のデータベースが必要です。いわゆる時系列データベースというものになります。

このデータベースの課題として、お金と性能というトレードオフに取り組んでいます。 観測により、自然科学の観測のような世紀の大発見があるわけではなく、ソフトウェアのバグだとかリソースが足りないとか、相対的に価値の低いものしか得られないので、お金が重要になってきます。 発表では、簡単にアイデアを紹介していますが、より具体的には サーバモニタリング向け時系列データベースの探究 / The study of time-series database for server monitoring // Speaker Deck をみてください。(ところで、ここからさらに発展した内容を5月にそれっぽい舞台で発表することになっています。)

さて、観測の次にやりたいことがあり、それは「実験」です。要は、コンピュータシステムの未知について、科学のアプローチを実施しようというような考えです。 実験というのは、Netflixの Chaos Engineering から連想しています。 ただし、Netflixの一連のツール群を使っているという話はあまり聞きません。本番に導入するにはやはりハードルが高いと感じています。 そこで、観測して得たデータを使って、システムモデルを構築し、シミュレーションのような安全な手段で、システム特性を明らかにし、弱点などをシステム本体にフィードバックするというビジョンを考えました。 ここは本当にジャストアイデアの段階で、例えばモデルって具体的になんですかと言われても答えられません。今のところ、フィードバック制御の理論あたりからヒントを得られないかと考えています。

このようなシステムを作って、人間をコンピュータの未知への恐れから解放したい、そう考えています。

神の怒りというのは、比喩ではありますが、単なる比喩ではなく話の根幹となるような話作りを意識しました。 観測と実験という概念は、最初から考えていたわけではなく、神の怒りからの連想ゲームから、うまく情報システムに落とし込める概念を見つけられたと思っています。

ipsjoneとは関係なく、昨年matsumotoryさんが発表されたなめらかなシステムとは違うものを提案しようとずっと考えていました。 (なめらかなシステムについては レンサバの常識を覆す「なめらかなシステム」に挑む──運用技術を学術研究して実際のサービスへ適用 - はてなニュース)

残念ながら僕は名前を付けられませんでしたが、観測と実験というのをテーマにこれからやっていこうと思います。

いただいた反応

別分野の研究者の方からおもしろかった、スライドがよいとフィードバックいただいたのはうれしいですね。 その他、また聞きですが研究者の方から、一番おもしろかった、我々は神の怒りと戦っていかねばならん、というようなコメントをいただいたと伺っています。 システムビジョンにも共感の声があり、思った以上に伝わっているという手応えを得ることができました。

登壇に至るまで

さて、そもそもなんでお前がそんな場所で発表しているんだという話ですね。 僕はそもそも研究者どころか、修士課程を中退しています。 そこからはてなに入社し、いわゆる現場で運用をやっているエンジニアをやっています。今月にEOLを迎えるCentOS 5の撤退みたいな10年前のシステムを相手にすることもやっていたりしました。 技術者としての実績はそれなりに積んでいるつもりですが、アカデミアにおける実績はほとんどありません。なぜこんな人間が採択されたのかは、今だによくわかっていません。

きっかけは、昨年の登壇者である matsumotory さんに、昨年の6月ごろに、IPSJ-ONEというものがあるので、登壇しないかと声をかけていただいたことです。そのときは、雑にいいですよみたいなことを言っていました。 そのときは、いつもの話で大丈夫と言われた記憶があるのですが、ある意味いつもの話ではあるものの、とんでもない無茶振りであることが後々わかってきます。 その頃はIPSJ-ONEというものがどういうものかあまりわかっておらず、matsumotory さんがちょっと前に登壇したやつぐらいの認識でした。 家に帰って改めて2016年の動画をみていたら、おいおいこれなんか違うやつなんじゃない?、そもそもトップの研究者が集まるとか書いてるじゃんって思いはじめて、その話を忘れていた11月ごろに、matsumotory さんから声がかかってきました。

今、声をかけていただいたDMを見直してみると、めちゃめちゃ大風呂敷を広げた上で、それを回収するみたいな方法で頑張ったのでそれがよさそうと書かれていて、本当にその通りになって笑ってしまいました。加えて、y_uukiが一番得意でかつ、そこに本番までに+アルファできるようなものを提案できると最高とも書かれていました。これも、僕の認識ではその通りになっていて、結果的に、DiamonDBの実装に加えて、観測と実験によるフィードバックループを回すというアプローチの紹介ということになりました。

しかし、最終的に自分のやっていることが世界にとってどういう意味があるかということを加えるとよいという話もあったのですが、ここは本番では組み込めなかった部分です。自動化されて、運用から解放されて、遊んで暮らせるようになるだけなのか?という漠然とした疑念はありました。科学の歴史をみてみると、例えば未知であった電気現象を逆に利用して、今ではコンピュータのような複雑なものを動かすことができるようになっています。そこからさらにメタなレイヤで、同じようなことが起きないかといったことを考えているのですが、これはこれからの宿題ということにします。

そこから、IOT研究会のほうで講演をしないかとという話になったので、招待講演させていただくことになりました。その経緯はブログに書いています。 情報処理学会でウェブオペレーション技術について招待講演した話 - ゆううきブログ

ipsjoneの5分は、僕の発表経験でも3本の指に入る大変さだったので是非頑張ってくださいとも書かれていました。はい、がんばりましたよ。最初は、そんなに大変なことがわかっていなかったのですが、準備を進めるたびに、とにかく大変であることがわかってきました。僕の感覚では、6ヶ月連続200users以上のブログ書いたり、1000usersのブログ書くよりはるかに大変でした。

何が大変だったのか。今までのアウトプットは、自分がやったこととやったことを汎用的な視点で捉えるだけで済みました。 しかし、今回は逆に未来を描いて、自分がやっていることに紐付けるという、頭が痛くなるような手法でした。 しかも、それを一般向けかつLTで伝えることは、余分なものを削ぎ落として、専門家だからこそ難しく書きたくなるようなことを削っていく作業になりました

さらに、僕は自身のテーマというものが、そもそも固まっているわけではありませんでした。ざっくりWebオペレーション技術、SREといった職種/分野の専門性を高めているという程度で、会社の仕事とはまた別の軸で何をやりたいのか、ということを発表準備を通してつくろうとしていました。 テーマがなければ実績もないわけで、実績がある研究者はいいな〜と思いながら、matsumotoryさんの去年のスライドをみると、それまで積み上げてこられた実績が1ページにさくっと書いているだけで、あとはこれからやっていくことが書かれていました。

ようやく、matsumotoryさんの無茶振り具合がわかってきて、初見ハードモードで放り込まれたような気分になっていきました。matsumotoryさんには感謝しています。

ところでこれはトークが採択されたときのmatsumotoryさんの様子です。

f:id:y_uuki:20170321233516p:plain

あとがき

スライドだけみると、なんてことのない単なるライトニングトークにみえるかもしれませんが、その裏でいろいろと試行錯誤したことを記しておきたかったという気持ちで、この記事を書きました。

前述したように、最もこだわったことは、一般の方にちゃんとわかるように話をするということです。 見て動くような内容であれば、工夫をこらさなくてもなんとなく伝わります。我々がいつもやっているような、見えないものをどう伝えるのか、ということを深く考えさせられました。

実は、事前に社内の勉強会で発表したときは、驚くほど無反応でした。だいたい予想はしていたものの、考えすぎて全然だめなのかなーと思って、かなり落ち込んでいました。

しかし、そこから5分の制約を相手に、ボツスライドのほうが多くなるぐらいブラッシュアップを繰り返して、何度も練習して、全然専門家じゃないはずの両親がニコ生で発表をみていて、内容がわかった、わかりやすかったと言ってもらえたことで、発表してよかったと思えるようになりました。

フィードバックの数で言えば、普段書くブログのほうが圧倒的に多いです。しかし、普段のブログや発表はコンテキストを共有しているので、フィードバックが多いのは当たり前です。ちょうど id:Soudai さんが書かれているように、アウェーの舞台で伝えることに向き合った結果、伝えることの難しさ/うれしさを再確認できました。

敢えてアウェーで戦う事に意味があるって話 - そーだいなるらくがき帳

最後になりますが、ipsjone運営委員の皆様のご尽力には頭が上がりません。1回目を立ち上げるのももちろん大変なことだったと思いますが、その後「継続」することは、立ち上げ時の苦労とはまた異なる種類の苦労をされたのだろうと、「運用」を生業とする者としてご推察します。本当にありがとうございました。

2016年のエンジニアリング振り返り

はてなに入社して3年経った。

3年というのは節目と言われる。働き方や考え方の軸が多少変わってきたように思う。 技術観点では、仕事が少しつまらなくなっていた時期があった。 技術的におもしろいことより、つまらないことのほうが優先度が高くなってしまうというよくあるやつだと思う。 もしくは、おもしろいところまで到達できずに、仕事としては十分な成果になってしまうということもあった。

去年の振り返りに、来年はコードを書くと書いていて、多少はできたものの実感としてはあまりできていない。これからのオペレーションエンジニア/SREは、ソフトウェアエンジニアリングによる問題解決ができないと時代に取り残されてしまうという危機感がある。

技術的挑戦を続けていくためには、自分だけでなく、周囲の環境も変えていかないといけないと思い、マネジメントし始めたり、リーダーシップをとったり、直接的な採用活動をするような局面が増えてきた。 それはそれで自分でやると言ってやっていることだし、悪くはないのだけど、これ自分でやっていればアウトプットもできるのになと思いながら、任せないといけないことも多かった。 慣れないことをやっていると、大したことやってなくても疲れるもので、アウトプット活動が止まってしまった時期もあった。

一時的にそういった期間があることは仕方ない、いつも最高の環境があるわけじゃないので、意識的に環境に作用できるようになれれば、それは自分の強みになると言い聞かせてきた。 最終的には、社内外の期待をかけてくださる方々にいくつかのきっかけをいただいて、来年は技術的に挑戦できる年になるという気持ちで年を越せそうだ。 サーバモニタリング向け時系列データベースの探究 / The study of time-series database for server monitoring // Speaker Deck に書いた設計を自分の代表的プロダクトにすべく、プライベートリポジトリでちまちまとコードに落とし込んでいたりする。 このあたりは、今年大変仲良くしていただいたid:matsumoto_rさんと、あとはMackerelチームのプロデューサーである id:sugiyama88 さんのおかげだ。

振り返ってみると、今年は次の挑戦のための土台づくりに専念した年かもしれない。

成長

内在的な技術的成長は多少はあったものの、アウトプットにつながっていないものは成長とみなさないことにしているので、今年は技術的成長があまりなかったといえる。

あえていえば、実際の運用で導入したKeepalivedのシンタックスチェッカーや今書いているソフトウェアの要素であるGraphiteの式のパーザーなど、これまで書けなかったタイプのコードを書けるようになった。トークナイザーとYACCを書いてるだけはあるけど。

あとは、はてなのこれまでのスタックにはないようなアーキテクチャを構築する機会がいくつかあり、アーキテクチャで解決するという手持ちの札が増えてきたように感じる。

技術以外の成長では、多少マネジメントをしたり、プロジェクト管理みたいなことを覚え始めた。SRE本の第18章"Software Engineering in SRE"にも書かれているが、インフラの領域でも、ソフトウェアエンジニアリングを本格的にやるなら、サービス開発のプロジェクト知見も必要なので、役に立つと思う。周囲の方々の助けもいただいて、多少の手応えもつかめた。

そして、今年一番の収穫は、ストーリーをつくるという意識かもしれない。 ストーリーというとプレゼンのようなものを連想する。もちろんプレゼンも含むのだけど、もっとこう自分の技術の取り組みのストーリーみたいなものを考えるようになった。 普通のエンジニアである僕がなぜか来年に登壇することになったIPSJ-ONEの演題を考えたり、研究会での登壇があったり、あとまだ公開されていない何かのためにまつもとりーさんの論文や口頭発表、ブログを読み返したことが影響している。 博士課程では、複数回のジャーナルを通して、最後にそれらをまとめるということをやるようなので、その手法にも影響を受けている 博士課程の予備審査にいってきました - 人間とウェブの未来, NAKAHARA-LAB.NET 東京大学 中原淳研究室 - 大人の学びを科学する: 博士論文とは「構造を書くこと」である!?。 自分のストーリーがあれば、次に何を勉強するかも決まってくる。 僕のように瞬発力とか手の速さで勝てない凡人は、ひたすら考えて、自分のやってきたこと、これからやることを繋いでいくしかない。

アウトプットまとめ

いつものようにブログやOSS活動を振り返る。

ブログ

いつものブログに加えて、今年から技術メモとしてGitHubにちまちまとメモを残していたりする。

順位 エントリ
1位 Linuxサーバにログインしたらいつもやっているオペレーション - ゆううきブログ
2位 ウェブアプリケーション開発に新言語を採用したときにインフラで考えたこと - ゆううきブログ
3位 Googleが数千台もある10年前のLinuxディストリをライブアップグレードした話 - ゆううきブログ
4位 自作Linuxコンテナの時代 - ゆううきブログ
5位 インフラエンジニアがGo言語でオペレーションツールを書くことについて - Hatena Developer Blog
6位 2015年の心に残った技術エントリ - ゆううきブログ
7位 ISUCON予選突破を支えたオペレーション技術 - ゆううきブログ
8位 2016年ウェブオペレーションエンジニアの新卒研修 - Hatena Developer Blog
9位 情報処理学会でウェブオペレーション技術について招待講演した話 - ゆううきブログ
10位 2016年はてなWebオペレーションエンジニアのアウトプット - Hatena Developer Blog
11位 ウェブオペレーションエンジニアになるまでの思い出 - ゆううきブログ
12位 リモートワークにおけるSlack Call活用と終業15分前の雑談 - Hatena Developer Blog
13位 nginxのステータスコード444 · yuuki/yuuki
14位 nginxのステータスコード499 · yuuki/yuuki
15位 Keepalivedのシンタックスチェッカ「gokc」を作った - ゆううきブログ
16位 リバースプロキシのコンフィグテスト

合計 8000 users+くらい。

発表

合計8件。

OSS

f:id:y_uuki:20161231215324p:plain

Graphiteへのパフォーマンス改善PR。

go-sql-driver/mysqlのMySQL 4.0対応をして、MySQLプロトコルの知見を深めたりした。 https://github.com/yuuki/go-sql-driver-mysql

他には、ISUCON6予選の出題側としてGo実装とインフラまわりの手伝いをやったりした。

まつもとりーさんの振り返り にも書いていただいているように、今年はペパボさんのエンジニアの方々と交流させていただくことが多く、大変刺激になりました。 はてなの技術力が非常に高いと称していただいていますが、僕としてはどちらかというと我々はまだまだだなあと思っていて、ペパボさんの取り組みは、前へ進む勢いを感じさせられるというか、一本筋が通ってみえるというかそんな気がしています。 我々はまだ場当たり的に問題を解決していってて、このままではいけないと思い、はてなシステムについて考えてたりしている。

あとがき

他のエンジニアの方々の振り返りを眺めていて、たぶん自分より若い人の台頭がすごいなあと感心している。

悔しいので、負けないようにがんばろう。

今年もお世話になりました。来年もよろしくお願いします。

ウェブオペレーションエンジニアになるまでの思い出

書籍「ウェブオペレーション」の中で、「ウェブオペレーションは技芸であり科学ではない」*1という言葉がある。 実際、その通りだと思う。 しかし、技芸というのはどうやって学べばよいのか。 教科書のようなトップダウンな知識体系を構築しようと試みようとしても、どうしても特定の組織に依存したり、特定の技術スタックに依存してしまう。

現時点では、体系立てて学ぶというより、やはりボトムアップに学ぶしかないと考えている。 「ウェブオペレーション」の内容も、基本はストーリー仕立てのエッセイ集になっているのは、そういうことだろう。

Hatena Engineer Seminar #7では、もともとウェブオペレーションの学び方の話をしようと思っていたが、前述のような事情で、自分(id:y_uuki)の場合の学んできたことを例として挙げることにした。 ウェブオペレーションエンジニアの前提となるスキルセットの作り方の一例として紹介する。LT資料なので勢い重視なのは許してほしい。

大学1年からLinuxを触り始めたときからはじまり、C言語を学び、ネットワークプログラミングを学び、アルバイトで巨大なCのプロジェクトをgdbを駆使してトレースしたり、はてなインターンにいったり、研究でSIMDとかGPUとかネットワークスタックとか触ってたり、はてなアルバイトでMackerelの前身を作ったり、子どものころを振り返ってみてシステムっぽいものが好きだったり、といった内容の話をした。

ウェブオペレーションエンジニアになった動機の一つに、教科書に書いてあるような古典的な知識が現場で活用されていることがおもしろいと感じていたことがある。 例えば、書籍「大規模サービス技術入門」*2では、MySQL(MyISAM)のテーブルファイルをあらかじめcatで読ませて、OSのページキャッシュにのせることで暖機運転がわりにする手法に感心したのを今でもよく覚えている。 このような考え方は、自分の技術スキルの方向性にも影響しており、2015年Webサーバアーキテクチャ序論 - ゆううきブログ自作Linuxコンテナの時代 - ゆううきブログ などに表れている。

わざわざ語るような大層な経験はなく、ごく平凡な来歴だなと思う一方で、アウトプットだけは人並み以上にやってきたという自負がある。ちまちましたことでも続けていれば、それなりの何かにはなるものだ。 もし今回の話に共感するところがあり、ウェブオペレーションやSREという技術領域に興味をもってもらえたなら、うれしく思う。

ちなみに僕の場合は、自然科学実験みたいな物理作業をとにかくやりたくなくて情報科学科に入ったので、「モノ」としてのサーバやネットワーク機器にあまり興味がないけど、なんとかやっていけている。

あわせてよみたい

同僚にはこういう変な人もいる。

*1:John Allspaw、Jesse Robbins編、角 征典訳,ウェブオペレーションーーサイト運用管理の実践テクニック,オライリージャパン

*2:伊藤 直也、田中 慎司,[Web開発者のための]大規模サービス技術入門 ―データ構造、メモリ、OS、DB、サーバ/インフラ (WEB+DB PRESS plusシリーズ), 技術評論社

情報処理学会でウェブオペレーション技術について招待講演した話

情報処理学会インターネットと運用技術研究会が主催されているIOTS2016という研究会で、「サーバモニタリング向け時系列データベースの探究」というタイトルで招待講演をしてきました。

講演のきっかけ

インターネットと運用技術研究会(以下IOT研究会)というのは僕にとっては id:matsumoto_r さんが所属されている研究会です。 matsumotoryさんが、ちょうど2年前のアドベントカレンダーで書いた僕の記事に日本語だとIPSJのIOTは分野的にもインターネットの運用技術が含まれるので興味深い論文が沢山あると思う とコメントしていただいたのが最初に研究会の存在を知るきっかけだったと思います。 そのときはそんなものもあるのかと思ってちょっとプログラムを眺めた程度でした。 しかし、まさかその2年後にこうして招待していただくことになるとはもちろん思っていませんでした。 id:MIZZYさんがserverspecの論文をだされた研究会でもあります。

きっかけは、今年の6月ごろです。 やはりmatsumotoryさんに講演とは別件のとあるびっくり無茶振りを受けました。 そして、少し前にIOT研究会へいくつかの資料を提出したところ、次のIOTS2016で講演してくれという話をいただきました。 IOTSがどんなものかわかってなかったのですが、査読付きで1年で1番大きな研究会であり、matsumotoryさんがそこで招待講演できるの羨ましいとおっしゃっていたので、じゃあやります、と答えました。

講演内容

講演するにあたって、当たり前のことですが、まず伝えたいことを考えました。 IOTS2016の開催案内をみてみると、「運用でカバーする」、「運用担当者の人柱の上に成立する前時代的で野蛮な構造物」、「不快な卑しい仕事をやる必要がなくなるのは、人間にとってひじょうな福祉かもしれないが、あるいはそうでないかもしれない」といったなかなか興味深いセンテンスが散りばめられていることに気づきました。 研究者と技術者という、コンテキストが異なるものの、同じ運用技術に携わっているという前提があります。 そこで、ウェブサービスの運用の世界で実際に起きていることと生の課題を伝えようと思いました。

これを伝えるための話作りには、いくつかの案がありました。 ひとつは、そのまま「ウェブサービスの運用の世界」といったタイトルで、ウェブオペレーションを概観する話をするというもの、もうひとつは、時系列DBやコンテナ型仮想化など特定の技術の話をするというものです。

最終的には後者にしました。 ちょうど時系列DBのアーキテクチャ刷新に取り組んでいるため、成長するサービスとスケーラビリティといういかにもウェブオペレーション技術っぽい話ができます。 自分がまだ大学にいた頃から取り組んでいたことであり、時系列DBの話をすることは自分がこれまでがんばってきた技術の話をすることにもなります。 さらに、研究会なのだから、論文にできそうなテーマならなおよいはずと思って、最新の取り組みを紹介したかったというのもあります。

だいたい話すことは決まっていたものの、ストーリー化することには苦労していて、2日くらい前にインフラチームの同僚何人かに見せたら反応が芳しくなかったので、同僚の意見を取り入れて、大幅にスライドを書きかえました。 無意識に研究発表的なスライドっぽくつくってしまっていた気がします。 トップダウン視点ではなく、自分視点に置き換えていって、アーキテクチャの説明はすべて図にしました。 会社としてというよりは個人として招待されたと思っているので、結果として自分視点になってよかったと思います。

matsumotoryさんには、見事に上記の意図をすべて汲み取っていただきました。

講演の導入には、まず異なるコンテキストのすり合わせをしようと思って、開催案内を引用させていただきました。 不快な卑しい仕事というのは、書籍Site Reliability Engineeringに書かれている"toil"に相当し、Googleでさえtoilからは逃れられていないが、toilではないエンジニアリングに価値を置いていると伝えました。 toilを消すことは、最近のエンジニアのコンテキストにおいても重要であり、そのような研究活動には価値があるということを暗にお伝えしたつもりです。

発表スライド

発表スライドを以下に貼っておきます。 あとで読む資料としてはまとまりがない点についてはご容赦ください。

若いと言われるが実際若くて平成生まれとか、IOTSの開催案内を会社の全体朝会で紹介したら社員のみんなが大喜びだったとか、アルバイト時代になんか癒やしとか言われてだまされてRRDtoolのCPANモジュールつくってたとか、入社するころにはRRDtoolは若者にはふさわしくないことがわかってきたとか、いつものように調子よくしゃべってたら笑いもとれたので、話をしていて楽しかったです。 以下のスライドがハイライトです。

講演を終えて

僕のことをご存知の方は、3年前に大学院を中退したことを覚えておられるかもしれません。 単に特定の環境とあわなかっただけというだけかもしれません。しかし、自身の体験だけでなく、社会人になってからも、大学の研究室で苦しんでいる学生たちの声を何度か聞くこともありました。 このこともあって、研究活動そのものはともかくとして、大学や研究室といった環境に強いネガティブな感情を今だにもっています。

今回の件は、大学から離れ、現場のエンジニアとしてがんばってきた成果をアカデミックな場で話すよい機会でした。 幸いなことに、思った以上に「話が通じる」という感覚を得られ、うれしく思いました。 もちろん、何を言ってるのかさっぱりだと思われた方も少なくはないでしょうが。 他の発表でもAmazon RedshiftとかKibana、Graphana、Elasticsearchなど見慣れた単語がとびかっていたので、安心感があります。

一方で、大学関係のシステムの運用を対象とした話がやはり多く、それらについてそれほど興味があるわけではありませんでしたが、おもしろく聴けた発表がいくつかありました。 特に柏崎先生の発表はとにかくいきおいのあるスライドというかこれは本当に学会発表か?と思うほどでした。 @hirolovesbeer さんの異常検知の話は質問したところ、イベントネットワーク以外にもサーバのログの異常検知にも使える可能性があるとのこと。

これ使えるなーと思ったものが論文優秀賞をとられていて、エンジニアの視点でよいものがちゃんと評価されるんだなと感じました。

ウェブオペレーションやSREに関する学術研究発表があればもっとおもしろく感じるだろうなと思います。 というのは、最近のウェブエンジニア界隈を眺めていて、それは本当に有用なのか、新しいおもちゃを使わされているだけになっているんじゃないかと疑問に思うことが増えてきて、真に有用な技術ってなんだろうなと考えたりすることがあるからです。

そういった考え方、アカデミックなアプローチで技術をつくるという方向性は自分の課題意識とマッチしているのではと思うことはあります。 博士過程へのお誘いもいただいたりしたのですが、前述のネガティブなイメージを払拭するのはすぐには難しいですね。 そもそも生半可な覚悟では社会人で博士号取得なんてできるわけないので、今後、「おもしろそう」「すごいことをやっていそう」「成長できそう」といった強いポジティブなイメージに転換できるかどうかが鍵になると思っています。

帰り際に、あのゆううきブログの中の人ですよね?と話かけていただいて、大学の中の人にまでリーチしているのかとちょっとびっくりしました。 大学を去ったその後に、大学の中の人に影響を及ぼしているというのは不思議な気分ですね。

この記事は、はてなエンジニアアドベントカレンダー2016の4日目の記事です。昨日は id:wtatsuru によるセキュリティ会の取り組みでした。 明日の担当は、buildersconで発表してきたばかりの id:shiba_yu36 です。