Home

日記
トラブル内容の解説 (10:00)Edit

データコピーにまだまだ時間がかかるんで何がどうなってどうなったのか書いてみたりすると、blogmap用にRSSを収集するプロセス(収集プロセス)があるわけです。そいつはまず各種アンテナからサイトの更新状態を取得し(本当は更新情報チェックプロセスも別プロセスになってるけど)、その更新状態を見ながら新しいRSSを収集してきます。で、RSSをアイテム単位にばらしてDBに突っ込みます。このとき内容はチェックしません。で、それとは別プロセスとして、収集したRSSの内容から被リンク情報とかもろもろを解析し、その後不要になった情報を捨て去るというプロセス(解析プロセス)があります。集めて捨てるというプロセスが正常に動作していることで、生態系が安定していたわけですが、この間気づかないうちに結構長い間解析プロセスの方がこけていました。んでもって、最近スパム系のいらん情報がものすごく増えているのもあって、そのすきにデータ収集用テーブルのサイズがMySQL(+Linux)の限界を超えてしまったわけです。そうなるとMySQLは4G境界あたりに腐ったデータ(インデックスとの整合性がないやつ)を作り出したりしてしまい、DBが腐ります。ひとまず解析プロセスを復活させてデータサイズに余裕を持たせてみたのですが、あまり時間がなかったのでデータサイズには多少しか余裕がなくなっていました。また、腐ったDBからレプリケーションしていた分散用DBのデータも徐々に腐っていたのですが、同期をとる時間がなかったのでそのまま運用を続けていました。多少不正確でも許される検索にしか使っていないレプリケーションサーバーなんで、そのまま使ってきましたが、レプリケーションサーバーはあまり腐る(マスターとの不整合が大きすぎると)とレプリケーション自体ができなくなります。で、限界を超えたんでレプリケーションサーバーを切り離したところ、マスターサーバーにかかる負荷が倍増して、高負荷で接続できない状態が断続的に起こるようになったわけです。で、昨夜あたりにサービスをいったん止めて、不要データを削除するプロセスを一晩走らせてから、マスターDBを完全復旧させ、さらにそれとレプリケーションとの同期を取り直している最中、というのが現状なわけです。まあ一番の敗因はキーになるテーブル(RSS情報管理)を作業テンポラリ兼用にしていた設計なわけなんですが、トランザクションのないMySQL(MyISAM)と例外処理のないPHPの組み合わせだと、その辺分離するよりもまとめちゃった方がいろいろましかなーと思ったんだよねー。結果としてこんなことになったんで、多少苦労してでも作業テーブルは分離しておくべきだったね。

Published At2005-11-23 00:00Updated At2005-11-23 00:00

日記
安定稼働し始めました (14:45)Edit

ここ一週間くらいご迷惑をおかけしました。まだゴミ処理プロセスが動いているので、安定して重い状態になっていますが、来週くらいになるとかなり軽くなると思います。

もうちょい暇があれば、分散ブックマークシステムとかも試してみたかったな。データがMM/Memo互換のブックマークツールを作り、補助的な機能はMM/MemoサーバーからAPI経由で取得し、適当なタイミングで差分同期をとる仕組みを持たせれば、だいたいいけそう。サーバーアプリにするのとWindowsアプリにするのは、どっちが便利かな。同期の仕組みをPUSH、PULL両対応にしておけば、どっちでもいけそうだな。

Published At2005-11-24 00:00Updated At2005-11-24 00:00

日記
都内の河原にカブトムシの幼虫がわらわらいた (14:54)Edit

