Category Archives: program

レンタルサーバにPlaggerをインストール


最近契約したinetdというレンタルサーバに、Plaggerをインストール。Plaggerはなにかっつーと、要するにmixiとかBloglinesとかLivedoor Readerとかそういうところからデータを持ってきて、何かしら変換して吐き出すためのPerlスクリプト。俺の場合は普段Livedoor Readerを使ってRSSを読んでるので、そっから未読のフィードだけを取ってきてGmailで読めるようにした。ついでにmixiのマイミク新着記事やメッセージも、全部Gmailで読めるように。すばらしい。

Plaggerは依存モジュールがかなり多いので、インストールは結構大変。でもまぁPerl素人な俺でも出来たので、基本的には誰でも出来そうな気がする。手順としては

$ perl -MCPAN -e shell

で、色々質問されるけど全部デフォルトでOK。で

>cpan test Plagger

して依存モジュールがバラバラ出てくるので片っ端からinstallしていくだけ。基本的にはhttp://capsctrl.que.jp/kdmsnr/diary/20060803.html#p02に書いてあるようにすりゃいけるはずなんだけど、そう甘くなかった。とりあえず、

$ perl -MCPAN -e ‘CPAN::Shell->install(CPAN::Shell->r)’

で最新にして、あとはエラーが出てるモジュールをシコシコ手動でインストールしたらいけた。

足りないモジュールをメモっておく→1つずつCPAN searchで調べる→tar.gzなファイルをwgetで持ってくる→perl Makefile.PL→gmake→gmake test→gmake install の繰り返し。時間かかったけどとりあえず動くようになった…のでcronでmixiは1時間ごと、フィードは10分ごとに回してる。快適すぎる!つかEntryFullTextプラグインがすごい。del.icio.usのnetwork RSSなんかもオリジナルのサイトへ行って全文取ってきてくれるので非常に便利。やばい。

というわけで、俺のmixiのログイン時間は常に1時間以内になっていると思われ、かつマイミクのみんなのとこには足跡が付きまくっていると思われ…まぁ気にしない方向でお願いします。

XSS – 表示系パラメータに存在する盲点


ぼくはまちちゃん!で有名なはまちや2さんのエントリ、XSS – 表示系パラメータに存在する盲点を見て。

そもそもWebアプリケーションにおいて、表示系だとかユーザからの入力で云々だとか、そんなこととは関係なくシステムが扱う外部からの入力では、かつ出力に影響する部分ではすべからくスクリプトの無効化を行うべきでしょう。パラメータ然り、HTTPヘッダ然り。改行コードを削除して、>・<・’・”・&・スペースは全部エスケープ。コーディングする人は「それが実際にエスケープする必要があるのかどうか」は考えなくていいようにするべきだ。

たとえばどう考えても数値しか取らない変数hogeと、何が入ってくるのかわからない変数mogeがあったとして、それを出力するときにmogeだけをエスケープするのは間違っている。hogeもmogeも同じように処理するのが正しい。なぜならhogeが数値しか取らないことを確認するためには、ソースコードの他の部分を参照して確認する必要があるからだ。そんなのは時間の無駄。そこだけを見て問題ないことが確認できるようにしておくべき。もちろんエスケープすると想定の動作をしないこともあるわけだが、そんなことは例外。どうしてもタグを出力したいとかいうときだけ、例外的に特定のタグだけ許すようにするべき。

なんでそういうことをちゃんと書いてあるセキュリティ関係の本ってないのかな。あるけど俺が知らないだけ?

[MySQL] MyISAMとInnoDB


今運用している某システム、MyISAMのある難癖によって非常に辛い目に遭っております。それはもちろんテーブルロック。これはもうMyISAMを選択した時点でどうしても避けては通れない道。そこんところ仕組みをちゃんと理解してないと、MyISAMのほうが速いって言うから選んだのに、なんだよ全然遅いじゃん!っていうか使い物にならないよウワァァァァンみたいなことになりがち。今のシステムでどうやってMyISAMかInnoDBかを分けたのかというと、単純に更新頻度だった。頻繁に更新されるテーブルはInnoDB、そうじゃなければMyISAM。参照が殆どならInnoDBを選択するメリットは何もないと思っていた。が、実は全然そうじゃなかった。

MyISAMが辛いのは、INSERT文実行時にテーブルロックされることもそうだが、時間のかかるSELECT文を実行したときにREADロックされることなんじゃなかろうか。特に業務系のシステムを構築する場合、何かと複雑なSQLを発行せざるを得ない場合がある。それはもちろんテーブル設計を行った者の技量不足や、プログラマの技量不足が原因であることが多いのだが、不可避な理由(例えばクソくだらない出来損ないのコーディング規約など)によってそうせざるを得ない場合も、悲しいかな下っ端風情の一プログラマには良くあることだ。そこを正していくのが本筋だけども、そこはオトナの事情というかまぁ色々あるので以下略(もちろん技量不足が理由の大半なんだろうけども)。

