RailsアプリでActiveRecordとMongoidを両方使ってみる

今までRDBMSで動いてたRailsアプリをMongoDBにマイグレーションする~的な
話が出てきたので、検証を兼ねて、VirtualBoxのUbuntuにRailsアプリをインストールして、
ActiveRecordとMongoidを両方動かしてみる事にしました。
 
■ 環境周り
またいつものように環境設定にゴタゴタしまして、、、
・Rails立ち上げようとしたら、Could not find a JavaScript runtime~とか言われて、
 エイヤってapt-get install nodejsとかやっちゃったのですがこちらの記事がドンピシャでした。
・vimで作業する時にFuzzyFinder使って検索したいな~って思って入れたら動かなくて、
 vundlerの定義にL9というのが必要だったりとか。

 Bundle ‘tpope/vim-rails’
 Bundle ‘The-NERD-tree’
 Bundle ‘quickrun’
 Bundle ‘vim-ruby/vim-ruby’
 Bundle ‘Shougo/neocomplcache’
 Bundle ‘L9’
 Bundle ‘FuzzyFinder’

んま、他にもちょいちょいありましたが、その辺は端折る感じで。。
 
■ 使用するデータ
データはFluentdを使ってお手軽に集める事にしました。
今回はsquid3をプロキシサーバー(ポートは8888)にしました。

# Squid normally listens to port 3128
http_port 8888

んで、/var/log/squid3/access.logをtailプラグインで集めてきます、と。
なんでSquidのaccess.logにしたかっていうと、たまたま見かけた
↓のブログにグッときてしまったから、、っていう話なのですが。。
fluentdのformat(正規表現)の作り方について試行錯誤中 #fluentd – Glide Note – グライドノート
 
■ Fluentdのプラグイン
fluentdはmongoとmysql用の両方のプラグインがあるので、
https://github.com/fluent/fluent-plugin-mongo
https://github.com/tagomoris/fluent-plugin-mysql
それらを使うだけなのですが、特にMongoDBに突っ込むのは設定もチョーお手軽でした。
Fluentd本体もプラグインもgemでサクっと入ります。

# gem install fluentd
Fetching: msgpack-0.4.7.gem (100%)
Building native extensions.  This could take a while...

次にMySQLプラグイン

# gem install fluent-plugin-mysql
Fetching: mysql2-cs-bind-0.0.5.gem (100%)
Fetching: fluent-plugin-mysql-0.0.2.gem (100%)
Successfully installed mysql2-cs-bind-0.0.5
Successfully installed fluent-plugin-mysql-0.0.2
2 gems installed

続いてMongoDB用のプラグイン

# gem install fluent-plugin-mongo
Fetching: bson-1.6.4.gem (100%)
Fetching: mongo-1.6.4.gem (100%)
Fetching: fluent-plugin-mongo-0.6.11.gem (100%)
Successfully installed bson-1.6.4
Successfully installed mongo-1.6.4
Successfully installed fluent-plugin-mongo-0.6.11
3 gems installed

データを入れ込むFluentdの設定
・MySQL(Insert文を書く感じ)

<source>
  type tail
  path /var/log/squid3/access.log
  tag mysql
  format /^(?<date>[^ ]+)s+(?<duration>.*) (?<address>.*) (?<result>.*) (?<bytes>.*) (?<method>.*) (?<url>.*) (?<rfc931>.*) (?<hierarchy>.*) (?<contenttype>.*)$/
  pos_file /root/hoge/fluent/acceess_log_pos_mysql.log
</source>

<match mysql.**>
  type mysql
  host 127.0.0.1
  port 3306
  database hoge
  username root
  password
  key_names date,duration,address,result,bytes,method,url,rfc931,hierarchy,contenttype
  sql INSERT INTO mysql_accesses (date,duration,address,result,bytes,method,url,rfc931,hierarchy,contenttype) VALUES (?,?,?,?,?,?,?,?,?,?)
  flush_intervals 5s
</match>

当初は”contenttype”の所をただの”type”にしてたのですが、
↓のように怒られたのでカラム名変えました。

This error is raised because the column 'type' is reserved for storing the class in case of inheritance

・MongoDB(えらくお手軽な感じ)

<source>
  type tail
  path /var/log/squid3/access.log
  tag squid
  format /^(?<date>[^ ]+)s+(?<duration>.*) (?<address>.*) (?<result>.*) (?<bytes>.*) (?<method>.*) (?<url>.*) (?<rfc931>.*) (?<hierarchy>.*) (?<contenttype>.*)$/
  pos_file /root/hoge/fluent/acceess_log_pos_mongo.log
</source>

<match squid.**>
  type mongo
  database hoge
  collection mongo_accesses

  host 127.0.0.1
  port 27017
</match>

それぞれFluentdのプロセスを起動して中身が入ってることを確認します。

# fluentd -c access_log_mongodb.conf
2012-12-20 11:56:53 +0900: starting fluentd-0.10.29
2012-12-20 11:56:53 +0900: reading config file path="access_log_mongodb.conf"
2012-12-20 11:56:53 +0900: adding source type="tail"
2012-12-20 11:56:53 +0900: adding match pattern="squid.**" type="mongo"
# fluentd -c access_log_mysql.conf
2012-12-20 11:56:51 +0900: starting fluentd-0.10.29
2012-12-20 11:56:51 +0900: reading config file path="access_log_mysql.conf"
2012-12-20 11:56:51 +0900: adding source type="tail"
2012-12-20 11:56:51 +0900: adding match pattern="mysql.**" type="mysql"

MySQLの件数

mysql> select count(*) from mysql_accesses;
+----------+
| count(*) |
+----------+
|     1197 |
+----------+