昨日は昼過ぎからうちの野球チームの最終戦を見物し(俺は子連れだったんで参加できず)に行った。荒川の土手のグラウンドだったんだけど、ムスコが虫取り網を持っていたのを見た、グラウンドの管理人のおっちゃんが、そこらの枯れ草の山の下からカブトムシの幼虫をわらわら掘り出して、ムスコに10匹くらいくれた。都内の河原になんてカブトムシの幼虫がいるもんなのか。ちなみにうちにはもともと、今年飼っていたカブトムシが産んだタマゴから孵した幼虫が5匹いたんだけど、新しくもらった幼虫はもともといたやつらの半分くらいの大きさしかなかったのは、やっぱり自然環境の方が成長に厳しいからかな? それとも単に生まれたタイミングの違い? ともかく今家にあるケースには多すぎるくらいの数に増えてしまったんで、このままにしておくと何匹か死んじゃいそうだ。子供の保育園にでも半分もらってもらおうかなー。

Published At2005-11-24 00:00Updated At2005-11-24 00:00

日記
うわ、やられた!? (10:28)Edit

クレジットカードの明細を見たら、身に覚えのないリボルビング払いの請求が混ざっていた。項目がAmazonになっているから、てっきり自分で買ったものだと思っていたんだけど、今まで一度もリボルビング払いでなんて買い物してねーよ。なんだよこれ。

