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

TOMOLOG

こにゃにゃちわ

elasticsearchのGet APIで特定のフィールドを取得する。

elasticsearchのGet APIで特定のフィールドを取得する方法を試す。

特に指定せず、普通に取得すると以下のようになる。

[user@search001 ~]$ curl -XGET "http://localhost:9200/user_v1/searchable_user/1/_source?pretty=true"
{
  "birthdate" : "1989-07-07T15:00:00.000Z",
  "register" : "2014-07-08T07:00:17.232Z",
  "update" : "2014-07-10T02:04:29.302Z",
  "gender" : "female",
  "zodiacSign" : "cancer",
  "userId" : 1,
  "name" : "チョコレート",
  "isNew" : false,
}

特定のフィールドを取得する場合は、クエリーストリングで _source={FIELD} を指定する。

[user@search001 ~]$ curl -XGET "http://localhost:9200/user_v1/searchable_user/1/_source?pretty=true&_source=name"
{
  "name" : "チョコレート"
}

複数のフィールドで絞り込みたい場合は , でセパレートする。

[user@search001 ~]$ curl -XGET "http://localhost:9200/user_v1/searchable_user/1/_source?pretty=true&_source=name,gender"
{
  "gender" : "female",
  "name" : "チョコレート"
}

mongodbでsecondaryに参照クエリを流す

目的

mongodbは特に指定しない場合、write/read共にprimaryに対して処理が行われます。 これをsecondaryに対してもread処理を流すようにすることで、負荷分散ができますよというお話。

Read Preference

MongoのクライアントにRead Preferenceというオプションがあります。 これは、クライアントからMongoDBの読み出しを行う際、どのメンバーに対してread処理を行うかを指定できる設定です。 docs.mongodb.com

  • primary : primaryからのみread処理を行う。
  • primaryPreferred : primaryからread処理を行うが、もし処理が行えない場合はsecondaryからread処理を行う。
  • secondary : secondaryからのみread処理を行う。
  • secondaryPreferred : secondaryからread処理を行うが、もし処理が行えない場合はprimaryからread処理を行う。
  • nearest : ネットワークレイテンシーが最も低いメンバーから優先的にread処理を行う。

secondary readを試す

> db.test.find().readPref({mode:'secondaryPreferred'})
{ "_id" : "hoge", "name" : "fuga" }

↑のようにクエリごとにread処理を決めることができます。
アプリケーションなどで利用する場合、単純に全てのクエリに対してsecondaryを指定すると、参照処理が全てsecondaryに向いてしまうため、 処理ごとに明示的にわけるか nearestを指定するなどでクエリがバラけるようクライアントの設定を調整しましょう。

補足

MongoのクライアントにWrite Concernというオプションがあります。 これは、クライアントから『書き込み処理がどこまで行えたら成功とみなすか』を指定できる設定です。 docs.mongodb.com

今回、参照処理をslaveに流す対応を行いましたが、タイムラグが許されないデータに関しては、write concernをmajorityにするなど厳密な設定が必要になります。その場合、writeのスループットに影響するため、 secondary read = パフォーマンス向上 に繋がるとは安易に言えません。 サービスやデータの特性に応じて、secondary readを導入すべきか慎重に検討しましょう。

TOTEC2015で優勝しました!

TOTECという、サイバーエージェントの社内ISUCON的なエンジニアコンペで優勝しました!

今年はチーム戦ということで以下のメンバーで参戦しました。
ともっくす - infla
はぎ - server
ゆし - front

このメンバーは、ピグブレイブというサービスの立ち上げを一緒にやったメンバーで、お互いのことを熟知した状態で大会に望めたのが大きかったなと思います。当日も阿吽の呼吸感がすんごかった。チーム力大事ですね。

事前準備から当日まで、本当にわいわい楽しくやれたのもこのメンバーだからこそなので、改めてはぎとゆしにはありがとうと伝えたいです。

チーム名のマイナスツンデレーションについて、
「そのチーム名なんなん」
と聞かれることが多かったのですが、説明が難しいので決まるまでの過程を貼っておきますね。 f:id:tomox1001:20151114140328p:plainf:id:tomox1001:20151114091821p:plain

やったこと - 事前準備

コンペに向けて、事前準備はかなり念入りにやりました。
「入賞しなくてもベスト準備賞は狙えるかもねw」 という話も出るくらいに。 ベスト準備賞なんてないけどw