この場合レプリケーションしていたとしても、悲惨な結末を辿る。例えばマスタ1台に対してスレーブを3台用意していたとしよう。普通に考えるとスレーブへの接続はラウンドロビンで順番に割り振ってやるわけだが、あるSQLによって1台のスレーブが長時間テーブルロックするとシステム全体に影響が及んでしまう。アクセス数が多ければ多いほど(というか発行するSELECT文が多ければ多いほど)、ある時間のかかるSQLによってどっかがテーブルロック→ロックしてないスレーブではすぐに結果を返す→単純なラウンドロビンなのでロックしてるスレーブにすぐに順番が回ってくる→ひたすら実行待ちSQLがキューに入る→コネクション使い切る。かと言ってロックを監視して、それによってどのスレーブに接続するかを選択するってのはオーバーヘッドが大きすぎる気が。ロックによる待ち時間よりは全然ましかも知れないけど…

と言うわけで、InnoDBにするかMyISAMにするかは、単純に更新頻度で考えてはいけないことになる。例え参照が大半を占めようとも、ある程度複雑で時間のかかるSQLを投げることが避けられないのならInnoDBにするべきだ。で、InnoDBとMyISAMと共存してるけど、特にInnoDBだからどうこうということはないように思うです。バックアップに関してはレプリケーションしてれば特に問題ないと思うし、気になるとすれば速度とディスク容量でしょうか。結構InnoDBは容量食うので注意が必要。速度に関してはSQLによるとしか言いようがないので、実際に試してみる以外ないかと。naoyaさんが言っているような「運用が面倒臭いのは萎える」のは例えばどのようなことを言ってるのかわかりかねますが…俺の中のイメージでは定期的にoptimizeしてあげたりしなくちゃいけない分、MyISAMのほうが運用は面倒なのではと思ったりします。

ちなみにMyISAM の「速い」というのがどう速いのか、という疑問についてはインデックスが絡んでいるのでは?MyISAMは文字列のキーに対してプリフィックス圧縮を行うのに対してInnoDBでは単なるB-Tree。また、InnoDBではINSERTやUPDATEのたびにインデックスの統計情報が最適化されるが、MyISAMではoptimize tableしない限り最適化しない。あとMyISAMはMVCCじゃないので、COUNTがインデックス見ただけで分かるので速い。それ以上はソース読んでないのでわかりませぬ…ちゃんと読んでみようと思いながら怠けてます。

結局のところ俺の中では、単純なSELECT文しか発行しない、かつDELETEやUPDATEが極端に少ないテーブルならMyISAM、それ以外はInnoDB、という結論で落ち着いています。あくまで4.1系の話ですが…5系はInnoDBが極端に遅いという話も聞く(検証はしてない)のでよくわからず。でも5.1からNDB Clusterがオンメンモリじゃなくても動くようになるらしいので、それについては動向をウォッチして行きたい所存。

[MySQL]optimizeの落とし穴


MySQLのMyISAM型テーブルは、レコードの追加・削除を繰り返しているとどんどん効率が悪くなっていく。そこで定期的にoptimize tableを発行して統計情報の更新や、インデックスページのソートを行ってやることでテーブルの状態を最適化することが出来る。のだが…そこで思いっきり嵌った。

全部のテーブルをoptimizeして、今までslow-logに出ていたあるSQLを実行すると7秒かかっていた処理が1秒かからないまでに実行時間が短縮されたため、効果が出たと喜んでいたのだが。しばらく経って普通にシステムを使ってみると、時折異様に処理が遅いことがある。いままでDBの構成はMaster1+Slave1の2台構成だったのだが、メンテナンスでSlaveを2台増やした。どうも増設したSlaveにアクセスすると重いことがわかった。既存のSlaveと増設Slaveでの違いは、optimizeしたかどうか。optimizeしたSlaveのほうが、ある特定のSQLで200倍も遅くなっていることが判明した…200倍って!

問題になったSQLは、outer joinやunionを使いまくった、一目見ただけでは何をしているのかサッパリわからないほど複雑なSQLだった。保守性を考えれば、そういう複雑なSQLは使わずに、プログラム側でループを使うなりハッシュを使うなりしてわかりやすくするべきだ。しかし今回はあくまで処理速度重視というかアプリサーバとDBサーバ間の通信を極力減らす必要があったため、複雑なSQL1発で済ませなければならない事情があった。

最適化していないDBでは、explainしてみるときちんとインデックスが使われているのに対し、最適化したほうのDBではkeyがnullになっており、あるテーブルがフルスキャンされていた。そのフルスキャンされているテーブルはレコードが100万近く入っており、そりゃ時間かかるわなって話。2000秒以上テーブルロックして(MyISAM型は行ロックではなくテーブルロックがかかる…その間readもwriteも不可)、そのせいでアプリサーバもウェブサーバもコネクション使い切って死ぬ。

結局その問題はforce indexを使うことで無理矢理解決。あるいはstraight joinを使うことでも同様の効果が得られた。たまたま同じデータで最適化したものとしてないものがあったので、explainでどのindexを使えば速くなるのかすぐわかったので助かった…

