21

Java サーバー アプリケーションをクラスタ化/配布するための最良の方法は何ですか? アプリケーション サーバーとデータベース サーバーを追加することで、水平方向にスケーリングできるアプローチを探しています。

  • この種の問題に取り組むために、どのような技術 (ソフトウェア エンジニアリング技術または特定の技術) を提案しますか?
  • パーシスタンス レイヤーを設計して多数のリーダー/ライターにスケーリングするために使用する手法は何ですか? アプリケーション トランザクションをスケーリングし、共有データへのアクセスをスケーリングします (最善の方法は、共有データを排除することです。共有データを排除するためにどのような手法を適用できますか)。
  • トランザクションの読み込みが多いか書き込みが多いかによって、異なるアプローチが必要になるようですが、「読み込み」でも効率的な「書き込み」が多いアプリケーションを最適化できればいいと思います。

「最良の」ソリューションは、単一ノード用の Java アプリケーションを作成し、できれば共有データへのアクセス/ロックの詳細のほとんどを「隠す」ことができます。

分散環境で最も困難な問題は、共有データにアクセスする複数のトランザクションを持つことです。同時トランザクションには 2 つの一般的なアプローチがあるようです。

  1. 明示的なロック(これは非常にエラーが発生しやすく、分散システム内の複数のノード間で調整するのに時間がかかります)
  2. ソフトウェア トランザクショナル メモリ(STM) 別名楽観的同時実行性。共有状態が変更されたことが検出された場合、コミット中にトランザクションがロールバックされます (トランザクションは後で再試行できます)。どのアプローチがより適切にスケーリングし、分散システムのトレードオフは何ですか?

私は、次のようなスケーリング ソリューション (およびスケーリング方法の例を提供する一般的なアプリケーション) を研究してきました。

  1. Terracotta - Java メモリ モデルを拡張して、Java の同時実行ロック メカニズム (同期、ReentrantReadWriteLocks) を使用して分散共有メモリを含めることにより、「透過的な」スケーリングを提供します。
  2. Google App Engine Java - どのサーバーがトランザクションを処理するかを分散し、BigTable を使用して永続データを格納する「クラウド」サーバー間で分散される Java (または python) アプリケーションを作成できます (共有にアクセスするトランザクションがどのように行われるかはわかりません)効果的にスケーリングできるようにデータまたはロック競合を処理します)
  3. Darkstar MMO サーバー- Darkstar は、Sun のオープン ソース MMO (大規模マルチプレイヤー オンライン) ゲーム サーバーであり、スレッド トランザクション方式でトランザクションをスケーリングし、特定のトランザクションを特定の量だけ実行してコミットし、時間がかかる場合はロールバックします (ソフトウェア トランザクショナル メモリ)。彼らは、スケーリングのためにマルチノード サーバーのセットアップをサポートするための調査を行ってきました。
  4. Hibernate の楽観的ロック- Hibernate を使用している場合は、楽観的同時実行サポートを使用して、ソフトウェアのトランザクション メモリタイプの動作をサポートできます。
  5. Apache CouchDBは、メッシュ構成の多くのリーダー/ライター DB に自然に「スケーリング」することになっています。(データのロックやトランザクションの分離を管理する方法の良い例はありますか?):
  6. JCache - Google appengine で memcached にアクセスし、他の頻繁に読み取られるデータをキャッシュするために使用できる一般的なクエリに結果をキャッシュすることにより、「読み取り」負荷の高いアプリをスケーリングします。

Terracotta は、(@Root オブジェクトと @AutoLockRead/Write メソッドを定義した後)スケーリングをサポートするように既存のサーバー アプリケーションを「簡単に」変更できるという点で、最も完全なソリューションのようです。問題は、分散アプリケーションから最大限のパフォーマンスを実際に引き出すことです。分散システムの最適化は、オブジェクト アクセスがネットワーク I/O によってブロックされる可能性があることを知って設計する必要があると考えた後ではないのです。

適切にスケーリングするには、データのパーティション分割と、特定の「実行ユニット」(CPU コア -> スレッド -> 分散アプリケーション ノード -> DB マスター ノード) のようなトランザクションの負荷分散に常に帰着するようです。

クラスタリングによってアプリを適切にスケーリングするには、データアクセスの読み取り/書き込みに関してトランザクションを分割できる必要があるようです。アプリケーション データ (Oracle、Google BigTable、MySQL、データ ウェアハウス) を配布するために人々が思いついたソリューションと、一般的にパーティション化されたデータ (多くの書き込みマスター、より多くの読み取り DB など) をどのように管理しますか?

データ永続レイヤーのスケーリングに関して、データを多くのリーダー/多くのライターにパーティション分割するという点で、どのタイプの構成が最適にスケールアウトされますか (通常、特定のユーザー (または一般的にあなたのコア エンティティである任意のコア エンティティ) に基づいてデータをパーティション分割します) 「ルート」オブジェクト エンティティ) が単一のマスター DB によって所有されている)

4

6 に答える 6

3

素晴らしい Java クラスタリング/分散プラットフォームを見つけたと思ったので、これを再開したいと思いました-

チェックアウトhttp://www.hazelcast.com

テスト プログラムを実行しました。非常にクールで、非常に軽量で、使いやすいです。ピアツーピア構成のクラスター メンバーを自動的に検出します。機会は無限です。

于 2010-05-20T15:57:07.107 に答える
2
于 2009-10-23T23:54:11.067 に答える
2

すべての可能性を 1 か所にうまくまとめてくれてありがとう。

ただし、ここでは 1 つのテクニックが欠けています。MapReduce-Hadoop です。問題を MapReduce パラダイムに当てはめることができれば、それはおそらく最も広く利用可能なソリューションです。また、Actor Framework パターン (JetLang、Kilim など) をクラスターに拡張できるかどうかも疑問です。

