いつきコンテンツ

ヘルプ

カウンター


2007-11-09 色々テスト中

とりあえず、rubyにmysqlのdbiを入れる

[日記][FreeBSD] rubyにmysqlのdbiをインストール

/usr/ports/databases/ruby-dbiでmake install

おしまい。

[日記][FreeBSD] とりあえずmysqlにtDiaryテスト用のユーザとデータベースを作成してみる。

mysql -h IP -P port -p -u root

デフォルトポートで動かしてる時は-P portは省略可能

と、ここまでやって、rootはlocalhostからしかアクセス許可を出していない事に気づいて、dbサーバにログインしてmysql -p -u rootとしてログイン。

まずはデータベースを作成。tdiary_blog_testというDBを作成する。

create database tdiary_blog_test;

次に、こんな感じでユーザ(tdiary_testuser)を追加

grant select,insert,delete,update,create,drop,
alter,index on tdiary_blog_test.* to tdiary_testuser@アクセス元IP
identified by 'パスワード';
flush privileges;

これで、特定のIPからログインできるtdiary_blog_testuserができあがる。

ちなみに、ユーザを消す時は

drop user ユーザ名

データベースを消す時は、

drop database データベース名

らしい。

んでもって、新しく作ったユーザでログインできる事を確認。

mysql -h IP -P PORT -p -u tdiary_testuser

んでもってtDiary:dbi_ioに従って必要そうなテーブルを作る。

use tdiary_blog_test;
CREATE TABLE DiaryData (
diary_id varchar(8) NOT NULL,
year varchar(4) NOT NULL,
month varchar(2) NOT NULL,
day varchar(2) NOT NULL,
title LONGTEXT,
last_modified BIGINT NOT NULL,
visible BOOLEAN NOT NULL,
body LONGTEXT NOT NULL,
author LONGTEXT,
style LONGTEXT,
CONSTRAINT DiaryData_pkey PRIMARY KEY (diary_id)
);
CREATE INDEX diary_id_DiaryData_key ON DiaryData (diary_id);

CREATE TABLE CommentData (
diary_id varchar(8) NOT NULL,
name LONGTEXT,
mail LONGTEXT,
last_modified BIGINT NOT NULL,
visible BOOLEAN NOT NULL,
no BIGINT NOT NULL,
author LONGTEXT,
comment LONGTEXT
);
CREATE INDEX diary_id_CommentData_key ON CommentData (diary_id);
CREATE TABLE RefererData (
diary_id varchar(8) NOT NULL,
count BIGINT NOT NULL,
ref LONGTEXT NOT NULL,
no BIGINT NOT NULL,
author LONGTEXT
);
CREATE INDEX diary_id_RefererData_key ON RefererData (diary_id);

と、一気に作った。PostgreSQLと違って、テーブル名の所には"がいらないとか、varcharは短すぎるだろう(最大256文字ってどうよ)ということでLONGTEXT(Max 4G)にしてみたり、bool型が無くてboolean型にしてみたり、int8じゃなくてBIGINTにしてみたり位のいじり方で出来たっぽい。

というわけで、tDiary:dbi_ioにあるソースコードもテーブル名を囲っている\"を片っ端から外した。

んでもって、変更後のdbi_io.rb(勝手に_を付けた)を~/tdiary/の中へ放り込む。ちなみにdefaultio.rbとかがあるディレクトリーな。

んで、~/tdiary.confにこんな行を追加。

require 'tdiary/dbi_io'
@io_class = TDiary::DbiIO
@pgsql_driver_url = 'dbi:mysql:database=tdiary_blog_test;socket=inet;host=IP;port=PORT'
@pgsql_user = 'ユーザ名'
@pgsql_passwd = 'パスワード'

最初、socket=inetを指定してなかったり(違うサーバに読みに行くからunix socketじゃダメなんです)、IPを間違えたりしながらも、何とか動く。

ここまでやって'mysql' (DBI::InterfaceError)となる事に気づく。むむっ。

/usr/ports/databases/ruby-dbd_mysqlでもmake installが必要な様だ。

あと、テーブル作成の時に、ほっとくとMyISAMになるので、type=InnoDB;と最後に付け加えるか、alter table テーブル名 type=InnoDB;をやるとInnoDBが使える様になる。今回はめんどくさいのでMyISAMのままで。

ここまでやって、トップページが表示できる事を確認。

