2006年7月31日月曜日

Sledgeのセッション用テーブルはMyISAMにしています。

naoyaさんのエントリーnaoyaのはてなダイアリー - MyISAM vs InnoDBに反応して、久々にエントリを書いてみます。

FlipClipは、すべてMyISAMで運用しているんですが、理由はあんまりなくて、デフォルトでMyISAMだからってのが大きいのと、スナップショットを取るのにmysqlsnapshotに手を加えたものを使っているので、InnoDBにするとそれを使えなくなるというのが主な理由です。それにまだDBがボトルネックだうはーってな状態になったことがないってのもあります。

それでも少し前にサーバのチューニングをそろそろ考えたほうがいいかなーということを考えたことがありまして、
その時にチューニングの候補に考えたものの一つが、Sledgeのセッション用のテーブルをMyISAMからInnoDBに替えてみるということでした。
セッションテーブルはスナップショットを取る必要ないですし、InnoDBにして早くなったらラッキーってのと、Sledgeのセッション用のテーブルは1リクエストで必ず1回書き込みが行われるので、読み込みと書き込みが同程度発生するので、更新系が多い場合はInnoDBがよいというのにあてはまるかなと思ったからです。

そこで実際にSledgeで作ったアプリケーションを使ってセッションテーブルをInnoDBにした場合と、MyISAMにした場合でどれほど性能に差がでるかabを使って簡単にベンチマークしてみました。

以下がabを使って同時10リクエストで合計1000リクエスト実行した際の結果です。

MyISAMの場合


>

Benchmarking rakuda.localhost (be patient)
Server Software: Apache/1.3.36
Server Hostname: rakuda.localhost
Server Port: 80

Document Path: /
Document Length: 14911 bytes

