投稿

ラベル(server)が付いた投稿を表示しています

Disqus のスケール - Django で月間80億PVを処理する

私が把握してる限り Django で一番大きなサービス Disqus のスケール (執筆時点ではサービスダウンしてる)。元ネタは Scaling Django to 8 Billion Page Views です。 月間80億PV 、 45k req/s のほぼすべてのトラフィックを Django で処理しているとのこと。抄訳になるかな。 WAF は 高速開発とパフォーマンス 、 新しい人が入ってすぐに開発に参加できることとカスタマイズ 等のトレードオフがあります。この記事ではそのトレードオフである高速開発とパフォーマンスをどう両立させるか、Disqus のノウハウが紹介されています。 >>> なぜ WAF (Web Application Framework) は遅いのか 最初に思い浮かぶのは、アプリケーションに必要ではないボイラープレート ( django.contrib とか?) や不要なコードがあるため。そもそも Django の思想が Python 同様 " バッテリー同梱 (batteries included) " のため、Django は他の Python 製 WAF よりボイラープレートが多いです。Disqus 曰く "実は 言語や WAF は遅さにあまり関係ない " それより " ネットワーク内の他のサービスとの通信 " のオーバーヘッドが原因とのこと。これは一般的によく言われてることですし、大規模になればなるほどそう。Disqus の場合は PostgreSQL, redis, Cassandra , Memcached 等のサービスが使われているそうです。DB へのスロークエリーやネットワークのレイテンシーは Django のようなボイラープレートによるオーバーヘッドを軽く上回ります。この待ち時間を回避する一番メジャーな方法はキャッシュの使用です。Django では キャッシュフレームワーク を使用します。Django でキャッシュを使うのは簡単ですし、バックエンドに Memcached を使うと充分高速化できます。 はい。ここまでは一般的な話です。こっから。 >>> 45k req/seq を処理する キャッシュしたところで...

Netflix のスケール - オートメーション編

