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

2012年12月14日金曜日

本当にあったredisの怖い話

出稼ぎのとある案件で、redisを使ってますが、色々ヤラれますね。

  • 運用面
    • スキーマ(に相当する概念)を、整数で管理しなければならない
      • 故に、DBを取り違えても、書き込めてしまう。
        • 書き込み先DBを間違えてることに、果たして何時気がつくやら。
      • 端的に言えば、複数のredisインスタンスを使い分けるような運用を想定してないのでしょう。
        • 逆に言えば、そんな使い方するならredisを選択するのが間違ってます。
    • バックアップは、永続ファイル1個をコピーするしかない。
      • 逆にいうと、バックアップが必要になるような運用にredisを選択するのが間違ってます。
    • appendonly=true は永続ファイルを壊す可能性は減るが
      • 実はジャーナルなので、永久に増え続ける。
        • 長期運用するとG単位になるケースもある。そこまで来ると再起動に20分とか掛かる。
  • プログラム面
    • DB全体から「検索」或いは、hashの中身を取得すると、hitした全件を取得するしかない。
      • PHPは、メモリを食いつぶすと、即死するので、非常に相性が悪い。
      • 例えば Set型を使って、タグの運用が楽にできますよー。http://gihyo.jp/dev/feature/01/redis/0004 とか得意気にいってるが
        • 50万件hitしたら、それが$resultにドカーんと送信してくるわけです。
        • ini_set("memory_limit","8000M"); にすりゃいいとかって話でもない。
        • 基本、バッチ実行で使うことを想定してる気がする。
    • expireは、メモリ次第で、期待より早期に消える場合がある
      • キャッシュとしての想定しかないのでしょう。
      • だったらmemcacheでいいじゃねえか。
    • phpredisは https://github.com/nicolasff/phpredis
      • オブジェクト類を、テキトーにシリアライズして保存してはくれるが独自実装なので、他の言語から使うときには互換性がない。
        • そんな想定ないけどね。
      • 本来はsession_handlerに使う程度の想定しかないんじゃねえかと。https://github.com/nicolasff/phpredis#php-session-handler

そんな訳で、それをwebソーシャルゲームのフロントから使ってるオレらが悪いんですけどね。そんなに言うなら使うなって?もちろん使いませんよ。選んだのは小生じゃない。「3ヶ月前から決まってるから、オレの顔に泥を塗るんじゃねえ!」とか言われたら引き下がりますよ。面倒臭いし。こっちは外注の身ですから。

MongoDBでいいんじゃね?と思ってるしね。

2012年2月28日火曜日

mongodbの真の売りは性能にあらず

最近あんまりmongodb触ってません。

以前の案件でのmongodbは近日停止しちゃうし、現在従事してる案件はredisです。
なんでredis?っと思いましたが、半年も前から決めちゃってる話で、
性能で選んだらしい。色々調べてみるとそれなりには納得。

http://blog.brandonc.me/2011/11/memcached-vs-redis.html
色々まとまってるのは上記ですね。中国語ですが。

#自分で測定する時間と元気は今はありません。済みません。

性能測定上は、redisはmongodbより3倍速いってことなのでしょう。
実際そうなのでしょう。

ただしmongodb経験者からみると、redisは機能が低すぎてビビります。
「データベース番号」とか。考え方が10年ぐらい前。
番号#defineしろってことですかい?
ちょっと待て、今21世紀で、CPUは64ビットだぜ?頑張ってるのはインテルだけど。


mongodbの真の売りは性能ではありません。その柔軟さにあります。

表面上は_idをキーにしたKVSとして使えます。しかし、value値の一部で検索することが出来ます。MySQLとかでは普通だしそれが売りですが、KVS(redis)には逆立ちしても無理な話。しかもmongodbには大小比較や集合演算すら可能です。
http://www.mongodb.org/display/DOCS/Advanced+Queries

また、レコードの要素を増減しても怒られません。ALTER TABLEとか要りません。※ただし増減した分のフィールドは、検索には引っかかったり引っかからなかったりするので、これはこれで注意が必要。

何がイイって、「完璧なテーブル構造&構成」を最初から考える必要がなくなる。もちろんSIerの皆さんは完璧に考えたいに違いない。受注案件ならそうでしょう。ただしクラウドで、SaaS(という呼称は病原体みたいでイヤなのだが)なご時世では、最初から「完璧」は不可能だし、毎日alter tableなんてやってられない。

テーブルに相当する概念が緩いです。コレクションと呼びますが。動的に増やしても怒られません。そのため「(従来で言うところの)テーブルの検索キーの一部を、テーブル名として使う」なんて、MySQLだと面倒臭くて叶わん処理が、アッサリ書けます。
http://www.mongodb.org/pages/viewpage.action?pageId=18448682