よしよし。

次の課題は、現在のファイルからDBへの移行だ(笑)

その前に、適当にテスト文章を入力してみた。

Plugin Error
Plugin error in '01sp.rb'.
Plugin error in 'misc/plugin/title-navi.rb'.

なぬん。

トップページを表示

argument out of range (ArgumentError)

./tdiary.rb:1693:in `local'
./tdiary.rb:1693:in `initialize'
index.rb:63:in `new'
index.rb:63

なぬん!?

……とりあえず、contribにマージされてる様なので、そっちを使う事にする。

dbi_io.dbを~/tdiary/に上書き、~/pluginにrefererDbiIO.rbを放り込む。

何かテーブル構造も変わってる(笑)ので修正。

例によってmysqlで通らないところはちまちまと書き換えた。

TEXTが通らないのでLONGTEXTに。INTEGERじゃなくBIGINTに。

CONSTRAINT diarydata_pkey PRIMARY KEY (author,diary_id)が通らないので、CONSTRAINT diarydata_pkey PRIMARY KEY (diary_id)に(いいのか?と思うが、一人でしか使わないのでおそらく問題は無かろう。)

ついでにCREATE INDEX diary_id_diarydata_key ON diarydata (diary_id);を追加。

以下同様の変更で3テーブル作った。

んでもって何かtdiary.confも書き換えが必要らしいので

@dbi_driver_url = 'dbi:mysql:database=tdiary_blog_test;socket=inet;host=IP;port=PORT'
@dbi_user = 'ユーザ名'
@dbi_passwd = 'パスワード'
@dbi_author = 'ituki'

今度は違うエラーが出た。

Table 'tdiary_blog_test.DiaryData' doesn't exist (DBI::DatabaseError)

ぉぃ!

というわけで、ソースコードを追いかけたらDiaryDataと大文字になってるところを発見したので、小文字に変更。

お、今度こそ動いたー。

早速負荷をかけてみる。

Too many connections

orz

とりあえず、DBサーバのmysqldの項目にmax_connections = 500とか書き込んでmysqlをリスタート。んで、再度負荷をかけてみる。

300秒で4105回OK。

はやっ!

このレベルになると、プロセスのforkにかかる時間も馬鹿にならなくなってくる事が分かった。

とりあえず、DB移行するために現在の日記データをDBに喰わせてみる。

スクリプトを作ろうと思ったがめんどくさいので(笑)何か手段はないか探してみる。

misc/convert2.rbのPStoreIOの部分をDeaultIOにすればいけそうだね

と言うのを発見。早速試してみる。

require 'tdiary/defaultio'をrequire 'tdiary/dbi_io'に書き換え、DefaultIO::newをDbiIO::newに書き換え。

~tdiaryでruby misc/convert2.rb

……あー。まちごーた。

require "#{PATH}/tdiary/pstoreio"をrequire "tdiary/defaultio"に書き換え、PStoreIO::newをDefaultIO::newに書き換えて再トライ

お、動いてるっぽい挙動をした(笑)

うむ、うまくいったようだ。

というわけで、一番重いページでテストしてみる事にした。20060615.htmlな(笑)

結果、300秒で3329回。おぉ、かなりいい感じな速度になってる。

fork & execの時間を減らす為にFastCGIを使ってみることにする。

/usr/ports/www/mod_fastcgiでmake install。/usr/local/etc/apache2/httpd.confに#LoadModule fastcgi_module libexec/apache2/mod_fastcgi.soという行が追加されているので先頭の#を外す。で、apachectl restart

んでもって、nemuiDoc: 既存のCGIを変更無しでFastCGIに当たりを読んで、index.fcgiを作る。

内容はこんな感じ

index.fcgi

#!/usr/bin/env ruby

require 'fcgiwrap'
FCGIWrap.each {
load '~tdiary/index.rb'
}

で、RubyForge: FastCGI for Ruby: ファイルリストから、fcgiwrap-0.1.5.tgzをDLしてきて、中のrbファイルを~tdiary/に置く。

portsにあったので、それを使う。/usr/ports/www/ruby-fcgiwrapでmake installするとかってにfcgiも入る。

んでもって、.htaccessにこんな行を追加

<Files "index.fcgi">
SetHandler fastcgi-script
</Files>

一回試してみる。

ついでに、普通にアクセスしたときにindex.rbではなくindex.cgiを読み込みに行くように変更。実は最初はindex.fcgiではなくfindex.rbだったのだが、拡張子が.cgiと.rbはスクリプトとして実行されるため、おとなしくindex.fcgiになおした(笑)

で、アクセスしてみた。

考え込んだ後Internal Server Errorになる(汗

ちなみに

server "~tdiary/index.fcgi"has failed to remain running for 30 seconds given 3 attempts, its restart interval has been backed off to 600 seconds
FastCGI: comm with (dynamic) server "~tdiary/index.fcgi" aborted: (first read) idle timeout (30 sec)

とか言われる。何か間違っているらしい。

色々調べた結果、ほっとくとsuexecを使わずに動くらしい。なめんな!

というわけで、その設定を探しに行く。

FastCGI 化というページに回避策(?)がのっていた。

FastCgiWrapper /usr/local/sbin/suexec

こんな記述が(多分httpd.confに)必要らしい。というわけで/usr/local/etc/apache2/httpd.confに追加。

<IfModule mod_fastcgi.c>
FastCgiWrapper /usr/local/sbin/suexec
</IfModule>

これで動くようになった。

早速、mod_rewriteの設定を書き換えてみる。

RewriteRule ^([0-9]+)\.html$ index.fcgi?date=$1
RewriteRule ^$ index.fcgi
RewriteRule ^index\.html$ index.fcgi

んでちゃんと走ることを確認。

よしベンチマークだ!

300秒で……1765回?

……遅くなってる(汗

何が原因だー と思って調べると、rubyが最大で10個しか立ち上がってない。多分これだー!(笑)

FastCgiConfigを読んで、多分こんなんだろうなー、って設定をhttpd.confに追加

FastCgiConfig -minProcesses 1
FastCgiConfig -maxProcesses 50
FastCgiConfig -maxClassProcesses 20

当然、<IfModule mod_fastcgi.c>の中ね。

300秒で4358回になった。

maxClassProcessesは増やしすぎても減らしすぎてもダメッポイ。

さて、今度はシステム側のCPU利用率が異様に高くなったわけだが(汗

→システムログを吐かないようにしたら5%ほど落ちた(が、なぜか読み込み成功回数も減った)

後考えられるとしたらネットワーク周り……か。

ちょっと試験的にmysqlとの接続をunix socket使ってやってみる。ぐあ、jailまたぎだとエラーになるのねorz

良い方法を模索中。無い。

諦め。

秒間10アクセスを超えるようになったら考えよう。うん(笑)

→サーバ再起動して、デフォルト設定のwwwは10Mbit/sまでねー、という状態にしたら4390回になった(笑)微妙にあがっとるがな。

→さらに、ローカルのmysqlに投げるパケットに対し、ipfwによるフィルタリングを優先的に実行させると、システム側のCPU使用率が多少減った。これで4400回まで増えた。

ストアドプロシジャーを、とか一瞬思ったが、複雑になるため却下。

重いのはlockf処理か? と解析しながら思ったのでちょっと試してみる。

FastCgiConfig -maxClassProcesses 8

3040回。lockfが重い以上に同時アクセス不可だと遅いっぽい。

20に戻した。

何が重いんだろう……

とりあえず、無理矢理unix domain socketを使おうとして、mount_nullfsやったらエラーになりあがるであんの。

しょうがないので、ちょっとjail環境のマウント先を変更して、jailデータベースのディレクトリ内にwebサーバを入れてベンチマークを取ってみる。

相変わらずsysが多い。

実行結果=2603回……おやぁー?

tcp/ipとあんまりかわらんのぉ(謎

というわけで、環境を書き戻す。むーん。何がネックなんだろうか。


ここまでやって気づいた。

なぜにカウンターは更新されないか(笑)

Last Update: 2015-08-20 10:24:55

カレンダー

2003|04|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|07|08|11|
2013|03|05|08|
2014|01|
2015|04|05|06|07|09|10|12|
2016|01|03|05|06|10|11|
2017|06|
2018|05|08|09|10|11|
2019|04|08|12|
2020|03|08|09|11|
2021|05|
Generated by tDiary version 4.1.2 + amazon(DB Patch 0.2.1) + counter(DB Patch 0.2) + IKPatch version beta 4.0.1.
Powered by Ruby version 2.1.5-p273 with ruby-fcgi