実際のところforce joinよりもstraight joinのほうが、optimizerが順序を考えなくて済む分若干速いのかな?その辺はちゃんと調べる余裕がなかったので謎。まぁ複雑なクエリを投げるときはoptimizerに頼っちゃダメってことですな…

俺メモ : bashでCSVを扱う


bashで本格的なCSVを扱うにはPerlなんかを使うほか道はないっぽいけど、ダブルクォート内のカンマは文字列として扱うとか、そういうことを無視して極単純なCSVを扱うだけならbashだけで以下のようにいける。


$ cat read_csv
IFS=,
while read FILE
do
set -- $FILE
echo "field1:" $1 ",field2:" $2
done
$ cat data.csv
aiueo,12345
hogehoge,mogemoge
$ sh ./read_csv < ./data.csv
field1:aiueo,field2:12345
field1:hogehoge,field2:mogemoge

なんかPerlとか使うと負けた気がするのよね…

lessとtail -f


  • lessでファイルを開いてshift+f押すとtail -fのように動作する。止めるときはctrl+c
  • tail -fと同じ動作をする(厳密には微妙に違うが)その名もズバリtailfというコマンドがある

知らなかった…

j2se5.0から1.4へ


新しもの好きの俺的には、仕事にも新しいものをガンガン取り入れて行きたい派。なので、今回のプロジェクトもJavaは5.0、MySQLも5.0ととにかく最新の安定版を使った開発を提案して実践していた。幸いPMも新しもの好きだったので、あっさりOK出て良かったのだが。

でも客としてはやはり枯れた技術に拘りたいみたいだ。つか最初に確認したハズなんだが、今更になってJavaは1.4じゃなきゃダメとかいいだして大惨事に。なんとか1日でコンパイルは通るように修正したが、殆ど全部のファイルを修正する羽目になってしまった。

Generics使え、enum使えと口うるさくメンバーに言っていたので、非常に気が重かった…。せめてもの罪滅ぼしに(って俺が悪いわけではないのだが)、2/3ほどひとりで修正してenumもTypesafe Enumパターン使って全部置き換えた。Typesafe Enumは日本語のドキュメントがあまりないのだが、まぁEffective Java読めってことです。

しかしこれ、switch文で使えないのが難点なのよね。Java5.0でも逆コンパイルしてみたら結局if-elseになってた。なにか美しい方法はないのかな……

Winnyの技術


Winnyの技術
買って読んだ。ソースコードは一行も書いてないが、ネットワークに関する深い知識が無くても(基本的な知識さえあれば)普通に読める。ノードの管理方法、クエリやキーの管理方法、暗号化、プロトコルに至るまで、一通りの説明がなされている。これを読んだらWinnyと同等の機能を持ったソフトを作ることも、ある程度の知識がある人ならば可能だろう。

なんか金子勇氏本人が、この書籍をPDF化したものをWinnyに流すとか言っているようだが、興味があるならそんなケチくさいこと言わないで買うべき。説明も凄くわかりやすいので、やっぱこの人は頭がいいのだなぁと改めて思う。

AjaxFaces


JSFでAjaxを簡単に実現 – AjaxFaces 1.0公開

AjaxはWebのUIにおいては、とても有益な技術というか手法であることは間違いないのだけど、実装が異様に面倒だという点で敬遠していた人も多いのではないかと思う。なので、こういったツールが出現することは必然ではあったのだけど、吉報ですな。他にもDWRSajaxなんかがあるけど、選択肢が増えるのはいいことだわ。早速明日にでも、会社で遊んでみようかと。

RSSリーダー


新しいプロジェクトの絡みで、RSS関連のサービスについてあれこれ調べたり使ってみたりしている。主に調べているのはソフトをダウンロードして、クライアント側で使うRSSリーダーではなく、Web型のもの。で、単なるRSSリーダーではなく、なんらかの付加機能(たとえば今注目されている記事をお勧めしてくれる、とかそんなような機能)の付いているものを調査中。

今日Internet Watchで紹介されていたFeedBringer、凄い。Alpha版ということで、まだ実装されていない機能があったりするんだけど、使い勝手がいい。個人的にはBloglinesより好きだ。ドラッグ&ドロップ使えるのが新しい感じ。Ajax駆使してますな…

今日も今日とてさんで言及されているが、個人的にありがたいのはフォルダが2階層掘れる点。元々Sageを使っていたんだけど、このOPMLをエクスポートしてBloglinesでインポートしてみたら上手くいかなくて、イラついていたのです。FeedBringerではサックリとインポートできた。

あとはユーザ数が増えたときに、どれだけ安定して動作するかって点が問題か。こればっかりは時間が経ってみたいと評価しようがないのだけど。これからBeta、正式版とバージョンがあがるにつれて、どんなサービスが提供されるのか注目していきたい。

ていうかぶっちゃけた話、非常においしいタイミングで出てきてくれたサービスなんだな。今、某所某プロジェクトの企画書書いてる段階なんだけど、ガッツリ参考にさせてもらいますよw