遅くなったけど続編。前回 TODO にしてたスケールアウトのオートメーションあたり。AWS のオートスケールについては、 本家ドキュメント に一通り書いてあります。その機能を大まかにまとめると、 スケールアウト、バランシングが自動化できる 複数のゾーン (Availability Zone) にまたがっていても一元管理できる (AZRebalance ELB を指定してインスタンスを追加できる 不健全なインスタンスを自動的に入れ替えれる >>> オートスケールの設定 大きく分けると 3 つのステップ CPU やメモリ等のリソースを識別する CloudWatch に各リソースをモニタリングするためのメトリクスを作成する デフォルトでモニタリング可能なリソースが用意されている ( デフォルトで用意されているリソース EC2 の CPU 負荷、ディスク I/O、ネットワーク I/O ELB のホスト数 (健全/不健全)、 リクエスト数 、レイテンシ Netflix 推奨は ELB の rps (req/sec クラスメソッドさんが カスタムメトリクスの追加 について超わかりやすく解説されています。 リソースの変化に基づくアラームやオートスケール等のポリシーを定義する ポリシーベース: 負荷が高くなったら EC2 インスタンスを増やし、負荷が減ったら EC2 インスタンスを減らす スケジュールベース: 負荷の予測が可能な場合は、インスタンスの増減をスケジュールする (バッチ処理にも素敵 >>> Netflix がオートスケールから学んだこと Netflix さんが実際にオートスケールを運用して、その結果を フィードバック されています。以下抄訳とかメモとか 早めにスケールアップ 例えば負荷テストで 25rps (rec/sec) を超えると待ちが発生するとする。その場合は待ちが発生しないように、20rps を超えた際にキャパシティーを増やすよう設定する。この rps の上限設定は以下の目的がある。 オートスケールイベントのトリガーでは間に合わない程の、予想をはるかに超える rps もありうる このバッファーが "キャパシティスパイラル" を回避するセーフ...

Dropbox のスケールとか

イメージ
Python なサービス みんな大好き Dropbox のスケールとかメモ。以下のページ辺りからピックアップ。Parted? みたいなので、続編がでたら追記するかも。 Scaling lessons learned at Dropbox, part 1 ( comment ) Dropbox - Startup Lessons Learned (slideshare) Dropbox -Yコンビネーターが生んだスタートアップの軌跡と未来 - スケール関係ないですが、 2006 年当時はオンラインストレージサービスがいっぱいあった ようで、VC から資金調達したときのやり取りがおもしろい VC "クラウドストレージサービスなんて腐るほどある" Drew "なにか使ってるのありますか?" VC "NO" Drew "..." 完璧で、スケーラブルで、クロスプラットフォームなクラウドストレージ!当時、プライベートベータのビデオが 12000 digg (<- 懐かしい) され、ベータリストの登録が 1 日で 5 千人から 7 万人に増えたことも。 現在 、 5000 万人のユーザ が、 2 億 5 千万デバイス から、 48 時間で 10 億ファイル 保存してるとのこと。 ファイルの POST/PUT で 5787 rps となると GET を合わせると。。。すごいですね! スケールの記事を書かれているのは、2011 年まで Dropbox でスケールを担当されていた Rajiv Eranki (← URL w) 氏です。Dropbox のバックエンドはほとんど 1 ~ 3 人で面倒を見ていたとのこと。順不同で以下抜粋。なお、Dropbox さんは有効であるのは間違いないですが、ストイックと思われる箇所もあるので、18 最未満の方は保護者の同意の下w >>> 利用しているテクノロジー 言語: ほとんど Python, ちょっとだけ C データベース: MySQL WSGI: Paster / WAF: Pylons / テンプレートエンジン: Cheetah ファイルブロックの保存と提供: S3/EC2 キャッシュと...

Pinterest のスケール

V 先生から 教えて頂いたので、Instagram 同様 Django/AWS 構成の Pinterest のスケールをメモ。 Pinterest はいつものアカウント名が初めて 先取 されたサービスなので、今後使わないと思います 。 本題に入る前に、Python には The Zen of Python ( 日本語 ) という思想があります。私はこの思想を Python でのプログラミングだけでなく、インフラの構築の際も意識するように心がけています。" Simple is better than complex " です。Instagram や Pinterest のスケールを見て、この思想がもっと好きになりました。 Instagram はよりシンプルなインフラに更改していくことで、ただスケールするだけでなく、運用や変更のコストも最小限になるように最適化していると思います。結果的に Android アプリ公開等のサービス拡大時にも少ないエンジニアリングで柔軟に対応できたのかと。これはあくまでもイメージでしかありませんが、AWS 上でスケールアップできるところまでスケールアップし、限界が見えたところでスケールアウトで最小限のエンジニアリングコストをかける。インフラで解決できるところはインフラで解決しているというイメージです。Pinterest のスライドでは、インフラをシンプルに更改した過程が紹介されています。 >>> インフラの遷移 2010/05: 創設 RackSpace 小規模な Web Engine × 1 小規模な MySQL DB × 1 2011/01: AWS へ フロントに nginx を立て垂直分割、MySQL をマスタースレーブ構成に垂直分割、ヘビーな処理をタスクキューに分割、MongoDB を導入。 Amazon EC2 + S3 + CloudFront nginx × 1 Web Engine × 4 MySQL: Master × 1 / Slave × 1 Task Queue × 1 / Task Processors × 2 MongoDB × 1 2011 年後半: ターニングポイント LB, Web サーバを増加、MySQL をシャー...

Instagram のスケール正攻法

Instagram がどこに買収されたとかは他のニュースサイトにお任せして、 Django アプリケーションを正攻法でスケールして "成功" してるのがとても興味深いです。現時点で Instagram Engineering で紹介されていることと TechCrunch にも掲載 された スライド から個人的なメモとしてまとめてみました。 Instagram の哲学は シンプル であること オペレーション負荷を最小化 すること すべて装備 とのこと。 Instagram は以下の OSS, サービスで構築されているようです。 >>> OS / ホスティング Ubuntu Linux 11.04 を Amazon EC2 にホスティング。以前のバージョンは高トラフィックになると固まる問題があったようです。運用は 3 人。EC2 にホスティングしている理由は、調査結果によるものではなく、" まだ進化途中だから " だそうです。 ハードウェアの選定、導入、セットアップの手間も省けますし、パッケージ管理等の運用も軽そうですね。 >>> ロードバランサ Amazon ELB を利用。もともとは DNS ラウンドロビン + nginx のロードバランサでバランシングしてたらしいですが、DNS の更新が遅いので止めたとのこと。nginx の負荷を軽減するために SSL も ELB までで、あとは HTTP。ELB はほんと素敵なサービスだと思います。DNS も Amazon Route 53 を利用。GUI での管理が素敵とのことです。 >>> アプリケーションサーバ Django アプリケーションを EC2 の High-CPU Extra-Large インスタンスで実行。2012 年開始ぐらいでは約 25 インスタンスと書かれています。Android アプリを公開して 10 日で 1000 万ユーザ (20 時間で 100 万ユーザ) を獲得したようなので、今はもっと多いでしょうね。こういうサービスの拡大に柔軟に対応できるのも EC2 を含むクラウドの魅力だと思います。High-CPU にしている理由はおそらく PIL を多用するからでしょう...

WSGI on Qt (PyQt or PySide)

イメージ
こんにちは、Python 会の。。。思いつきませんでした。初 " Python Web フレームワーク アドベントカレンダー2010 " に参加させていただくことになりました。よろしくおねがいします。アドベントカレンダー参加者のブログは cielquis.net に綺麗にまとめられていますよ。 ごめんなさい。Web アプリケーションフレームワークの作成なんて 1 日じゃむりぽ><。メインで使ってるフレームワークは、 Django か webapp ぐらい。。。最近 dis られてるので、Django 記事書くのもあれだ・・・。 ということで本題です。Python は WSGI (Web Server Gateway Interface) という Web アプリケーションと Web サーバ間の共通インターフェースがあります。そのインターフェースを実装したオブジェクトは、Web アプリケーションとして動作させることができます。ということで、デスクトップアプリケーションを Web アプリケーションにする方法を書きたいと思います。今回は Qt の Python binding な PyQt / PySide で WSGI アプリケーションを作ってみたいと思います。実装は PySide ですが、 PyQt でも動くはずです。 STEP1: PySide で Hello World! ほんと Web アプリケーションじゃなくて申し訳ないですが、最初に PySide で "Hello World!" を表示します。 import sys from PySide import QtCore, QtNetwork, QtGui class QWSGILabel(QtGui.QLabel): def __init__(self, text, parent=None): super(QWSGILabel, self).__init__(text, parent=parent) class QHttpWidget(QtGui.QWidget): def __init__(self, parent=None): super(QHttpWidget, self).__init_...

ubuntu に mongodb をインストール - with pymongo / vs couchdb

一段落ついたので、couchdb に引き続き mongodb もインストールしてみた。環境は同じく VMWare 上の ubuntu。シングルサーバ、シングルクライアント (python) な環境で比較することに。 というのも、設定に誤りがあるためか、 couchdb が期待できるようなパフォーマンスが出なかったため。100 万件のデータを insert 処理するストレステスト (本番バッチ処理環境を考慮) をしているのですが、途中で conflict -> socket error -> down になってしまう。途中 sleep を入れると socket error は出なくなるけど、それだと遅いのと、なんだか気持ち悪い。前ポストで書いたように、0.8.0, 0.11.0b, 0.10.0 で試したけど、結果は同じでした。何が悪いのだろう・・・。 気は取り直して、mongodb は期待する結果が得られたので、インストールと pymongo 経由での処理方法です。 依存パッケージ類のインストール sudo aptitude install tcsh git-core scons g++ sudo aptitude install libpcre++-dev libboost1.37-dev libreadline-dev libmozjs-dev git から mongodb のダウンロードとインストール (/opt/mongo へ) cd /usr/src/ git clone git://github.com/mongodb/mongo.git cd mongo sudo scons all sudo scons --prefix=/opt/mongo install mongo ユーザの追加 sudo adduser --system --home /opt/mongo/ --no-create-home --shell /bin/bash --group --gecos "mongoDB Administrator" mongo db データディレクトリーの追加とパーミッション設定 sudo mkdir -p /data/db s...

CentOS に Django をデプロイ - with python2.6, mod_python, mysql

Ubuntu でしか作ったことなかったけど、CentOS 5 系 で Django をデプロイしてみる とりあえずパッケージを最新に更新 # yum update python 2.6 のインストール CentOS ってデフォルトでは 2.4 なんですね。2.6.4 をソースから入れる。まず zlib, sqlite を入れる。sqlite いれないと import sqlite3 できない # yum install zlib zlib-devel sqlite-devel python ソースのダウンロードとビルド、インストール # wget http://python.org/ftp/python/2.6.4/Python-2.6.4.tgz # tar xvfz Python-2.6.4.tgz # cd Python-2.6.4 /opt/python2.6 にインストール。path は個人的な趣味。 --enable-shared オプションを追加する # ./configure --prefix=/opt/python2.6 --with-threads --enable-shared Setup ファイルで zlib のところのコメントを外す。 # vi Modules/Setup --- #zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz +++ zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz # make # make install python 2.6 環境設定 (2.4 と共存させる) パス周りを設定 # vi /etc/ld.so.conf.d/opt-python2.6.conf # /sbin/ldconfig # sudo ln -s /opt/python2.6/bin/python /usr/bin/python2.6 # cd 個人的な趣味で、PATH は.bash_profile, alias は .bashrc にセット # vi .bash_profile --- PATH=$PATH:$HOME/bi...

ubuntu で nginx から memcache を利用する

memcached, python-memcache のインストールと起動 sudo apt-get install memcached python-memcache sudo /etc/init.d/memcached start 初期設定だと 11211 番ポートで起動しています。変えたい場合は /etc/memcached.conf で。 memcached とお話してみる (telnet 編) まずは telnet 経由でお話してみる。プロトコルについては official wiki を見ればいいと思います。 telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. 'foo' という key で フラグ 0、無期限 (0)、 3 byte のデータ 'bar' を格納 set foo 0 0 3 bar STORED 'foo' という key の value を取得する get foo VALUE foo 0 3 memcached の情報を見てみる stats items STAT items:1:number 4 STAT items:1:age 56560 memcached とお話してみる (python-memcache 編) 上記の一連の流れを python-memcache でやってみる。 >>> import memcache >>> cache = memcache.Client(['127.0.0.1:11211']) >>> dir(cache) >>> cache.flush_all() # いったんクリアしといた >>> cache.set('foo', 'bar') True >>> cache.get('foo') 'bar' >>> nginx に memcach...

ubuntu への nginx のインストールと load balancer としての利用

nginx のインストール aptitude で リポジトリからインストールしてみる。 sudo aptitude install nginx sudo /etc/init.d/nginx start nginx の初期設定 ubuntu では、(apache 同様) サイト毎の conf がモジュール化されており、default のモジュールは /etc/nginx/sites-enabled/default となっている。 sudo vi /etc/nginx/sites-enabled/default 私は apache2 同様、 ./sites-available/* にモジュール化したサイトの conf をつっこんでおき、 ./sites-enabled/* 内にシンボリックリンクを作成するようにしています。 nginx では、いまのところ apache2 のように a2emod などのコマンドがないため、自作しておくと便利かも(指定されたモジュールのシンボリックリンクをはるだけだけど・・・)。 ロードバランサの設定 テストとして、google のホストをロードバランスしてみる。ubuntu の nginx.conf は ./conf.d/* を include するため、 conf.d 内に loadbalance.conf を作成する。 sudo vi /etc/nginx/conf.d/loadbalance.conf 以下のように書いてみる。 upstream httpdcluster { server www.google.com:80; server www.google.co.jp:80; server www.google.co.uk:80; } server { listen 8080; server_name localhost; location / { proxy_pass http://httpdcluster; } } 例では、 httpdcluster と命名したサーバー郡をロードバランシングする。 これにより、 8080 番の /* を httpdcluster 郡に振り分けることができる。 http:...