Java サーバー アプリケーションをクラスタ化/配布するための最良の方法は何ですか? アプリケーション サーバーとデータベース サーバーを追加することで、水平方向にスケーリングできるアプローチを探しています。
- この種の問題に取り組むために、どのような技術 (ソフトウェア エンジニアリング技術または特定の技術) を提案しますか?
- パーシスタンス レイヤーを設計して多数のリーダー/ライターにスケーリングするために使用する手法は何ですか? アプリケーション トランザクションをスケーリングし、共有データへのアクセスをスケーリングします (最善の方法は、共有データを排除することです。共有データを排除するためにどのような手法を適用できますか)。
- トランザクションの読み込みが多いか書き込みが多いかによって、異なるアプローチが必要になるようですが、「読み込み」でも効率的な「書き込み」が多いアプリケーションを最適化できればいいと思います。
「最良の」ソリューションは、単一ノード用の Java アプリケーションを作成し、できれば共有データへのアクセス/ロックの詳細のほとんどを「隠す」ことができます。
分散環境で最も困難な問題は、共有データにアクセスする複数のトランザクションを持つことです。同時トランザクションには 2 つの一般的なアプローチがあるようです。
- 明示的なロック(これは非常にエラーが発生しやすく、分散システム内の複数のノード間で調整するのに時間がかかります)
- ソフトウェア トランザクショナル メモリ(STM) 別名楽観的同時実行性。共有状態が変更されたことが検出された場合、コミット中にトランザクションがロールバックされます (トランザクションは後で再試行できます)。どのアプローチがより適切にスケーリングし、分散システムのトレードオフは何ですか?
私は、次のようなスケーリング ソリューション (およびスケーリング方法の例を提供する一般的なアプリケーション) を研究してきました。
- Terracotta - Java メモリ モデルを拡張して、Java の同時実行ロック メカニズム (同期、ReentrantReadWriteLocks) を使用して分散共有メモリを含めることにより、「透過的な」スケーリングを提供します。
- Google App Engine Java - どのサーバーがトランザクションを処理するかを分散し、BigTable を使用して永続データを格納する「クラウド」サーバー間で分散される Java (または python) アプリケーションを作成できます (共有にアクセスするトランザクションがどのように行われるかはわかりません)効果的にスケーリングできるようにデータまたはロック競合を処理します)
- Darkstar MMO サーバー- Darkstar は、Sun のオープン ソース MMO (大規模マルチプレイヤー オンライン) ゲーム サーバーであり、スレッド トランザクション方式でトランザクションをスケーリングし、特定のトランザクションを特定の量だけ実行してコミットし、時間がかかる場合はロールバックします (ソフトウェア トランザクショナル メモリ)。彼らは、スケーリングのためにマルチノード サーバーのセットアップをサポートするための調査を行ってきました。
- Hibernate の楽観的ロック- Hibernate を使用している場合は、楽観的同時実行サポートを使用して、ソフトウェアのトランザクション メモリタイプの動作をサポートできます。
- Apache CouchDBは、メッシュ構成の多くのリーダー/ライター DB に自然に「スケーリング」することになっています。(データのロックやトランザクションの分離を管理する方法の良い例はありますか?):
- JCache - Google appengine で memcached にアクセスし、他の頻繁に読み取られるデータをキャッシュするために使用できる一般的なクエリに結果をキャッシュすることにより、「読み取り」負荷の高いアプリをスケーリングします。
Terracotta は、(@Root オブジェクトと @AutoLockRead/Write メソッドを定義した後)スケーリングをサポートするように既存のサーバー アプリケーションを「簡単に」変更できるという点で、最も完全なソリューションのようです。問題は、分散アプリケーションから最大限のパフォーマンスを実際に引き出すことです。分散システムの最適化は、オブジェクト アクセスがネットワーク I/O によってブロックされる可能性があることを知って設計する必要があると考えた後ではないのです。
適切にスケーリングするには、データのパーティション分割と、特定の「実行ユニット」(CPU コア -> スレッド -> 分散アプリケーション ノード -> DB マスター ノード) のようなトランザクションの負荷分散に常に帰着するようです。
クラスタリングによってアプリを適切にスケーリングするには、データアクセスの読み取り/書き込みに関してトランザクションを分割できる必要があるようです。アプリケーション データ (Oracle、Google BigTable、MySQL、データ ウェアハウス) を配布するために人々が思いついたソリューションと、一般的にパーティション化されたデータ (多くの書き込みマスター、より多くの読み取り DB など) をどのように管理しますか?
データ永続レイヤーのスケーリングに関して、データを多くのリーダー/多くのライターにパーティション分割するという点で、どのタイプの構成が最適にスケールアウトされますか (通常、特定のユーザー (または一般的にあなたのコア エンティティである任意のコア エンティティ) に基づいてデータをパーティション分割します) 「ルート」オブジェクト エンティティ) が単一のマスター DB によって所有されている)