読者です 読者をやめる 読者になる 読者になる

Rock Me!開発者ブログ

DEVELOPERS BLOG

FuelPHPのMongoDBでデータベースを使い分ける

PHP

弊社のあるシステムではMongoDBを使用しています。
参照データは基本的にMySQLから一度使いやすい形にしてMongoDBに格納し、APIからはMongoのデータをメインで使用する事によってパフォーマンスを保っています。
データを本番反映するまでテスト -> チェック -> 本番と確認のステップを分けており、各環境で確認を行うことができるようにしています。
これを実現するためにMongoDB上に同じ構成のDBを3つ作り、確認を得たデータからSync処理を行うことにより反映していきます。

サーバ構成図

サーバ構成図

設定ファイル

MongoDBに下記のように3つデータベースを構築し、設定しておきます。

config/development/db.php

<?php
    return array(
        'default' => array(
            'connection'  => array(
                'dsn'        => 'mysql:host=localhost;dbname=test_database',
                'username'   => 'username',
                'password'   => 'XXXXXXX',
            ),
        ),
        'mongo' => array(
            'default' => array(
                'hostname'   => 'localhost',
                'database'   => 'test_database',
            ),
            'check' => array(
                'hostname'   => 'localhost',
                'database'   => 'check_database',
            ),
            'prod' => array(
                'hostname'   => 'localhost',
                'database'   => 'prod_database',
            ),
        ),
    );

使い方

FuelPHPのMongo_Dbではインスタンス作成時にDB名を指定できます。(デフォルトはdefaultに指定したもの)

<?php
    $db_name = 'prod' // or 'check' or 'default'
    $mongo = \Mongo_Db::instance($db_name);
    $mongo->where(array('id' => $id));
    $data = $mongo->get_one($collection);

Sync

サンプルとして、シンプルにひとつのデータだけをSyncするクラスを書いてみました。
単純にfromとtoを指定して、同じコレクション、idのデータをSyncします。
弊社システムではこのような処理を積み重ねた、もっと大きなデータセットのSyncを行っています。

<?php
class Mongo_Sync
{
        private $from;
        private $to;

        function __construct($from, $to) {
            $this->from = $from;
            $this->to = $to;
        }
 
        private function sync_one($collection, $id)
        {
            $data = $this->get_one($collection, $id);
            if ($data) {
                $this->save_one($collection, $id, $data);
            } else {
                // TODO:Error
            }
        }
    
        private function get_one($collection, $id)
        {
            $mongo = \Mongo_Db::instance($this->from);
            $mongo->where(array('id' => $id));
            $data = $mongo->get_one($collection);
            return $data;
        }
    
        private function save_one($collection, $id, $data)
        {
            unset($data['_id']);
            $mongo = \Mongo_Db::instance($this->to);
            if (! $mongo->where(array('id' => $id))->update($collection, $data, array("upsert" => true))) {
                // TODO:Error
            }
        }
    }

弊社ではエンジニアを募集しています。 是非リクルートページをご覧になってください。

リクルートページ