MongoDBの件数

> db.mongo_accesses.count();
1197

いやー、なんともお手軽ですこと。さすがFluentd…。
 
■ Railsで使う用のgem
gemでmysql2入れようとしたら怒られたから、、、

# gem install mysql2
Building native extensions.  This could take a while...
ERROR:  Error installing mysql2:
	ERROR: Failed to build gem native extension.

        /usr/bin/ruby1.9.1 extconf.rb
checking for rb_thread_blocking_region()... yes
checking for rb_wait_for_single_fd()... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lmygcc... no
checking for mysql_query() in -lmysqlclient... no
*** extconf.rb failed ***

devなクライアントパッケージインストールして、、

# apt-get install libmysqlclient-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  zlib1g-dev

ようやく、、、

# gem install mysql2
Building native extensions.  This could take a while...
Successfully installed mysql2-0.3.11
1 gem installed
Installing ri documentation for mysql2-0.3.11...
Installing RDoc documentation for mysql2-0.3.11...

でもって、、

# bundle update
Fetching gem metadata from https://rubygems.org/...........
Fetching gem metadata from https://rubygems.org/..
Using rake (10.0.2)
~略~
Using mongoid (3.0.14)
Using mysql2 (0.3.11)
~略~

Railsアプリ内でMongoDBの設定は mongoid.yml というファイルで行いますが、
↓こんな感じ。(rails.vimを使っています)

:Rgenerate mongoid:config

 
■ Railsアプリをジェネレート
・MongoDBの方でScaffold
 (invoke mongoidという感じになります)

:Rgenerate scaffold mongo_access date:string duration:string address:string result:string bytes:string method:string url:string rfc931:string hierarchy:string contenttype:string
      invoke  mongoid
      create    app/models/mongo_access.rb
      invoke    test_unit
      create      test/unit/mongo_access_test.rb
      create      test/fixtures/mongo_accesses.yml
      invoke  resource_route
       route    resources :mongo_accesses
      invoke  scaffold_controller
      create    app/controllers/mongo_accesses_controller.rb

・MySQLの方はModelをActiveRecordでジェネレート(active_record:modelってする)してからScaffold
 ↓こちらのブログを参考にさせていただきました。
 ActiveRecordとMongoidは共存できる | Aerialarts

:Rgenerate active_record:model mysql_access date:string duration:string address:string result:string bytes:string method:string url:string rfc931:string hierarchy:string contenttype:string
      create  db/migrate/20121220015706_create_mysql_accesses.rb
      create  app/models/mysql_access.rb
      invoke  test_unit
      create    test/unit/mysql_access_test.rb
      create    test/fixtures/mysql_accesses.yml

Scaffoldではmongoidになってしまうのでモデルの上書きはSkip。

:Rgenerate scaffold mysql_access date:string duration:string address:string result:string bytes:string method:string url:string rfc931:string hierarchy:string contenttype:string
    conflict    app/models/mysql_access.rb
  Overwrite /root/hoge/app/models/mysql_access.rb? (enter "h" for help) [Ynaqdh] n
        skip    app/models/mysql_access.rb

#ってかscaffoldでactive_record:modelが自分が試したところ出来なかったのですが、
#ひょっとして出来たりするですかね、、、?
 
■ 画面からアクセスしてみると、、、
ソレっぽく見えてるーーヽ(´▽`)ノ
・MySQL

・MongoDB

 
業務的にも、こっちはでRDBMSでMongoDBで~とかって局面はありそうなので、
手応えが掴めてよかったです。
 
■ せっかくなのでページネーション
その昔、RailsアプリはScaffoldしただけでページネーションしてくれたものですが。
最近ではkaminari(https://github.com/amatsuda/kaminari)が流行ってるみたい。
Rails勉強会とかでお話伺った事ある人のなので使ってみよー、と。
 
Gemfile追加してbundleしてコントローラーとビューにチョコっとだけ手入れました。

# cat Gemfile | grep “kaminari”
gem ‘kaminari’
# bundle update
Fetching gem metadata from https://rubygems.org/………..
~略~
Installing kaminari (0.14.1)
~略~

 
・MySQL
-Controller(mysql_accesses_controller)

@mysql_accesses = MysqlAccess.page(params[:page]).per(10)

-View(index.html.erb)

<%= paginate @mysql_accesses %>

-画面

 
・MongoDB
-Controller(mongo_accesses_controller)

@mongo_accesses = MongoAccess.page(params[:page]).per(10)

-View(index.html.erb)

<%= paginate @mongo_accesses %>

-画面

 
Orderしようとしたら、なんかMongoの方でメソッドがに無い~的なメッセージが
出てたのでscopeとか使ってソレっぽい書き方しなきゃかなーとかありますがとりあえず動きましたよ、と。
 
いやー、さすがRailsアツい…。 
 

MongoDBイン・アクション
MongoDBイン・アクション

posted with amazlet at 12.12.20
Kyle Banker
オライリージャパン
売り上げランキング: 10800

コメント

  1. […] 先日↓のようなブログを書いたのですが、 RailsアプリでActiveRecordとMongoidを両方使ってみる | shinodogg.com その中で↓のように記載させていただいたのですが、、、 […]

  2. Anirudh Banarji より:

    Hi Ej,

    I was searching for fluentd plugins and that brought me
    to this page and then I saw ur pic on the top right.This was exactly what I wanted,so I thought I ll leave a comment.Thanks!!!

  3. shinodogg より:

    Hey Banarji!
    Thank you for your comment!! How have you been?
    Yea, Fluentd is very cool log collector tool developed by Japanese engineer. Recently, I work for variety of companies and they are using it!

タイトルとURLをコピーしました