事前すり合わせでやっておいてよかったと感じたのは、やることの優先順位をチームとして決めておいたことです。
我々は「まずはアプリを作る、動かす!」をポリシーとしていました。
当日は時間がない中でやることが無限にあるので、まずは動くものを最速で作ることを決めておいたことで何をすればいいのかが明確になったかなと思います。

以下、事前準備用のメモです。
こうしてみるとほんと色々やったなぁとしみじみ。
f:id:tomox1001:20151114095038p:plainf:id:tomox1001:20151114095042p:plain

やったこと - 当日

「まずは動くものを最速で作る」
のポリシーに従い、よいスタートダッシュを切るために、事前に用意していたSTART:DASH!!!というToDoリストを元に環境構築をしました。
大きな事故もなく、開始1時間くらいでアプリが動くところまでいけました。 f:id:tomox1001:20151114095939p:plainf:id:tomox1001:20151114095947p:plain

システム構成は、2インスタンスがアプリサーバー(計測用の1台にはリバプロとロードバランサー - nginx共存)、1インスタンスがDBサーバーというシンプルな構成でした。 アプリはnodejs、テンプレートエンジンはectを使いました。自分の手に馴染んでいるもので、というのが選択理由です。
データストアはmongoredisを予定してたのですが、渡されたデータの容量がjson化しても1.5GBぐらいだったので、「オンメモリわんちゃん」というはぎの一声でDB全部捨ててオンメモリでいく方針にしました。起動まで3分くらいかかりましたが、なんとかメモリに載りきりました。この時点でDB用に用意していたインスタンスもアプリサーバーに切り替えることにし、再プロビジョニングしました。

一応、newrelickataribeなどのパフォーマンス計測ツールも用意していたのですが、そもそもの実装量が膨大だったのでチューニングにはあまり時間をかけられなそうでした。ので、割り切りでこの辺のツールも事前にオフっておきました。
ちなみに、競技終了前にやるべきことは忘れそうだったのでEND:DASH!!!というToDoリストにまとめてありました。 f:id:tomox1001:20151114095956p:plain

まとめ

色々書きましたが、 まとめると
- オンメモリわんちゃん
- 最速実装への振り切り
- チーム力!!

が、主な勝因かなと思っております。
あとは、運の要素も大きいです。はっていたヤマが当たったり、定めていたチームポリシーがたまたま競技にマッチしたり。

個人的にはエンジニアが一同に介してわいわいやるのは本当に楽しかったのでぜひ来年も期待しております!

運営のみなさま、参加者のみなさま、本当にお疲れ様でした!!

Mac OS X Lionでrvmがインストールできない件

mac

rvmインストールがうまくいかなかったので備忘録代わりに書き残します。
Lionでrvm install 1.9.3しても下記のエラーが出てしまいうまくいきませんでした。

$ rvm install 1.9.3

で、実行しても

Installing Ruby from source to: /Users/jamie/.rvm/rubies/ruby-1.9.3-p0, this may take a while depending on your cpu(s)...
 
ruby-1.9.3-p0 - #fetching 
ruby-1.9.3-p0 - #extracted to /Users/jamie/.rvm/src/ruby-1.9.3-p0 (already extracted)
Fetching yaml-0.1.4.tar.gz to /Users/jamie/.rvm/archives
Extracting yaml-0.1.4.tar.gz to /Users/jamie/.rvm/src
Configuring yaml in /Users/jamie/.rvm/src/yaml-0.1.4.
Compiling yaml in /Users/jamie/.rvm/src/yaml-0.1.4.
Installing yaml to /Users/jamie/.rvm/usr
ruby-1.9.3-p0 - #configuring 
ERROR: Error running ' ./configure --prefix=/Users/jamie/.rvm/rubies/ruby-1.9.3-p0 --enable-shared --disable-install-doc --with-libyaml-dir=/Users/jamie/.rvm/usr ', please read /Users/jamie/.rvm/log/ruby-1.9.3-p0/configure.log
ERROR: There has been an error while running configure. Halting the installation.

となる。。

どうやら、新しいXcode(4.2以降?)がTraditionalなGCCを持っていないことが原因らしい。なので下記のオプションを適応して再度実行。

$ rvm install 1.9.3 --with-gcc=clang

で、うまくいきました。