おっと、最近はパーティショニングで近いことが出来るらしいですね。

つまり、大量のデータを高速で処理するのを目標に置いてるであろう、とは言えます。
map/reduceの実装にも、それは当てはまります。
http://www.mongodb.org/display/DOCSJP/MapReduce

KVSの延長線上とは交わりません。

MongoDBに限らず、NoSQLは、トランザクションが無いだの、データを破損する危険があるだの言われたりしますが、MYISAMもInnoDBも壊れますよ。という話が抜けてる。不公平な議論です。

MySQL+memcachedbでやっていたような案件は、全てMongoDB単体でやっていけるんじゃね?と言うのが小生の主張です。

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イラズだからです。

2010年8月15日日曜日

もうmongodbでいいんじゃね?

出稼ぎ先の都合で、key value storeのNoSQLを検討する必要が出てきました。

KVSで有名なのは、apache cassandraですが、
http://cassandra.apache.org/
資料を眺めて残念に思ったのが、データベーススキーマの定義がxmlなこと。
http://wiki.apache.org/cassandra/StorageConfiguration

#どうも、javaな人々は、「xmlの設定」に抵抗が無くてアレですが、
#筆者は、人間に優しくない「設定ファイル」は大反対です。
#eclipseがあるからヘッチャラだぜとか、それは何か違うと思う。
#個人的にはもう全部yamlにしようぜと思っています
http://www.yaml.org/spec/1.2/spec.html
# 2011年11月現在では、定義ファイルは、yamlになってるっぽい。そうだよね。普通はそこに落ち着くでしょう。

それと、設置にはcassandra自身の他にhadoopが必要で、
ぶっちゃけ面倒臭そう。で、筆者はその辺りで心が折れました。

とは言え、
google datastoreで言うところのreferenceproperty入れ子、の様な事も
出来そうな感じなので、今回の「都合」より複雑なニーズであれば
考慮する必要はありそうです。

他の選択肢は色々ありますが、

couchdbは、
http://couchdb.apache.org/
「httpでイイヨ」で売っているのが微妙に引っかかりました。
まあ改めてポートを開けなくて良いのは助かるけど、
実装全体としては、それだけでは助からないので。

couchの語源は、ソファです。http://en.wikipedia.org/wiki/Couch
だらだらしようぜ。って意味らしいけど。
どうなんだこれ。

そして、最後の選択肢、mongodb
いやもうこれでいいんじゃね?
#「最後」じゃネエだろ、って突っ込みは間に合ってます
http://www.mongodb.org/

一つは内蔵のクエリ言語が、javascriptであること。
クエリに関数をねじこむと、mapreduceしてくれる。ってんじゃありませんか。
http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-ShellExample1
頼もしくね?
いや、今回の「都合」はそこまで要らない筈ではありますが。

もう一つは、起動が簡単過ぎること。

最低限のコマンドラインは、dbpath。意味はご想像通り。
しかもデフォルト値に合わせるんなら設定要りません。

mongod自身のメッセージ表示は、止めた方が良いかも知れません。
限界性能レベルでは、メッセージ出力のI/Oがネックになったりとかするので。

しかも、テーブルのスキーマ定義は不要です。
コマンドライン(?)では、JSONのオブジェクトを受け付けます。
もうそれで済んでしまう話。
しかも、オブジェクトのプロパティに対して、ちゃんとクエリを掛けられます。
PHP等の実装では、多段連想配列を渡します。まあ理屈は一緒なんだが。

しかして、その限界性能レベルでは、実に馬鹿っ速い。
2秒ぐらいで、10万レコードがスルっと入ります。
DBネックの心配は、当面要らないでしょうこれなら。

core i5でした。まあ実施自体は簡単なんで、皆さんもお試し頂ければよろしいかと。

mongodbの「スケール」は、「シャーディング」或いは「レプリケーション」です。

前者は試してませんが、正規のサーバの前段に、シャーディング管理サーバを挟む形態。
http://www.mongodb.org/display/DOCS/Sharding+Introduction

レプリケーションは設定が簡単しかも動作が速い。


コマンドラインで、レプリケーション元サーバのIP等を指定するだけです。
http://www.mongodb.org/display/DOCS/Replication

ubuntu 10.04には一応は標準パッケージがあるので、
apt-get出来ますが、何故かlibmozjs.soのリンクに失敗しますが、
仕方がないので筆者はxulrunnerのモノをld.so.conf.dに書き足してます。

ubuntuのパッケージには、当然/etc/mongodbが有りますが、
前述の通り、基本的にコマンドラインで事足ります。