PHPド素人がYahoo!検索プラグインを開発〜リリースするまでのまとめ
- 本日Yahoo検索プラグインが公開されました。
Yahooプラグインとは?
一言で言えばYahooの検索結果に独自情報を付加できます。
プラグインを入れた人以外はそのままの検索結果が表示されますが、便利なので
今回の公開を機にユーザーも対応サイトも徐々に増えていくと思います。
早速簡単なプラグインを開発して、公開するところまでやってみました。
意外と簡単
私はperlプログラマですがphpは名前を聞いたことがあるだけで今回はじめて触りました。
そんな私でも2-30分でプラグインを開発して公開することができたので、
この喜びを一人でも多くの人に体験してもらいたいと思っています。
用意するもの
- Yahooアカウント
今回はエディタすら使いません!!
プラグイン作成に必要と思われるスキル
- HTMLの基本的な知識
- いずれかのプログラミング言語でif文を書けるレベル
- 自分でサイトやブログを作成した経験があれば尚良し
このブログを見ているなら、多くの人が上記にあてはまると思います。
せっかくなので是非チャレンジしてみてください!!
下準備
- Yahooアカウントを用意します。
- 自分が所有するサイトのプラグインを作る場合はサイトエクスプローラーで認証しておきます。
- アイコンがあったほうがいいので作成するサイトの16*16 85*65のアイコンを準備します。
http://developer.yahoo.co.jp/other/searchplugin/
に詳細情報があります。ブックマークしておきましょう。
ここまでについては解説しません。
Yahoo!検索プラグイン 開発ツール 開発ガイド
http://developer.search.yahoo.co.jp/
にて作業をすすめます。ここでYahooIDが必要です。
ソース全文
public static function getOutput() { $linkurl = Data::get('yahoo:index/dc:identifier'); $itemkey = 0; $match; if(preg_match('/luxury-la.com\/\d+\/\d+\/(.+?)\.html/', $linkurl, $match)){ $itemkey = $match[1]; } $ret = array(); /* If you leave these blank, the default title and summary will be shown */ $ret['title'] = Data::get('yahoo:index/rel:Posting/dc:title'); $ret['summary'] = Data::get('yahoo:index/rel:Posting/dc:description'); /* Now you fill in the rest. Use Data::get and Data::xpath to get data */ // Image if($itemkey){ $ret['image']['src'] = 'http://a248.e.akamai.net/f/248/37952/1d/image.shopping.yahoo.co.jp/i/g/' . $itemkey; }else{ $ret['image']['src'] = 'SM_VAL_DEFAULT'; } $ret['image']['alt'] = SM_VAL_DEFAULT; $ret['image']['title'] = SM_VAL_DEFAULT; // Deep links - up to 4 $ret['links'][0]['text'] = SM_VAL_DEFAULT; $ret['links'][0]['href'] = SM_VAL_DEFAULT; $ret['links'][1]['text'] = SM_VAL_DEFAULT; $ret['links'][1]['href'] = SM_VAL_DEFAULT; $ret['links'][2]['text'] = SM_VAL_DEFAULT; $ret['links'][2]['href'] = SM_VAL_DEFAULT; // Key Value pairs - up to 4 $ret['dict'][0]['key'] = SM_VAL_DEFAULT; $ret['dict'][0]['value'] = SM_VAL_DEFAULT; $ret['dict'][1]['key'] = SM_VAL_DEFAULT; $ret['dict'][1]['value'] = SM_VAL_DEFAULT; $ret['dict'][2]['key'] = SM_VAL_DEFAULT; $ret['dict'][2]['value'] = SM_VAL_DEFAULT; $ret['dict'][3]['key'] = SM_VAL_DEFAULT; $ret['dict'][3]['value'] = SM_VAL_DEFAULT; /* This is for infobar apps You can put a subset of HTML in here See the docs for more details */ $ret['infobar']['blob'] = SM_VAL_DEFAULT; return $ret; }
ソースの解説
$linkurl = Data::get('yahoo:index/dc:identifier');
でリンク先のURLを取得しています。
if(preg_match('/luxury-la.com\/\d+\/\d+\/(.+?)\.html/', $linkurl, $match)){ $itemkey = $match[1]; }
でURLからアイテムのキーを取得しています。
if($itemkey){ $ret['image']['src'] = 'http://a248.e.akamai.net/f/248/37952/1d/image.shopping.yahoo.co.jp/i/g/' . $itemkey; }
でアイテムのキーから画像のURLを作って渡します。
独自のプラグインを作るヒント
$ret['links'][0]['text'] = SM_VAL_DEFAULT; $ret['links'][0]['href'] = SM_VAL_DEFAULT;
をいじると関連リンクを4件まで設定できます。
トップページへのリンクを入れてもいいでしょうし、
少々プログラムの知識は必要ですが、カテゴリページ等にリンクすることも可能です。
$ret['dict'][0]['key'] = SM_VAL_DEFAULT; $ret['dict'][0]['value'] = SM_VAL_DEFAULT;
をいじるとキーバリュー形式で任意の値を4件まで表示できます。
商品ページであれば価格を入れる、とか
ブックマークされた数を入れる、とかあとはあなたのアイデア次第です。
Tokyo (Cabinet|Tyrant|Dystopia)で作る全文検索の色々な方法まとめ
前提としてTokyoCabinet(若しくはTokyoTyrant)にテーブルDBがあり、
その複数カラムにまたがって全文検索ができるようにしたい。
例えばブログでいえばタイトルと本文と追記から全文検索をしたいとする。
Tokyoシリーズを使うということは平林幹雄氏の製品を信頼しているということなので、
できればmade by mikioで検索できればいいなと思って調べてみたところ、
想像以上に様々な方法があって迷った。
有力そうな4案について勝手に長所と短所をまとめてみるので参考にして下さい。
http://hyperestraier.sourceforge.net/index.ja.html
- Tokyo Tyrantにインデックスを張る
- Tokyo Tyrant+Lua拡張で転置インデックスを作成
- Tokyo Dystopiaを使う
Hyper Estraier案の長所
- まあまあ簡単
- 柔軟性もある
- 検索CGIのサンプルがついている
- 歴史があるのでネット上に情報が多い
Hyper Estraier案の短所
- 本体とインデックス以外に別途est形式のデータを作って保持する必要がある
- Hyper Estraierについての知識が別途必要
- リアルタイム検索にはあまり向かない
- 最近は更新されていない(最終更新2007年)
- 速度的にはそこそこ
Tokyo Tyrantにインデックスを張る案の長所
- 非常に簡単
- 本体のデータをそのまま活かせる
- ネット上にある程度情報がある
Tokyo Tyrantにインデックスを張る案の短所
- インデックスが非常に大きくなる
- 他の方法と比べると柔軟性が低い
- 大規模データを扱うのには向かない(主に速度的な面で)
- リアルタイム検索には全く向かない
Tokyo Tyrant+Lua拡張案の長所
- リアルタイム検索に向く
- 速度的にもオンメモリなら超高速
- 柔軟性あり(Luaスキルに依存)
Tokyo Tyrant+Lua拡張案の短所
- 大規模データを扱うのには向かない(メモリに乗らなくなってメリットが消える)
- 十分なメモリが必要
- 多少難しい(Luaの知識があればそうでもないがある人は少ない)
- ドキュメントが少ない
Tokyo Dystopia案の長所
- 最高速が見込める
- 極めて高い柔軟性
- 大規模データでも安心
- リアルタイム検索も可能
Tokyo Dystopia案の短所
- 難易度が極めて高い
- 実装に時間がかかる
- ドキュメントは無いに等しい
間違いや他の選択肢があれば是非教えてください。
はじめてのRuby(Rack)挑戦記録
5:07
おはようございます。
今日は今までやろうやろうと思って放置していたRubyに初挑戦します。
perl使いなので書き方や考え方がperlに偏っているかもしれませんがご了承下さい。
5:10
まずはRubyのインストール
sudo apt-get install librack-ruby
5:13
hello world
参考にしたのはこのページ
http://route477.net/d/?date=20080716
mkdir rack
cd rack
vi criticalspeed.rb
rbというのはperlでいうところのpmなのだろうか?
→plのようなものらしい(by IRC)
criticalspeed.rb
require 'rubygems' require 'rack' class CriticalSpeed def call(env) [200, {"Content-Type" => "text/plain"}, ["Hello, World"]] end end
vi criticalspeed.ru
criticalspeed.ru
require 'criticalspeed' run CriticalSpeed.new
rackup criticalspeed.ru
no such file to load rubygems
sudo apt-get install rubygems rackup criticalspeed.ru
無事wgetでhello world成功。9292番portが標準みたい。
9:36
もう30分経過。新しいことをやると時間が経つのがはやいなあ。
次はKyoto Cabinet入れる。
実はこれのrubyバインディングが触りたくて今日rubyをはじめたようなもの。
参考にしたのはこのページ
http://1978th.net/kyotocabinet/spex-en.html
http://1978th.net/kyotocabinet/rubydoc/
sudo apt-get install g++ cd /tmp wget http://1978th.net/kyotocabinet/kyotocabinet-0.9.8.tar.gz tar zxvf kyotocabinet-0.9.8.tar.gz cd kyotocabinet-0.9.8 ./configure make make check sudo make install cd .. wget http://1978th.net/kyotocabinet/rubypkg/kyotocabinet-ruby-1.0.tar.gz tar zxvf kyotocabinet-ruby-1.0.tar.gz cd kyotocabinet-ruby-1.0 ruby extconf.rb
no such file to load mkmf
extconf.rb は Makefile.pl相当?
ruby のバージョンは1.8.7みたい。1.9を入れるべきかもしれないけど、よくわからないので保留。
sudo apt-get install ruby1.8-dev ruby extconf.rb make sudo make install
インストールに成功した模様
6:02
開始から約1時間経過。
今度はKyotoCabinetに値を入れる練習。
cd ~/rack
vi make_kyotocabinet_benchmark_htmls.rb
make_kyotocabinet_benchmark_htmls.rb
require 'kyotocabinet' include KyotoCabinet DB::process('casket.kch', DB::OWRITER | DB::OCREATE) do |db| db['www.example.com/index.html'] = 'hello kyoto cabinet' end
何故DBを閉じなくていいのかわからない。do |db|ってなんだ?tie?
→IRCで教えてもらったけどまだ???状態
エラーが出ていないので値が入ったと仮定して先に進む。
→作者のブログで解説が出て理解できた
mixi Engineers’ Blog » 京都収納棚紅玉束縛: Rubyで簡単、DBプログラミング
6:27
KyotoCabinetから値を取り出してRack経由で表示してみる。
criticalspeed.rb
require 'rubygems' require 'rack' require 'kyotocabinet' include KyotoCabinet class CriticalSpeed def call(env) req = Rack::Request.new(env) fullpath = req.fullpath().sub(/^\//, '') output = nil DB::process('casket.kch', DB::OREADER) do |db| output = db[fullpath] end if output [200, {"Content-Type" => "text/html"}, [output]] else [404, {"Content-Type" => "text/plain"}, ['404 not found']] end end end
置換の違いにとまどったけど、なんとかできた。
perl版とちょっと違うけどrubyのほうが短く書けるなあ。
7:25
別のマシンからベンチマークを取ってみる
/usr/sbin/ab -n 100 -c 10 http://192.168.1.123:9292/www.example.com/index.html Request per second: 15.81 [#/sec] (mean)
Rack(WEBrick)が遅いなあと感じる。Rackで使えるウェブサーバーって何がオススメ?
いずれにしても私のrubyスキルでは最適化なんてとても無理っぽい。
7:35
@j_kinjou さんからThinやEventedMongrelがいいとの情報 thx。
twitter便利。
sudo apt-get install gem sudo gem install rack sudo gem install thin rackup --env production -s thin criticalspeed.ru /usr/sbin/ab -n 10000 -c 100 http://192.168.1.123:9292/www.example.com/index.html Request per second: 1193.70 [#/sec] (mean)
Mongrelを入れて何これはやい。もしかしてperl版よりはやいんじゃないか?
と思ったらデータが帰って来ていない。
Thinも何故か動かない
本日初のハマリなので朝食を食べる
9:00
とりあえずこの記事を公開する。
あとRubyのIRCに入ってみた。日本語が使えるのが嬉しい。
はまった原因は --env productionだった模様。その遠因としてRackのバージョンが0.1だった。
というわけでRuby Enterprize EditionというのをIRCで教えてもらいインストールした。
その後流れで、Passengerをインストール
http://www.modrails.com/install.html
11:04
IRCで教わって環境を新しくした結果Thinが動いた
sudo apt-get install gem sudo gem install rack sudo gem install thin rackup --env production -s thin criticalspeed.ru /usr/sbin/ab -n 10000 -c 100 http://192.168.1.123:9292/www.example.com/index.html Total transferred: 190000 bytes Request per second: 591.91 [#/sec] (mean)
16:00
お昼寝していたらこんな時間になった。
50000ページKyotoCabinetに突っ込む時間を計測することにする。
make_kyotocabinet_benchmark_htmls.rb
require 'kyotocabinet' require 'rubygems' require 'random_data' require 'net/http' include KyotoCabinet Net::HTTP.version_1_2 html_body = Net::HTTP.get('www.real-unreal.info', '/readmejp100.html') DB::process('casket.kch', DB::OWRITER | DB::OCREATE) do |db| domain = 'www.example.com' db[domain + '/index.html'] = html_body; 10000.times do rand_word = Random.alphanumeric(5) dir_name = domain + '/' + rand_word ["index", *"index2".."index5"].each{|base| db["#{dir_name}/#{base}.html"] = html_body} end end
time ruby make_kyotocabinet_benchmark_htmls.rb 1.34s user 1.76s system 12% cpu 24.262 total /usr/sbin/ab -n 10000 -c 100 http://192.168.1.123:9292/www.example.com/index.html Total transferred: 138440000 bytes Request per second: 182.61 [#/sec] (mean)
というわけではじめてのRubyプログラミングとしてやりたいことは一応できました。
IRCで助けてくれたRubyコミュニティの方々ありがとうございました。
ソースでRubyらしくない書き方とかあると思うので気がついたら教えてください。
WEBrickとThinでパフォーマンスが一桁以上違うんですね。
18:00
RubyのIRCでソースを見てもらう。
Net::HTTPが1行で書ける事をおしえてもらったので修正
18:13
10000.times.do end という書き方を教えてもらったので修正
もはや最後のは元々自分で書いたコードと別物に修正
追記:作者の方の解説(ちょっと難しいです)
mixi Engineers’ Blog » 京都収納棚紅玉束縛: Rubyで簡単、DBプログラミング
KVSをWebサーバーとするとどうなるのか?ベンチマークを取ってみた。
一昨日公開した拙作のクリティカルスピードですが、ベンチマークを公開していなかった為、
どの程度使えるのかよくわからないというご意見を頂きました。
クリティカルスピードについてはMOONGIFT様の紹介をご覧下さい
KVSを使った高速配信Webサーバ「クリティカルスピード」
そこで古いサーバーでベンチマークを取ったので結果のみご紹介いたします。
Celeron 430 1.80GHz メモリ2Gのサーバーで実験
WRITE性能
ファイルベースの場合(普通のウェブサーバー)
クリティカルスピードの場合(KVSをウェブサーバーとして使う)
READ性能
ファイルベースの場合(普通のウェブサーバー)
Plack::Middleware::Staticでサーバーを立て、ローカルネットワーク内から10000回アクセスする
/usr/sbin/ab -n 10000 -c 100 http://192.168.1.123:7777/index.html
Time taken for tests: 14.398395 seconds
Total transferred 139290000 bytes
Requests per second: 694.52 [#/sec](mean)
Time per request: 1.440ms
クリティカルスピードの場合(KVSをウェブサーバーとして使う)
Plackでサーバーを立て、ローカルネットワーク内の別PCから10000回アクセスする
/usr/sbin/ab -n 10000 -c 100 http://192.168.1.123:7778/www.example.com/index.html
Time taken for tests: 25.397102 seconds
Total transferred 139030000 bytes
Requests per second: 393.75 [#/sec](mean)
Time per request: 2.540ms
TokyoTyrantをWebサーバーとみなし、ローカルネットワーク内の別PCから10000回アクセスする
/usr/sbin/ab -n 10000 -c 100 http://192.168.1.123:1979/www.example.com/index.html
Time taken for tests: 12.56123 seconds
Total transferred 138348192 bytes
Requests per second: 829.45 [#/sec](mean)
Time per request: 1.206ms
まとめ
以上WRITE性能については改善したといって良いと思います。
実行時間は2/3になっていますし、CPU負荷が1/4になっています。
READ性能については40%ほど遅くなっていますが
古いサーバーで秒間400アクセス捌けているので、
実用に耐えると考えています。
そして、TokyoTyrantを直接Webサーバーとして使った場合は
ファイルベースの時と比較しても12%速い結果となっています。
速度を目指してKVSをウェブサーバーとして使うという選択肢も
十分ありえることを示唆していると思います。
但し、TokyoTyrantを直接ウェブサーバーとして使う場合設定が複雑になる為、実用を考えると
PlackやRack等でWebサーバーをたてて、そこからKVSにアクセスするのが良いと考えます。
また、クリティカルスピードの場合、localhostにファイルを置く時と
同じような感覚で別のサーバーにファイルを配置することができます。
速度的にも5万ページを2分なら十分実用的といえると思います。
以上のベンチマークの結果、クリティカルスピードは書込時の負荷を減らしたい人、
あるいは別のサーバーに素早く書込みたい人には実用的な選択肢として検討していただけると思います。
ベンチマークのソースは次回バージョンアップ時に
比較表等をつけて同梱する予定です。
クリティカルスピードやこのベンチマークについて
ご質問やご意見がありましたら、twitterにてお気軽にどうぞ。
twitter
良かったらあなたのサーバーでのベンチマークも是非教えてください。
4月14日追記
OSS ipediaにて事例紹介
http://ossipedia.ipa.go.jp/case/102/
自己紹介
はじめまして岡部典孝と申します。
http://twitter.com/noritaka_okabe
はてなダイアリーでは主に技術的なことを書いていく予定です。
プログラミング perl plack TokyoTyrant nginx KVSあたりが好きな方、
今後ともよろしくお願いします。