GAE開発の落とし穴
Googleのクラウド環境をつかったGoogle App Engineによる開発するにあたり、初めての試みで苦悩する開発者達の経験をもとに、各開発フェーズにあわせて問題点やどう解決したかをご紹介します
ブックマークされました!
ブックマークがエラーになりました。もう一度お願いします。
作者 Abel Avram , 翻訳者 南 伸二 投稿日 2009年7月5日
Twitterサービスチームの主任エンジニアであり、主に最適化とスケーラビリティを担当しているEvan Weaver氏が、QCon London 2009においてTwitterのアーキテクチャ、とりわけ過去一年にわたって行ってきたウェブサイトの最適化について語った。
Twitterで使われているツールの多くはオープンソースである。そのスタックは、フロントサイドにRails、中間のビジネス層にC、Scala、Java、データストアとしてMySQLを利用してつくられている。すべてがRAM上に保持されており、データベースは単なるバックアップである。Railsのフロントエンドはレンダリング、複合キャッシュ、DBクエリ、同期的挿入を扱う。このフロントエンドは、MySQLクライアント、Memcachedクライアント、JSONクライアントなどの、多くはCで書かれたいくつかのクライアントサービスを主につなぐ役目も果たしている。
ミドルウェアとしては、Memcached、ページキャッシュとしてのVarnish、Scalaで書かれたMQであるKestrelを利用している。さらに同じくScalaで書かれた、多数のつぶやき(tweets)をトラッキングしようと考えているクライアントが使うCometサーバを利用するための作業が進行中である。
Twitterは“メッセージングプラットフォームではなくコンテンツマネジメントプラットフォーム”として始まっており、そのため、まとめて読むことを基礎にした初期モデルから、すべてのユーザが最新のつぶやきで常に更新される必要がある現在のメッセージングモデルに変更するために、多くの最適化が必要とされた。変更は、キャッシュ、MQ、Memcachedクライアントという3つの領域で行われた。
各つぶやきは平均126ユーザにトラッキングされている。そのため、明らかにキャッシングが必要である。当初の設定では、APIだけがユーザからつぶやきが届くたびに無効化されるページキャッシュを持ち、残りのアプリケーションはキャッシュレスであった。
アーキテクチャの最初の変更は、64ビット整数で直列化されたtweet IDの配列を含むライトスルーキャッシュであるベクターキャッシュ(Vector Cache)をつくることだった。このキャッシュは99%のヒット率を持っている。
2番目の変更は、ユーザとつぶやきのデータベースレコードを含む別のライトスルーキャッシュである列キャッシュ(Row Cache)を加えることだった。このキャッシュは95%のヒット率を持ち、Cache Moneyと呼ばれるNick Kallen氏のRailsプラグインを利用している。Nick氏はTwitterのシステムアーキテクトである。
3番目の変更は、つぶやきの直列化バージョンを含むリードスルーキャッシュである断片キャッシュ(Fragment Cache)を導入することであった。ここで、つぶやきの直列化バージョンとは、APIクライアントを通してアクセスされ、JSON、XML、あるいはAtomでパッケージングされているものである。このキャッシュも同じく95%のヒット率を持つ。断片キャッシュは「直接ベクターを消費し、もし直列化された断片がその時点でキャッシュされていたら、誰かが見ようとして要求したつぶやきの実際の列データをロードしない。そうやって、データベースアクセスを避けて、多くの時間を節約する」とEvan氏は述べた。
さらにもう1つの変更は、ページキャッシュとは分離されたキャッシュプールをつくることだった。Evan氏によれば、ページキャッシュプールは直接的な無効化ではなく、世代型キー手法(generational key scheme)を用いている。その理由は、クライアントは
HTTPのif-modified-sinceを送ることができ、リクエストの中で好きなときにタイムスタンプを押すことができます。また、私たちはその列をスライスして、クライアントが見たいつぶやきだけをクライアントに提供する必要があります。しかし、クライアントが利用した可能性のあるキーをすべてトラッキングしたくはないのです。この世代型手法には大きな問題がありました。なぜなら、すべての無効なキーを削除することができなかったからです。つぶやきの数にしたがってユーザが受け取る各ページが追加されるたびに、キャッシュ内の有効なデータを押し出してしまいます。その結果、私たちのキャッシュは5時間の実効時間しか持つことができませんでした。これらのページキャッシュのすべてがずっと流れ続けているからです。
ページキャッシュがプールに移動されることで、キャッシュミスは50%削減された。
以下の図が現在Twitterによって使われているキャッシュ手法の図である。
Twitterのトラフィックの80%がAPI経由であるため、そこには2つのレベルのキャッシュが追加されている。それぞれのキャッシュは、その前の層から来るリクエストの最大95%を提供する。全体のキャッシュの変更は、計20から30の最適化によって達成され、それによってもたらされたものは
10倍のキャパシティの改善でした。もっとできたかもしれませんが、私たちはその時点で別のボトルネックにぶち当たったのです…。私たちの戦略は、まずリードスルーキャッシュを追加し、それが正しいものを無効化することを確かめ、その後で、ライトスルーキャッシュに移し、新しいtweet IDが届くたびごとにキャッシュを壊すのではなく、修復してオンラインにすることです。
各ユーザには平均して126のフォロワーがいるので、各つぶやきに対するキューには126のメッセージが存在するということになる。そうでなくても、トラフィックがピークに達する時というのがある。それはオバマ大統領の就任式のときなどで、そのときには、毎秒数百のつぶやき、言い換えるとキューの中に数万のメッセージがあるという状態になり、そのトラフィック量はその当時の通常のトラフィックの3倍の量であった。MQはピークを見つけて、それを時間をかけて分散するようにし、その結果として、さらなる多くのハードウェアの追加をしなくてよいようにする。TwitterのMQはシンプルである。Memcachedプロトコルをベースとしており、ジョブの順序づけはなく、サーバ間の共有状態もなく、すべてはRAMに保持され、トランザクション処理である。
MQの最初の実装はRubyで書かれたStarlingを利用していたが、特に世代型ではないRubyのガベージコレクションのためにうまくスケールしなかった。その結果、ガベージコレクタがその作業を終えるまでの間キュー処理全体がある時点で止まってしまうことが理由でMQがクラッシュした。そこで、MQをより成熟したJVMのガベージコレクションを利用するScalaに移植することが決定された。現在のMQはたった1200行のコードからなり、3つのサーバ上で稼動している。
Memcachedクライアントの最適化は、クラスターのロードの最適化を目的としたものだ。現在のクライアントが使っているものは、libmemcachedであり、Twitterがその最も重要なユーザであり、コードベースへの貢献者となっている。そのlibmemcachedをもとにして、一年以上かけて断片キャッシュの最適化を行うことにより、1秒間に処理するページリクエストが50倍に増加した。
リクエストに局所性がないため、リクエストを処理するもっとも高速な方法は、データを必要なときに各サーバで再処理することではなく、データを事前処理しネットワークRAM上にストアすることである。この手法はWeb2.0のサイトの多くで利用されているもので、それらのサイトはほぼ完全にメモリ上で稼動している。次のステップは、Evan氏によれば、「1年間読み取りのスケーリングを行って、その後、書き込みのスケーリングを行う。それから、複数コロケーションの問題に取り組む」とのことだ。
QConでのプレゼンテーションのスライドがEvan氏のサイトで公開されている 。
【ネクストスケープ】.NET、C#のアプリケーション開発者募集
世界の先進エンジニアが集結 - QCon TOKYO 2012 早期割引実施中!
Googleのクラウド環境をつかったGoogle App Engineによる開発するにあたり、初めての試みで苦悩する開発者達の経験をもとに、各開発フェーズにあわせて問題点やどう解決したかをご紹介します
去る1月12日、定理証明支援系ツールCoqの初心者向けチュートリアルが開催さ れた(http://kokucheese.com/event/index/23667/)。今後も2月2日 (http://kokucheese.com/event/index/23744/)、2月9日、2月16日と引き続き開 催されていく予定である。本記事では、開催の様子をレポートする。
Neal Gafter氏はOracleによるJava買収の影響に関する議論、Javaにセグメンテッドスタックやメタオブジェクトプロトコルを追加することについての主張、そしてJavaとC#との比較について話をしてくれた。
GoogleはVMをともなう新しい言語であり、JSコンパイラでもあるDartをプレビューした。 InfoQはDartのアプリの構築に貢献する文法の裏側を探った:スナップショット、Isolate、モジュール方式
本記事ではCSPベースの「マルチドメイン・モデル検査ツール」である、PAT(Process Analysis Toolkit)について紹介する。モデル検査は、形式手法(Formal Method)という方法論を基礎とする技術であり、複雑さが増大しながらも安全性を求められる、現在のソフトウェア開発の状況に対する処方箋の1つとして注目されている手法である。
前回まで、Jenkinsの幾つかの側面に注目して解説をしてきました。シリーズ最後の今回は、Jenkinsをサービスとして使う方法を紹介します。
Alloyは、MITにて開発された仕様記述言語であり、ツールによる自動解析を使い、インクリメンタルに形式仕様が書けることが特長である。筆者らはAlloy開発者による、Alloyを使った形式手法入門書を翻訳、今夏にオーム社より刊行した。本記事では、Alloyの簡単な概要と、翻訳書『抽象によるソフトウェア設計』(「Alloy本」)を紹介する。
スマートフォンを中心としたマルチデバイスにおけるタッチユーザーインターフェイスへの対応は、既に必須の項目となりつつある。本記事では、Windows デバイスにおける UX のベースとなっている「メトロ」というデザイン言語を掘り下げながら、既存環境を意識しつつもどのようにタッチユーザーインターフェイス開発に取り組んでいくべきであるかについて解説していく。
No comments
スレッド表示 返信