AWS CloudSearch を使ってみた
Elasticsearch を調べたあと、最近は CloudSearch も機能強化されて日本語の検索も簡単にできていることを知り、いろいろ試して使ってみました。 結果、すごく良さそうなので今開発中のプロジェクトで採用することにしました。
調査しつついろいろコツというか知っておくべき点があったのでメモを残しておきます。 Elasticsearch との比較という観点で調査・検証していたので、Elasticsearch をある程度知った状態で読んでいただいた方がいいかも。
CloudSearch と Elasticsearch の比較
- Elasticsearch ではシャード数は index 作成時に決定しなくてはならないが、CloudSearch なら自動でスケールアップしてくれる。
- 検索のパフォーマンスに関しては Elasticserch でもあとから replica 追加可能なのでスケールアウト可能。しかし、インデックス更新のパフォーマンスは上げられない。
- 日本語検索は両者とも ok
- 特定の条件を重要視したスコアリングなども両者とも ok
- CloudSearch の場合、インデックスの作成や構造を変更するとき (カラムの追加とか) にはかなり時間がかかる + 別途料金 (1GB あたり 0.98 USD) がかかるので注意が必要。
CloudSearch を使う上で知っておきたいこと
- 検索クエリの書き方は simple, structured, lucene, dismax の 4形式をサポートしている。単純に全カラムを対象に全文検索を行うなら simple クエリで十分だけど、いろいろ条件を複合して絞り込みを行うなら structured クエリが複雑だけど柔軟度が高そう。
- 検索結果のスコアリングに影響を与えない、"filter" クエリも structured クエリ書式で書くことができる。Elasticserch にもある機能。
rails から扱いたい場合は https://github.com/wellbredgrapefruit/asari の v1.0 ブランチがよさそうfq
パラメータにちゃんと対応していないのでちょっとつらかった。https://github.com/stevenjl/rawscsi を検証してみる。これもクエリの自由度に欠けるためダメ。- 結局 AWS SDK の 2.0 の pre 版を使うのがよさそう。 http://docs.aws.amazon.com/sdkforruby/api/index.html
- CloudSearch を使うとローカルで検証ができないのが辛いところ (chatwork では検証用に m1.small の CloudSearch インスタンスを立ち上げて使っているらしい: https://speakerdeck.com/tanakayuki/kai-fa-zhe-karamitacloudsearch?slide=16)
インデックスの更新について
- インデックスの更新は "add" と "delete" の2種類で、それぞれ JSON をアップロードすることで更新する。
- add は常に上書き更新となり、一部のカラムだけ更新とかはできない。
- 複数の add, delete の操作をまとめて送ることができて(その単位をドキュメントバッチと呼ぶ)、なるべくドキュメントバッチのサイズ上限である 5MB に近いデータを送るようにした方がパフォーマンスがいいらしい。
- 僕はいったん更新/削除用の json をデータベースに貯めておいて、一定時間おきに sidekiq で最大 5MB ずつのバッチに分けてアップロードしています。
- json 以外のデータもアップロードできるらしいけど、そのユースケースが自分にはないので調べてないです。
- インデックス上のドキュメントを識別するための id は ActiveRecord のオブジェクトの id でももちろん ok
料金体系
- 次の 4つで課金されます。 -> インスタンス料金、ドキュメントの更新、インデックスの再構築、データ転送
- うち、インスタンス料金以外はかなり安いので無視してもよさそう。
- ちなみに最低で 0.082 * 24時間 * 30日 = $59.04/月 くらい (マルチAZ無し)
参考文献
Elasticsearch メモ
最近仕事で使いたいと思い、Elasticsearch で遊んだりしています。
$ brew install elasticsearch
したらローカルで動いたのですが、そこから何すればいいのかさっぱりわからなかったので急がば回れということで本を読みました。
高速スケーラブル検索エンジン ElasticSearch Server
- 作者: Rafal Kuc,Marek Rogozinski,株式会社リクルートテクノロジーズ,大岩達也,大谷純,兼山元太,水戸祐介,守谷純之介
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2014/03/21
- メディア: 大型本
- この商品を含むブログ (3件) を見る
epub 版は以下から。
高速スケーラブル検索エンジン ElasticSearch Server【委託】 - 達人出版会
上記書籍は Elasticsearch 0.90.11 を元に書かれているので、実際に使う前に差分を公式のドキュメントで確認することをお勧めします。(そんなに大きくは変わってないですし、概念を学ぶにはぜひ書籍を)
雑多なメモ
elasticsearch-head
elasticsearch-head プラグインを使うとブラウザから elasticsearch の状態を見たり操作したりできます。これがないといちいち curl で API を叩かないとクラスタの様子がわからない。
$ plugin -i mobz/elasticsearch-head # インストール $ open http://localhost:9200/_plugin/head/
Rails から使うには
以下の gem を使う。ちなみに以前は tire という gem が主流のようでしたが、現在そのリポジトリは karmi/retire · GitHub という名前になって引退しています。(お茶目)
elasticsearch-model を使って、適切にインデックスの mapping をしたり query を組み立てたりすることができますが、デフォルトでは as_json
メソッドの値をそのままインデックスに登録しているので、雑に使う分にはそれで十分かもしれません。
あとは Article.search('title: hoge').records
とかすれば、タイトルに hoge を含む検索結果に基づいて where id IN (1, 3, 4)
みたいな SQL でレコードを取得できます。
ちゃんとインデックスを定義したい場合はモデルで mapping を定義して as_indexed_json
をオーバーライドすることで Elasticsearch に登録する情報を定義したりできます。
クラスタリング
config/elasticsearch.yml の cluster.name
が同じ elasticsearch の node がネットワーク上に存在すると、勝手にクラスタ化されます。すごいですね。
ちなみに Homebrew でインストールした場合は network.host: 127.0.0.1
をコメントアウトしないとクラスタに参加してくれませんでした。この辺検証するときは Vagrant でやるとか、公式からアーカイブ落としてきて起動するとかした方が楽かもしれません。
AWS 上で運用する際は以下のドキュメントが参考になります。 (node が参加するべきクラスタを EC2 API を叩いて探してくれたりする)
ただ、このドキュメントだいぶ古いので注意が必要です。
シャード数はインデックス作成時にだけ指定できるみたいですが、レプリカ数はあとから足したり引いたりすることが可能なようです。 検索のパフォーマンスが足りなくなったなぁと思ったら増やす感じですね。
シャードやレプリカの配置は Elasticsearch に勝手配置してもらったり、任意の routing を定義したりもできるようです。
日本語全文検索
kuromoji というトークナイザーを使えば日本語での全文検索が可能です。
詳しくは以下。
パーフェクト Ruby on Rails を読んだ
パーフェクトRuby on Rails を読みました。
いまさら!?という感じですが、しばらく仕事では iOS をメインでやっていたのですが、最近またサーバーサイドに戻ってきたそのタイミングで電子版が発売されたので。
ちなみに epub 版は 以下の URL から買えます。
Rails で仕事をしている人にはこの辺がオススメ
全体的には仕事、趣味を問わずバリバリ Rails を使っている人にこそ必要な本だなーという印象でした。 特に4章と9章が今後の自分の設計指針にとって非常に参考になりました。
4章の “Railsのロードパスとレイヤーの定義方法” は Model, View, Controller 以外の層 (Worker とか Service とか) を定義して使うための方法について書いてあります。ジョブキューでよく使われている sidekiq が例に出ているのでわかりやすくて実践的です。
そして9章の “より実践的なモデルの使い方” では4章で得た知識を使って、どうやって複雑になりがちな ActiveRecord::Base
を継承したモデルを整理しきれいな設計をするか、という内容を具体的なコードを挙げながら説明してくれています。
rails がデフォルトで持っている app/models, app/controllers, app/views での MVC ではモデルないしコントローラが複雑になってしまってなんだかうまくいかないなーと感じている人は、ぜひ4章と9章を読んでみることをオススメします。
書籍とは関係ありませんが、最近 肥大化したActiveRecordモデルをリファクタリングする7つの方法(翻訳) | TechRacho を読んで、自分が rails がデフォルトで作る models, controllers, view ならびに concerns に無理やりコードを収めようとし過ぎて、レールの下敷きになってしまっていたことにようやく気付き反省したところでした。 この パーフェクト Ruby on Rails を読んでさらに設計に対する姿勢を柔軟にすることができたと感じています。
Rails を勉強中の方にはこの辺がオススメ
6章の “Railsアプリケーション開発” は具体的なアプリケーションを実際に作りながら rails の機能をどのように使えばいいか、そしてどのようなところに気をつければいいか、について解説されている章です。
この章に従って一通りアプリケーション作りをしてみることは Getting Started with Rails — Ruby on Rails Guides (和訳: Railsをはじめよう — Ruby on Rails Guides) や Ruby on Rails Tutorial (3rd Ed.), Learn Web Development with Rails - Michael Hartl | Softcover.io (和訳: https://www.railstutorial.jp) を終えた人にとって非常によい練習になると思います。
この章を教材にすると中級者向けの Rails 講座とかやれそうですね。
まとめ
最近の Rails 周りの情報を一気にキャッチアップできるよい本だと思います。 読んでよかったです。
- 作者: すがわらまさのり,前島真一,近藤宇智朗,橋立友宏
- 出版社/メーカー: 技術評論社
- 発売日: 2014/10/31
- メディア: Kindle版
- この商品を含むブログ (1件) を見る
はてなブログに出戻り
wordpress -> はてなダイアリー -> Lokka -> はてなブログ -> octopress -> middleman-blog と来て、またはてなブログに戻ってきました。 ついでなので、過去の記事もなるべく移行してきました。
octopress の頃の記事は middleman-blog にちゃんと移行してあったので、あとは以下のようなスクリプトで MT 形式に書き出しました。
# $ bundle exec middleman console 内で。 template = <<EOT AUTHOR: %s TITLE: %s DATE: %s CATEGORY: %s ----- BODY: %s ----- -------- EOT File.open('/tmp/blog.mt', 'w') {|f| blog.articles.each do |article| body = article.body f.puts template % ['satococoa', article.title, article.date.strftime('%m/%d/%Y %H:%M:%S'), article.tags.join("\nCATEGORY: "), body] end }
Lokka の記事もだいたいそんな上記みたいな感じで。 Lokka は heroku に置いてあったので書き出した後のテキストファイルをどうやって手元に持ってこようか悩んだのですが、
を使うことで解決しました。
Web デザイナ向け GitHub ハンズオン at PHPカンファレンス2014
PHPカンファレンス2014 で P4D として Web デザイナ向け GitHub ハンズオン を開催します。
今回のハンズオンは前半・後半の2部構成で行います。 後半に関しては PHP カンファレンスの参加登録 以外にハンズオンへの 参加登録 も必要ですので、希望者は 忘れずに お願いいたします。
(前半は PHP カンファレンスの参加登録だけでご参加いただけます。)
前半: 講演 x 3 「Web デザイナが GibHub を使うと嬉しいこと」
前半は実際に GitHub を使って開発を行っている 3 名の方に講演をいただきます。
- @kenclo さん: (デザイナー)
- @machida さん: (デザイナー)
- @hiro_y さん: (エンジニア)
前半は事前登録等は不要です。そのまま会場へお越し下さい。 (希望人数によっては立ち見や、残念ながら入室いただけない可能性もありますのでお早めにどうぞ。)
後半: 「Web デザイナ向け GitHub ハンズオン」
後半は Web デザイナさん向けに、実際に GibHub でコミュニケーションができるようになるまでを体験していただくハンズオンをやりたいと思います。
Git についての事前知識は特に必要ありません。また、Git のバージョン管理という側面については最低限しか解説しない予定です。あくまで「GitHub を使ってエンジニアとコミュニケーションをとりながら楽しく開発ができる」ようになるためのハンズオンです。
そういう意味ではややニッチではありますが、取っ付きやすいテーマだと思いますのでぜひお気軽に参加してください。
参加される方は必ず以下の準備をしてきてください
- 充電が十分なノート PC
- GitHub アカウントを取得しておいてください
- GitHub for Mac か GitHub for Windows をインストールしてきてください
ハンズオンへの参加希望の方は Web デザイナ向け GitHub ハンズオン in PHPカンファレンス2014 から参加者登録をお願いします。
STCTabView というライブラリを作った
某スマートニュースや某グノシーみたいなタブっぽい UI を実現させるために STCTabView っていうライブラリを作りました。
https://github.com/satococoa/STCTabView
ドキュメントもテストも無いですが、ヘッダ見てもらえば使い方はなんとなくわかる。。。と思います。
詳しくは Example を見ていただければ、と思いますがこんな感じにタブバーを定義できます。
STCTabItemView *item = [[STCTabItemView alloc] initWithFrame:CGRectZero];
STCTabItemView *item2 = [[STCTabItemView alloc] initWithFrame:CGRectZero];
item.text = @"foo";
item.backgroundColor = [UIColor colorWithRed:26/255.0 green:188/255.0 blue:156/255.0 alpha:1.0];
item.selectedBackgroundColor = [UIColor colorWithRed:22/255.0 green:160/255.0 blue:133/255.0 alpha:1.0];
item2.text = @"bar";
item2.backgroundColor = [UIColor colorWithRed:52/255.0 green:152/255.0 blue:219/255.0 alpha:1.0];
item2.selectedBackgroundColor = [UIColor colorWithRed:41/255.0 green:128/255.0 blue:185/255.0 alpha:1.0];
[self.tabView appendTabItem:item];
[self.tabView appendTabItem:item2];
[self.tabView setSelectedTabIndexChangedHandler:^(TabIndex tabIndex) {
NSLog(@"%ld 番目のタブが選択されたよ", (long)tabIndex);
}];
ゆるふわ Development Club
ゆるふわ Development Club というコミュニティを始めました。
このコミュニティについては @netwillnet さんが ゆるふわ Development Club というサークルができた - willnet.in で紹介してくださったので、簡単にこのコミュニティを始めた経緯とかを書いてみたいと思います。
P4D
以前から デザイナー向けプログラム部 (P4D) というコミュニティを主催しています。
最初の頃はデザイナさん向けの「勉強会」として活動していました。
例えばデザイナさんに Git を教えるための WebデザイナーのためのGit勉強会 というハンズオン形式の勉強会を開いたり、JS や Ruby で TODO アプリを作ってみるハンズオンをやったり、といった具合です。
その活動を続けた結果、参加してくださっているデザイナさんとは普通に GitHub を使って仕事ができたり pplog のようなプロダクトづくりをできたり、またデザイナとエンジニアで組んでハッカソンをしたりできるところまで達成する事ができました。
そのような流れもあり、最近の P4D では「教える」ということよりはそれぞれのプロダクトを作る活動をメインに行っています。 (もちろんその中で教え合いや相談は普通に発生しているのですが。)
ふと見直してみると、現状の P4D の活動は言うほど「デザイナ向け」でもないし、「勉強会」っぽくなくなってきたなーという実感がありました。
そこでそろそろ P4D の活動内容を見直すと同時に、今出来上がりつつある「それぞれのプロダクト作りをがんばるコミュニティ」を P4D とは別のものとして立ち上げた方がいいんじゃないかなーと思うようになってきました。
kamabata #とは
今年に入ったあたりから P4D を通じて知り合った仲間と idobata を使って お互いのプライベートなプロジェクトのコミットログを流し合ったり、esa.io で日報を書いたり、といった試みを続けています。
(たまたま蒲田周辺に住んでいる人が多かったので p4d/kamabata というルームを idobata に作ったのでした。)
esa や idobata を使う事でそれぞれの開発の進捗を共有したり相談やレビューをしたり、ときには一緒に開発したりということが容易になりました。 特にプライベートリポジトリで作業をしている場合や TestFlight でβ版を触ってもらいたい場合などにはその場は本当に心強いです。
また、idobata を見に行くといつも誰かのコミットログが流れてくるので否が応でも自分のモチベーションも刺激されます。
この kamabata の活動をもうちょっとオープンにした形でコミュニティをやれば、個人で趣味の開発をしている人でもチーム開発の良さを享受し、プライベートな開発のモチベーションを上げていけるのでは...。
そんなことをぼんやり先月くらいから考えていました。
趣味の開発サークルをやりたいというポエム
そんな事を考えているときに @netwillnet さんがポエムに投稿した内容が実はほとんど kamabata で実践していることとそのままでした。(やってたわー、それ数ヶ月前からやってたわー)
すぐに @netwillnet さんを kamabata に招待して実際に体験してもらい、これは面白そうだという感想を得たので一緒に主催という形でゆるふわ Development Club を立ち上げたのでした。
#ydclub もしくは "ゆるデブ" の具体的な活動
当面は P4D でやっていた内容に近い感じになります。
月2回の都内でのミートアップと、たまにハッカソンや開発合宿やらをやっていこうと思います。 平行して idobata にコミットログを流したり、そこから誰かの開発を手伝ったり、レビューしたり、相談したり、お寿司スタンプを送り合ったりという活動をしていきます。
P4D の今後の活動について
月2回のミートアップはお休みします。 (もし引き継いでくださる方がいらっしゃれば、引き継ぎたいと思います。)
代わりに、定期的にハンズオンかセミナー形式での勉強会を開きたいと思います。 内容は Git や Rails、iOS あたりを考えています。
まとめ
そんな感じで、もしゆるデブ活動に興味を持ってくださった方がいらっしゃれば気軽に idobata のルームを覗いてみたり、 ミートアップに遊びに来てくださったりすると幸いです。
今後ともよろしくお願いします。