ラベル cloud の投稿を表示しています。 すべての投稿を表示
ラベル cloud の投稿を表示しています。 すべての投稿を表示

2010年11月14日日曜日

mysqlかpostgresqlかNoSQLか

postgresqlとmysqlとどっちを使えば良いかは、
いやっちゅーほど繰り返されてきた議論ですが、
両者とも明確なメリット&デメリットがあり、
極論するなら、消去法で選択するしかありません。

postgresqlの場合

  • insertが比較的早い
  • updateを繰り返すと、性能が落ちてくる。vacuumが必要。
  • vacuumするには、テーブルロックが必要。な場合がある。
  • レプリケーションが未実装。
  • connectは比較的遅い。


mysqlの場合

  • readだけなら早い→そんな案件今時あるの?
  • レプリケーションが比較的簡単&安定→readonlyスレーブ増やして負荷分散、はよくある発想。面倒だが。
  • innodb insert/updateが激遅い。
  • sqlに方言がやたら多い。
  • 複雑なsqlを投入すると、最適化に失敗する。と言うか最適化する気がないっぽい。
  • connectは比較的早い。
  • myisamは結構壊れる。(しかも普通に使っていて)
  • innodbも稀に壊れる。(しかも普通に使っていて)


エンタープライズ業界なら、これの何れか、もしくはOracleでイイヤ、
って話になるでしょうけど、
ソーシャルゲームであると、データ量、時間あたりの処理量が
指数的に増大します。


テーブル分割に対する実装コストも馬鹿になりません。
であれば、NoSQLを使ってしまえ、というのは手です。

NoSQLは数有りますが、近頃実績が増えてるっぽいのが、mongodbでしょう。
http://www.infoq.com/jp/news/2010/10/4square_mongodb_outage
これらのトラブルも、過渡期であるが故です。

それにこのトラブルは、会員数300万人とかのレベルなんで、
仮にmysql/postgresqlで運用していたとしても、
別のトラブルが有ったであろう人数と言えましょう。知らないけど。

シャードの不均一化が原因だって話なんで、
最初から、細かいテーブル(コレクション)に分割してしまえば済む話かも知れません。
メモリ使用的にもその方が有利らしいし。
http://www.mongodb.org/pages/viewpage.action?pageId=18448682

こんな事が出来るのも、スキーマレス、create tableイラズだからです。

ソーシャルゲームの実装は、トモダチ1000人居るだけで大変

最近は、ソーシャルゲームが流行り?で、
作ってみようかって案件は少なくないと思いますが、
「一般的なポータルサイト」と同じように作ると、
かなり大変なことになります。

「一般的なポータルサイト」には無かった概念として、
「フレンド」が有るでしょう。
こいつのお陰で、内部の処理量が指数的に増大します。
よほど上手く作らないと、何処かがネックになります。

「ページビュー」だけで、負荷は計れない。ということです。

誰かさんがゲームを開始すると同時に、
彼のフレンドの個々の情報を取得する、
のはよくある話だと思いますが。

500人の人が、500人づつのフレンドを持っていたすると、
いきなり250000の検索をしなければならなくなります。

同時に来たら、と思うと、血の気の引く件数ですね。

どう考えても、想定してない人数です。
馬鹿正直に実装したらmysqlとかphpとか、
どっちかのメモリが足りなくなるでしょうね。

と言うわけで、ソーシャルゲームの実装の鍵は、
如何にフレンド処理をサボるか、
これに尽きるでしょう。

と言うか、「収益の出る集客」を目指すなら、
ン10万人を最初から想定しなければならない訳で
必然、性能だけじゃなくて、テーブルのサイズの心配もしなければなりません。
テーブルパーティショニングとか、シャーディングとか、
自力で実装するには面倒臭すぎます。

バックエンドに、mysqlとかpostgresqlとかは、
ぼちぼち無理なんじゃないでしょうか。って言うか、筆者はもう勘弁してほしい。

であれば、初めから「それらの機能を内蔵したNoSQLに全部お願い」
それも手だなと。思う次第です。

2010年10月23日土曜日

大規模WEBサービスは、クラウドに倣うべき

日本国内の、主にケータイサイトの裏側は、「apacheとmysqlで構築してます」
なんて話は良く聞きますが、いずれも物理サーバを自前で置いている場合です。

最近ではamazon ec2の利用が増えているであろうと思いますが、
これを、ただ「安価なレンタルサーバ」として使うのは全面的に間違っています。

