頑丈?なカウンター探してます

[上に] [前に] [次に]
me 2000/05/29(月) 00:05:08
頑丈っていう表現が正しいか解かりませんが
数字が飛んだり、0に戻ったりしない(ログが消えない)
カウンターCGIを探しています。
>上記、表現については答えなくて良いですよ(^^ゞ

実際、アクセス解析等の機能がついていなければ
それなりに大丈夫だとは思うのですが、
やっぱりダメなんです。たまに消えます。
現在、2000hit/1日です。
頑丈という点だけを考えたカウンターを
教えてください。

D.D. 2000/05/29(月) 00:29:53
ていうか、2000hits/dayで壊れるのなら相当アレなスクリプトかアレなサーバだと思いました。

http://www.byakuya-shobo.co.jp/hj/cgi/vol1/counter.txt

しなのむし 2000/05/29(月) 02:16:49
http://www.tohoho-web.com/wwwperl2.htm#flock
にflockに関する良い説明があるのでまずは読んでみては?

http://www.byakuya-shobo.co.jp/hj/cgi/vol1/counter.txt
は強度的にちょっと疑問ありですね。

I don't like monday 2000/05/29(月) 02:30:59
>頑丈?なカウンター探してます

取り敢えず、根拠は無いですが・・・(^_^;
http://www.tohoho-web.com/wwwcount.htm
で試してみて、アレなようだったら、そのとき再質問してみてはいかがでしょうか?。

謎の人 2000/05/29(月) 14:38:12
サーバーがUNIXならflock使用のカウンタがおすすめです。
一時ファイルやsymlink使用のカウンタより頑丈だと思います。

ねね 2000/05/29(月) 14:43:05
よくflockはUNIXじゃないと使えないって書いてありますが、
WinNT+NTFSでも使えますよ。

もた 2000/05/29(月) 15:24:53
MiniBBSの作者氏の本では、「flockによる排他は容易に破られる」
としてフラグファイルによる排他を行っているようです。
また「壊れないカウンタ」としてGDBMを使ったものとファイルサイズを
つかったものを紹介しています。
GDBMカウンタは氏のサイト「Web裏技」にも置いてあるみたいです。

アム [E-Mail] [HomePage] 2000/05/29(月) 17:57:44
探すことよりも作ってみてはどうでしょう。
どこ行っても多分簡単な作りのものしか見つからないと思います。

僕の場合だとデータファイルは1つは本物で1つはコピーを作ります。
もし本物が故障したら(0リセット)、コピーで復元してしまうと言う
形態を取っています。
また、データの破壊はいたずらによるものが多いので、
僕の場合はカウンターCGIとアクセス解析CGIを合体させた
CGIを作成&利用しています。

B-Cus 2000/05/29(月) 20:55:41
> 「flockによる排他は容易に破られる」
その理由について書いてありましたか? 書いてあったなら
教えて下さい。

> flock使用のカウンタがおすすめです。
> 一時ファイルやsymlink使用のカウンタより頑丈だと思います。
どうしてですか?

もた 2000/05/29(月) 21:31:44
>> 「flockによる排他は容易に破られる」
>その理由について書いてありましたか? 書いてあったなら
>教えて下さい。

『ただし、それ(flock)を利用して本当にファイルが壊れないかという
ことですが、たとえばアクセスカウンタなどの頻繁に書き換え処理がされる
プログラムで実験してみると、現実にはあまりにも容易に破られてしまい
ました』
(「CGIレスキュー実践Perlプログラミング」P.85)

ということで、著者の使用環境での実験による経験則のようです。
サーバーOSやHTTPデーモンの種類、実験方法等に付いては記述されていません。
flock()がどこまで信頼できるかというのは興味深いテーマだと思うので
もうちょっと情報が欲しいところですが。

謎の人 2000/05/29(月) 21:38:52
B-Cusさんへ
あまり追求しないで...。
ただ、私の経験からそーだっただけです。

>flockはあまりにも容易に破られてしまい〜
私の場合、一度も経験していません。
一時ファイルやsymlink使用は何度か経験あります。

バギンズ 2000/05/29(月) 22:29:57
本当に排他したいならセマフォですよね?
でも、私はCGIでセマフォを使ったことないので、
どんなものかがよく解りません。
(っていうかUNIXでセマフォを使ったこと無いです(^_^;))
Perlのsemgetとかsemopってどうなのでしょう?

B-Cus 2000/05/29(月) 22:33:26
どうも>お二人

flock はダメだとか、symlink はダメだとか聞きますが、
根拠のある理由を聞いたことがなかったもので。

> 本当に排他したいならセマフォですよね?
symlink や flock ではダメだ、ということでしょうか?
それともセマフォという手もあるよ、という意味ですか?

バギンズ 2000/05/29(月) 22:44:19
>B-Cusさん
いつも参考にさせていただいてます。m(_ _)m

>> 本当に排他したいならセマフォですよね?
>symlink や flock ではダメだ、ということでしょうか?
>それともセマフォという手もあるよ、という意味ですか?
セマフォは排他のためにあるのだから、
セマフォが使えるなら使いたいなって感じの意味です。
ですから、CGIで一般的なsymlink や flock ではダメなら
「セマフォって使えますか?」って聞きたかったのです。

実は以前から疑問に思っていた内容なものですから。(^_^;)

ねね 2000/05/29(月) 23:01:15
flockもsymlinkも、それが有効な環境なら、理論的には完璧なはずです。
それでも壊れるなら、それはファイルをOPENしているときに別の理由でプロセスが死んじゃったとかいうケースでは?
推測ですが、flockは内部でセマフォ(ミューテクスかな?)を使っているような気がします。
だからロックするためにファイルアクセスが発生するsymlink法よりは、理論的には頑丈と言えると思います。
そういう前提で考えるなら、何が何でも絶対に壊れないカウンタを作ることは不可能なわけですから、
ロック機構には一番頑丈と思われるflockを使い、あとは予期せぬプロセスダウン時にファイル内容が失われる可能性を限りなく少なくするような
ロジックを組むしかないのではないでしょうか?

    open(CNT, "+< count");
    flock(CNT, 2);
    $cnt = <CNT>
    seek(CNT, 0, 0);
    print CNT ++$cnt;
    close(CNT);

こんな感じでしょうか。

バギンズ 2000/05/29(月) 23:49:33
>セマフォ(ミューテクスかな?)
あっそうか、すいません。勘違いしてました。(^_^;)
セマフォじゃなくてミューテックスでした。
手元のPerlの本がセマフォしか載ってなかったので
勘違いしてしまいました。

>ねねさん
なるほど、そーいう事ですか。

ところで、私の持ってる本のflockの解説には、
「UNIX系のプラットフォームではflock(2)が実装されている場合は
flock(2)システムコールを実行し、flock(2)が実装されていない場合は
perl5.004以降ではfcntl(2)をシステムコールを実行し、どちらもない
場合はlockf(3)が実行されます。」
と書いてあるのですが、どう違うのでしょうね?
私はどうもこの辺弱くて(^_^;)

D.D. 2000/05/30(火) 00:48:45
>http://www.byakuya-shobo.co.jp/hj/cgi/vol1/counter.txt
>は強度的にちょっと疑問ありですね。
疑問はさておき(謎)、普通のサーバ(謎)なら数万/日やそこらでは壊れないという実績とかもあったりしますが、まあ、こだわりません。

B-Cus 2000/05/30(火) 00:59:11
> 「セマフォって使えますか?」って聞きたかったのです。
わかりました。
# セマフォについては使ったことがないので根拠はありませんが、
# 多分使えると思います。

> flockもsymlinkも、それが有効な環境なら、理論的には完璧なはずです。
> それでも壊れるなら、それはファイルをOPENしているときに別の理由で
> プロセスが死んじゃったとかいうケースでは?
そそそ。例えば httpd からシグナルが飛んできたとか。
ブロックしていないからプロセスが終了しただけなのに、
symlink や flock のせいだと勘違いしているのでは
ないでしょうか。

M.Nakawaki [HomePage] 2000/05/30(火) 07:15:56
手前味噌ですが、小生のサイトに壊れにくいアクセスカウンタを置いてあります。
ファイルロックしてオープン、数字に一足して上書きという方法ではなく一カウント
でログファイルのサイズを一バイト大きく追記モードで書くので簡単に壊れないかと。

D.D. 2000/05/30(火) 10:33:23
数万ヒット(謎)とかになるとスペース的にアレだと思った。

SSC 2000/05/30(火) 23:34:43
> D.D. 2000/05/30(火) 10:33:23
> 数万ヒット(謎)とかになるとスペース的にアレだと思った。
でも数万と言ったって何十Kbyteでしょう?
画像等と比べれば、サイズ的な問題はあまり無いと思いますが。

総計ではなくて、一日に1万なんて場合は別でしょうけどね。

とほほ 2000/05/31(水) 00:44:23
> ログファイルのサイズを一バイト大きく追記モードで書く
データサイズを気にしなくてもよいなら、私も一番のオススメはこれですね。

open(OUT, ">> count.dat"); print OUT "x"; close(OUT);
ほぼ同時に2人がアクセスすると1つしかカウントアップしないこともあるけど、
リセットされるよりはいいし、壊れにくいし、とても簡単。

「カウンターが壊れた」=「ロックの強度が弱い」というのは
そう言えることも、そう言えないこともある訳で、例えば、
open(OUT, "> count.txt"); flock(OUT, 2); なんてやっていると
「ロックした時には既に他の人が空ファイルを読み取っている」
状態になってしまいます。

open(LOCK, "> dummy.txt"); flock(LOCK, 2);
open(OUT, "> count.txt"); print OUT $count; close(OUT);
flock(LOCK, 8); close(LOCK);
とするとずいぶんマシですが、それでも、print OUT する直前に
プロセスが殺されると、カウンターは壊れます。

その他にも、OSがキャッシュをディスクにフラッシュする前に
OSがハングアップしてしまったとか・・・
ディスク(磁気円盤)に書き込んでいる最中にクラッシュしたとか・・・
「ロックが完璧でもファイルは壊れる」ってのが正しそうです。

ファイルが壊れた時は、ロックが原因なのか、ロック以外が原因
なのか見分ける必要がありそうですね。

D.D. 2000/05/31(水) 03:02:51
>現在、2000hit/1日です。
な人(誰)に薦めるんでしょ?

謎の人 2000/05/31(水) 09:49:38
>open(OUT, "> count.txt"); flock(OUT, 2); なんてやっていると
>「ロックした時には既に他の人が空ファイルを読み取っている」

これ、ありえないでしょう〜
だって、起動されるプロセスは同じプログラムですから...。
まぁ、違うプログラムでflockしていなきゃ別ですが...。

しなのむし 2000/05/31(水) 11:46:26
>これ、ありえないでしょう〜

ん〜、有り得るんじゃないでしょうか。
open(OUT, "> count.txt"); flock(OUT, 2);

openとflockの隙間にアクセスされた場合。

あと、別の誰かが、flockしてても
ファイルを読みこんでる最中に
open(OUT, "> count.txt"); flock(OUT, 2);
をやられたらデータが壊れそうですね。

謎の人 2000/05/31(水) 11:54:53
>openとflockの隙間にアクセスされた場合。
今は同じプログラムでの複数プロセスの排他を考えて下さい。
そうした場合、「隙間にアクセス」されても全然問題ないのでは...。

しなのむし 2000/05/31(水) 12:22:21
>今は同じプログラムでの複数プロセスの排他

もう少し、具体的に説明していただけますか?

>謎の人さん

謎の人 2000/05/31(水) 12:41:14
カウンタのCGIプログラムは一つですが、
同時に複数のアクセスがあると同じプログラムだけど複数のプロセスになります。
つまり、同じロジックが複数動くわけです。

で、
open(OUT, "> count.txt"); flock(OUT, 2);
は、複数プロセスはopenに関係なく先にflockを実行したもの勝ちになります。
ですので、排他は完璧ですよね。(ハード的な場合は除いて)

しなのむし 2000/05/31(水) 13:22:53
open(OUT, "> count.txt"); flock(OUT, 2);
では、flock実行以前にファイルを空にしてしまうのが
問題なのだと思うのですが、
>同じプログラムだけど複数のプロセス
ではそれが起こらないということでしょうか?

謎の人 2000/05/31(水) 13:45:32
しなのむしさん、ゴメンナサイ!
勘違いがありました!

open(OUT, "> count.txt");

open(OUT, "+> count.txt");
と思って話していました。

今日はラウンジから撤退します。
あとは、同名の「謎の人」に任せます...。

バギンズ 2000/05/31(水) 13:52:19
flockの実験が見れるこんなページを見つけました。
http://www2d.biglobe.ne.jp/~gama/cgi/lock/
わかりやすくて、いいですね。(^_^)

>open(OUT, "> count.txt"); flock(OUT, 2); なんてやっていると
>「ロックした時には既に他の人が空ファイルを読み取っている」
>状態になってしまいます。
出力用にオープンしているって事は、既にcount.txtを1回読んで
クローズした後の話なのでしょうか?
なんか変だな...

>open(LOCK, "> dummy.txt"); flock(LOCK, 2);
>open(OUT, "> count.txt"); print OUT $count; close(OUT);
>flock(LOCK, 8); close(LOCK);
このロック方法いいですね。(パクパク(^_^;))

>とするとずいぶんマシですが、それでも、print OUT する直前に
>プロセスが殺されると、カウンターは壊れます。
では、一旦別ファイルに書き出してからコマンドで対象ファイルへ
上書きコピーしちゃうとかはどうでしょう?
コピーコマンドがOSに依存してしまうのが欠点ですが...

>その他にも、OSがキャッシュをディスクにフラッシュする前に
>OSがハングアップしてしまったとか・・・
>ディスク(磁気円盤)に書き込んでいる最中にクラッシュしたとか・・・
この手の話は実際にありえるのはわかりますが、そこまでプログラム
で考えるのはちょっと...

ロック方法の優先順位なのですが

flock>symlink>単なるロックファイル

が理想的って考えていいのでしょうか?
(Win95/98とMacは単なるロックファイルしか使えないのがちと悲しいけど)

バギンズ 2000/05/31(水) 13:54:24
あっ、ちんたらレス書いてたら、先に書かれてましたね。(^_^;)

>謎の人さん
>あとは、同名の「謎の人」に任せます...。
えっ、謎の人さんはたくさんいるのですか...知らなかった...

とほほ 2000/06/01(木) 02:29:53
> では、一旦別ファイルに書き出してからコマンドで対象ファイルへ
> 上書きコピーしちゃうとかはどうでしょう?
一旦別ファイルに書き出してから、その書き出しが成功したことを
確認した上で、rename()するのが安全そうです。

> この手の話は実際にありえるのはわかりますが、そこまでプログラム
> で考えるのはちょっと...
open(OUT, "> file.txt"); の代わりに、
open(OUT, "+> file.txt");とseek()の組み合わせを用いることで、
壊れる確率を随分減らすことができます。

> flock>symlink>単なるロックファイル
> が理想的って考えていいのでしょうか?
flock > mkdir > symlink >>>> 単なるロックファイル
じゃないかと思っています。
mkdirであれば、Win95などでも使用できますから・・・

しなのむし 2000/06/01(木) 03:51:16
>open(OUT, "+> file.txt");とseek()の組み合わせを用いることで、
>壊れる確率を随分減らすことができます。

open(OUT, "+< file.txt");
ですよね?>とほほさん

とほほ 2000/06/02(金) 00:33:47
あ、そうですっ。すみません。

eS 2000/06/02(金) 01:07:14
ちなみにファイル名をロックに使ったらどうなります?(笑)

バギンズ 2000/06/02(金) 04:04:20
リネームって事ですか?
どうなんでしょう?

バギンズ 2000/06/02(金) 04:19:57
あと、↓このやりとりでちょっと気になったのですが、
>しなのむし 2000/06/01(木) 03:51:16
>>open(OUT, "+> file.txt");とseek()の組み合わせを用いることで、
>>壊れる確率を随分減らすことができます。

>open(OUT, "+< file.txt");
>ですよね?>とほほさん

>--------------------------------------------------------------------------------
>とほほ 2000/06/02(金) 00:33:47
>あ、そうですっ。すみません。

open(OUT, "+> file.txt");とopen(OUT, "+< file.txt");って
ファイルが既にある場合は一緒だと思っていたのですが違うのでしょうか?

ファイルがないときは
open(OUT, "+> file.txt"); は新規作成
open(OUT, "+< file.txt"); はエラー

しなのむし 2000/06/02(金) 05:13:17
おはようございます。(笑)

open(OUT, "+> file.txt");
だと、openした時にファイルが空になっちゃうんですよね・・・

バギンズ 2000/06/02(金) 06:31:41
>open(OUT, "+> file.txt");
>だと、openした時にファイルが空になっちゃうんですよね・・・
なるほどそーでしたか。ありがとうございます。m(_ _)m

しなのむし 2000/06/03(土) 08:09:15
ちなみに
ファイルが無い場合は新規作成、
存在する場合はアップデート(ファイルを空にせずに読み書き)
というのは、sysopenを使えば実現出来ます。

use Fcntl;
sysopen(OUT,"file.txt",O_RDWR|O_CREAT);

バギンズ 2000/06/03(土) 12:07:56
あっなるほど、Perl5からじゃないとできないのですか。

しなのむし 2000/06/03(土) 13:10:13
>あっなるほど、Perl5からじゃないとできないのですか。

Perl4では使えないみたいですね。

現在、Perl4、Perl5環境の使用比率って
どのくらいなんでしょうね?

[上に] [前に] [次に]