MongoDB 3.2の新機能を先取りチェック
MongoDB 3.2の新機能について言及している記事を読んだので、簡単に要約を書く。
MongoDB 3.2の新機能を早送りで見てみよう
MongoDB 3.2は2015年の終わりにリリースされる見込みだということが、MongoDB Worldで報告されました。新機能を見てみますが、開発中なのでリリースまでには変更する可能性があります。
今回はこの3つについて見てみます。
- ドキュメント バリデーション
- Partial Index
- Aggregationでjoin ($lookup)
カンファレンスではスキーマについて多くの話がありました。MongoDBはこれまでスキーマレスを売りにプロモーションされてきたので、スキーマについて言及されることは奇妙に見えます。これは、MongoDB, Incがデータベースに格納された文書への規則的な構造を再評価していることなのでしょうか。
MongoDBのエンタープライズツールではscans collectionsやeverse engineers a schema from the collectionsなど、スキーマについてのものがリリースされています。これらは3.2で、コレクションをより便利で整然とするための新機能への提案になるでしょう。
1. ドキュメント バリデーション
[SERVER-18227] Document Validation - MongoDB
3.1.3でリリース済み
コレクションと条件式を指定するシンプルな形のバリデーションです。バリデーションにパスしなかったら error 121 DocumentValidationFailureを出します。
条件式は、greater than, less than, existsなどの式が使えますが、今のところgeo nearやtext search, whereは使えません。
db.runCommand({"collMod": collName, "validator" : {a: {$exists: true}}})
注意点。すでに存在しているコレクションのvalidateはできない。insert, update時のみ。
2. Partial Indexes
JIRAチケット: System Dashboard - MongoDB
3.1 RequiredでOpenだが、3.1.5で試したところ動いた。
2010年からJIRAに登録されている課題で、スキーマに関する新機能。filter expressionをパスしたドキュメントのみがindexされる仕組み。
db.myusercoll.createIndex({ name: 1 }, { partialFilterExpression: { status: { $eq: "active" } } } )
ユーザーをactive, inactiveというステータスで管理している状況を考える。例えばsoft remove実装。 上記のクエリを流すと、activeなユーザーのみがnameでindexされる。
巨大なデータでのパフォーマンス改善になるだろう。filterにマッチしなかったドキュメントはクエリーでスキップされるだけではなく、insert やupdate時のindexingもスキップされる。
3. Aggregationでjoin ($lookup)
JIRAチケット: [SERVER-19095] $lookup - MongoDB
3.1.6でリリース予定
Aggregationフレームワークで、コレクション間のjoinに関する機能。普段の業務でjoinは使わなくても、analyseで使いたくなる時がある。MongoDB, Incはこれまでそのような場合は非正規化をするようにアドバイスしてきた。
これまでのAggregationフレームワークでは、単一のコレクションについてのパイプラインしか実行できなかったが、新機能の$lookupオペレータでは他のコレクションのデータを取得できるようになる。言い換えると、Aggregationステージでleft outer join機能を提供する。
$lookupは大きなポテンシャルを秘めているだろう。ユーザーはデータを非正規化しなくてもよくなる。ただ、実際にどのくらい使える機能なのかはalpha/beta版のリリースを待たなければならない。
まとめ
これらの3つの新機能は、サーバーサイドのMongoDBアーキテクチャにとって課題だった点への取り組みである。MongoDB 3.2 alpha/betaがリリースされた時、その改善を目に出来るだろう。3.2での他の変更点のほとんどはストレージエンジン、認証、他ツールとの連携とレプリケーションである。今後、残りの新機能についても取り上げていく。
ActiveRecord4, Rails4のinverse_ofについて理解したメモ
MongoDB(mongoid)でも使える。
inverse_ofとは
inverse_ofを指定したリレーションのある2つのモデルでは、双方から同一のインスタンスを参照できるようになる。両者ともメモリ上で同一のインスタンスとして扱われる。
逆に、inverse_ofの設定が無いと同一として扱われず、一方からの変更がもう一方から参照しても変更されていない。
具体例
UserモデルとMenuモデルが1対多でリレーションしている状況を考える。Userが複数のMenuを登録できるWebサービスのイメージ。
class User < ActiveRecord::Base has_many :menus end class Menu < ActiveRecord::Base belongs_to :user end
inverse_ofが無かったら
Userのフィールドnameの変更が、Menuからたどった場合に変更が参照できない。メモリ上で別インスタンスとして扱われているから。
user = User.first menu = user.menus.first user.name == menu.user.name # => true user.name = "change" user.name == menu.user.name # => false
inverse_ofを指定すると
class User < ActiveRecord::Base has_many :menus, inverse_of: :user end class Menu < ActiveRecord::Base belongs_to :user, inverse_of: :menus end
メモリ上で同一インスタンスとして扱われるようになり、userもしくはuser.menuからnameを変更しても、常にuser.name == menu.user.name
がtrueを返すようになる。
ドキュメント
MongoDBをtarからインストールしてCentOS 7のsystemdで起動/停止する設定
CentOS 7では、これまでのSysVinitからsystemdが使われるようになりました。 MongoDBもyumやrpmでインストールするとsystemdで管理できるようになるみたいです。 ただ、yumに上がっていないリリース直後のMongoDBをtarからインストールしたい場合、自分で設定する必要があります。ちょうどCentOS 7に最新のMongoDBを環境構築する機会があったので、作業メモとして残します。
一番手っ取り早いのは、yumなりrpmなりでMongoDBをインストールした後、インストールされた/usr/binディレクトリにあるバイナリを差し替えることです。ただし、そうするとyumで管理しているバージョンと差異が出るので注意しないといけません。
今回はyumでのインストールを行わずに、MongoDBのtar + Githubリポジトリにあるrpm用の設定ファイルを使ってsystemdでの起動設定を行います。作業はすべてrootユーザーで行いました。
環境
手順
1. MongoDB 3.1.5のインストール
Downloads - MongoDB から最新のMongoDBをtgz形式でダウンロードします。今回は、RHEL 7 Linux64-bitです。
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.1.5.tgz
設定ファイルはMongoDBのgithubにひな形があるので、ダウンロードして使います。
https://github.com/mongodb/mongo/blob/master/rpm/mongod.conf
他にもgithubのrpmディレクトリにはsystemdで管理する際に必要となるファイルがありますので、後ほど使います。
まずは、rootユーザーでMongoDBが手動で起動するところまで進めます。
cd /opt wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.1.5.tgz tar zxfv mongodb-linux-x86_64-rhel70-3.1.5.tgz ln -s /opt/mongodb-linux-x86_64-rhel70-3.1.5/ /opt/mongodb wget https://raw.githubusercontent.com/mongodb/mongo/master/rpm/mongod.conf mv mongod.conf /etc/mongod.conf mkdir /var/log/mongodb mkdir /var/lib/mongo mkdir /var/run/mongodb
準備できました。起動の確認を行います。
[root@xxxx ~]# /opt/mongodb/bin/mongod -f /etc/mongod.conf about to fork child process, waiting until server is ready for connections. forked process: 6637 child process started successfully, parent exiting
起動しない場合は、/var/log/mongodb/mongod.log
を確認しましょう。
mongoシェルから接続を確認します。
[root@xxxx ~]# /opt/mongodb/bin/mongo MongoDB shell version: 3.1.5 connecting to: test Server has startup warnings: 2015-07-13T15:46:30.961+0900 I CONTROL [initandlisten] 2015-07-13T15:46:30.961+0900 I CONTROL [initandlisten] ** NOTE: This is a development version (3.1.5) of MongoDB. 2015-07-13T15:46:30.961+0900 I CONTROL [initandlisten] ** Not recommended for production. 2015-07-13T15:46:30.961+0900 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended. 2015-07-13T15:46:30.961+0900 I CONTROL [initandlisten] >
WARNINGがいくつか出ると思いますが、今回の記事では気にしないこととします。 接続できたことが確認できたら成功です。
次の手順でsystemdによる起動を行うので、いま起動させたmongodプロセスは停止させましょう。 mongod.lockファイルの削除も忘れずに。
kill `cat /var/run/mongodb/mongod.pid` rm /var/lib/mongo/mongod.lock
2. systemdによる起動設定
ここから本題のsystemdによる設定に入ります。まずはmongodグループとmongodユーザーを作成します。コマンドはgithubにあるrpm用のspecファイルを参考にしています。
https://github.com/mongodb/mongo/blob/master/rpm/mongodb-org.spec
/usr/sbin/groupadd -r mongod /usr/sbin/useradd -M -r -g mongod -d /var/lib/mongo -s /bin/false -c mongod mongod
関連するディレクトリの所有者をmongodに変更します。
chown -R mongod:mongod /opt/mongodb chown -R mongod:mongod /var/log/mongodb chown -R mongod:mongod /var/lib/mongo chown -R mongod:mongod /var/run/mongodb
systemdのserviceファイルをgithubからダウンロードして配置します。
wget https://raw.githubusercontent.com/mongodb/mongo/master/rpm/mongod.service mv mongod.service /usr/lib/systemd/system ln -s /usr/lib/systemd/system/mongod.service /etc/systemd/system/multi-user.target.wants/
daemon-reloadの後、起動させます。
systemctl daemon-reload systemctl start mongod.service
systemctl statusで起動を確認しましょう。
[root@xxx ~]# systemctl status mongod.service mongod.service - High-performance, schema-free document-oriented database Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled) Active: active (running) since Mon 2015-07-13 16:16:04 JST; 5s ago Main PID: 6774 (mongod) CGroup: /system.slice/mongod.service └─6774 /opt/mongodb/bin/mongod --quiet -f /etc/mongod.conf run Jul 13 16:16:04 xxx systemd[1]: Starting High-performance, schema-free d..... Jul 13 16:16:04 xxx systemd[1]: Started High-performance, schema-free do...e. Jul 13 16:16:04 xxx mongod[6772]: about to fork child process, waiting u...s. Jul 13 16:16:04 xxx mongod[6772]: forked process: 6774 Jul 13 16:16:04 xxx mongod[6772]: child process started successfully, pa...ng Hint: Some lines were ellipsized, use -l to show in full.
Activeがactive (running) となっていたら成功です。お疲れさまでした!
停止コマンド
systemctl stop mongod.service
3. OS再起動時に/var/run/mongodbを作成する設定
CentOS 7は/var/run はtmpfsとなっているので、OS再起動時に削除されます。 /etc/tmpfiles.d/mongod.confを作成して再起動後もディレクトリが作成されるようにしましょう。
echo "D /var/run/mongodb 0755 mongod mongod -" > /etc/tmpfiles.d/mongod.conf
PipelineDBとContinuous Queryについて調べたこと
TechCrunchの記事で、PipelineDBがオープンソースでリリースされたことを知ったので調べてみた。
記事には、
このオープンソースのデータベースはSQLのクェリを連続的にストリーミングで流し、結果のテーブルを次々と保存する。協同ファウンダのDerek Nelsonはこう説明する: “連続的な処理とリレーショナルのストレージを一体化しているので、ストリーム処理をしながら、別途、外付けのストレージシステムを管理しなくてもよい”。
とあるが、何のことかさっぱりわからないので、マニュアルを読んでみる。
Introduction — PipelineDB 0.8.0 documentation
Continuous query
読み始めたはいいが、マニュアルに頻出する単語、continuous queries
がさっぱりわからないので、検索してみる。
この資料 http://www.ieice.org/iss/de/DEWS/proc/2004/paper/doc/ms-1.pdf によると、
データストリームからの到着データへ繰り返し問合せを適用する処理方式。 到着データをタイムスタンプが付加された無限のタプル列とみなす。
なるほど。このデータストリームにSQLで問い合わせできるのが特徴なわけね。
PipelineDBとは
特徴を整理する。
- PostgleSQLベースで開発されているオープンソースなDB
- まだDBに保存していないデータストリームを扱うことができる
- データストリームにSQLで繰り返し問い合わせでき、テーブルやビューのように扱うことができる
使い方のイメージ
実際にどんなシーンで使えるか。データストリームへの問い合わせとはどういうことかは、PipelineDBのトップページをみるとJavaScriptのアニメーションがあるのでわかりやすい。
公式ページのExamples
大量に流れてくるデータ、ログをモニタリングしてごにょごにょするのが使いどころか。 ポイントは、ごにょごにょの処理でSQLで書けるところ。まだDBにInsertする前なのに。 例えば、サーバーのログを監視しておいて、レイテンシがnミリ秒以上なレスポンスが1分以内に50回あったらアラートという処理がSQLで書ける。これまではDBにInsertする前のデータストリームの状態では、アプリケーションで使っているプログラミング言語、もしくはCQL(Continuous Query Language)で処理を書く必要があった。
PipelineDBを使えば、SQLで書けるね。これまでバッチ処理をしていたSQLをそのままリアルタイム処理にできるよってのがメリットかな。
ソースコード
CROSS 2015でデザイナーパネルディスカッションやってきました #cross2015
技術評論社のサイト gihyo.jp にレポートが掲載されました
企画したきっかけ
スタートアップを立ち上げて自分たちのWebサービスをスクラッチから作ってきたのですが、最近はデザイナーさんとのやり取りが多くなってきました。前職はSIerだったためデザイナーさんと仕事で関わることは無く、最初はどうやって進めていったら良いのか悩んでいました。幸いにも周りの人たちの協力で少しずつデザイナーさんとの共同作業に慣れてきましたが、ずっとエンジニアとデザイナーの関係についてのベストプラクティスについて考えていました。そこで、友人や紹介していただいたデザイナーさんに参加してもらって、デザイナーさんの視点からエンジニアとのコミュニケーションや仕事の進め方について語ってもらおうという俺得企画です。
パネリスト
- 株式会社nanapi 木村 真理さん
- 株式会社FULLER 櫻井 裕基さん
- 株式会社サイバーエージェント 新妻 里夏さん
- 株式会社LIG 堀口 誠人さん
概要
デザイナーの作業領域がコーディングよりになっていっている背景をもとに、エンジニアはデザインついてどこまで踏み込めば良いのか、そしてエンジニアとデザイナーの理想の関係を考えるというテーマでディスカッションを行いました。
パネリスト紹介
株式会社nanapi 木村 真理さん
株式会社FULLER 櫻井 裕基さん
株式会社サイバーエージェント 新妻 里夏さん
株式会社LIG 堀口 誠人さん
toggetter
CROSS 2015 デザイナーからのラブレター #cross2015 - Togetter
感想
ディスカッションの中での話題で、この2つが心に残りました。
- エンジニアもデザイナーもお互いの作業領域に踏み込んでいくことが大切
- コミュニケーション、共通認識が大事。(例: エンジニアとデザイナーで共用Pinterestアカウントを作り、良いと思ったデザインサイトをピンしていく)
- 仕様変更を前提とした修正しやすいデザインを作っている人がいる
特に3番目は、拡張しやすいコードが正義なエンジニアにとってとてもわかりやすいことでした。拡張しやすいデザイン、再利用しやすいデザインがデザイナーさんたちの間でも広がっていってるんだなと知りました。
最後になりましたが、参加者とCROSS2015運営スタッフの皆さんに感謝いたします!