2016-08-31 10 views
0

リポジトリパターンに関する質問があります。私はデータがメモリに保存されているが、データの耐久性のためのデータベースがある分散プロジェクトに取り組んでいます。システムの規模を拡大するために、データはアプリの複数のインスタンスにわたって分割されます。このため、いずれかのノードに問題が発生するたびに、データはデータベースから再ロードされ、分散キューを使用して再構築されます。リポジトリインタフェースは実装のキャッシュをクリアするclear()メソッドを公開する必要がありますか?

私たちはリポジトリインターフェイスを作成して、ドメインがデータを処理するようにしました。このインターフェイスの実装では、マップを内部キャッシュとして使用し、Hibernateを使用してデータベースと通信します。

再作成を開始するためにアプリケーションのインスタンスが作成または削除されるたびにキャッシュをクリアする必要があるため、私はこの目的のためにリポジトリにメソッドを公開しています。これは正しい方法ですか?これは、実装の内部に関連するメソッドを公開するインタフェースではありませんか?もう1つの解決策は、リフレッシュをトリガするサービスにキャッシュを挿入することですが、それはパーシスタンス層の実装に関する情報が漏れることを意味します。

アイデア?

ありがとうございました。アプリについてもう少し

EDIT

。シャーディングが実行された理由は、データが増加した場合にアプリケーションを拡張できることでした。これらのチャンネルは最大数千になることがありますが、1秒あたり最大2件のメッセージを送信するさまざまなチャンネルを購読する必要があります。受信したすべてのメッセージについて、すべてのデータを調べ、メッセージの情報と一致するものを見つけて、それらのすべての通知を送信する必要があります。これをスケールするには、データは各インスタンス間で分割され、各インスタンスは所有するデータを処理します。

データはユーザーによって作成され、そのために作成されたRESTエンドポイントがいくつかあります。その意味では、クライアントは作成したデータを作成、更新、削除、取得することができるシンプルなアプリケーションとして動作します。リポジトリは、典型的なCRUD操作およびメソッドを特定の情報に基づいて照会するように公開しており、実装はキャッシュおよびデータベースにデータを追加し、要求に応じて一方または他方からデータを取得します。キャッシュミスが発生した場合、データベースからデータを取り出してキャッシュに入れることはできません。なぜなら、データが存在しなければ、別のものが必要になるからですクラスタ内のインスタンスで、独自のキャッシュにデータを格納します。これを処理するために、リクエストをリダイレクトするために使用するキューとトピックがあります。

このため、キャッシュをクリアする必要があります。クラスタのトポロジに変更があるたびに、新しいノードがある場合、またはキャッシュの1つとしてデータベースからデータを再度取得する必要がある場合に、キャッシュ内のデータを再調整する必要があることを意味します下がった。どのデータが欠落しているか正確にはわからないので、キャッシュをクリアしてデータベースから再投入します.1つのノードをデータローダーとして使用し、分散キューを使用してデータを破棄します。 このジョブはかなり高速に処理されるので、この間にクライアントからの要求は拒否されます。アプリにはクライアントからの多くの同時リクエストはありません。問題は、引き続き維持する必要があるサブスクリプションチャンネルにあります。

+0

なぜ 'clear()'を実行する必要があるのですが、キャッシュ内のどのデータも再度要求されていないことは確かですか?その時間中にアプリケーションとそのパフォーマンスはどうなりますか?リポジトリ内部がシャーディングと実際に関係していることを詳しく説明できますか? – cruftex

+0

質問を編集して詳細を追加しました。あなたの質問に答えてくれることを願っています – Kilian

答えて

0

実際、clear()メソッドを公開したくないです。

2つのサービスがあるとします。説明したリポジトリと、クラスタの状態と変更された時期を知っているクラスタマネージャ。

トポロジが変更されたときに、クラスタマネージャがリポジトリAPIを消費し、必要な操作をすべて呼び出すコードを追加できるようになりました。 しかし、リポジトリー実装からクラスター・マネージャーへの依存性だけがあります。クラスタマネージャは、他のクライアントにサービスを提供するためにリポジトリを知る必要はありません。

唯一の問題は、呼び出しが元に戻り、クラスタマネージャがリポジトリを呼び出す必要があることです。これを解決するには、クラスター・マネージャーAPIの一部であるイベント(例:TopologyChanged)を定義して、リポジトリーの実装で通知を受けたいことをクラスター・マネージャーに伝えさせます。

サイドノート:

すでに業務のまさにこのような操作を行う可能な製品は、例えば、ありますApache Ignite、Hazelcast、Infinispan

+0

実際には、クラスタ通知プロバイダとしてIgniteを使用しています。使用するキューとトピックはIgniteの実装であり、トポロジの変更に対してサブスクリプションが作成されています。しかし、私たちが持っているものはあなたの言うことです。この変更のサブスクライバは、リポジトリ(またはキャッシュ)を呼び出してキャッシュをクリアします。私が理解するところでは、レポ自体がクラスタ通知にサブスクライブすることをお勧めします。レポがこのイベントを購読する必要があるのでしょうか?それは、永続性に関係しないものには気を付けるべきではないと思いました。 – Kilian

+0

これが当てはまる場合、キャッシュも行われません。キャッシュのために、それらのイベントが必要です。 OTOHでは、あなたが持っているコンポーネント、それらのライフサイクル、そしてどのコンポーネントが相互に作用しているかを調べます。同じライフサイクルを持ち、お互いにしか話していない2つのコンポーネントがある場合、それが一緒に属している強いインジケータ;) – cruftex

+0

コメントありがとうございました。我々は少し全体を再設計しようとしており、この場合、爽やかさの必要はありません。キャッシュはIgniteを使用して共有されるため、データの再調整を管理するのはクラスタ自体の責任です。そうすれば、私たちはこのすべてを忘れることができます。ありがとう! – Kilian

関連する問題