symfony1系 + MYSQL + Redisでソーシャルゲームの設計
2回目の登場。 ソーシャルアプリ事業部のトーマスです。
早いもので、今年ももうすぐ梅雨になりお楽しみの夏ですね。
ちなみに僕は夏は嫌いですorz
暑がりなので冬が一番好きです。
ああ、いかん。
話が日常会話になってしまう。。。
あーあーあー
では表題の話へ NoSQLのRedisが気に入ってここ数年いろいろ遊んでます。
遊んでいる内にバージョンが1系から2系に進化し、どんどん安定してきました。
そこで、symfony1系 + MYSQL + Redisでゲーム設計が出来ないかと思い 最近はDIYで休日等にせっせと設計しながら実装をしています。
今の段階ではMYSQLのスレーブのスレーブとして設計してます。
処理のイメージ
Redisにデータがあるか
↓ある ↓ない
↓ MYSQLでselect
↓ ↓
↓ 取得したデータをRedisにセット
↓ ↓
symfonyへ symfonyへ
現在、この処理を実現させる為、RedisPeer.phpなるものを実装中です。
※まだ、実装途中なので完成したらどこかにアップします!!
出来るだけ既存のPeerで使用出来るよう Peerで実装されているメソッド名で拡張してます。
doSelectOne doSelect等。
今回はイメージが伝われば幸いです(^^;)
既存のPeerに実装
1 2 3 4 5 6 7 8 |
[code lang="bash"] public static function get($params) { $criteria = new Criteria(); $criteriaの処理 return RedisPeer::doSelect($criteria, $connection); } [/code] |
RedisPeer.php側の実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[code lang="bash"] ~~~~中略~~~~ public static function doSelect(Criteria $criteria, PropelPDO $con = null) { $peerName = self::getPeerName($criteria); $values = self::doSelectRedis($peerName, $criteria); $result = null; if (!$values) { $configName = DbBase::getConfigName(); $result = $peerName::populateObjects($peerName::doSelectStmt($criteria, $con)); if (count($result) > 0) { self::setHash($criteria, $peerName, $result, $configName); } } else { $result = $values; } return $result; } ~~~~中略~~~~ [/code] |
この実装がイメージ通り完成すれば、スレーブの台数をグッと削減できるはず!!
ただ、このままだとDBにinsertやupdateがあった時に最新のデータを取得出来ない。
では、いつRedisのデータを消せばいいのかと思い symfonyのBaseObjectの処理を覗いてみました。
…φ(・ω・` ) あります!便利な機能! さすがsymfony!!
le symfony est merveilleux!!
今回overrideしたメソッドです。
preSave ⇒save処理の前に呼ばれるメソッド “DB名”.php側を拡張します。
1 2 3 4 5 6 7 8 9 10 |
[code lang="bash"] public function preSave(PropelPDO $con = null) { // キャッシュがあれば削除 if (RedisPeer::isCache(self::PEER, $keys)) { RedisPeer::clearCache(self::PEER, $keys); } return parent::preSave($con); } [/code] |
RedisにはTransactionの機能がないので、rollBackが出来ません。
なので、DBにinsertやupdateがある時は問答無用で消します。
ふー。
と、まぁ、こんな感じでちょこちょこ実装してます。
Redisにはkey => value以外の型があり いろいろな用途で利用が出来ますがその話はまた今度の機会に☆彡
この実装をしてから、KVSを意識したDBの設計が必要なんだと思い知らされました。
では、中の人に呼ばれたので、仕事に戻りますm(_ _)m
ちなみに、「le symfony est merveilleux!!」は、「symfonyは素晴らしい」という意味のフランス語です。