CGI-BBS > CGI > Perl > NFSサーバーでのファイルロック方法について


カレッヂ
カレッヂ


質問者 たくぞう  投稿日 5/12(土) 23:17:56
現在利用しているISPではNFS(ネットワークファイルシステム)を使用して複数のサーバーを並列稼動させているそうですが、NFSの場合FLOCK関数が保証されないという事を言われました。
UNIXサーバーの場合、ファイルロックは推賞に過ぎないと聞いていますが、本当にファイルロックしなくても排他制御できるのか、また出来ない場合はFLOCK関数に代わる排他制御の方法があるものなのか???
今までは、FLOCK関数を使ったCGIを業務で動かしていましたが、先日突然幾つかのCGIが動作しなくなり困っています。どなたか教えて下さい。
回答者 まさ  [削除]  投稿日 5/17(木) 16:32:55
おっしゃるようにflockは完全にファイルをロックできません。

flockを使わずにファイルをロックする方法のひとつにファイルをrenameする方法があります。
しかしこれはWindowsサーバーなどflockがサポートされていない場合の代替手段です。flock
が使えるのならそれを使った方がいいです。

そもそもflockを使うにしても使わないにしても完全なロックと言う物はないと思います。
flockを使っているロックでもそのアルゴリズムによってロックの強度は違ってきます。

例えば

  $datafile = "data.txt";

  open(F, $datafile);
  $data = <F>;
  close(F);

  $data++;

  open(F, ">$datafile");
  flock(F, 2);
  print(F $data);
  close(F);

これは間違いの例ですがこのようなロックをしていると思ったように機能しません。

  $datafile = "data.txt";

  open(F, "+<$datafile");
  flock(F, 2);

  $data = <F>;
  $data++;

  truncate(F, 0);
  seek(F, 0, 0);  # ファイルへの書き込み位置を最初に移動させる

  print(F $data);

  close(F);

これはflockの正解例ですがこうしておけばほぼ大丈夫でしょう。
まだまだ完璧に近づけることもできますが、スクリプトが長くなるので省略します。
ようはアルゴリズム次第だと思います。

質問者 たくぞう  [削除]  投稿日 5/17(木) 23:53:26
「まさ」さん ありがとうございました。
Perlは独学で修得したのですが、flock関数の使用方法については、まささんが間違えた使い方とおっしゃる使い方を平気で紹介している本が多く、私も間違った使用法をしていました。と言っても、どうしてこの使い方では、思ったような働きをしないのかまだよく分かっていませんが。。。
回答者 まさ  [削除]  投稿日 5/18(金) 00:11:36
間違いの例の使い方をしていらしたんですか。それでは同時にアクセスがあった場合には
ファイルが壊れる可能性は非常に高いですね。

確かに出回っているスクリプトを見てみてもflockの間違った使い方をしているのをよく
見かけます。flockでロックするやり方は実は奥が深いのです。

これが何故間違いなのかは同時に2つのスクリプトが動いていると仮定して、順を追って
見ていくとよくわかります。

この間違いの例では flock(F, 2);の次に同じスクリプトが動き出したら$dataはどんな
数字であっても壊れて結果「1」になります。例えflock中でもopenは動くのです。

flockについては正確な動作をマスターする必要があります。流用ではなく自分で同時に
アクセスがあった場合どのように動くかを見てみる必要があると思います。

回答者 プロフェッショナル  [削除]  投稿日 2016/7/19(火) 09:48:29
1.ファイルA.txtをロックする場合は、別のフォルダ下で同名のa.txtをMKDIR(フォルダ作成)
 して作成します。
2.MKDIRの結果、エラーならすでにファイルロックされてるということです。10秒程度待ち、
 再度MKDIRします。それでもエラーならエラーではじけばいいでしょう。
3.MKDIRが成功したらファイルA.txtをアクセスします。
4.ファイルA.txtのアクセスが終わったら、MKDIR(フォルダ削除)します。

どーですか、簡単でしょ。どんなシステムでも応用できるでしょう。

ちなみにIISやAPACHE等のウェブ越しでは、ブラウザを落とされると、
タイミングによってはフォルダが削除されずに残る場合があります。
そんなときは、MKDIRしたフォルダのタイムスタンプで本当にロックしてるのか、
それとも不具合でロックしてるのかの切り分けもできます。
10秒、1時間、1日後に、自動回復処理も入れておけばなお完璧でしょう。

返信(回答)する


Web裏技