于 2009-10-23T22:59:33.963 に答える
1

Oracle Coherence および提案されている他の多くのソリューションはデータ共有に適していますが、分散環境で状態の変化を管理する方法としてロックと STM のみを挙げました。これらはどちらも、一般に状態管理をスケーリングする方法としてはかなり貧弱です。別のサイトで、最近、(たとえば) シーケンス カウンターを実装する方法について次の記事を投稿しました。

カウンターを見ている場合、Coherence EntryProcessor のようなものを使用すると、単調に増加する任意の数のシーケンスに対して「一度だけ」の動作と HA を簡単に実現できます。実装全体は次のとおりです。

public class SequenceCounterProcessor
        extends AbstractProcessor
    {
    public Object process(InvocableMap.Entry entry)
        {
        long l = entry.isPresent() ? (Long) entry.getValue() + 1 : 0;
        entry.setValue(l);
        return l;
        }
    }

うん。それでおしまい。自動でシームレスな HA、動的なスケールアウトの弾力性、1 回限りの動作など。

EntryProcessor は、2005 年に導入された分散クロージャの一種です。

余談ですが、Java 8 (まだリリースされていません) では、プロジェクト Lambda が言語と標準ライブラリで公式のクロージャ サポートを導入しています。

基本的には、分散環境でデータの「所有者」の場所にクロージャーを配信するという考え方です。Coherenceは、動的パーティショニングを使用してデータ所有権を動的に管理し、分散システムが実行中の様々なマシンおよびノー​​ド間でデータの負荷を分散できるようにします。実際、デフォルトでは、これはすべて 100% 自動化されているため、データをどこに置くか、またはデータの量をどこに置くかを実際に指定することはありません。さらに、他のノードや他の物理サーバーで管理されるデータの 2 次 (およびおそらく 3 次など) のコピーがあり、プロセスが失敗したりサーバーが停止した場合に備えて高可用性を提供します。繰り返しになりますが、これらのバックアップ コピーの管理はデフォルトで完全に自動化され、完全に同期化されます。つまり、システムはデフォルトで 100% HA になります (つまり、構成なし)。

クロージャーがデータ所有者に到着すると、それはトランザクション ワークスペースで実行され、操作が正常に完了すると、安全に保管するためにバックアップに送られます。データの変更 (操作の結果など) は、バックアップが正常に作成された後にのみ、システムの残りの部分から見えるようになります。

上記のいくつかの最適化には、最適化されたシリアライゼーションのために ExternalizableLite および PortableObject インターフェイスを追加すること、および「ネットワーク対応」形式のデータを直接追跡することによってボックス化された long のシリアライゼーションを回避することが含まれます。

public Object process(InvocableMap.Entry entry)
    {
    try
        {
        BinaryEntry binentry = (BinaryEntry) entry;
        long l = entry.isPresent() ? binentry.getBinaryValue()
                .getBufferInput().readLong() + 1 : 0L;
        BinaryWriteBuffer buf = new BinaryWriteBuffer(8);
        buf.getBufferOutput().writeLong(l);
        binentry.updateBinaryValue(buf.toBinary());
        return l;
        }
    catch (IOException e)
        {
        throw new RuntimeException(e);
        }
    }

ステートレスなので、シングルトン インスタンスをすぐに使用できるようにしませんか?

public static final SequenceCounterProcessor INSTANCE =
        new SequenceCounterProcessor();

ネットワーク上のどこからでも、1 行のコードと同じくらい簡単に使用できます。

long l = (Long) sequences.invoke(x, SequenceCounterProcessor.INSTANCE);

「x」は、使用する特定のシーケンス カウンターを識別する任意のオブジェクトまたは名前です。詳細は、次のCoherenceナレッジ・ベースを参照してください: http://coherence.oracle.com/

Oracle Coherence は分散システムです。Coherenceノードを起動すると、すでに実行中の他のCoherenceノードと結合し、エラスティック・クラスタを動的に形成します。そのクラスターは、パーティション分割された高可用性 (HA) でトランザクション的に一貫性のある方法でデータをホストし、そのデータを「1 回限り」の方法で操作する (上で示したような) 操作をホストします。

さらに、任意のCoherenceノードからそのロジックを呼び出したり、そのデータに透過的にアクセスしたりする機能に加えて、ネットワーク上の任意のプロセスからそのロジックを呼び出したり、そのデータに透過的にアクセスしたりすることもできます(認証が必要です)。もちろん、承認も必要です)。したがって、このコードは、任意の Coherence クラスタ ノードまたは任意の (Java / C / C++ / C# / .NET) クライアントから機能します。

完全な開示のために、私はオラクルで働いています。この投稿で表明された意見や見解は私自身のものであり、必ずしも私の雇用主の意見や見解を反映するものではありません.

于 2013-08-11T22:14:02.430 に答える
1

Erlang のMnesiaを忘れないでください。

Mnesia は、通常の DB で慣れ親しんだトランザクションのようなものを提供しますが、リアルタイム操作とフォールト トレランスを提供します。さらに、ダウンタイムなしで再構成できます。欠点は、メモリ常駐データベースであるため、非常に大きなテーブルを断片化する必要があることです。最大テーブル サイズは 4Gb です。

于 2009-10-23T23:07:07.527 に答える
0

それらのスライドが役立つかもしれません。私たちの経験から、Oracle (Tangosol) Coherence と GigaSpaces を最も強力なデータおよび処理分散フレームワークとしてお勧めします。問題の正確な性質によっては、そのうちの 1 つが輝く場合があります。テラコッタは、いくつかの問題にも非常に適しています。

于 2009-12-11T19:39:17.537 に答える