今まで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アツい…。
オライリージャパン
売り上げランキング: 10800
コメント
[…] 先日↓のようなブログを書いたのですが、 RailsアプリでActiveRecordとMongoidを両方使ってみる | shinodogg.com その中で↓のように記載させていただいたのですが、、、 […]
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!!!
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!