KinesisかS3か

Kinesisを触ってはみたものの、特別「これは使いやすい!」という印象ではなかった。

Kinesisの用途は要するに

  • AWSにガンガンデータを送る
  • AWS側では、送られてきたデータを片っ端から処理する
  • AWS側に着いたデータは処理しようがしまいが一定期間(現在は24時間)で消える

というもの。

しかし、AWSへの送信は単純にHTTPSのPOSTリクエストであり、さらにBase64エンコードされているということで特に効率的な方法ではない。むしろ効率をまったく考慮しておらず、シンプルさ、扱いやすさに徹している。

HTTPSのPOSTリクエストであるにも関わらずサイズ上限(現在は50KB)がきついので、小さなデータを送る用途に限定される。

個人的に数十~百台程度のサーバからAWSへのログの集約(Log Aggregation)を計画しているのだが、Kinesisの用途にぴったりか?と考えた一方で、S3でもいけるのでは?と思った。

S3も

  • AWSにデータを送るために使える
  • HTTPSのPOSTリクエストでデータを送ることができる

という意味ではKinesisとまったく同じ。各オブジェクトのサイズの上限はKinesisよりずっと緩い(具体的にいくつなのかは調べてませんスミマセン)。

そのため、ログ集約にS3を使うというのも十分に悪くない考えのように思える。

S3では

  • 秒間100以上のPUT要求がコンスタントに発生する場合

を「high request rate」と定義しているようである。(ドキュメントへのリンク)

そのため、Kinesisとは1桁以上、対象としているトラフィックの性質が異なるようだ。
ただしS3へは例えば「ログを100行まとめて1つのオブジェクトに入れる」みたいに少し工夫するだけでこの問題は解決する。

KinesisにするべきかS3にするべきか。

シンプルさ

S3の場合、各サーバがそれぞれS3にアップロードリクエストを送るだけでAWSへの集約そのものは終わるというシンプルさが非常に大きな利点になる。

Kinesisでは各サーバがAWSへデータを送る一方で、AWS側には別途Kinesisアプリケーションを配置しなくてはならない。

データの消去

Kinesisが自動的に古いデータを消すという点については、ケースによってメリットになったりデメリットになったりするだろう。

データの順番

Kinesisで送られてきたデータはストリームとして扱われるので、あるデータを処理したら「次のデータ」を取得する、というアクションが可能である。
S3では各オブジェクトはバラバラなので、「次のデータ」のような概念が必要な場合には、ユーザが自分でその仕組みを考えなくてはならない。
数多くのセンサーのようなものからAWSに対してデータを送信し、時系列で処理していきたい場合などには、Kinesisの方が向いていることになる。
S3で時系列に処理していきたい場合には、S3へのアップロードのログが取得できるようになった時点で、ログを元に処理していくような方法が考えられるだろうか。

モニタリング

KinesisはAWSコンソールでほぼリアルタイムに使用状況を把握できるが、S3はできない。この点は明らかにKinesisの勝ち。

ざっくりとした結論

数百~千/秒以上の、それぞれのサイズはそれほど大きくないデータを扱いたい場合にはKinesis、~数百/秒でそれぞれのデータのサイズはそれなりに大きくなる(50KB以上)場合にはS3だろうか。

(余談: FluentdやFlumeは当然向いているのだと思うが、今回はとにかくシンプルにAWSだけで片付けることを考えている)


Elastic BeanstalkでJenkinsを動かしたけどすぐやめた感想

Elastic Beanstalk(Tomcatのやつ)はAuto Scalingするようなウェブアプリケーションに向いている。つまりサーバのインスタンス自体は状態を持たないことを前提とする設計が向いている。

今回、Elastic Beanstalkそのものを触ってみたかったので、手っ取り早く手元にあったjenkins.warをアップロードしてみた。

Jenkinsはプラグインのインストールやジョブの設定、ジョブの実行ログなど、基本的にローカルファイルシステムにデータをじゃんじゃん蓄積するものなので、そういう意味で「状態もちまくり」であり、真のMutableアプリケーションという感じ。

Elastic Beanstalkは設定変更を行ったりするとすぐにイメージをまっさらな状態で作り直すので、その際にJenkinsが貯めていたデータはすべて破棄される。なので基本的に向いてない。もちろん工夫を重ねればElastic Beanstalk上で運用することもできるだろうけど、メリットが小さいなという印象。

Elastic Beanstalkそのものの完成度やコンセプトは素晴らしい。EC2やVPCその他、AWSの知識がある人には、「なるほどこう組み立ててくれるのね」という感じで便利。逆にあまり詳しくない人は「どこまでがElastic Beanstalkなんだ!?」となりそう。


Amazon Kinesisに触ってみた感想

公式ドキュメントにあるサンプルソースコードを参照に、データのput/getを試してみた。
(IRecordProcessorは軽く見ただけ)
以下、感じたことを箇条書き。

 

富豪的ネットワーク転送

(個人的に富豪的なのは嫌いじゃないんだけど…)
データは基本的にbyte[]を送るんだけど、Kinesisの最も低レベルなAPIではHTTPのPOSTリクエスト、かつボディ部がJSONという形式で送られる。

{"StreamName":"teststream1","Data":"dGVzdERhdGEtMA==","PartitionKey":"partitionKey-0"}