カード利用状況を過去にさかのぼって(カード会社のオンラインサービスを使うと過去のもまとめてみられる)調べてみたら、なんか6月くらいからそういうものが混ざっている。しかも、項目名にわけのわからない記号(「  -  ( 」なんて感じ)が書かれた項目まである。

うわー、もしかしてどこかのオンラインショップとかからカード番号が漏れたか! 1万円以下程度の買物を、リボルビング払いで分割に均されちゃうと、俺みたいに細かい金計算していないやつは気付けねーってばよ。俺ってば半年もクレジットカード盗用されて、全然気づいていなかったマヌケですか!

あわててカード会社に電話したところ、

  • 俺の契約カードでは、海外決済(Amazon.co.jpも海外決済扱い)が自動的にリボルビング払い扱いになるように設定されていた。つまり、今までAmazonで買ったものがリボルビング払い枠にためられていただけ。
  • 変な記号の項目は、単にネット閲覧用のPDFに変換するときの文字化けで、紙に印刷した明細ではきちんとした(身に覚えのある)請求元だった。

ということでしたとさ。ひとまず紛らわしいんで、今後は海外決済も通常の支払方法をとるようにしてもらった。過去の分も一括払いに変更してもらえる(=リボルビング手数料・利子を取られない)らしいけど、手続きが面倒だからまあいいや。そういや6月くらいにAmazon登録カードを今のカードに換えたんだっけ。

Published At2005-11-25 00:00Updated At2005-11-25 00:00

日記
インフルエンザの予防接種を受けてきた (12:06)Edit

土曜日に家族全員で。今年はやばそうだから。でも子供は2回に分けて受けなきゃいけないんだっけ。3週間後にもう一回行かないと。ちなみに3000円だった。

Published At2005-11-28 00:00Updated At2005-11-28 00:00

日記
カーテンと加湿器とエアコンを買った (12:17)Edit

さらに風邪対策として、厚手のカーテンと大型の加湿器と寝室用のエアコンを買った。薄手のカーテンだと窓のそばがしんしんと冷えるようになってきたし。あと、もともとスチーム式の加湿器はあったんだけど、それとは別にリビング用に大型の気化式加湿器を追加。サンヨーの洗濯機を買ったばかりだし、サンヨーつぶれず頑張れということでサンヨー製品を選択。さらに寝室用の安いエアコンも買ったんだけど、加湿器で湿度を上げておくと体感温度がずいぶんあがるんで、寝室用のエアコンまではいらなかったかもなー。ちなみにこっちもサンヨー製品だったけど値段と暖房のパワー(W数)だけで選んだんで製品名は覚えてないや。今月は子供の風邪でずいぶんひどい目にあった(まるまる一週間休まされた)んで、さらに痛い目に遭う前にできるだけの対策は取っておこう。

Published At2005-11-28 00:00Updated At2005-11-28 00:00

日記
ゴミ処理プロセス終わらんなー (14:34)Edit

DBのゴミ掃除がなかなか終わらんなー。すでに3Gバイトくらい削除したんだけど、まだ1Gくらいはゴミが残っていそうだ。

当初の予定ではデータがあふれそうになる前に、mergeテーブルを使った設計に切り替えて、重要度の低い(=自動収集したがどこも参照していない&どこからも参照されていない)データも残していこうかと思っていたんだけど、そんな設計変更をしている余裕がないし、CPU/メモリリソース的にも厳しいんで、ある程度古くて重要度の低いデータはばしばし消していく方針に変更。テクノラティあたりなら余裕で全データ保持しているだろうし、うちで取っておく必要はないだろう。

というわけで、今週になってもまだ全体的にサービスが重いです。さすがに全部で1億レコード近くなると結構時間がかかるなー。表側のサービスを動かしながらじゃなければ、1日程度で終わりそうだけど。

Published At2005-11-28 00:00Updated At2005-11-28 00:00

日記
データとテンプレートの配置 (15:16)Edit

ちょっと暇(というか仕事がぐだぐだになってきたんで、いったん調整のためにサスペンド)ができたんで、Ajax関連のことを考える時間に使ってみることにした。

Ajaxの具体的な使い方は、もちろん各機能要素のスペックが許す範囲でいろいろあり得るわけだけど、基本的な方針としてどういう使い方をメインにするべきだろう。

Ajaxのできることというと、結局のところ、

  • サーバーからデータを取得し、
    • JavaScriptのロジックで使用する(XML、JASON、その他)
    • 画面要素(HTML、DOM、その他)として使用する

になるんだろうけど、その後者のパターンにおいては、どういうやり方が一番いいんだろう。具体的にはテンプレートをどこに置くのが一番スマートなんだろう。

俺は基本的にサーバーサイドメインで考えるから、画面要素を取得する場合には、HTMLレベルまでサーバーサイドで展開してしまう方が好みだ。JavaScriptのテンプレートライブラリとかも使ってみたけど、いまいちしっくりこなかった。

ただ、Ajax(というか今後のJavaScriptを多用したアプリケーション)のメリットの一つである、UIに関するクライアントサイドでの自由度を低めてしまうのは、もしかしたらあまりよろしくないのかなーとも思ってしまう。

自分1人の問題ならば、どうせ何かあったらサーバーサイドいじっちゃうからいいんだけど、一般ユーザーがクライアントサイドでカスタムできる可能性ってのは、Ajax(もしくはJavaScriptベースのアプリ)の世界においてはそう簡単に捨ててはいけない要素のような気がする。

でもやっぱりJavaScript側でテンプレートを持つのはいやだなー。

と書いているうちに、何となく次のような設計にすればいいんじゃないかと思いついた。

  • 基本的にはサーバーサイドにテンプレートを持つ。サーバーサイドで処理をする場合はそれを使ってテンプレート展開する。
  • JavaScriptサイドでは、以下の3つのメソッドを用意する。
    • サーバーからデータを取得するメソッド
    • サーバーからテンプレートを取得するメソッド(このテンプレートは、サーバーサイドで持っているテンプレートデータから生成する)
    • テンプレートにデータを適用するメソッド

結局JavaScript側にテンプレートライブラリを持つわけだけど、JavaScriptで独立したものにはせず、データはサーバーと共用できるようにしておく。そうやっておくことで、同じHTMLをサーバーサイドで生成する場合もクライアントサイドで生成する場合も、テンプレートデータ自体は同じものを利用できる。クライアント側でテンプレート取得回りのロジックをいじればUI変更とかもできる。もちろんデータ取得メソッドは独立して利用できる。

すでにそういう方針で作られた(できればPHPの)ライブラリとかフレームワークはないかなー。

俺的に一番まっとうなアプローチは

SmartyのJavaScript用コンパイラ(データと同じスコープでevalすると、そのデータを使ってHTML展開された結果を返すようなJavaScriptコードを生成する)を書くことなんだろうなー。テンプレートデータの構文解析自体はPHP用のものをそのまま使えるだろうから、あとは各構文ごとの展開処理をJavaScript用に差し替えていけばいいのか。完全互換は難しいだろうけど、主要な構文だけだったら何とかなるかなー。さわりだけ試してみて、本格的に手を出す価値があるかどうかを検討しよう。

evalのスコープは

PHPとは違ってJavaScriptは未宣言の変数がグローバルスコープになっちゃうから、PHP互換でコンパイルした後に利用変数を頭に戻ってローカルスコープで宣言し直す必要がありそう? JavaScriptのevalってどういうスコープで実行されるんだろう? evalが実行される場所のスコープになるんだよね、きっと。

Published At2005-11-28 00:00Updated At2005-11-28 00:00

日記
ただいまサービス停止中 (05:25)Edit

DB最適化作業中につきサービス停止中。1時間程度で復帰する予定です。というか間違って寝ちゃいそうだから、1時間後に自動復帰するようにしておくか。

思ったよりも時間がかかっているんで

リスタート予定を08:00に延期。

まだ終わらない

どうも08:00には間に合わないっぽいんで、再開時間を09:00に延期します。それにしても時間がかかるなー。

うわー、すみません

なんか見積もりが全然あってない。まだ終わりそうもないんで、再開時間は10:00に延期します。おかしいなー。他の同サイズのテーブルはこんなに時間がかからなかったのに。激しく断片化されたvarchar(255)のuniqueインデックスみたいなものがあるとさすがに時間がかかるのかなー。

さらに、すみません

残り400Mバイトまで来て処理速度が大幅に落ちてしまい、10:00にも間に合わなそうです。11:00に延期します。くそー、こんなことなら早朝じゃなくて深夜帯に作業するんだったなー。

Published At2005-11-29 00:00Updated At2005-11-29 00:00

日記
データとテンプレートの配置 その2 (15:12)Edit

データとテンプレートの配置」の続き。

サーバーサイドメインで行く場合のアプローチとしては、挫折するまではこの間書いた方向で試してみようと思ってはいるんだけど、

んだけど実際作ってみた感じ、オレにとっては最善の選択肢ではなく、createElementなどでがりがりDOM弄った方が楽だった

http://subtech.g.hatena.ne.jp/secondlife/20051129/1133228965

という記述を読んで、さらに具体的なイメージを考えてみた。

自前でcreateElementするようなアプローチでは、新しく生成した画面要素オブジェクトを、そのまま変数に入れてロジックで管理できる。だから、動的に構成した画面要素の管理がわかりやすく書ける。というのが、上記の体験談の骨子なのではなかろうか。

サーバーサイド、クライアントサイドに限らず、テンプレートによってHTML展開するような構造の場合は、生成された画面要素にロジックからアクセスしたい時に、そのオブジェクトへの参照を得るためには手間がかかる。具体的にはidやnameを使って解決したり、あるいはDOMツリーを順次たどって目的のオブジェクトを取得する必要がある。各手段のうち、idでの解決方法ならばシンプルに書けるが、それ以外の方法で解決するのは面倒だ。

逆に言うと、テンプレートによるHTML展開を使った場合でも、必要なオブジェクトに対して簡単にアクセスできるような方法が用意されていれば、十分に楽だと感じられるのではないだろうか。

ぱっと思いつくアプローチは2つ。

  • テンプレート展開する要素に何らかのルールに基づくidを割り振り、idベースでオブジェクトへの参照を解決する
  • テンプレート展開する際に、単にHTML文字列として展開するのではなく、DOMオブジェクトを返すJavaScriptコードとして展開する

前者の場合は、id命名のルールとして実用的なものを考える必要があるだろう。現時点ではあまりいい方法を思いつけていない。後者の場合は、テンプレート展開処理がとても面倒くさくなりそうだ。単に外側をdivで囲うだけでいいなら簡単だけど。

ともかく、サーバーとクライアントで共通のテンプレートを利用するという方針に加えて、テンプレート展開した画面要素に対して、JavaScriptコードから簡単にオブジェクトとしてアクセスできるようにする、という方針も考慮するようにしよう。

とかのんびり考えていられる時間は今日でおしまいなんだけどね。

Published At2005-11-29 00:00Updated At2005-11-29 00:00