dat->html化自動処理プログラムをつくるスレ
1 :
デフォルトの名無しさん :
02/01/29 22:23
2get
3 :
デフォルトの名無しさん :02/01/29 22:44
4 :
デフォルトの名無しさん :02/01/29 22:45
6 :
デフォルトの名無しさん :02/01/29 22:56
できる限り負荷を抑えなくてはいけません。
お、採用されてる(w 漏れも意見出したいけどlinuxはまだ勉強中。。。 みなさんコーディング頑張って下さい。
8 :
デフォルトの名無しさん :02/01/29 23:18
>>7 linux特有なのはloadavgだけだからジャンジャン参加してくれや
間違っても誰かフォローする
どーでもいいけど、今重くない? テレホだからか?
backlogで待たされてる可能性を忘れてました。スマソ。
じゃあmain。あとは任せた。load averageは/procからとれたはず。 using namespace std; int main(int argc, char** argv) { string directory(where_to_work); list<string> files; get_datfilelist(directory, files); try { while (files.length()) { if (exist_corresponding_html(directory + files.front())) files.pop_front(); else { while (get_loadavg() > threshold) usleep(1000); try { generate_html(directory, files.front()); } catch (const runtime_error& e) { cerr << "failed: << files.front() << endl; } } usleep(10); } } catch (...) { cerr << "something is wrong." << endl; } return 0; }
cじゃないやん。
どうせ gcc でコンパイルするんだろうからどっちでもいいだろ
1、2、 せっかくのマルチタスクOSなんだから、priorityを10とか15にしておけば、 apacheやbbs.cgi、read.cgiが優先して走る 純粋にユーザーランドでcpu使うぶんには、priolityをさげるだけで問題ない これなら、長時間はしっても問題ないだろ あと、、システムコールの平均値をへらしたり、HDDアクセスを減らすため、1つ処理する毎に、 数百ミリ秒〜1秒ほどsleep入れれば、ほかのI/O処理などにも大きな影響を与えない 5、 それじゃ、夜のアクセス集中時が大変じゃない? priolityをsageて動かすので、負荷によってはかなり長時間かかるので、 実行は、一日一回、アクセスが少ない時間帯、日本時間午前5時〜6時スタートでいいんでは? とりあえず、 wwwroot/板名/dat/1234567890.dat ファイルを、 wwwroot/板名/kako/1234/12345/1234567890.dat.gz と、 wwwroot/板名/kako/1234/12345/1234567890.html.gz で、dat -> html は、read.cgiのソースをパクッってくる gz可は、zlibを利用する でいいんですよね? >>NNN の、レス番号のリンクは、アンカーにして参照できるようにしたいな
16 :
デフォルトの名無しさん :02/01/30 01:18
>>15 wwwroot/板名/dat/1234567890.dat
にはdat落ちしていないdatがあって、dat落ちするとどこかに移動されると思います。
自信がないので、そこらへんは.hで定義できるようにしておけば良いかと。
#define PROC_LOADAVG "/proc/loadavg" #define LOADAVG_MAX 100 /* return the integer part of the loadavg. for the past 1 min. */ int get_loadavg(void) { FILE *fp; char s[40]; /* open /proc/loadavg. */ fp = fopen(PROC_LOADAVG, "r"); /* take it seriously if the file cannot be read. */ if (!fp) return(LOADAVG_MAX); if (!fgets(s, sizeof(s), fp)) return(LOADAVG_MAX); close(fp); /* the form should be "x.xx x.xx x.xx x/x xxxx". */ return(atoi(s)); }
新たなプロジェクトお疲れさまです。期待と感謝を込めてsage。
read.cgi からの流用部分1 char *BigBuffer = NULL; int lineMax = -1; int zz_fileSize = 0; int dat_read(char const *fname) { int in; zz_fileSize = getFileSize(fname); if (zz_fileSize > MAX_FILESIZE) html_error(ERROR_TOO_HUGE); if (zz_fileSize < 10) html_error(ERROR_NOT_FOUND); /* エラー種別は別にした方がいいかも */ in = open(fname, O_RDONLY); if (in < 0) { html_error(ERROR_NOT_FOUND); return 0; } BigBuffer = malloc(zz_fileSize + 32); if (!BigBuffer) html_error(ERROR_NO_MEMORY); read(in, BigBuffer, zz_fileSize); close(in); lineMax = getLineMax(); check_logtype(); get_title(); return 0; }
int getFileSize(char const *file) { struct stat CountStat; int ccc = 0; if (!stat(file, &CountStat)) ccc = (int) CountStat.st_size; return ccc; }
int getLineMax(void) { int line = 0; char *p = BigBuffer; char *p1; if (!p) return -8; p1 = BigBuffer + zz_fileSize; /* p1 = 最後の\nの次のポインタ */ while (p < p1 && *(p1-1) != '\n') /* 最後の行末を探す 正常なdatなら問題無し */ p1--; if (p1 - p < 10) /* 適当だけど、問題は出ないはず */ return -8; do { BigLine[line] = p; if (line > RES_RED) break; ++line; p = (char *)memchr(p, '\n', p1-p) + 1; } while(p != p1); /* 最後のレスの次に、ファイル末へのポインタを入れておく。 これにより、レスの長さはポインタの差ですむ。 (dat_out_rawでstrlenしている部分への対応) */ BigLine[line] = BigBuffer + zz_fileSize; return line; }
static void get_title() { char *s[20]; char p[SIZE_BUF]; if (lineMax) { splitting_copy(s, p, BigLine[0], sizeof(p) - 20, 0); strncpy(zz_title, s[4], sizeof(zz_title)-1); } }
>>19 dat_read() 引数を fname だけにした。
html_error() は新たに作った方がよさそう。
check_logtype() は要らないと思う。
>>22 splitting_copy() は未検討。
read.cgi の main() 中からは、あと dat_out() とgz圧縮パイプを検討すればよいはず。
圧縮部分の負荷最適化、よくわからないのでお願いします。。。
akiさんのところにプロジェクトがあるとうれしいなあ と密かに祈ってみる
少しまじめに考えてみた。 ※基本的なこと ・実行時のディレクトリは/test/でよいのか? ・htmlにある、「掲示板に戻る」は相対指定しなくても良いか? 鯖移転考慮は?he.netドメインからのアクセスは無視? ・プライオリティ(nice値?)はどうするのか? ・C++(せめてSTL)にしてよいか? ※実は、これらの作業が結構めんどい 1./bbs/kako/1xxx/1xxxx/index.htmlを作成/更新。 タイトル取得のため、既変換分を読みこんでからソート。 /bbs/kako/index9.htmlも同様。 2./bbs/kako/1xxx/index.htmlの作成/更新(スレ数)。 3./bbs/kako/index.htmlの更新(新規に倉庫が増えた場合)。 ・これらを更新する場合には、htmlの文面はそのままにすべきか? ・また、新規作成時のテンプレは?(現行はスクリプト埋めこみと思われる) ※ちょと考えたこと ・バナーをどうするか。 現在は先頭にBIGのバナーが入るだけだが、 隊長の話だと、板別広告なら出す企業が結構あるように見える。 「過去ログ検索有償化」との兼ね合いで何とも言えないが、 google等での過去ログHit率を考えると 「板別に過去ログ広告を売る」というのも商売になりそうな気がする。 で、そうなった場合に備えて、例えば /bbs/kako/top_banner.txtがある時は、先頭にそれを埋めこみ、 ない時は、(オンメモリの)BIGのバナーを埋めこむ。 /bbs/kako/bottom_banner.txtがある時は最後にそれを埋めこみ、 ない時は何もしない。 等にしておく方法が考えられる。 (また、必要があれば、過去ログに限り、datの最後(1002番目等)に ツールでも読める形式のテキスト広告を置くことも、一応可能ではある)
>・htmlにある、「掲示板に戻る」は相対指定しなくても良いか? <a href="/tech/">掲示板に戻る</a> でよくない?
>>17 をちょっと改造してみた
#define PROC_LOADAVG "/proc/loadavg"
#define LOADAVG_MAX 100
/* return the integer part of the loadavg. for the past 1 min.
*/
int
get_loadavg(void)
{
#ifdef __linux__
int fd;
char *s;
/* open /proc/loadavg. */
fd = open(PROC_LOADAVG, O_RDONLY);
/* take it seriously if the file cannot be read. */
if (fd == -1)
return LOADAVG_MAX;
s = mmap(NULL, 40, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
/* the form should be "x.xx x.xx x.xx x/x xxxx". */
return s != MAP_FAILED ? atoi(s) : LOADAVG_MAX;
#else
double avg;
return getloadavg(&avg, 1) == 1 ? avg : LOADAVG_MAX;
#endif
}
あと
>>19 の dat_read() では dat落ちしたのはもうカキコされることはない
はずだから MAP_SHARED で mmap() しちゃっても問題ないような気はする......
/kako/.../index.htmlの更新は、他のスクリプトに任せるか 早朝で余裕があるときに一括してやる方がよさそう。 その場合は、タイトルを含めた一覧が必要なんだけど、 .htmlからタイトルを取得するのは(ここみたいに少ない所ならいいけど) 何万もスレがある板がいくつもあるから、 たった3行読むだけといっても、負荷はバカにできないと思う。 今もそうなっているかもしれないけど、 html化待ち(a.txt)と同様に、dat名とタイトルだけのテキストが どこかにあるんじゃないかな。(subject.txtかsubback.htmlみたいな感じ) で、html化が終了したらどんどん追記していって、 index更新時には、それを読んで一覧作成と。 そうすれば、制限時間で終了する時の整合性も あまり気にしないで済むみそう。 ただ、「全部の.htmlの一覧」を作ると簡単に数MBに膨らんじゃうから 「/kako/index.htmlには載ってないhtml化済みの.html一覧」を作って /kako/index.htmlを更新する時にクリアするのが現実的かな。 あと、html化待ちの.datの削除とかには関知しなくていいのかな? .dat.gzと.htmlと.html.gzを作ったら.datは用済みなんだけど、 スレストが掛かっている.datは書きこみ禁止になってると思われるので 移動や削除はできないかもしれない。 それに、過去ログの.dat.gzは有償化に伴って .htmlとは別のディレクトリに置かれるようになる場合も考えないと。 1ディレクトリに数千個のファイルがある場合、 ディレクトリ内のファイル数が負荷に影響している可能性もあるので。
GET /butter/a.txt HTTP/1.0 Host: tora3.2ch.net User-Agent: Monazilla/1.00 Accept-Encoding: gzip で、a.txtを見てみたが、 これは、単に、temp/でlsした結果を出力しただけだな。 ツールがofflaw.cgiの動作をテストできるように一覧を用意しただけと見た。 結論として、普通の板にはこんなものは存在しないので、 素直にディレクトリを読む必要がある。鯖上の板リストも同様。 ディレクトリが板であるかは、(document_root)/dir/subject.txtの 有無を見るだけでは移転された後に取りこぼすので TEMP_DIRをopendirしてみるのが確実だろう。
int dat_out(void) { int line; for (line = 0; line < lineMax; line++) { int lineNo = line + 1; if (!isprinted(lineNo)) continue; if (out_html(line, lineNo)) { line++; break; /* 非0が返るのは、エラー時とimodeのMaxに達した時 */ } if (lineNo==1 && is_imode() && nn_st<=1 && nn_ls==0) ++out_resN; } out_html1(); /* レスが1つも表示されていない時にレス1を表示する */ if ( is_imode() ) pPrintf(pStdout, R2CH_HTML_FOOTER_IMODE); else pPrintf(pStdout, R2CH_HTML_PREFOOTER); pPrintf(pStdout, R2CH_HTML_FOOTER); return 0; }
static int out_html1(void) { if (out_resN) return 0; html_head(zz_title, lineMax); out_resN++; return 0; }
おお、html化待ちスレッドの数が表示されるようになったのか
http://teri.2ch.net/test/read.cgi/accuse/1011025896/559 559 :夜勤 ★ :02/02/04 04:05 ID:???
>>557 うおっ すごい。
ここんとこ忙しくて、、、すんません。
・プライオリティ(nice値?)はどうするか。
ヘッダー等で定義して、いろいろ試してみないと最適値を
決めるのは難しいなぁと思っています。
・/bbs/kako/index.html /bbs/kako/index9.html /bbs/kako/1xxx/1xxxx/index.html の更新もするか?
これが重要だったりします、かつとっても重い作業のような気がします。
/bbs/kako/index.html /bbs/kako/index9.html はこちらの cgi で更新するとして
/bbs/kako/1xxx/1xxxx/index.html は更新していただけるとありがたいです。
・/bbs/temp/にあるファイルは/bbs/kako/xxx/xxxx/に移動させてよいか。
dat は移動させません。 kako 以下には、 .html .html.gz .dat.dz が生成
されるように現在はなっています。踏襲してくださーい。
・gz圧縮はどうすればいいか。
中でやっていただけると、負荷が少なくて好都合ですが、
zgip 呼び出しても ok かな? 負荷との兼ね合いです。
あと、削除等が発生するので、一度 html 化しても消されることが
良く起こります。その場合は、再度 html 化(datからレス等が削除されている)
が必要になります。
なーんか、すみませんねー。
何も書きこんでなかったけど、ヘタレC++で一応作ってみてます。
◆nnmm.69Aさんとは逆に、変換部分は後回しにして
一覧取得/時間制限/圧縮といった方向から作っているのだけれど
変換部を移植する段になって、read.cのグローバル変数依存体質で
結構引っかかってます。
ftp://readcgi.dyndns.org/incoming/dat2html/を元に 、
なんとか動くようにしてみます。
それと、最低でも全体のサイズ制限は外さなければいけないし、
過去ログを再処理する可能性も考えれば、行数制限や
レスの文字数制限(8192)も外さなくてはいけないでしょう。
作りながら考えた点として、
処理済み.datはどこか別のディレクトリ(/kako/1xxx/ではない)に
移動することを考えています。
こうすることで、次回起動時に同じファイルを処理する事がなくなります。
削除等で再度処理する必要があれば、また放りこめば済みます。
また、同じディレクトリ内に処理済みの.datの一覧を
subject.txt形式で追記するようにして、
index.htmlの更新の手助けにしようかと思ってます。
もし、過去ログの再処理で、ログ形式の違いにも
柔軟に対応する必要があるなら、区別する必要がありますが。
index.htmlの更新は、別プログラム(perl可)で、
早朝にでも動かすのでもよいのではないでしょうか。
こちらも、壊れたり、スレ削除されたりする場合に備えて
追加分だけを加えて更新する/全過去ログindexを再構築するの
両方を考える必要があると思います。
一応、動くようになった。今のところ、 ・変換と圧縮のみで、index.html作成はしない ・.datを変換したら、/kako/done/done.txtの一覧に追加し、 .dat自体も/kako/done/に移動する ・バナーは、板別→鯖別の順に探して、見つからなかったらデフォルト という感じ。 2、3日前のmona板にあった約450スレ/56MBを変換、gz9で圧縮するのに Windows上のP2-266で11分程度かかった。 d2h_html.cppはdat2html.cppの内部でincludeしているので、 dat2html.cppだけコンパイルして、zlibとリンクする。 (bcc32だと、inline不可等で警告出まくり) linux(unix)知らないので、 ・プライオリティは変えてない(変え方知らない)。 ・mkdir()の第二パラメータに何を渡すべきか知らない。 ・Makefile作ってない。zlib置いてない。 ・動作確認は、Windows上のbcc32でしかしてない。 ・linux上のgccでは、コンパイルが通ることだけ確認。 linuxに対応/動作確認してくれる人募集中。
>42 cvsのやつでいいのね? とりあえずビルドするだけのMakfileと.cvsignore突っ込んだ。 あとヘッダのタグに大文字が沢山入っていたので小文字化した。 (タグの小文字への統一は圧縮率向上とXHTML互換のため) あとChangeLogも置いたので、変更履歴書いてね。
乙鰈。cvsミラーされるまで見られないので外れているかもしれませんが…
>>41 処理済み.datは/kako/xxx/xxxx/に.dat.gzを置くので、それでいいんじゃないかな。
削除が起こった場合は、削除スクリプトの動作と各種indexの作成方法にもよるよねぇ。。。
もうちょっと話を詰める必要がありそう(とりあえず後回しか)。
/kako/xxx/xxxx/index.htmlだけなら、せっかくタイトル取得していることだし、
内部で処理しちゃうのもいいと思います。
>42 関数やクラスに、動作内容や仕様のコメントほすぃー。皆で弄るとき便利。
>47 はげどう 書式は特に決めなくてもいいだろうけど、記述すべきは ・動作の概要(簡潔に1行で) ・入力の想定条件 ・処理に変なことしてる場合はその理由 ぐらいだよね。 最初のはコードをざっと探すときに便利。 残りはコードから直接読み取れないので必要。
ういー。コメントがんばります。 プライオリティはsetpriorityってところまで調べたけど、 #defineで指定して内部で設定しちゃっていいのかな? 外部から設定する方が良さそうな気もするので。 それと、やっぱり.cppをincludeするのは良くないので、宣言と定義分離します。
>(生成時刻だけでも)古いdatから処理するように並べ替え 9桁.datを除外すれば、ファイル名順=古い順だから削ってもいいのでは。 st.st_mtimeすら削って負荷を抑えてもいいくらい。気にしすぎか?
コメント一応付けました。分かりにくかったらごめんなさい。 >50 とりあえず、mkdir()を0755にしました >51 set<time_t>を使っていますが、 このtime_tはlastmodではなく、.datのファイル名から作成しているので、 負荷的には文字列比較と大差無いと思います。
コメント書き忘れ。 ・バナー探しにsprintf()を使っていて、 結果の文字列の長さが0ならオープンも試みない ・ファイルを読むときには、ファイルサイズ+1バイト確保して 最後に'\0'/'\n'の番兵をつけている ・vector<char>をreserve()だけして、バッファに使っている その他、全体的な事では、 ・へたれC++なので、多態は使っていない ・へたれC++なので、投げる例外も時間制限だけ ・へたれC++なので、new/deleteは使っていない ・へたれC++なので、iostreamではなく、stdioを使っている などです。 index.html関係(早朝起動時に…とか)は全く手をつけていません。 プライオリティは、#define PROCESS_PRIORITY 10 とかしておいて、main()の先頭で setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY)すれば良いのかな?
冒頭にいきなりコードでないものを#if 0で囲んでいるが コードを殺すときには #if 0 コードでないものはコメント としてほしいな。 構文読むツール類にやさしく(笑)
あちゃ。 C++にすると、Cと比べて読める(メンテできる)人が減っちゃうけど、 この規模でも文字列/コンテナ/メモリ管理をCでやるのは、 個人的にはちょっと鬱。
Cに移植しやすい部分も多いので、簡単なとこから見通しよくしていきますかね。
そうですね。 classやfor_each使ってるところなんかも、必然性は全然無くて 「どうせC++だから」という理由で使っただけなので、 (最終的にstringやSTLを捨てるかは、後で決めるとして) 直しやすい部分から、どんどんCライクに 読みやすくしていって良いと思います。 あと、他の人が触りやすいように、名無しに戻ります。 今日はもう眠いので。
>>58 同意ー。
名無しに戻る必要はないと思うけどね。
むしろコテハンの方が叩かれやすいので率直な意見が出るかもよ(藁
>>53 プライオリティーは、
#include <sys/time.h>
#include <sys/resource.h>
#define PROCESS_PRIORITY 10
こんな感じにしたあと、mainの最初のほうで、
setpriority(PRIO_PROCESS, getpid(), PROCESS_PRIORITY);
みたいな感じでオッケーです
今cvsweb見てきました #include <sys/time.h> #include <sys/resource.h> #define PROCESS_PRIORITY 10 上の3つは、すでにあるので、 dathtml.cpp の、mainのすぐ後の、 setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY); を setpriority(PRIO_PROCESS, getpid(), PROCESS_PRIORITY); に変えれば大丈夫です だれかcvs使える方、更新してくだされ
あ、setpriolityの、whoが0だと、カレントプロセスをさすんですね
今迄知らなかった(大恥
よって、
>>60-61 は無視してください
>61 ほい、やっときました
>>63 すまん、おれの勘違いなので、・・・って、もうcommit済み?
なんで、ver 1.4は取り消してください
>64 戻した(笑)
なんかかっこわるいので、1.5と1.4を取り消して1.3まで・・・
>66 cvsは一度commitしたものは取り消せませんし、取り消すべきでもありません。 そうでないと履歴管理の意味がない。
うっ オレはC++があまりよくわからない人種なんだけど......でも
主にコーディングして下さる皆さんがC++の方がよいということなら
それで構いません
それはともかくとして 今までLinux上でよく検証してなかったので
気付かなかったのですが どうやら /proc/* に対してはmmap()は
使えないようですね ということなので
>>27 で書いたget_loadavg()
中のmmap()のところはread()を使うように書き換えとかないとマズー
ですね ◆nnmm.69Aさん版の方は影響がありますスマソ でも42さん版
の方は最初からmmap()使ってないので影響はないですね ただ普通の
ファイル読み込みのところはmmap()使うようにしたいなぁと思いますが
>>68 >>39 はもう42さん版に統合されてるのでだいじょぶです(^^
作業してらっしゃる方々、お疲れさまです。ぺこり。
とりあえず、betterC化、一段落しました。 あとやるとしたら非constの参照引数をポインタに直すくらい。 STLとstringをなくすのは、ずっと後回しで。
/proc/がmmapで読めないのは予想していました。 .datや.htmlの読みこみにmmapを使わなかったのは、 末尾に'\0'や'\n'を加えてそのまま使う事が出来ない、 (別のバッファにコピーしたら、OSのバッファを介してreadするのと同じ) 結局全体を読みこむので、デマンドローディングの恩恵がない、 何度も走査して(.datが4回、.htmlが2回)いる上、 I/Oよりも、変換・圧縮によるCPU負荷の方がずっと大きい、 などが理由です。 もちろん、自分がテストしにくいというのもあります。
気になったので、ちょっと時間を計ってみました。 アバウトですが、readfile(), dat2html(), gzw_compress()の 入り口と出口の間で費やした時間です。 事前に大きなファイルをコピーしてから計っています。 (他のことをしながらなので、誤差もかなりあります) writeはOSのバッファにコピーするだけなので、 実際はどこの時間に含まれるかはわかりません。 大きなdatが多いmonaと小さいdatが多い(と思う)eventで 計ってみました。ファイルの大きさにもよりますが、 圧倒的に圧縮に時間を取られています。 monaの場合、圧縮率を標準にすると実行時間は1/3以下です。 過去ログ圧縮は基本的に1回しか行わないので 出来るだけ高圧縮率にしたいところですが、 どうしても負荷を優先したい場合は 圧縮率を下げる事を考えた方が良いかもしれません。
・/mona/56MB/Z_BEST_COMPRESSION (gzip -9) worked 669 sec. converted 449 dat I/O (read) = 26093 msec. Conv (conv+write) = 29924 msec. Arc (gzip) = 605896 msec. ・/mona/56MB/Z_DEFFAULT_COMPRESSION (gzip -6) worked 203 sec. converted 449 dat I/O (read) = 29471 msec. Conv (conv+write) = 29310 msec. Arc (gzip) = 137814 msec. ・/event/10MB/Z_BEST_COMPRESSION (gzip -9) worked 53 sec. converted 397 dat I/O (read) = 4597 msec. Conv (conv+write) = 5768 msec. Arc (gzip) = 38482 msec. ・/event/10MB/Z_DEFAULT_COMPRESSION (gzip -6) worked 44 sec. converted 397 dat I/O (read) = 4051 msec. Conv (conv+write) = 5788 msec. Arc (gzip) = 29025 msec.
>>74 >どうしても負荷を優先したい場合は
>圧縮率を下げる事を考えた方が良いかもしれません。
今回は、Priorityをsageてるので、純粋にプログラム中でのcpu処理だけの負荷については
さほど影響ないのでは?
システムコールによる負荷は、ほとんどがディスクIOなので、圧縮率を下げても
システムコール関連の負荷は減らないような
ひまがあれば、実行してvmstatとか取ってみる
確かに、I/O関係は特に他のプロセスとの兼ね合いでネックになるというのは 十分に考えられるので、調べてもらえると助かります。 それでも、2500個に8時間とかの話を聞くと、 このプロセスがかけるCPU負荷を下げる/実行時間を短くするのも一応は…。 で、とりあえず、圧縮率を変えた場合の、圧縮後のサイズも調べてみました。 .html.gzと.dat.gzの合計で、()内は1ブロック4Kの場合の占有量です。 24,465,533 (26,320,896) /mona/BEST 24,922,871 (26,804,224) /mona/DEFAULT 7,175,450 (8,900,608) /event/BEST 7,218,526 (8,970,240) /event/DEFAULT 意外に差は小さいという感想です。 この程度の差で済んで、(板によっては)負荷が格段に減らせるなら、 BESTにこだわらずに圧縮率をヘッダ/時間帯/鯖/板等で指定する方法も 考えていいと思います。
皆さん乙カレー様です
>>72 言われてみるとそうですね
>>75 さんのデータでも処理時間の
大部分は圧縮に取られているようですし mmap()の利点を最大限に
生かすとなれば コピーもせず書き込みもせずということになり
ますが これはちょっとややこしいことになるでしょうし
ただ一般的にはmmap()使った方がカーネル時間の節約になると思うので
若干はサーバ負荷軽減に寄与できるとは思うのですけどね
mmap()に対応したつもり。 けど、コンパイルが通ることを確認しただけ。 その他微修正。
もしかして、完成してる?
dat>html変換の際に>>nをアンカーポイントリンク(もちろん番号にアンカーポイントを設定)に変更することは出来ないのですか?
<a href="../test/read.cgi/tech/1012310594/70" target="_blank">
>>70 </a>
↓
<a href="#70">
>>70 </a>
・変換と圧縮のみで、index.html作成はしてない ・ちゃんと .html .html.gz .dat.gz を作るようになった ・.datを変換したら、/kako/done/done.txtの一覧に追加し .dat自体も/kako/done/に移動する (移動せず削除することも可能:REMOVE_DATFILE) ・バナーは、板別→鯖別の順に探して、見つからなかったらデフォルト ってことで、夜勤さんに見てもらおうか?(できたらばたーあたりでテスト)
>>79-83 乙カレーさまです でオレも独断でちょっと手を加えてみました
bzip2+base64のパッチの形で上げておきますね
それで赤帽Linux上でテストしてみました dat2html.nommapが"USE_MMAP"を外したもの
dat2html.nogzwが"USE_GZWRITE"を外したものです(ただのdat2htmlは両方定義したもの)
[naarisan@redhat ~/dat2html]$ uname -a ; gcc -v
Linux redhat 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686 unknown
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
[naarisan@redhat ~/dat2html]$ time ./dat2html
worked 402 files / 101 sec.
69.050u 4.830s 1:41.38 72.8% 0+0k 0+0io 60548pf+113w
[naarisan@redhat ~/dat2html]$ make resetdat
accuse: Procesed.
[naarisan@redhat ~/dat2html]$ time ./dat2html.nommap
worked 402 files / 103 sec.
69.110u 6.240s 1:42.60 73.4% 0+0k 0+0io 22963pf+222w
[naarisan@redhat ~/dat2html]$ make resetdat
accuse: Procesed.
[naarisan@redhat ~/dat2html]$ time ./dat2html.nogzw
worked 402 files / 108 sec.
75.280u 4.150s 1:47.59 73.8% 0+0k 0+0io 60268pf+116w
全体の実行時間: 無印 ~= nommap < nogzw
カーネル時間: nogzw < 無印 < nommap
ってな感じですかね ちなみにgcc-3.0.3(on Solaris8)使った時には
無印以外のはコンパイルエラーになっちゃいます
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
とりあえず、サーバのloadavg取得ルーチンの、BSD対応版 4.3BSDのころから、この機能がつかえるらしいので、 だいたいのBSDでオッケーなんでは? 取得できなければ -1、取得できれば整数部分だけ返す あとは、#ifdefなどで、OSによって処理を分ければいいかな? #include <stdlib.h> #define LOAD_AVE_NELEM ( 3 ) /* 1min - 0 ; 5min - 1 ; 15min - 2 */ #define LOAD_AVE_ELEM ( 0 ) int get_loadavg(void) { double loadavg[LOAD_AVE_NELEM]; if (getloadavg(loadavg, LOAD_AVE_NELEM) == -1) return -1; else { return (int) loadavg[LOAD_AVE_ELEM]; } }
gzwrite使うと更新日時が保存されなくていや〜んなのよね〜 compress2も圧縮自体は全く同じだから、 差が出てくる理由は、crcの計算を細切れにすることで キャッシュの効果が現れているだけ(結構差が出てる)。 それなら、全体をsprintfに置き換えて 「書き出した.htmlをもう一度読みこむ」のをやめるのがいいと思うな。 同時にz_streamを使って圧縮も細切れにする、と。
loadavgは、2chの鯖以外はテスト環境でしょ? 実際に他の環境で使用するとしても、loadavgを気にしながら実行することって あまりないと思うんだけど。 もし、それでいいなら、linuxとそれ以外で切り分けて、 linux以外は全てOKを返すようにしてもいいんじゃないかな。
>85-86 やったつもり
/kako/xxxx/xxxxx/index.html のことなんだけど、dat2htmlは "dat番号,スレタイトル,レス数\n" の連続する index.txt を /kako/xxxx/xxxxx/ に作ることにして、 index.htmlは別途作ることにした方が、 /kako/index.html や /kako/index9.html の作成にも応用できていいと思うのだけど、どう? 既存の過去ログを洗い直す必要があるのが難点だが。
同じく、index.htmlの更新について、考えてました。 夜勤さんの話に、 不要 /accuse/kako/index.html 不要 /accuse/kako/index9.html ?? /accuse/kako/1000/index.html 作成 /accuse/kako/1000/10004/index.html とあったので、/1000/index.htmlも作る必要があると思っていたのですが、 調べてみると板名や鯖名などSETTING.TXTからも 直接取得できない要素が幾つもあります。 /kako/index.htmlから取得することも考えたのですが、 よくよく見直すと/kako/index.htmlと/kako/1000/index.htmlは、 ほぼ同じ形式で、同じスクリプトで作られているようです。 とすれば、/1000/index.htmlは作らないでも良さそうです。 で、/1000/10004/index.html(/999/index.html)だけ考えます。 こちらは、一覧以外の部分は非常に簡素になっているので、 読みこんで解析(既変換分を取得)し、新規に変換されたものを加えて 書きこむ形でよさそうです。(d2chhtml.hから流用出来る部分もあります) 新規作成/再構築する場合でも、板毎に異なるのは「掲示板に戻る」の リンクだけなので、ロジックは簡単だと思います。 負荷的にも「/10004/index.htmlを一度読みこみ、新規変換スレを加えて書き出す」 だけなら、終了直前に毎回行っても問題にならないでしょう。 (ただ、index.htmlがない場合は「過去ログの.htmlを全て開いてタイトルを取得」 しか方法はないと思います)
問題は、「過去ログのスレ削除」にどう対処するかでしょう。
新規変換分を追加する一方だと、削除されてもリンクが残ったままです。
「追加があった倉庫に対しては、同時にディレクトリ内の.html一覧を取得し、
.htmlが存在するスレのみを書き出す」という方法もありますが、
倉庫に追加される度にディレクトリを開くのは、ファイルが多い板の場合には
(例えば
http://corn.2ch.net/entrance/kako/index9.htmlの下には .html .html.gz .dat.gz合計で1万を超えているのが幾つもあります)
無視できない重い処理になる可能性があります。
また、この方式であっても、
「1つも新規に変換したスレがない倉庫内でスレ削除があった」時は
削除自体に気がつかず、indexを更新することができません。
結局、index.htmlのスレと実際に.htmlがあるスレとの整合性を保つためには
「過去ログのスレ削除が行われたら、どれでもいいから同じ倉庫内の
他のスレを(html等は残したままで)もう一度HTML化待ちに加える」という
方式を(削除スクリプト/削除した人が)とらない限り、
何らかの手段/時点で、全倉庫を調べる必要が生じます。
起動オプション等でこれを行うようにするのは問題ないでしょうが、
「スレ削除が行われるたびにindex.htmlを最初から作成し直す」のは、
できる限り避けたいところです。
それと、/kako/以下の各index.htmlも、あらかじめindex.html.gzが
作成されているようなので、これも更新したら圧縮する必要があります。
また、.gzの圧縮率は皆 gzip -6 相当(オプションなし=DEFAULT)のようです。
mod_gzipも(SETTING.TXT取得時に確認した限りでは)同等です。
で、作りかけてます。 一つの板が終了(時間切れ含)する時に、index.htmlを更新する必要がある倉庫について index.htmlが既にあったら、既変換分を読みこむ なければディレクトリと既存の.htmlから読みこむ し、 新規に変換した分をマージし index.htmlを書き出す という動作を考えています。 この程度の動作なら極端に重くはないと思われるので、 起動毎に行っても構わないと思います。また、終了前に更新されるので 「変換済み一覧(done.txt)」が不要になります。 「なければディレクトリと既存の.htmlから読みこむ」が ちょっと面倒なのでこれを後回しにして あれば新規変換分と合わせて更新し、なければ新規変換分だけでindex作成 まで作って、なんとか動くようになったらcommitするつもりです。 あと、/accuse/kako/index.htmlと/accuse/kako/1000/index.htmlの方なんですが、 こちらはタイトルやレス数は必要なく、必要なのはスレッド数だけなので 夜勤さんスクリプトの方で、ls等を使って調べている気がします。
みんなおつかれー。
>>93 削除関係は、レス削除にしてもスレ削除にしても、削除スクリプトとの兼ね合いから
考える必要がありますね。
夜勤さんとの話し合いになると思いますが、過去ログ削除は例外的なことなので、
削除スクリプトの方で(もしくは簡易のシェルスクリプトか何かで)対応するのが
現実的かなと思います。
一応動いた。 まだ、「index.html新規作成時に倉庫内のhtmlを探す」動作はしていない
index.htmlの作成と圧縮を付けた。これで、一応は要求仕様を満たした、、と思う。
お久しぶり&乙カレーです. ところで,現在どういう状態なんでしょう? D-born対策等でそれどころじゃない!?
SYN-flood・HDD増設・ime.nuなどで忙しくて
テストしてる暇なんか無さそうだけど、少し変更してみた。
主な変更点は
・.htmlの圧縮を、出力ファイルを読みこまずにメモリ上で行うようにした
・index.htmlの更新を板終了毎→各倉庫ディレクトリ終了毎に
・コマンドラインで多少動作を変更できるようにした
・旧形式のログの変換ミスを修正
など。
と、週末の変更が一段落ついたのでこちらにも書きこみ。
個人的には、
夜勤さんが
http://yasai.2ch.net/test/read.cgi/event/1012552935/ に書きこむ位の暇ができたら、テストも出来るんじゃないかと。
微修正。主な変更は ・「掲示板に戻る」のリンクを"/bbs/index.html"から"/bbs/"に ・既に変換済みのログの形式を.dat.gzから判別することも可能にした ・既に変換済みの.htmlからタイトル等を取得する部分のバグ修正
index.html内のタグを小文字で統一し、 「投稿日」の曜日等の補完もできるようにしてみた。
保全。。。
・壊れたdatを変換しないよう(設定で変更可能)にした ・移転後の残骸は無条件で変換しないようにした ・移転後の.datにレスが続いているもの(古いdatに存在)の扱いを 変換する/壊れたdatと同じ から選べるようにした
>>106 昨日声掛けたんだけど、ヒマがないらしい・・・(;´Д`)
108 :
期待AGE!!!! :02/03/02 19:27
どもども、いつもお世話になっています。
おいちゃんだ〜〜。 遅いのは気にしなくていいと思われ。 こっちはマターリ待ってますんでヽ(´ー`)ノ
時間に余裕が出来たら、ローカル環境とかで
>>106 をやってみて
問題がでたら教えてくださいな
顔出してくれてありがとー。またーりやりましょね。
なかなか 忙しくて、ここにこれない私。 なんとか 今週中には ダウンロードしてコンパイルに挑戦したい。
お疲れさまです。
なかなか 忙しくて ここにこれない夜勤 ★さん。 むしろ 漏れが 手伝ってあげたい。
過去ログをime.nu固定にするのはチョトコワイ、、、
>>118 double-free問題は展開時の問題。
これやread.cgiは圧縮しかしないから平気っしょ。
>>119 そういえばそだね (`ο`)シンダフリ
dat2Html が実戦投入されないのは、 dat落ち過去ログにお金払ってくれる人が減っちゃうから?
122 :
デフォルトの名無しさん :02/03/21 22:49
dat2htmlを改造して、 dat落ちから○日以上たったスレだけをhtml化・・・とかでもいいけどね
どのサーバも重くてネ (なんにもできないぞー) まずは、サーバ増強がはじまるので、それからっ ですー スンマセン
おつかれさまれす。
127 :
デフォルトの名無しさん :02/04/20 23:27
128 :
デフォルトの名無しさん :02/04/21 00:55
サーバ増強が待ち遠しいな
130 :
デフォルトの名無しさん :02/04/30 00:04
静岡人消えれ
↑ちょっと同意
132 :
デフォルトの名無しさん :02/05/14 13:28
ageてみる
133 :
デフォルトの名無しさん :02/06/01 21:44
漏れら極悪非道のageブラザーズ! 今日もネタもないのにageてやるからな!  ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ∧_∧ ∧_∧ age (・∀・∩)(∩・∀・) age (つ 丿 ( ⊂) age ( ヽノ ヽ/ ) age し(_) (_)J
保守っとく
135 :
デフォルトの名無しさん :02/07/07 17:01
保守あげ?
夜勤め。
保守
138 :
デフォルトの名無しさん :02/08/14 11:59
保守
139 :
デフォルトの名無しさん :
02/08/23 09:27 最近dat→htmlの変換処理をしていないってのは本当かい? ●を買わせるためとはいえ、ちょっと酷いんじゃないかい?