データが消えても良いことを最初から考慮して、
むしろ2分で新しいインスタンスが立ち上がることを積極的に利用するべき。

「スケーラブル」にしなければならないのに、「インスタンス1台づつ手動で立ち上げて」どうこうするのは無駄。

つまり、物理サーバとは別の運用パラダイムが必要です。
なんて話は、海外のクラウド畑ではあたりまえの話でしょう。
判ってないのは日本国内のお客さんだけ。

筆者が常用している海外のサービスは、最近ではtumblrぐらいですが、
どうも最近不安定。ポスト失敗したり。ダッシュボードが出なかったり。
リブログ主体ですから、画像の取扱いの主体が大変だろうと推測。

似て非なるtwitterは、質的にはリアルタイムチャット、
twitterのトラフィックの異常さは想像に難しくありません。

彼らの努力を見習って、同じ苦労は極力削減するべき。
この不景気、車輪の再生産をする余裕はありません。

運用面の工夫

TwitterがBitTorrentで高速にデプロイしている仕組みについて
http://www.publickey1.jp/blog/10/twitterbittorrent.html

そこでBitTorrentを使ってデプロイする「Murder」というツールを開発をした。Murderは、BitTorrentを包含して内部ネットワーク用にオプティマイズしたもの。これまで約900秒かかっていたデプロイの時間が約12秒になり、75倍も速くなった。


Twitterの大規模システム運用技術、あるいはクジラの腹の中(前編)~ログの科学的な分析と、Twitterの「ダークモード」
http://www.publickey1.jp/blog/10/twittertwitter.html

Twitterのクジラ解剖学、あるいは彼らがいかにサーバの処理能力を向上させたか
http://www.publickey1.jp/blog/10/twitter_4.html
ボトルネック調査

Twitterの大規模システム運用技術、あるいはクジラの腹の中(後編)~Twitterのサブシステム「Unicorn」「Kestrel」「Flock DB」
http://www.publickey1.jp/blog/10/twittertwitterunicornkestrelflock_db.html
ボトルネックの具体的な解消。ミドルウエアの積極的な交換。

kestrel
tiny queue system based on starling, in scala
http://github.com/robey/kestrel
タスクスケジューリングの解法(cronやatには限界があるのは周知)
memcachedの基盤を利用して、大規模分散キューを実現してる。らしい。

ストレージ面

基本的にshardingだけど、アプリケーションが個別に頑張るんじゃなくて、
RDBとの間にアダプタを挟むのが現実的。

Twitterが分散フレームワーク「Gizzard」公開! Scalaで書かれたShardingを実現するミドルウェア
http://www.publickey1.jp/blog/10/twittergizzard_scalasharding.html

GizzardはScalaで書かれたJavaVM上で動作するミドルウェアで、PHPやRubyといったWebアプリケーションからの要求を自動的にデータベースに分散することで、大規模で可用性の高い分散データベースを容易に実現するためのものです。

なんか日本語が変。「ScalaでかかれたJavaVM」に読める。こういう書き方をする人は多いですが。

GizzardはJavaVM上で動作するミドルウェアで、Scalaで書かれてる。Webアプリケーションからの要求を、自動的にデータベースに分散することで、大規模で可用性の高い分散データベースを容易に実現するためのものです。

http://engineering.twitter.com/2010/04/introducing-gizzard-framework-for.html
http://github.com/twitter/gizzard

NoSQLは
思ったより運用実績はないみたいですね。

TwitterとDiggがNoSQLの「Cassandra」を選ぶ理由
http://www.publickey1.jp/blog/10/twitterdiggnosqlcassandra.html

Twitterが、Cassandraの本採用を断念。「いまは切り替えの時期ではない」
http://www.publickey1.jp/blog/10/twittercassandra.html

それにしても、このうちGizzardとKestrelが、Scalaで書いてるらしい。
JVMベースの、「JAVAでない言語」恐るべし。

2010年4月7日水曜日

MySQLはそれほど速くないし、PostgreSQLはそれほど遅くない in 2010

MySQL 5.0時代(2011年後期現在での最新は5.5.17)と、
PostgreSQL 8.0時代(2011年後期現在での最新は9.1.1)の知識で言います。

今では更に事情が変わってる可能性があります。
まあ、昔話と一般論を述べてると思ってもらえれば結構です。

同時期に作成したらしいベンチマークが或るので、貼らせてもらいます。





#大小文字の打ち分けが面倒なので、固有名詞は小文字で圧します。

端的に言えば、mysqlはマニュアル車、postgresqlはオートマチック車です。