Concurrency Level: 10
Time taken for tests: 110.009 seconds
Complete requests: 1000
Failed requests: 0
Broken pipe errors: 0
Total transferred: 15167000 bytes
HTML transferred: 14911000 bytes
Requests per second: 9.09 [#/sec] (mean)
Time per request: 1100.09 [ms] (mean)
Time per request: 110.01 [ms] (mean, across all concurrent requests)
Transfer rate: 137.87 [Kbytes/sec] received

Connnection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 292 1096 223.5 1031 1976
Waiting: 291 1096 223.5 1031 1976
Total: 292 1096 223.5 1031 1976
ERROR: The median and mean for the initial connection time are more than twice the standard
deviation apart. These results are NOT reliable.

Percentage of the requests served within a certain time (ms)
50% 1031
66% 1071
75% 1109
80% 1145
90% 1338
95% 1753
98% 1832
99% 1888
100% 1976 (last request)
<

InnoDBの場合


>

Benchmarking rakuda.localhost (be patient)
Server Software: Apache/1.3.36
Server Hostname: rakuda.localhost
Server Port: 80

Document Path: /
Document Length: 14911 bytes

Concurrency Level: 10
Time taken for tests: 110.730 seconds
Complete requests: 1000
Failed requests: 0
Broken pipe errors: 0
Total transferred: 15167000 bytes
HTML transferred: 14911000 bytes
Requests per second: 9.03 [#/sec] (mean)
Time per request: 1107.30 [ms] (mean)
Time per request: 110.73 [ms] (mean, across all concurrent requests)
Transfer rate: 136.97 [Kbytes/sec] received

Connnection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 765 1102 273.9 1010 2476
Waiting: 765 1102 273.9 1010 2476
Total: 765 1102 273.9 1010 2476

Percentage of the requests served within a certain time (ms)
50% 1010
66% 1059
75% 1120
80% 1180
90% 1466
95% 1787
98% 1973
99% 2198
100% 2476 (last request)
<


結果としてMyISAMもInnoDBも速度的にはほとんど変わらなかった(ちょっとMyISAMのほうが速かった)ので、今まで通りMyISAMでいいかという結論に達しました。

2006年6月25日日曜日

タグを頻繁に切るようなプロジェクトでのsvkの使い方。これでいいのか?

ここ最近はsvkを使ってバージョン管理をしているんですが、svk help introで見ることができるイントロで紹介されているように 、

>

# リポジトリをミラー
svk mirror svn://svn.example.com/project_x //mirror/project_x

# リポジトリを同期
svk sync //mirror/project_x

# ローカルリポジトリを作成
svk copy //mirror/project_x //project_x

<

として、同期したproject_xのリポジトリをそのままローカルリポジトリにするという方法でしばらく使っていました。最初はこれで問題ないように思えたんですが、元のリポジトリでブランチやタグを切った後、svk pull //project_xして、リポジトリの同期をとると、ブランチやタグがファイルの実体としてコピーされているようだということに気づきました。

僕の会社でのsubversionの使いかたは、trunkで開発を進めて、リリースの準備ができたら、ブランチを切り(例えば branches/RB-2.3)、実際にリリースする時にはタグを切る(例えば tags/REL-2.3.0)という形をとっているので、結構タグを切ることが多いです。

これだとタグを切るたびにsvk pullするとそのプロジェクト分のファイル容量が消費されてしまい、すごくディスクを無駄にしているような気がしていました。

そこで考えたのが以下の方法。

>

# リポジトリをミラー。ここは同じ
svk mirror svn://svn.example.com/project_x //mirror/project_x

# リポジトリを同期。ここも同じ
svk sync //mirror/project_x

# trunk,brancheのローカルリポジトリをそれぞれ作成。ここを変更
svk copy //mirror/project_x/trunk //project_x-trunk
svk copy //mirror/project_x/branches/RB-2.3 //project_x-rb2.3

<

ローカルリポジトリを作成する際にリポジトリそのままではなく、トランクとブランチをそれぞれローカルレポジトリとして作成してみました。
今はこの方法で開発をはじめてますが、pull, push,なんかも問題なくできますし、トランクの作業コピー上で、svk smerge //project_x-rb2.3として、リリースブランチの修正をトランクにマージすることもできているので、問題はなさそうです。

もうひとつ、考えられる方法として、mirrorする際に、trunkをミラーするという方法もできそうですが、なんかこの方法だと管理が複雑になりそうだったので上記の方法をとりました。

svkは結構柔軟にいろいろできるっぽいので、他のひとがどういう風に使っているのかちょっとしりたいなーと思いました。

2006年6月13日火曜日

MacOSX に IMAPサーバ構築 (Dovecot)

会社のネットワークセキュリティが厳しくて、ローカルのPostfixからメールを外部に送信できないので、メールのやりとりもローカルで完結するよう、ローカルにIMAPサーバをたてることにしました。
以前にIMAPサーバをたてた時はcourier-imapを使ったんですが、ググってみると、Dovecotというのがよさげだったので、そちらをいれてみることにしました。

構築はMac mini/3.メールサーバを参考に行ないました。というかほとんどここに書いてあるとおり実行しただけです。

インストールはDarwinPortsにパッケージがあるのでそれをいれました。簡単!
>

sudo port install dovecot
<

インストールが完了すると自動起動するには以下のコマンドを実行しろというようなメッセージがでてきたので実行しました。

>

sudo launchctl load -w /Library/LaunchDaemons/org.darwinports.Dovecot.plist
<

これをやると /etc/hostconfigにMAILSERVER=-YES-が追加されたりするみたいです。

参考にしたサイトだとここでDovecotユーザを作成すると書いてありますが、今回試したかぎりでは、
この時点ですでにDovecotユーザが作成されていました。

次にPAM認証の設定をしました。 sshdの設定を流用しました。

>

sudo cp /etc/pam.d/sshd /etc/pam.d/dovecot
<

/opt/local/var/runが必要ということで作成しました。

>

sudo mkdir -p /opt/local/var/run
<

サンプルをコピーして設定ファイルを作成しました。

>

sudo cp /opt/local/etc/dovecot/dovecot-example.conf /opt/local/etc/dovecot/dovecot.conf
<

設定ファイルは以下のように修正しました。
利用プロトコルをimapだけにして、SSLは無効にしました。

>

--- /opt/local/etc/dovecot/dovecot-example.conf 2006-06-12 10:43:19.000000000 +0900
+++ /opt/local/etc/dovecot/dovecot.conf 2006-06-12 10:59:57.000000000 +0900
@@ -18,6 +18,7 @@
# Protocols we want to be serving:
# imap imaps pop3 pop3s
#protocols = imap imaps
+protocols = imap

# IP or host address where to listen in for connections. It's not currently
# possible to specify multiple addresses. "*" listens in all IPv4 interfaces.
@@ -44,6 +45,7 @@

# Disable SSL/TLS support.
#ssl_disable = no
+ssl_disable = yes

# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
<

ここまできたら、OSを再起動すると、起動時にDovecotがたちあがるようになりました。

手動でdovecot 起動、停止、再起動するには以下のコマンドをたたけばいいようです。

>

sudo SystemStarter start Dovecot
sudo SystemStarter stop Dovecot
sudo SystemStarter restart Dovecot
<

MacBookでさくさく開発できるようになりました

どうしても欲しくて、いてもたってもいられず、会社近くのさくらやでMacBookを購入してから1週間くらいたちましたが、環境構築もだいたいおちついて、快適に開発できるようになってきました。

Windows+VMWareな開発環境と比べるとすべてがさくさく動いて涙がでそうです。
以前は svk pull と打ったあとにトイレいって帰ってきてもまだ終了してないってことがざらにあったんですが、
今はすぐに終了するのでトイレに行く暇もありません。

はじめてのMacだったんですがとなりの席のyoshidaさんにいろいろ教えてもらえたので、スムースに移行できたとおもいます。yoshidaさんがいなかったらアプリのインストールの仕方もわかりませんでしたw ありがとうございます。そしてこれからも色々教えてください。


2006年5月23日火曜日

JSON::Syckで改行を含むデータをダンプすると改行の後にスペースが2個入る

Ajaxる時のサーバとのデータ交換フォーマットとして、JSONを使う時、perlでサーバ側を実装する際にはJSONとかJSON::Syckというモジュールを使うとperlのデータ構造をJSONフォーマットに変換してくれるので便利です。

昨日これを使って、サーバからデータを取得し、textareaに取得したデータを入れるということをしたところ、改行を含んだテキストだと、改行の後にスペースが2個入ってしまうという現象に遭遇しました。
要はこうなってほしいところが、

><

こうなってしまうんです。

><

調べてみると、クライアントで受け取ったJSONデータをevalした段階ですでにスペースを含んでいたので、サーバ側でJSONデータを作成するところに問題がありそうだということがわかりました。
そこで以下のようなスクリプトを書いて、JSON,JSON::SyckがどんなJSONデータを吐き出すか見てみました。
>

#!/usr/bin/env perl
use strict;
use JSON::Syck;
use JSON;

my $data = {
key => "foo\nbar\nbaz\n"
};

print "# Dumped by JSON::Syck $JSON::Syck::VERSION:\n";
print JSON::Syck::Dump($data), "\n";

print "# Dumped by JSON $JSON::VERSION:\n";
print objToJson($data), "\n";

<

結果は以下のとおり。

>

# Dumped by JSON::Syck 0.12:
{"key":"foo\n\
bar\n\
baz\n"}
# Dumped by JSON 1.05:
{"key":"foo\nbar\nbaz\n"}

<

どうやらJSON::Syckを使ってダンプしたデータは、整形のため、改行の後に、スペースが2個入っているようです。それでこれをJavaScriptでevalするとこのスペースもデータとして含まれてしまうため、上記のような現象が起きたみたいです。
そもそも改行後にスペースが入ってしまうのが問題なのか、スペースが入るのは問題なくて、クライアント側のJavaScriptでのパースに問題があるのかわかってませんが、試した限りだと、IEとFirefoxでスペースつきのデータの扱い方が異なるようで、挙動が変わってしまい、困りました。

とりあえず、サーバ側で改行コードを[BR]とかに変換しておいて、クライアント側でそれを改行コードとか、<br />に変換するという風にして対処しましたが、ちょっと付け焼刃的ですかねー。

2006年5月21日日曜日

OOなJavaScriptの勉強がてら、ボタンの2度押し禁止機能を簡単に実現するライブラリを作ってみました

ちょっと時代に乗り遅れている気もしますが、最近prototype.jsをつかったOOなJavaScriptを書くのにはまっています。

今日はbindとbindAsEbentListenerの勉強がてら、これまたかなり昔話題になった「2度押し禁止ボタン」を実現するコードを書いてみました。

input.js

使い方はこんな感じです。

>

 // prototype.jsとinput.jsをロードします。
 <script type="text/javascript" src="/path/to/prototype.js"></script>
 <script type="text/javascript" src="/path/to/input.js"></script>
 <script type="text/javascript"><!--
 // windoのロード時に2度押し禁止機能を有効にします。
 Event.observe(window, 'load', function(){
  // ボタンのIDか要素のオブジェクトを渡せばクリックすると押せなくなります。
  new Input.DisableAfterClick('myButton');
 }, false);
  --></script>
<

ボタンのテキストを変えたい場合は2番目の引数に代替テキストを渡します。
画像の場合は代替画像のURLを渡します。
>

new Input.DisableAfterClick('mySubmitButton2', '送信中です');
new Input.DisableAfterClick('myImageButton2', '/path/to/image2.gif');
<

一定時間経過後にボタンを再度有効にしたい場合は、3番目の引数に有効にするまでの時間をミリ秒単位で渡します。
>

new Input.DisableAfterClick('myButton', '1秒後にまた有効になります', 1000);
<

サンプルページにサンプルがあります。

また、input.jsの中身はこんな感じです。画像ボタンの扱いはもっといい方法があるのかなーとも思うんですが、おかしなところがあったら突っ込んでください。

>

var Input = new Object();
Input.DisableAfterClick = Class.create();
Input.DisableAfterClick.prototype = {
initialize : function(input, alt, timer){
this.input = $(input);
this.alt = alt;
this.timer = timer;
this.org = this.input.type == 'image'
? this.input.src
this.stopEvent = this._stopEvent.bindAsEventListener(this);

Event.observe(this.input, 'click', this.disable.bind(this));
},
disable : function() {
this.input.blur();
if (this.input.type == 'image'){
if ( this.alt )
this.input.src = this.alt;
Event.observe(this.input, 'click', this.stopEvent);
} else {
if ( this.alt )
this.input.value = this.alt;
this.input.disabled = true;
}
if (this.timer)
setTimeout(this.enable.bind(this), this.timer);
},
enable : function() {
if (this.input.type == 'image'){
if ( this.alt )
this.input.src = this.org;
Event.stopObserving(this.input, 'click', this.stopEvent);
} else {
if ( this.alt )
this.input.value = this.org;
this.input.disabled = '';
}
},
_stopEvent : function (evt) {
evt.stop();
return false;
}
};

<

2006年5月18日木曜日

CentOS4.3なローカル開発環境がでけた

もう2週間も前になりますが、なかなか時間がなくて作れなかったローカルな開発環境をゴールデンウィークを利用して構築しました。Vmware Player上でCentOS4.3を動かしてます。
CentOSのデフォルトのロケールがja_JP.UTF-8なので、UTF-8な環境の構築も行いました。
さらに、今までbashを使ってたんですが、zshに変更しました。

それにしても環境構築まで長かった。。

最初、colinuxにCentOS4.3を入れようと思って「coLinux 用 インストーラ」を使って、はじめたんですが、OSのインストールに時間がかかるかかる。。最初はスムースに行くんですが、ちょっとすると、真っ青な画面になって、まったく動かなくなりました。固まっちゃったのかなと、何度かインストールをやり直してみましたが、やっぱり、青い画面でとまるので、そのまま放置して寝てみることに。
8時間くらい寝て、起きた後、画面を見てみると、ちょっとインストールが進んでいました。とまっているわけではないのだなと、さらに放置しておいたのですが、なかなか終わる気配がありません。。結局インストール完了するまでに、2日くらいかかりました。。ここまで我慢してがんばってきたんですが、起動してみるとネットワークカードを認識しない。。いろいろ試してみたんですが、うまくいかなかったので、Vmwareでも試してみるかとなりました。

Vmwareへのインストールはすんなりいって、今までの苦労はナンだったんだという感じですが現在が快適なのでよしとします。