blog.ishinao.net

306月/06

ノードAPIごしで属性インデックスを使いたい場合

Hyper Estraierのノードマスタを使って作成したノードでは、もちろん属性インデックスは作成されないし、ノードAPIには属性インデックスを作成するコマンドは用意されていない。

属性インデックスは文書を登録する前に作成しておく必要があるので、ノードマスタから新しいノードを作成したら、ノードマスタをいったん終了し、コマンドラインからestcmdを使って該当のノードインデックス([ノードマスタディレクトリ]/_node/[ノード名])に属性インデックスを作成する必要がある。その後は、再びノードマスタを立ち上げて、ふつうにドキュメントを追加していくだけでいい。

というわけで、リニューアル版1470.netのユーザーごとのメモ検索(http://1470.net/user/[ユーザーID]/search/)で、検索結果をユーザーで絞るのにユーザーID属性に属性インデックスをつけてあげたら、検索がまともな速度で動くようになったよ。最初属性インデックスなしでやったら、2万ドキュメントくらいで目に見えて検索速度が落ちたけど、属性インデックスをつけたら2万ドキュメントくらいでもまだまだ余裕がありそう。

次にスケール的な壁にぶつかった場合は、P2Pで分散させることを考える必要が出てくるんだろうけど、それはどのくらい先のことだろう。うちではそこまで考える必要は出てこないかなー。

すみません、嘘でした

ノードマスターの機能として、属性インデックスを作成する機能がありました。Hyper Estraier開発者のmikioさんのコメントによれば、

_confファイルのattrindexをいじると、ノードを作成した時に自動的にインデックスが張られるようになりまっす。

ということでした。

ノードマスターを起動する前に、あらかじめ_confファイルに属性インデックスに関する設定を記述しておくことで、そのマスターで作られたノードに、指定した属性インデックスが作られるようになります。

そんなところに作成手段があったのかorz...。

Filed under: 日記 No Comments
306月/06

tDiaryでリバースプロキシを使った場合のRSS

リバースプロキシを使ったら、RSS内の絶対URLがリバースプロキシ越しにアクセスしたURL(http://localhost:8080/〜とか)になってしまった場合、tdiary.confに

@base_url="http://正しいルートURL/"

を追加すると直る。

Filed under: 日記 No Comments
306月/06

本番環境への移行を始めました

リニューアル版の本番環境への移行を始めました。MM/Memo以外の機能についてはいったん停止し、リニューアル版で該当する機能がある場合は、そのURLにリダイレクトをかけています。

また完成度は低いんですが、旧版を動かしながら新版を動かしていると、負荷的な悪影響が大きく、また管理も複雑になってしまうため、上記のようなミスが起こりやすくなるので、一気に新版に差し替えつつ、欠けている部分はおいおい埋めていく、といった形を取ることにします。

MM/Memoについては、まだ一通りの機能を新版に搭載するには時間がかかりそうなので、しばらく旧版のまま動かしておきます。

Filed under: 日記 No Comments
306月/06

すみません、データが飛びました

リニューアルテスト版周りのサーバー構成を大幅に変更しようと作業していたら、リニューアルサイト用DBのデータが吹っ飛んでしまいました。状況・原因ともによく分からないのですが、いくつかのテーブルが消えてしまい、データを復元するのが難しい状態になったため、初期データから入れ直しています。原因不明のため、またすぐにおかしくなる可能性もありますので、ご注意ください。

どうやら原因がわかった

今までレプリケーションスレーブ側にテストDBを作ってテストをしていたんだけど、そろそろ本番環境に近いものも用意しておこうかと、マスター側でDBをいじっているうちに、テストDBと同名のdropがいくつかレプリケーション側に流れちゃって……、ということらしい(レプリケーションがdropの不整合で止まっていた)。作業ミスでした、すみません。

Filed under: 日記 No Comments
296月/06

PHPでmod_proxy_balancerのstickysessionは使えない?

Apache 2.2のmod_proxy_balancerを使ってみようと思ったんだけど、どうもうまく動かない。PHP標準のファイルハンドラーセッションを使っていたんで、セッション初期化時にセッションIDに.[route]を付与するようにしたんだけど、ロードバランス以前にセッション自体が生成されてくれない。

と思ったら、

ファイルによるセッションハンドラは セッション ID として使える文字は a-z, A-Z, 0-9 に限られます

だったのね。ファイルセッションハンドラを使っていたからstickysessionを使いたかったんだけどなー。PHPではmod_proxy_balancerのstickysessionはあんまり使えないってことなのか? DBセッションハンドラとか使うんだったら、アプリケーションレイヤーで対応できるから、ファイルセッションハンドラを使っているときこそ、この機能を使いたかったのに。stickysessionでセッションIDに「.」を使わない設定ってできないのかなー。

追記というか訂正(2006/9/5)

この記事にリファラーがあったんで、訂正を追記しておこう。

何もPHPの標準セッションIDを直接stickyにするためのキーとして使わなくても、別にstickyにするためのキーとなるIDを振るようにすればいいだけじゃん。PHP標準のセッションID以外のCookieだったら、別に「.」の使用制限もないわけだし。

ということで、この元記事はなかったものとしてスルーすることを推奨します。

Filed under: 日記 No Comments
286月/06

MM/Memoからのインポート

MM/Memoからのデータインポートスクリプトを作って、試しに自分のメモをインポートしてみた。MM/Memoではできなかった*1解析とか検索とかがまっとうに動くので結構楽しい。

MM/Memoユーザーの方で、自分のデータもリニューアル開発テスト版の方にインポートして欲しい方は、リニューアル開発テスト版の方にアカウントを登録した上で、MM/MemoのユーザーID(数値)とリニューアル開発テスト版のアカウント名(英数字)を教えてください(ここのコメントにお願いします)。

ちなみに対応するのはURLとASINに関するメモのみで、位置情報(互換性がなくなった)やテレビ番組情報(リニューアル版では取り扱っていない)はインポートできません。あと、URLに関しては古いデータだとすでに情報が取れないURLも結構たくさんあるみたいです。

データがある程度そろった状態じゃないと分からないこともいろいろあるので、ご協力お願いします。

ちなみに

今回のはあくまでも主にテスト目的のインポートであって、正式移行時のインポートの機会はまた別に用意しますよ。

特に問題がなければ、今回移行したデータはそのまま正式稼働時にも残すつもりではいますが、大規模な仕様変更(特にデータ構造的に)があった場合は、データをリセットする可能性もありますので。

*1 SPAMまみれで巨大化したblogmapデータベースと一体化していて重いクエリーが流せなかった

Filed under: 日記 No Comments
276月/06

これからのフィードはどの形式を採用するべきか

1470.netリニューアル開発テスト版にはまだRSS出力機能は一つもつけていない。

というのは、新バージョンではURI以外の情報もいろいろ含んでおり、また一つのメモに複数のURIが所属することもできるため、単純なURI=1アイテム型のRSSで置き換えることができないから、ってことが表面上の大きな理由ではあるんだけど、それ以前の問題として、今から新しく作るアプリケーションではどの形式のフィードを採用するのがいいんだろう、という根本的なところでの疑問もあったりする。

昔はいろいろ考えるのが面倒だし、日本での採用事例も多い(=提供するフィードを利用するアプリケーション側で扱いやすい)しってんで、基本的にRSS 1.0を使ってきたんだけど、最近ではフィードをハンドリングするライブラリも充実してきたし、後者の理由はもはや大きな理由にはならないだろう。で、前者の理由に関しても、今回はどうせ位置情報とか日時情報とかの扱いが絡むんで、いろいろ調べたり考えたりしなければならないことが多いから、ついでにちゃんと考えてもいいんじゃないかと思ったりしている。

ポイントとしては、URL、位置情報、日時情報あたりをうまくまとめて扱いやすく、将来的な活用可能性が高く(フィードとしてだけでなく、フィード内に含まれる各データ自体もそれなりに再利用性を持つ)、さらに現時点でもそれなりに利用できる(現行のフィードリーダー等でちゃんと扱うことができる)ようにするには、どういうフィードデータを吐けばいいのか、というところ。これもそれPla(ggerで後付けで加工すれば何とでもなるじゃん)禁止。

自分でもぼちぼち調べていきますが、よさげな情報をお持ちの方、ご教示ください。

1470.netリニューアル開発テスト版のアカウントをお持ちの方は

関連しそうな情報を「これからのフィードはどの形式を採用するべきか」グループでメモしておいてもらえるとありがたいです。

Filed under: 日記 No Comments
266月/06

「グループ」機能の導入

1470.netリニューアル開発テスト版に「グループ」機能を追加した。「グループ」はタグとまったく同じ機能を持ち、技術的には単に一つのメモに「タグ」と「グループ」という二つのタグ機能がついただけのものだが、いろいろと応用範囲が広いんじゃないかと思っている。

まず、従来MM/Memoで「メモ種別」として用意していた機能の代替として使える。この機能を使っている人はあまり多くなかったけれども、これはタグよりもキーワードの揺らぎを少なくすることによって、確実にメモをグルーピングするために用意した機能だ。

MM/Memoの「メモ種別」では文字数として2バイトしか使えないので、自由度がない代わりに、簡単なルールを決めたらほぼ確実にそのルール内でメモを分別できるようになる。また、その命名規則はタグの名前空間を汚さない。

たとえば、「ToDo」というタグを付けた場合、それが自分にとっての「ToDo項目」という意味なのか、それとも一般的な「ToDo」に関連する情報であることを意味しているのかが、タグだけでは区別できない。そこで、前者の「自分にとってのToDo項目である」という意味を表すタグを「グループ」に逃がすことによって、同じ「ToDo」というタグを使い分けることができるようになる。

また、ある本について購入前は「購入予定」グループに、購入後は「購入記録」グループに、読み終わった後は評価付きで「読了記録」グループに変更することによって、状態管理をグループを使って表現することも可能だろう。「後で読む」などもどちらかというとタグよりはグループに入れた方が管理しやすいように思う。

さらに、この「グループ」を活用して、いわゆるまとめサイトや人力検索系サイト的なものも表現できるのではないかと考えている。

たとえば「PHPのフレームワークに関する情報サイトを教えてください」というグループを作り、興味を持った人がそのグループに関連サイトをブックマークしていく。するとそのグループの新着情報や人気(登録数が多いURI)情報が、いわゆるまとめサイト的な情報となっていく。

もちろん同様のことはタグを使っても可能だが、タグの名前空間をそういう用途で汚してしまうのは、ユーザーにとってはあまりうれしくないだろう。タグの名前空間自体は通常の使い方で利用しつつ、そういう特殊な用途には同じ機能を持つ別の検索軸である「グループ」を使うことにより、タグの可能性が広がるのではないだろうか。

まあそういう使い方がうまく回るようにするためには、ユーザーインターフェースあるいはサイトナビゲーション的な工夫が必要になるだろうが、一応そういうことを考えて「グループ」という軸を導入してみたわけだ。

Filed under: 日記 No Comments
236月/06

1470.netリニューアル開発テストバージョン

まだプロトタイピングの段階なんで、ベータとか以前のバージョンだけど、だいぶまとまってきたんで、いったん晒してみる。まだ実用レベルではないし、データも保全しない可能性が高い(DB設計からやり直す可能性がある)のでそのつもりでどうぞ。

Zend Frameworkとの格闘も落ち着いてきて、前向きな作業の割合が増えてきたけど、そうなると何となく後回しにしてきたUI周りの設計を本格的にやらなきゃいけなくなって、懸案事項が盛りだくさんだ。

あと、JavaScriptの基礎知識が不足しているのに、Google Maps+Yahoo UI Library+prototype.jsとかを無理矢理使っているんで、ひとまず動くように書いたきちゃないコードを、いまどきのコーディングスタイルに直す必要があるだろうなー。

あと、今回はものすごく富豪的な作り方をしているんで、それでどのくらい負荷的に耐えられるのかも検証する必要がある。DB設計的には、従来バージョンよりもずいぶんましにはなっているんだけど、データ取得系はたいていデータオブジェクトのプロパティに見せかけつつ、裏でがんがんクエリーを投げる仕組みにしちゃってるからなー。

修正

  • コメントと評価の処理がおかしかった(保存および編集時の復元処理にバグがあった)のを修正
Filed under: 日記 No Comments
226月/06

Amazon WebサービスにHTTP/1.1でアクセスするとゴミが出る

Zend_Http_Clientをincubatorバージョンに変えてテストしていたら、Zend_Service_Amazonの動作がおかしい*1。なんでかなーと原因をたどっていったら、Amazon WebサービスへのリクエストがHTTP/1.0からHTTP/1.1に変わったことが原因だった。

以下再現コード。HTTP/1.1でのリクエスト。

$socket = fsockopen('webservices.amazon.co.jp', 80);
fwrite($socket, "GET /onca/xml?ResponseGroup=Request&SubscriptionId=[Subscription ID]&Service=AWSECommerceService&Operation=ItemLookup&ItemId=4774128104 HTTP/1.1\r\n");
fwrite($socket, "Host: webservices.amazon.co.jp\r\n");
fwrite($socket, "Connection: close\r\n");
fwrite($socket, "\r\n");
while (!feof($socket)) {
echo fread($socket, 8192);
}
fclose($socket);

結果。

HTTP/1.1 200 OK
Date: Thu, 22 Jun 2006 04:39:16 GMT
Server: Server
x-amz-id-1: 0TR0TFSQ68NG6TEF33NC
x-amz-id-2: Qc8vxAunuvNVpdAORHM5YVP2pvxgSkOv
Connection: close
Transfer-Encoding: chunked
Content-Type: text/xml; charset=UTF-8
36f
<?xml version="1.0" encoding="UTF-8"?><ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2005-10-05"><OperationRequest><HTTPHeaders><Header Name="UserAgent"></Header></HTTPHeaders><RequestId>0TR0TFSQ68NG6TEF33NC</RequestId><Arguments><Argument Name="SubscriptionId" Value="[Subscription ID]"></Argument><Argument Name="ResponseGroup" Value="Request"></Argument><ArgumentName="Operation" Value="ItemLookup"></Argument><Argument Name="Service" Value="AWSECommerceService"></Argument><Argument Name="ItemId" Value="4774128104"></Argument></Arguments><RequestProcessingTime>0.0139038562774658</RequestProcessingTime></OperationRequest><Items><Request><IsValid>True</IsValid><ItemLookupRequest><ItemId>4774128104</ItemId><ResponseGroup>Request</ResponseGroup></ItemLookupRequest></Request><Item><ASIN>4774128104</ASIN></Item></Items></ItemLookupResponse>
0

「36f」「0」などのゴミが混ざっている。上記を見るとボディ部の前後にゴミが混ざるように見えるけれども、もっと長い結果を返すリクエストの場合は、定期的に類似したゴミが混ざる。バッファ(最大0x2000バイト)から出力した文字数を16進数で出力しているっぽい。

続いてHTTP/1.0に変える。

$socket = fsockopen('webservices.amazon.co.jp', 80);
fwrite($socket, "GET /onca/xml?ResponseGroup=Request&SubscriptionId=[Subscription ID]&Service=AWSECommerceService&Operation=ItemLookup&ItemId=4774128104 HTTP/1.0\r\n");
fwrite($socket, "Host: webservices.amazon.co.jp\r\n");
fwrite($socket, "Connection: close\r\n");
fwrite($socket, "\r\n");
while (!feof($socket)) {
echo fread($socket, 8192);
}
fclose($socket);

以下、結果。

HTTP/1.1 200 OK
Date: Thu, 22 Jun 2006 04:39:16 GMT
Server: Server
x-amz-id-1: 0TXZ0YSV0W5WA2TQGFCD
x-amz-id-2: oew++LbGRDya+Ju9I49Vx7bXa6CAsn4V
Connection: close
Content-Type: text/xml; charset=UTF-8
<?xml version="1.0" encoding="UTF-8"?><ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2005-10-05"><OperationRequest><HTTPHeaders><Header Name="UserAgent"></Header></HTTPHeaders><RequestId>0TXZ0YSV0W5WA2TQGFCD</RequestId><Arguments><Argument Name="SubscriptionId" Value="[Subscription ID]"></Argument><Argument Name="ResponseGroup" Value="Request"></Argument><ArgumentName="Operation" Value="ItemLookup"></Argument><Argument Name="Service" Value="AWSECommerceService"></Argument><Argument Name="ItemId" Value="4774128104"></Argument></Arguments><RequestProcessingTime>0.00991702079772949</RequestProcessingTime></OperationRequest><Items><Request><IsValid>True</IsValid><ItemLookupRequest><ItemId>4774128104</ItemId><ResponseGroup>Request</ResponseGroup></ItemLookupRequest></Request><Item><ASIN>4774128104</ASIN></Item></Items></ItemLookupResponse>

こっちは正常な結果が返ってくる。

Amazon WebサービスへのリクエストはHTTP/1.0で行わなければならない、とか決まっていたんだっけ? どこに報告するべき問題なのかいまいちよくわからない。ひとまずZend_Http_Clientのincubator版はHTTP/1.1がデフォルトになっちゃってるから、このままだと正式版に格上げされたときにトラブりそうだな。

ああ

Transfer-Encoding: chunkedだからか! これで正常なのね。っつーか、HTTP/1.1で送るならば受信側がちゃんと対応しないといけないのね。HTTP/1.1のRFCちゃんと読んでおこう。

一応資料

ハイパーテキスト転送プロトコル -- HTTP/1.1 3.6.1 チャンク形式転送エンコーディング

すべての HTTP/1.1 アプリケーションは、"chunked" 転送コーディングを受信しデコードできなければならないし、理解できない転送コーディング拡張は無視しなければならない。

※参照するRFCを2068から2616に変更しました。

*1 コンストラクタのインターフェースが変わっていたのは修正した

Filed under: 日記 No Comments