生のbyte[]をどう扱うのかと思ってたらBase64だった(;´Д`)サイズ膨らみますね

HTTPのPOSTで送るだけでもオーバーヘッドがあるのにBase64っすか。。。って感じで意外でした。
大規模なLog Aggregationのシステムを組む場合、例えば1行ごとにKinesisに投げるように作ると、相当無駄なトラフィックが発生する感じ。
通信もHTTPSだしリクエスト毎に署名作業が発生するし、CPUにもそれほどやさしくなさそう。同じCPU使うなら圧縮すればいいのにとか思わないでもない。(もしかしたら転送時にgzip圧縮してたりするのかも。未確認)

 

 

期待していたよりやや複雑

ShardIteratorとかシーケンス番号とか、そこそこ複雑だった。もうチョイ楽にならなかったか?という印象。
IRecordProcessorを使うサンプルも見たけどそんなに楽になっていないような…
まぁ、APIが8種類くらいしかないのは、とりあえずシンプルでよかったです。

 

 

データ形式が潔すぎる

上でも書いた通り生byte[]なので非常にわかりやすいけど、JSONとかのサポートもあっても良かったんじゃないかと。
(もちろん自分でser/deすりゃいい話ですが)

これだけ(;´Д`)
ちょうどLog Aggregationを考えているところだったのでKinesisには非常に期待しています。とりいそぎ東京に早くきてほすぃ。


ソフトウェアのライフサイクルについて

前のエントリで「OSSなら使い続けてもOK」と書いた。
しかしそれを実際に行うには、そのソフトウェアをソースコードレベルでメンテナンスするための技術力を持った人間が必要になる。
(僕はPHPはメンテナンスできないのでWAFでなんとか逃げたが、これはベストではなくベターな選択肢だろう)
もし社内にOSSをメンテできる技術者がいない場合にはどうすればよいだろうか?多くの場合はいないだろう。
EOLを迎えたOSSに有料でパッチを開発してくれる開発会社などがあってもよさそうだ。
RedHatなんかはLinuxカーネルにバグが見つかった場合などに、古いバージョンのカーネルに対しても該当するパッチを開発してくれていると思うが、あれに似た感じ。

要するに、EOLを迎えたOSSを使い続けるには、コストがかかるということだ。
OSSは(少なくともある特定のバージョンは)大体どこかでEOLを迎える。例えばRDBMSのPostgreSQLはもうずいぶん前から広く使われているけど、現在も7系統や8系統を使っている人もいると思う。
いきなり最新版の9にバージョンアップできればいいんだけど、細かい仕様が変わっていたりするので、切り替えてもアプリケーションに不具合がでたりする。そのため、結局バージョンアップをためらっているうちにEOLになってしまう。

先に書いたようにEOLを迎えたOSSを使い続けるのはコストがかかる。では使っているソフトウェアがEOLにならないようにする、という戦略はどうだろうか。
できるだけポピュラーなソフトウェアを選択し、常に最新版に保つのである。
この場合、以下の問題がある。

・ソフトウェアの選択を誤ってしまい、徐々に開発が活発でなくなり、最終的にEOLになってしまう
・常に最新版に保つために、バージョンアップ作業に伴う作業コストが必要

どちらの場合にも言えることは、コストがかかるということだ。

結局、結論として言えることは、長い目で見た場合、OSSにただ乗りできたからといって最終的に安上がりだとは言えないということである。

では商用ソフトウェアならどうか?というと、最初からお金がかかるので当然コストがかかり、安上がりではない。そのため特に商用ソフトウェアが優れているということでもない。
特に、作ってみたが使われずに、すぐ死んでしまうアプリケーションなどは、初期コストがかからないOSSに向いていると言えるだろう。
内製という選択肢もあるかもしれないが、これも当然OSSを持ってきて使うより初期コストは高くなる。

さて視点を変えてみる。僕がStruts1の騒ぎを見ていて思ったのは、「Struts1のような古いソフトウェアが未だに使われているということは、けっして悪いことではない」ということだ。何が言いたいかというと、「皆に使われ続けている、実際に役に立つアプリケーションだからこそ、いまだにStruts1なのにそこにある」ということである。

ソフトウェア開発者なら経験があると思うが、開発されたはいいものの、結局ろくに使われず、消えていくアプリケーションはたくさんある。「モッタイナイ」の精神ではないが、せっかく作ったのだから、アプリケーションはたくさん使われて欲しいと思う。

「OSSを使い続けるにはコストがかかる」という認識を皆で共有し、たとえ(Struts1のように)EOLを迎えたものであっても、きちんとコストをかけて安全な状態を保ちながら使っていこう、というのがよいのではないだろうか。


Windows XPは使い続けてはダメだけどStruts1は使い続けてもいい理由

1行まとめ: OSSだからヽ(´ー`)ノ

ソフトウェアのライフサイクルの問題は、僕自身が10年以上続いているウェブサイトやウェブアプリをいくつかメンテナンスしていることもあり、非常に興味がある。
WindowsXPのように商用のソフトウェア場合、マイクロソフト以外がパッチを発行するわけにいかないので、「サポート終わりです」と言われたらもう使い続けることができない、という結論になるだろうと思う。

でもStruts1のケースは、WindowsXPとはまったく違う。「Struts1はEOLです」としているのはあくまでもStruts1の事実上の開発主体であったApache Software Foundationであり、ソースコードの改変の自由については、もちろん保たれたままだ。だから、Forkして自由に機能追加やバグ(脆弱性)修正を行うことができる。

今回話題になったClassLoaderにアクセスできる脆弱性などは、修正すること自体はそれほど難しいものではない。そのため、別に慌てることなく、淡々とパッチを開発して、それを適用すればよいという話になる。

go.jpやco.jpで拡張子が.doだからといって、叩かれる必要はない(もちろん今回の脆弱性に対する対策は何かしらするべき)。

僕自身では、ついこの間までPHP4.3という古いバージョンのウェブアプリケーションを運用していた。PHPのソース(C言語で書かれている部分)を読んでパッチを開発するというのはちょっと厳しかったので、基本的に脆弱性等の対策はWAFでやるというスタンス。