mysqlは実は、特定状況下でのみ、高性能を発揮します。らしいです。
特定状況下は、筆者は存じません。

大量のチューニングパラメタが或るのも、特徴でしょう。
これは、悪い特徴です。適当に使うと、まったく性能は出ません。

mysqlの強力なアドバンテージは、レプリケーションの内蔵。
それに「尽き」ます。それだけしか無い。
レプリケーションの設定は、非常に簡単です。
「同期」とは言えませんが、更新のタイムラグは概ね無視できる範囲でしょう。

一方、mysqlは、不可避レベルの「苦手」が幾つかあります。

SQLの文中で、select以外では、テーブルの自己結合が出来ません。
insertの文中で、既存のレコード数を数えて、+1してinsertしたい、
って良くあると思うですが、mysqlのinnodb/myisamではこれは不可能です。

これに限らず、複雑なSQLを投入すると、
不適切なindexを使う、もしくはindexを諦める場合があります。
2段サブクエリ程度で、もう駄目な感触です。
そのための FORCE INDEX なる、SQLの独自構文があります。
#どんだけ手動なのかと

mysqlで、大量のinsert/delete/updateをすると、
性能がゴッソリ落ちます。
大量の、というのは、数十万レコード、程度ですね。

故に、遅延insertなる方言があります。
なんかindexの作成が、下手なのかなあ。という感触です。

ランダム文字列系の、ランダム順insertは、かなり遅い。と思う。
postgresqlで同程度のクエリを流したときの、
数10倍、時間が掛かることがあります。

ちなみに、postgresqlで30分で終わるinsertが、
mysqlのmyisamで3時間、innodbで12時間でした。
信じるも八卦。信じないも八卦。

また、全部deleteする場合は、trancateを使おうね、とか
いや、運用でそんなケースそんなにあるのか?と
逆に聞きたいのですが。
手動でやってるなら、truncate使いますよそりゃあ。

postgresqlの問題点としては、vacuumを懸念している人は多いと思いますが、
実は、mysqlもvacuumをやっているのです。
しかも1レコードづつ。

いや、オフィシャルで「mysqlでvacuumやってます」
なんて記述は一つもないのですが、
遅いなあ、と思ってstraceしてみたら、
ファイルコピーしてやがった事がありました。
いや俺今delete fromしたよね?なんでファイルコピーが必要?みたいなね。

トランザクション量がもの凄い多い場合、begin〜commitが遠い場合は、
これまた性能がゴッソリ落ちます。
数10レコードづつcommitすれば劇的に改善しますが。

あと、myisamテーブルは壊れる可能性があります。
修復コマンドがあるくらいですから。

実は筆者の経験で、innodbが壊れたことも一度ありました。
実験機だったので、テストデータを入れ直しましたが。

mysql自身の苦手、とは違いますが、いや筆者が苦手ってことか。
ユーザ登録をgrant構文でやるのはどうにも気持ち悪いです。

一方、postgresqlは、設定項目が非常に少なく、
起動するだけならすぐです。

しかも、結構複雑な、3段サブクエリを投入しても、
なんとか結果を返します。
適切にindexを貼れば、ちゃんと使ってくれます。
普通に使ってたら、特に「○○が苦手」という感じはありません。

postgresql-8以降、使ってないので判りませんが
(しばらくmysqlの案件が続いたので)
簡易なvacuumをマメにやるようになってるらしいので、
テーブルロックレベルのvacuumは短時間で済むようになってる。らしいです。

とは言え、大量のinsert/updateを続けると、徐々に性能が落ちてくるのは確か。

数千レコードを舐めて再構築するタイプのトリガを、書かざるを得なかった事があり、
いや、仕事で書いてね、って頼まれたんですが、
テストで何度か回しているうちに、あれ?遅くなってきた?みたいな感触はあります。
ただそれでも、2分が5分になるだけです。
倍にはなってるんだけど、元々が「待っていられる」時間です。

最悪、トランザクションスクリプトにvacuum fullを含めちゃうのは手でしょう。

総評としては、

mysqlは、SQLサポートそのものが不完全なので、SQLの記述に手間取る。
結構ありがちな状況で、ゴッソリ性能が落ちやすい感触。

postgresqlは、問題の先送りで、
更新が多いっぽいときは、トランザクションにvacumm fullと書いちまえ。

結論としては、

どうしてもレプリケーションを使いたければmysqlしかない。
その他は、postgresql使っとけ。

もうそんな気持ちです。