- PR -

Flyweightパターンで取得したキャッシュの更新

1
投稿者投稿内容
かつひと
常連さん
会議室デビュー日: 2006/06/01
投稿数: 32
投稿日時: 2008-04-16 12:42
 お世話になります。

 Flyweightパターンで取得したインスタンスの更新について、よい実装方法をご存知の方ありましたら教えて頂けないでしょうか。

 現在開発中のシステム(C/S型、c#で開発)で、処理を軽くするためにDBサーバから取得したマスタデータ(例えば、分類や区分マスタなど)をクライアントアプリがFlyweightパターンでクラス内部に格納して共有しようと考えています。
パフォーマンスのボルトネックがDBサーバへ接続するネットワーク負荷の可能性が高いためです。

 これらのデータは滅多に変更や削除されないのですが、その可能性がないとも言えません。
そこで、それらのデータが変更された場合に各クライアントPCがそれを知ってクラス内部に格納しているインスタンスを更新する、といったことは可能なのでしょうか。
(DBに接続して、毎回レコードの更新日時などを見れば簡単に分かりますが、それだとパフォーマンスの向上が見込めません)

 それとも、少しでも変更の可能性があるデータに対しては、Flyweightパターンを絶対に用いるべきではないのでしょうか。
よろしくお願いいたします。


public class ItemType
{
 private Dictionary<int, ItemType> mItemTypeList = new ・・・・・・;

 private int mNo;

 public int No
 {
  ・・・
 }

 private string mName;

 public string Name
 {
  ・・・
 }

 public static ItemType Get(int no)
 {
  //更新があったという何らかの通知を受けている
  //もしデータが変更されていた場合は
  //新しいインスタンスを生成して返す

  if(mItemTypeList.ContainKey(no) == true)
  {
   return mItemTypeList[no];
  }

  //DB接続処理
  //・・・
  //・・・
 }
}
indigo-x
大ベテラン
会議室デビュー日: 2008/02/21
投稿数: 207
お住まい・勤務地: 太陽の塔近く
投稿日時: 2008-04-16 16:54
引用:

現在開発中のシステム(C/S型、c#で開発)で、処理を軽くするためにDBサーバから取得したマスタデータ(例えば、分類や区分マスタなど)をクライアントアプリがFlyweightパターンでクラス内部に格納して共有しようと考えています。
パフォーマンスのボルトネックがDBサーバへ接続するネットワーク負荷の可能性が高いためです。


ネットワーク負荷?そうなんですか?(わからないですが考えにくいです)

引用:

各クライアントPCがそれを知ってクラス内部に格納しているインスタンスを更新する、といったことは可能なのでしょうか。


Push的なのは、ちょと渋いと思います。
 たまにPolling位で更新でよいのでは。。。

あと
 最後はDBの言う所の楽観同時実行制御で勘弁していただく。。。

参考になればと思います。
holic
ベテラン
会議室デビュー日: 2004/08/24
投稿数: 74
投稿日時: 2008-04-16 17:13
引用:

Flyweightパターンで取得したインスタンスの更新について、よい実装方法をご存知の方ありましたら教えて頂けないでしょうか。



なぜ、Flyweight パターンを使おうと思ったのでしょうか?

引用:

 現在開発中のシステム(C/S型、c#で開発)で、処理を軽くするためにDBサーバから取得したマスタデータ(例えば、分類や区分マスタなど)をクライアントアプリがFlyweightパターンでクラス内部に格納して共有しようと考えています。
パフォーマンスのボルトネックがDBサーバへ接続するネットワーク負荷の可能性が高いためです。



ネットワーク負荷がボトルネックかどうかは確かめましたか?
すなおにDB参照した場合のレスポンスタイムは、要件に見合わないほど遅いのですか?

引用:

 これらのデータは滅多に変更や削除されないのですが、その可能性がないとも言えません。
そこで、それらのデータが変更された場合に各クライアントPCがそれを知ってクラス内部に格納しているインスタンスを更新する、といったことは可能なのでしょうか。
(DBに接続して、毎回レコードの更新日時などを見れば簡単に分かりますが、それだとパフォーマンスの向上が見込めません)



パフォーマンスは、後回しでよいので、要件を確認しましょう。

- どの程度の頻度で、それらのデータが更新されるのですか?
- アプリケーションの実行中に変更されるのですか?
- 変更されたとき、入力途中のデータはどう扱うのですか?
- すでににDBなどに永続化されているデータは、どう扱うのですか?

引用:

 それとも、少しでも変更の可能性があるデータに対しては、Flyweightパターンを絶対に用いるべきではないのでしょうか。
よろしくお願いいたします。



Flyweight の対象オブジェクトは、Immutable にするのが普通だと思います。
Immutable でないと使う側が楽できないので、Flyweight パターンの意図するメリットは受けられないでしょうね。

- 対象のデータは、enum で十分だったりしませんか?
- データを永続化するときに、楽観ロックを利用するだけで十分ではありませんか?
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-04-16 18:17
引用:

かつひとさんの書き込み (2008-04-16 12:42) より:
 それとも、少しでも変更の可能性があるデータに対しては、Flyweightパターンを絶対に用いるべきではないのでしょうか。


「絶対」かどうかは分かりませんが、使わないほうが良いと思います。
私は Flyweight パターンというものは、あまり意識して使ったことはないのですが、おっしゃるような場合に意識して使うのは Observer パターンでしょう。

ただし、この場合、あるインスタンスが Observer でもあり Observable でもある、というようになってしまい、ややこしくなります。昔から、こういうようにややこしくなる原因は、DBMS を主体に考えているためだと思います。DBMS が Observable になれれば良いのですが、多くの場合、DBMS が自身の変更を外へ通知してくれるということはないからです。一部の DBMS 用の API にはそういう機能もあるのですが、あまり一般的ではないと思います。

Observable になれるデーター管理用のサーバーインスタンスを建てて、それがクライアントとやりとりし、サーバーインスタンスがトランザクションデーターを DBMS にコミットする、という作りにしたほうがツブシがきくと思います。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-04-16 18:22
引用:

unibonさんの書き込み (2008-04-16 18:17) より:
Observable になれるデーター管理用のサーバーインスタンスを建てて、それがクライアントとやりとりし、サーバーインスタンスがトランザクションデーターを DBMS にコミットする、という作りにしたほうがツブシがきくと思います。


ただ、こうすると、脇から、そのサーバーインスタンスをバイパスして、ダイレクトに DBMS にアクセスされると、データーに矛盾が生じてしまいます。DBMS を使う限り、この問題がつきまとってしまいます。ファイルだとアプリケーション以外のものがアクセスすることなんて考えなくても良いのですが、なぜだか DBMS だと、脇からアクセスされてしまうことを気にしなくてはならなくなるのも不思議です。DBMS を自分のアプリケーションでロックして使えれば良いのでしょうけど、将来そうできない可能性が少しでもあるならば、そのようなキャッシュの仕組みははじめからやらないようにしたほうが良いのかもしれません。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2008-04-16 22:36
引用:
パフォーマンスのボルトネックがDBサーバへ接続するネットワーク負荷の可能性が高いためです。

C/S型のSとはDB自体を指すのではなくアプリですかね。だとすると、
・DBのデータを変更や削除するのはこのSだけ
・DBへの接続はボトルネックだが、C/S間の接続自体はボトルネックではない
という前提があれば、Sが「インスタンスを更新する必要があるか」の情報を管理していれば
Cは、必要ないときはC/S間のやり取りだけ、必要な場合はBDに接続、という風に作れますね。
かつひと
常連さん
会議室デビュー日: 2006/06/01
投稿数: 32
投稿日時: 2008-04-17 12:44
 unibon様が仰っておられる通り、Observerパターンを使おうとも検討しましたが、システム自体が複雑な設計になったり、直接DBにアクセスされたりすると対処しようがありません。

 また、holic様、indigo-x様、べる様から教えて頂いたように、要求をよく確認してどういう仕様になるのか再検討したいと思います。

 皆様、大変参考になるご意見を多数頂き、まことにありがとうございます。
indigo-x
大ベテラン
会議室デビュー日: 2008/02/21
投稿数: 207
お住まい・勤務地: 太陽の塔近く
投稿日時: 2008-04-25 21:15
(既に解決済みで見られていないかもしれませんが)

ADO.NET 2.0 のクエリ通知
http://www.microsoft.com/japan/msdn/vs05/adonet/querynotification.aspx
があったのを思い出したので。。。。

参考になればと思います。



1

スキルアップ/キャリアアップ(JOB@IT)