ツインシティーズコードキャンプ

分散キャッシングを使用した.NETアプリケーションのスケーリング

イクバル・カーン
プレジデント&テクノロジーエバンジェリスト

この分散キャッシュの実践的なデモを見て、さまざまな環境で .NET キャッシュを使用するためのベスト プラクティスを学びましょう。 この講演の内容は次のとおりです。

  • .NETアプリケーションのスケーラビリティのボトルネックの概要
  • 分散キャッシングの説明と、それがパフォーマンスの問題をどのように解決するか
  • アプリケーションのどこで分散キャッシングを使用できますか
  • 分散キャッシュのいくつかの重要な機能
  • 分散キャッシュを使用した実践例

概要

皆様、ご来場ありがとうございました。 私の名前はイクバル・カーンです。 外は素晴らしい天気です。 タンパから来ました。 したがって、ここでははるかに快適な温度です。 ここよりもずっと涼しい天気を期待していました。 それでは、屋内に留まっていただきありがとうございます。 私はこの会社のテクノロジー エバンジェリストです。 Alachisoft。 私たちはのメーカーです NCache。 次の XNUMX ~ XNUMX 分がマーケティング ステートメントになります。 したがって、.NET スペース用に XNUMX つの製品があります。 XNUMX つは、当社の主力製品です。 NCache これは .NET の分散キャッシュです。 それが私たちが持つ専門知識です。 したがって、私たちは約 10 年間この分野に携わっており、そうしてこの特定のトピックに関する専門知識を構築してきました。

という別の製品もあります NosDB これは私たちが昨年末に立ち上げたものです。 オープンソースです NoSQL database .NET用。 これは MongoDB レベルの機能に似ていますが、ネイティブの .NET であり、やはりすべてオープンソースです。 NCache もオープンソースです。 NosDB。 ぜひ当社の商品をご覧ください。

ですので、もっとインタラクティブな議論をしていきたいと思っています。 アーキテクチャの概念的な説明とソース コードを組み合わせて説明していきます。 したがって、実際にアプリケーションでキャッシュを使用する方法を確認できます。 それでは、始めましょう。

スケーラビリティ

邪魔にならないようにいくつかの定義を取得しましょう。 5 つ目は、 スケーラビリティとは何か。 スケーラビリティはパフォーマンスではありません。 したがって、アプリケーションが 5000 ユーザーで高速にパフォーマンスするとしても、50,000、500,000、または 5 ユーザーの下で同じ良好なパフォーマンスが得られない限り、拡張性はありません。 もちろん、アプリケーションが XNUMX ユーザーに対して高速に動作しない場合は、これから説明すること以外の側面に注目する必要があります。

線形スケーラビリティ

線形スケーラビリティは、どちらかというと展開アーキテクチャの用語です。 アプリケーションが、サーバーを追加して容量やトランザクション容量を増やすことができるように設計されている場合、ちなみに、私がスケーラビリティという言葉を使用するときは、主にトランザクション容量について話しているのであり、多くのことを話しているわけではありません。データの。 したがって、スケーラビリティの観点からは、テラバイト単位のデータについて話しているのではありません。 私たちは、大量のトランザクションやアクティビティを処理できるかどうかについて話しています。 したがって、線形のスケーラビリティとは、サーバーを追加するだけでトランザクション容量を拡張でき、ボトルネックがないことを意味しており、それが私たちが達成したいことです。

線形スケーラビリティ

非線形のスケーラビリティ

もちろん、非線形は私たちが達成したいことではありません。 これは、デプロイメント内のアプリケーション アーキテクチャに根本的なボトルネックがあり、それがスケーリングの妨げになっているため、サーバーをどれだけ追加しても、特定の時点以降パフォーマンスが低下することは問題ではないことを意味します。

非線形のスケーラビリティ

スケーラビリティが必要なアプリケーションはどれですか?

スケーラビリティが必要なアプリケーションの種類は何ですか? これらは通常、サーバー タイプのアプリケーション、ASP.NET、ASP です。.NET Core 現在、Web サービス (通常は WCF)、IoT バックエンド (通常は Web サービス) ですが、必ずしもそうである必要はありません。 ビッグデータ処理アプリケーション。 これらは通常 Java で実行されますが、.NET で実行すると、Java や大量のトランザクションを処理する必要がある他のサーバー アプリケーションで発生するのと同じ問題が発生します。 たとえば、何百万もの顧客を抱える銀行や金融サービス会社である可能性があります。 住所変更や送金などの電話がかかってきますが、コンプライアンスやその他の SLA の理由から、夜にはこれらすべてを処理しなければなりません。 したがって、これらはより多くのバッチ処理やバックエンド処理を持っていますが、それらは依然として大量の情報を処理できる必要がある他のサーバー アプリであり、それらが処理できない場合は、わかっています、あなたはとても困っています。

スケーラビリティの問題

これらのアプリケーションがある場合は、おそらくスケーラビリティが必要になります。 それでは、この問題がどこにあるのかについて話しましょう。 私たちが対処しようとしているスケーラビリティの問題はどこにあるのでしょうか? スケーラビリティの問題は実際にはアプリケーション層にはありません。 あなたのアプリケーション、私が説明したすべてのアプリケーションは、通常、サーバーを追加できるように設計されており、まったく問題ありません。 問題はデータストレージにあります。 つまり、アプリケーション データが存在する場所、つまりリレーショナル データベースのことです。 これは、SQL サーバー、Oracle、MySQL である可能性があります。 特定のベンダーではありません。 リレーショナル データベースの概念は設計上、拡張することができません。 実際には、データ量の点でも拡張できません。 それが理由です NoSQL databaseは非常に人気がありますが、特にトランザクション側で、メインフレームのレガシー データがある場合も同様です。 多くのアプリケーションはレガシー データにアクセスする必要があります。 つまり、そこにボトルネックが発生し、そのボトルネックがある場合、この層がスケーラブルであるかどうかは問題ではなく、スケーリングできなくなります。

NoSQL databaseが普及したのは、まさにスケーラビリティを提供するためです。 そして、ご存知のとおり、私たちには NoSQL database しかし、多くの場合、彼らは問題に対処しません。 技術的理由とビジネス上の理由が重なって使用できないため、問題に対処できません。 を使用するには NoSQL database リレーショナル データベースではなく、そこにデータを入れる必要があります。 あなたができるいくつかのデータ。 間違いなく入れられますよ NoSQL database しかし、従来のビジネス データの多くはリレーショナル データベースに残ることになります。 データを移動できない場合は、 NoSQL databaseす、ダメですよ。 したがって、たとえ NoSQL database 混合では、それはデータのサブセットにすぎません。 通常、これはリレーショナル データベースに代わるものではありません。 そして、 NoSQL database 会社の皆さん、ご存知のとおり、私は非常に正直に申し上げますが、お客様と話をするとき、私たちはリレーショナルの使用をやめるとは言いませんし、そんなことは決して起こりません。 私たちは、それをリレーショナルの拡張として使用すると言います。 したがって、リレーショナルを使用し続ける必要がある場合は、それを組み合わせてその問題を解決する必要があり、そこで分散キャッシュが登場します。それが、私たちがこの会話をしている理由です。

分散キャッシュの導入 (NCache)

分散キャッシュについて少し定義してみましょう。 分散キャッシュは分散されます。 ここでは、XNUMX つ以上のサーバーに存在します。 論理的に言えば、これは別個のキャッシュ層です。 物理的にはアプリケーションと同じボックス上に存在できますが、論理的には別のキャッシュ層になります。 通常、XNUMX つ以上のサーバーと分散キャッシュがクラスターを形成します。 したがって、通常はこれらのクラスターであり、TCP ベースのクラスターが最も一般的です。 NCache クラスタリングには間違いなく TCP を使用します。 そして、このクラスターは、すべてのリソース、すべてのサーバー、CPU、メモリ、ネットワーク カードがすべて一緒にプールされていることを意味します。 そうしてこれがスケーラブルになるのです。 容量を増やす必要がある場合は、さらにサーバーを追加できるためです。

分散キャッシュの導入 (NCache)

これはここでもできることです。 しかし、ここではそれができません。 先ほども述べたように、別の SQL データベースを追加することもできますが、これを考慮する必要があります。 これをイメージしたら、すぐにミックスに次のようなものが必要になります。

分散キャッシュは安価なサーバー上に存在します。 これらは、ハイエンド データベースの典型的な Web サーバー タイプの構成ではありません。 当社の顧客のほとんどは 8 コア ボックスを使用しており、以前はデュアル CPU だったようですが、現在では単に 8 コアと 64 ビットという言葉が多くのメモリを備えたものとして使われています。 ロットということは、16 ~ 32 ギガが、私たちが確認しているサーバーあたりの平均にほぼ相当することを意味します。 各ボックスで 64 ギガを超えることはお勧めしません。 64 GB を超えるメモリがある場合、.NET ではガベージ コレクションが必要になるためです。 GC 自体はかなり時間のかかるタスクであり、それ自体がボトルネックになり始めます。 したがって、本当にハイエンドのサーバーを少数しか持たないよりも、より多くのサーバーを持った方が良いのです。 キャッシュが設計上分散されているとしても、ボトルネックはガベージ コレクションになり始めているからです。 そして、私たちは長年にわたる多くのつらい経験を通じてこのことを学びました。 ご存知のとおり、128 ギガまで増加した顧客がいたため、突然 CPU に大きな負荷がかかりました。 そのため、処理能力を大幅に向上させる必要があり、よりデータベースらしく見えるようになりました。 そこで、私たちはそれを停止することをお勧めしました。

データベースに存在するデータをキャッシュします。 そして、基本的に 80% の時間はキャッシュ層にアクセスし、20% の時間はデータベースにアクセスします。 キャッシュはメモリ内で超高速であり、以下を含むどのデータベースよりもはるかに高速です。 NoSQL database自社よりも速いものも含めて NoSQL database. NCache どのデータベースよりも少なくとも一桁高速です。 ご存知のように、データベースはディスクに保存する必要があるからです。 ただし、もちろんすべての更新は実際のデータベースに送信される必要があります。 つまり、20% に加えて、もちろん一部の読み取りが発生します。

これを実行すると、突然データベースからすべての負担が軽減されます。 実行できるようになりました。 読み取りが大幅に高速になり、更新も高速になります。 つまり、そのスケーラビリティを実現できると同時に、アプリケーションがスケーラブルになっただけでなく、突然高速化することも可能になります。 ただし、キャッシュを使用する主な理由はパフォーマンスを向上させることではありません。これもまた、キャッシュはパフォーマンスを向上させるためにあるという従来の考えとはまったく逆です。 つまり、スタンドアロンの状況では、そうです。 データベースでもメモリ内キャッシュが使用されます。 私たちの NosDB も組み込みのキャッシュを使用しますが、これは実際にはスケーラビリティのためであり、できるようにする必要があるため、それは自分で解決できない問題であるためです。 スケーラビリティを得るために、より高価なハードウェアを購入することはできません。 スケーラブルなアプリケーションを実現するには、アプリケーションを設計し、適切なインフラストラクチャ、またはアーキテクチャの一部として適切なコンポーネントを使用する必要があります。

Java 側では、これはインメモリ データ グリッドと呼ばれます。 .NET 側では、分散キャッシュと呼ばれます。 これを別の言葉で表すと、「インメモリ」です。 NoSQL キー値ストア。 つまり、XNUMX つの異なる見方があるということです。 これは、 NoSQL database それはある NoSQL キー値をメモリ内に保存します。 なぜなら、永続化を行わず、永続的なストアを持たないからです。

したがって、このような図ができたら、アーキテクチャ的にはボトルネックのないアプリケーションが完成すると確信していただきたいと思います。 これをインフラストラクチャとして使用するようにアプリケーションを設計する場合。 さらに詳しく説明する前に、質問があればここまでにしておきます。

キャッシュが古いかどうか、それともケースの外で何かを更新したかどうかをどうやって知るかは詳細次第だと思います。 それについて話しましょう。 良い質問。

分散キャッシュの一般的な使用法

たとえば、アプリケーション アーキテクチャの一部として分散キャッシュが必要であると確信した場合、次に頭に浮かぶ疑問は、それをどのように使用するかということです。 キャッシュはどこで使用されますか?また、それぞれの使用方法に関連する問題は何ですか? したがって、.NET 開発者として、私の焦点は .NET ですが、同じ概念が他のアプリケーションにも当てはまります。

アプリケーションデータのキャッシュ

最も一般的な使用例は、アプリケーション データのキャッシュです。これまで説明してきたことは、データベースがあり、そこにデータをキャッシュするだけです。 したがって、目標はデータベースに頻繁にアクセスしないことです。 そして、私が話したすべての利点を得ることができます。 そうしますとすぐに問題が起きます、それが今おっしゃったことです。 データは現在 XNUMX か所に存在します。 XNUMX つは永続的なマスター ストア (データベースであり、常に必須) であり、XNUMX つ目はキャッシュです。 そして、実際にはキャッシュ内に複数の場所に存在しており、それについても説明します。

では、データが複数の場所に存在する場合、何が問題になるのでしょうか? 同期が失われる可能性があります。 したがって、分散キャッシュがその状況に対処できない場合は、読み取り専用データをキャッシュする必要があります。 実際、ほとんどの人は、キャッシュについて考えるとき、それが読み取り専用データのためのものであると突然反応します。 変更されるデータをキャッシュすると、それがトランザクション データと呼ばれるためです。 そうすると同期が外れてしまいます。 そして、同じ銀行口座から 10 万ドルを 15 回引き出すという古典的な問題がここに来ます。 つまり、キャッシュがこの問題に対処しない場合、対応できるのは非常に小さなサブセットに限定されることになります。 キャッシュできるのはデータの約 XNUMX% ~ XNUMX% だけですが、それだけでは十分ではありません。 したがって、優れた分散キャッシュはこの問題に対処する必要があり、それについて説明します。

ASP.NET固有のキャッシュ

XNUMX 番目の使用例は、ASP.NET アプリケーションがある場合、そのアプリケーションに XNUMX つの異なるものを保存できることです。 もちろん、新しいフレームワークが登場するにつれて、これは変わります。 したがって、最も一般的なのは ASP.NET セッション状態です。これは、ASP と ASP の両方に存在します。.NET core そして従来の ASP フレームワーク。 セッションは、デフォルトでインプロセスまたは SQL サーバーに保存されるものです。 どちらもスケーラビリティの問題を抱えています。 SQL にもパフォーマンスの問題があります。 また、リレーショナル データベースは BLOB を保存するように設計されていないため、セッションは BLOB として保存されます。 次に、アプリケーション データをキャッシュしてデータベースにアクセスしたくないのと同じ理由で、データベース内にセッションを保持したくありません。 したがって、これは ASP.NET アプリケーションにとって非常に理想的な使用例です。 そして、ご存知のとおり、これはほとんどのお客様が最初に使用するものです。 既存のアプリケーションがあり、分散キャッシュを組み込みたい場合、それを組み込むために必要な最小限の労力はセッションです。 なぜなら、ASP.NET framework サードパーティのキャッシュをプラグインできます。プログラミングは必要ありません。 web.config に変更を加えるだけです。 実際、それをすぐにお見せしましょう。 ただ前後にジャンプしていきます。

たとえば、この小さな ASP.NET アプリケーションがあり、ここに web.config があり、もちろん使用します。 NCache 例として挙げますが、次のように使用するとします。 NCache セッション状態プロバイダーとして、このアセンブリを配置する必要があります。 そこで、「アセンブリを追加」タグを付けます。 それで、この組み立ては、 NCache ASP.NET セッション状態プロバイダー インターフェイスを実装しました。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <machineKey validationKey="A01D6E0D1A5D2A22E0854CA612FE5C5EC4AECF24" decryptionKey="ACD8EBF87C4C8937" validation="SHA1" />
        <compilation defaultLanguage="c#" debug="true" targetFramework="4.0">
            <compilers>
                <compiler language="c#" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" extension=".cs" compilerOptions="/d:DEBUG;TRACE" />
            </compilers>
            <assemblies>
                <add assembly="Alachisoft.NCache.SessionStoreProvider, Version=4.6.0.0, Culture=neutral, PublicKeyToken=CFF5926ED6A53769" />
            </assemblies>
        </compilation>
        
        <customErrors mode="RemoteOnly" />
        <authentication mode="None" />
        <authorization>
            <allow users="*" />
        </authorization>
        <trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
        <!-- For NCache Developer Edition replace 'myPartitionedCache' with 'myCache' or any other local-cache-->
        <sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom" customProvider="NCacheSessionProvider" timeout="1">
            <providers>
                <add name="NCacheSessionProvider" type="Alachisoft.NCache.Web.SessionState.NSessionStoreProvider" exceptionsEnabled="true" enableSessionLocking="true" emptySessionWhenLocked="false" sessionLockingRetry="-1" sessionAppId="NCacheTest" useInProc="false" enableLogs="false" cacheName="myPartitionedCache" writeExceptionsToEventLog="false" AsyncSession="false" />
            </providers>
        </sessionState>
        <!--  GLOBALIZATION
        This section sets the globalization settings of the application. 
		-->
        <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
        <xhtmlConformance mode="Legacy" />
        <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
    </system.web>
    <system.webServer>
        <directoryBrowse enabled="true" showFlags="Date, Time, Size, Extension, LongDate" />
    </system.webServer>
</configuration>

つまり、それがASPに準拠している方法です.NET framework サードパーティキャッシュである仕様。 したがって、これが最初に行い、次に名前空間を変更します。 実際には、このタグを使用するだけです。 したがって、モードがカスタムであり、タイムアウトが 20 分ではないことを確認します。 XNUMX になるはずです。そして、この話に戻ります。 それがキャッシュ名です。

の場合 NCache、すべてのキャッシュに名前が付けられます。 話を戻します。 これだけで、アプリケーションはセッションをキャッシュに保存し始めます。 また、メモリ内で実行されるため、SQL よりもはるかに高速であり、パフォーマンスが向上することがすぐにわかります。 In-Proc よりは速くありませんが、SQL よりは高速ですが、どちらの場合もよりスケーラブルです。

ASP.NET の XNUMX 番目の使用例はビュー ステートです。MVC フレームワークを使用していない場合、または従来の ASP.NET にまだある場合はビュー ステートが存在しますが、これは知らない場合もあります。 知らない人のために説明すると、ビュー ステートは、Web サーバーによってブラウザに送信され、ポストバックがある場合にのみ戻ってくる暗号化された文字列です。 したがって、このサイズは数百キロバイトに達する可能性があります。 これに、アプリケーションが処理しなければならない何百万ものリクエストを掛けると、帯域幅を大量に消費することと、帯域幅が空いていないという XNUMX つの悪いことが起こっていることになります。 アプリケーションをホストするときは、帯域幅の料金を支払う必要があります。 次に、ペイロードがはるかに重いため、応答時間が遅くなります。 したがって、それをサーバー側でキャッシュできれば、それがすべて排除され、アプリケーションが高速化されます。

出力キャッシュは ASP です.NET framework これにより、ページ出力をキャッシュできるようになり、ページ出力が変更されない場合は、最後の実行から取得するだけになります。 したがって、各 Web サーバーに出力キャッシュの個別のコピーを保持するよりも、Web ファームに分散キャッシュを接続する方がよいでしょう。 実際にやりたいことは、アプリケーション管理の観点から、これらの Web サーバーを完全にステートレスにすることです。 ステートレスであれば、すべてのパッチを適用できます。すべてのバグ修正やアプリケーションのアップグレードは、ソフトウェアのアップグレードという観点から見ると、キャッシュのアップグレードよりもはるかに頻繁に行うことができます。 したがって、ここで状態が維持されていない場合は、Web ファームからそのボックスをドロップしても、ユーザーは気付かないでしょう。 なぜなら、すべての状態はここまたはデータベースで維持されており、これらもそれほど頻繁に触れるものではないため、やはりキャッシュします。

ASP.NET 固有のキャッシュの場合、これらすべてにプログラミングが必要ないという利点が XNUMX つあります。 したがって、何もせずにすぐに接続するだけです。 もちろん、行うことは健全性テストだけです。 たとえば、ASP.NET セッション状態をプラグインして In-Proc セッションを使用していた場合、すべてのオブジェクトがシリアル化可能ではないことが判明する可能性があります。 そして、あなたは知らないうちに、突然アプリケーションが例外をスローし始めます。 つまり、そのレベルのテストを行う必要があるということです。 しかし、ここで別の特有の問題が発生します。データのコピーが XNUMX つある場合とは異なり、データはキャッシュ内にのみ存在します。

では、インメモリ ストアがマスター ストアである場合、何が問題になる可能性があるでしょうか? マシンがダウンします。 そうですね、サーバーがダウンするとデータが失われますが、このデータ、特にセッションは失いたくありません。 したがって、優れた分散キャッシュはこれに対処する必要があり、これは通常、同じデータが少なくとも XNUMX つの場所に存在するレプリケーションによって行われます。それが起こらない場合は、そうでない限り、そのキャッシュにセッションを置かないでください。それは実際にはそうではありません…ユーザーがこのセッションを使用するかどうかは問題ではありませんが、ほとんどの状況ではそうではありません。

ランタイムデータ共有

XNUMX 番目の使用例は、 ランタイムデータ共有 イベントを通じて。 これは通常、メッセージ キューで行われることです。メッセージ キューには独自の場所があり、分散キャッシュはその代わりに存在するわけではありませんが、分散キャッシュははるかに高速でスケーラブルであり、メッセージやデータの共有が行われている場合には、分散キャッシュの方がはるかに高速です。同じ場所、同じデータセンターで実行されると、分散キャッシュを使用できます。 Pub / Sub やり方なら、それができます。 特定のアイテムに興味を示すことができる他の種類のイベントもあります。 たとえば、この項目が変更された場合は通知してください。 または次の場合 NCache という機能があります 継続的なクエリ SQL ステートメントを実行して次のように言うこともできます。CUSTOMER.CITY = NEW YORK の顧客を選択してください'。 このデータセットが更新、削除された場合、または新しいオブジェクトが追加、更新、または削除された場合は、私に通知してください。 つまり、アプリケーションがそのような種類の監視を行うことができ、消費者が通知を受けたいものについてより賢く判断できるようになると考えられます。 また、プロデューサーはキャッシュを更新し続けることができます。

これが XNUMX 番目の使用例ですが、多くの人は知りませんが、キャッシュがこれを行うのに非常に適した場所であることがますます明らかになりつつあります。 なぜなら、これら XNUMX つの理由ですでにキャッシュを使用しているからです。 したがって、これを入れてみてはいかがでしょうか。アプリケーションに組み込むのは非常に簡単です。 詳細に入る前に、何か質問はありますか?

デモ

そこで、まずキャッシュがどのようなものかを説明します。 それで、それを私たちが話しているすべての文脈に入れることができます。 私が使用します NCache 例として。 そのため、Azure には多数の VM があります。 これで、demo1、demo2、およびデモ クライアントが完成しました。 Demo1 と Demo2 は私のキャッシュ サーバー VM です。 デモ クライアントはアプリケーション サーバー ボックスです。 これがキャッシュ クライアントです。 それで、私はそれをすべて持っています。

Azure VM

ログインしています。たとえば、デモ クライアントにログインしています。 キャッシュを作成してみます。 それで、私は使用するつもりです NCache マネージャー、グラフィカルツール。 「新しいクラスター キャッシュを作成する」と言ってみましょう。

キャッシュを作成する

の場合 NCache、すべてのキャッシュに名前が付けられます。 詳細をすべて説明するつもりはありません。 各キャッシュに名前を付けます。

キャッシュ名の指定

キャッシュのトポロジを選択します。 トポロジー これは実際にはストレージとレプリケーションの戦略です。 つまり、トポロジの場合、 NCacheパーティション レプリカと呼ばれるトポロジがあるとします。 したがって、これら XNUMX つはここではキャッシュ サーバーであり、各サーバーには XNUMX つのパーティションがあります。 そこで、次の場合について考えてみましょう NCache, NCache サーバーごとに XNUMX つのパーティションを作成し、各サーバーには別のサーバーのパーティションのレプリカが含まれます。 各パーティションには、合計バケット数の n 分の XNUMX が含まれます。 の場合には NCache キャッシュごとに 1000 個のバケットがあります。

キャッシングトポロジ

つまり、500 ノードのクラスターの場合はそれぞれ XNUMX バケット、XNUMX ノードのクラスターの場合は XNUMX 分の XNUMX、XNUMX 分の XNUMX、XNUMX 分の XNUMX になります。

パーティション レプリカ。パーティションはアクティブですが、レプリカはアクティブではなく、パッシブです。 したがって、クライアントはパーティションとのみ通信し、クライアントがここで項目を更新すると、パーティションは先に進んでそれをレプリカに複製し、その複製はデフォルトでは非同期です。 なぜなら、真のスケーラビリティを得るには、この結果整合性モデルに移行する必要があるからです。 ただし、場合によっては、データは非常に機密性の高いものになります。 ご存知のとおり、銀行などの金融サービス会社はたくさんあります。 NCache そして彼らのデータは実際にはお金です。 したがって、その場合、最終的な整合性を保つことはできません。 したがって、そこでは同期レプリケーションを実行する必要があります。これは、アプリケーションが両方の場所でデータが更新されるまで待機することを意味します。 サーバーがダウンした場合、たとえば、3 ノードのクラスターがあり、サーバー 3 がダウンし、パーティション 3 がダウンした場合、レプリカ XNUMX がすぐにアクティブになります。

サーバーの追加時のデータバランシング

これが高可用性を実現する方法であり、アクティブになると、サーバーが 1 つしかなく、パーティションが 2 つしかないことが認識されますが、これは本来あるべき姿ではありません。 したがって、パーティション 2 および XNUMX とマージされ、それが完了すると、パーティション XNUMX のレプリカがここに作成されます。

以下の場合はすべて NCache アプリケーションはそれが起こっていることを認識することなく、実行時に実行されます。 同様に、2 ノードのクラスターを使用し、XNUMX 番目のサーバーを追加すると、マップ全体がここからここに自動的に変更されます。 つまり、その選択にはそういう意味があったのです。

それで、私はただ選ぶつもりです パーティションのレプリカ トポロジとして。

レプリケーション戦略

非同期レプリケーションは維持します。

レプリケーション戦略

最初のサーバーとしてデモ 1 を選択し、2 番目のサーバーとしてデモ XNUMX を選択します。

クラスター化されたキャッシュ メンバー ノードの選択

すべてデフォルトのままにします。 パーティション サイズを指定します。1 ギガのみです。

ストレージサイズの指定

あなたの場合、16 ギガのマシンがある場合、OS とその他のプロセス用に約 2 ~ 2.5 ギガを残し、残りのすべてをキャッシュと残りのメモリとして消費する必要があります。半分はアクティブ パーティション、残りの半分はアクティブ パーティションにする必要があります。そのうちレプリカ用です。

キャパシティ プランニングを行うときは、セッションの場合にセッションが保持できる十分なメモリを確保できるように、十分なメモリを割り当てることが非常に重要です。そうでない場合、キャッシュがこのメモリをすべて使い果たした場合、キャッシュはフルであるとみなされます。その場合、キャッシュが新しいエントリを拒否するか、既存のエントリの一部を削除するかの XNUMX つのうちの XNUMX つだけが起こります。 NCache XNUMX つのアルゴリズムを提供します。 ご存知のとおり、最も一般的なものは最も最近使用されていません。

エビクションポリシーの指定

そう、 NCache キャッシュがいっぱいであるとみなされると、キャッシュの 5% が直ちに削除されます。 これを作成したので、次にクライアント ノードを追加します。この場合はデモ クライアントであり、キャッシュを開始します。

クライアントノードの追加

したがって、キャッシュを開始するとき、舞台裏で多くのことが起こっています。 新たなクラスターが形成されつつある。 クラスターのメンバーシップが形成され、クライアントに伝播されます。 では、クライアントはクラスターのメンバーシップが何であるかを知っているのでしょうか? 分布図は何ですか? したがって、すべての作業が完了すると、すべてが完了します。 それでは、統計についてお話します。 PerfMon を見たいです。 そして、ストレス テスト ツールと呼ばれる、すぐに実行できるこのツールをすぐに実行したいと考えています。 環境内のキャッシュを迅速にテストします。

ストレス テスト ツールの実行

したがって、これを行うためにプログラミングを行う必要はありません。 ということで、キャッシュはこんな感じです。 このようなものをインストールします。 インストールするとします NCache。 アプリケーション サーバーが構成された 2 ノード クラスターを取得するには、これだけの時間しかかかりません。 あなたの場合、もちろん複数のクライアントがいるでしょう。 最も一般的な構成は、約 5 ~ 8 台のクライアントと 2 ~ 3 ノードのキャッシュ クラスターです。 そして、クライアントを追加すると、サーバーも追加されます。

キャッシュ統計

このキャッシュを実行したので、実際のトピックに戻りましょう。 したがって、これから行うことはすべて、この名前付きキャッシュがどのように作成されたかを念頭に置く必要があります。 ASP.NET 固有のセッション状態についてはすでに示しました。

アプリケーション データ キャッシュの概要 (API)

それでは、今日の私の講演の内容であるアプリケーション データ キャッシュについて説明しましょう。 したがって、アプリケーション データ キャッシュの場合は、プログラミングする必要がある API が必要になります。 なぜなら、ASP.NET core IDistributed Cache と呼ばれるインターフェイスが追加され、その API を呼び出して、舞台裏でサードパーティのキャッシュをプラグインできるようになりました。 Java 側には、JCache と呼ばれる非常に強力な API が標準としてありますが、.NET 側には何もありません。 したがって、ほとんどの場合、実際のキャッシュ API 自体をプログラムする必要があります。 ただし、API は非常に簡単です。

  • キャッシュ接続
    ICache cache = CacheManager.GetCache("myCache");
    cache.Dispose();
  • データの取得
    Employee employee = cache.Get<Employee>("Employee:1000"); 
    bool isPresent = cache.Contains("Employee:1000");
  • データの書き込み
    cache.Add("Employee:1000", employee);
    cache.AddAsync("Employee:1000", employee);
    
    cache.Insert("Employee:1000", employee);
    cache.InsertAsync("Employee:1000", employee);
    
    Employee employee = (Employee) cache.Remove("Employee:1000");
    cache.RemoveAsync("Employee:1000");

の場合 NCache お気づきのとおり、これは ASP.NET キャッシュ オブジェクトに非常によく似ています。 つまり、基本的にやっていることは、cache.Get を実行し、オブジェクトを取得することです。キャッシュ ドットの Add、Insert、Remove、またはその非同期バージョンもあります。 非同期とは、キャッシュが更新されるのを待たずにコントロールを返すことを意味し、その場合はコールバックを指定できます。

アプリケーションがどのようなものかを簡単に説明しましょう。 そこで、次の非常に単純なコンソール アプリケーションを作成しました。 NCache.

using System;
using Alachisoft.NCache.Runtime;
using Alachisoft.NCache.Web.Caching;
using Alachisoft.NCache.sample.data;

namespace BasicOperations
{
    public class BasicOperations
    {
        public static void Main(string[] args)
        {
            try
            {
            //Initialize cache via 'initializeCache' using 'Cache Name'
            //to be initialized. 
            Cache cache = NCache.InitializeCache("demoCache");
            cache.Clear();

            //Another method to add item(s) to cache is via CacheItem  object
            Customer customer = new Customer();
            customer.Name = "David Johnes";
            customer.Age = 23;
            customer.Gender = "Male";
            customer.ContactNo = "12345-6789";
            customer.Address = "Silicon Valley, Santa Clara, California";

            DateTime calendar = new DateTime();
            calendar.AddMinutes(1);

            //Adding item with an absolute expiration of 1 minute
            cache.Add("Customer:DavidJohnes", customer, calendar, Cache.NoSlidingExpiration, CacheItemPriority.Normal);
            Customer cachedCustomer = (Customer) cache.Get("Customer:DavidJohnes");
            ...

したがって、最初に行う必要があるのは、キャッシュ アセンブリを参照していることを確認することです。 NCache はXNUMXつです。 がある NCache。ランタイム、 NCache。ウェブ 次に、名前空間を使用する必要があります。これも次の場合は XNUMX つです。 NCache. NCache。ランタイム、 NCache.Web.キャッシング。 そして、アプリケーションの先頭、コンソールの場合はすぐそこにあります。 ASP.NET アプリケーションの場合、これはおそらく global.asax です。 キャッシュに接続する必要があります。キャッシュにどのような名前を付けても、ここでキャッシュ名が使用されます。 それがここに入ってくるんです。 そして、キャッシュ ハンドルを取得したので、アプリケーションを続行し、オブジェクトを作成して、次のことを行うことができます。 キャッシュ.追加。 文字列ベースのキーを指定しますが、キーは一意である必要があります。 ちなみに、これは良いキーではありません。 キーはより具体的である必要があり、これが目的です。 つまり、これが方法であり、後で行うことができます キャッシュ.取得 キャッシュからオブジェクトを取得できます。

さて、あなたが行ったこの呼び出しは、実際には次のような結果になりました。 NCache、それで、あなたがしたとき キャッシュ.追加、基本的には、ここから、データが入るはずのパーティションに移動しました。 そこで、そこにキャッシュを追加し、このパーティションがそのデータをレプリカに複製しました。 それが非同期アプリケーションの場合、このパーティションのみが更新され、制御が戻ります。 非同期呼び出しを行った場合は、このパーティションも、パーティションが更新されるまで待つこともありません。 でも、それだけで キャッシュ.追加 呼び出しの結果、このすべての作業が完了しました。

キャッシングトポロジ

そして、同様に、次のことを行うと、 キャッシュ.取得 クライアントはデータのある場所に直接アクセスします。 したがって、その下の分布マップを使用してデータがどこにあるかを知り、直接どこに行ってそれを取得します。 たとえば、項目番号 3 が欲しい場合は、そこからすぐに取りに行くでしょう。

つまり、このコードは舞台裏で実際に起こっていることなのです。 データベースへ。 あなたは何ですか。 それはただのキャッシュです。 実際、それについても少しお話します。 つまり、データを自動的にシリアル化/逆シリアル化しましたか? はい、実際にはそれ以上です。 したがって、データがここからここに送信される前に、オブジェクトをシリアル化する必要があります。 の場合には NCache, NCache シリアル化された形式でキャッシュに保持します。 そして、cache.Get を実行すると、それが返され、クライアント自体で逆シリアル化されます。 そして、あなたがそれを手に入れるまでに、それはすべてシリアル化解除されています。 つまり、API は非常に簡単に見えますが、多くの作業が行われています。

アプリのデータキャッシュ機能

さて、アプリケーションデータのキャッシュですが、最大の懸念はデータが XNUMX か所に存在するということでしたよね。 そして、キャッシュがその懸念に対処しない場合、その利点は実際に制限されることになります。 では、キャッシュはこの懸念にどのように対処するのでしょうか?

絶対有効期限

ナンバーワンが呼ばれます 有効期限 そしてそこにあります 絶対有効期限 これは、このオブジェクトを今から 10 分後に期限切れにすることを意味します。 したがって、すべてのオブジェクトについて、そのオブジェクトをキャッシュに保持しておく期間が安全であるという観点から、経験に基づいた推測を立てます。 そして、その時間が終了すると、キャッシュはそのオブジェクトを自動的に削除します。

コードでどのように見えるかを示しましょう。 したがって、次の場合には、 NCache 同じキャッシュ.Add 呼び出しを見ると、XNUMX 番目の引数は、今から XNUMX 分後の値を持つ日付時刻引数です。

public static void Main(string[] args)
{
    try
    {
        //Initialize cache via 'initializeCache' using 'Cache Name'
        //to be initialized. 
        Cache cache = NCache.InitializeCache("demoCache");
        cache.Clear();

        //Another method to add item(s) to cache is via CacheItem  object
        Customer customer = new Customer();
        customer.Name = "David Johnes";
        customer.Age = 23;
        customer.Gender = "Male";
        customer.ContactNo = "12345-6789";
        customer.Address = "Silicon Valley, Santa Clara, California";

        DateTime calendar = new DateTime();
        calendar.AddMinutes(1);

        //Adding item with an absolute expiration of 1 minute
        cache.Add("Customer:DavidJohnes", customer, calendar, Cache.NoSlidingExpiration, CacheItemPriority.Normal);
        Customer cachedCustomer = (Customer) cache.Get("Customer:DavidJohnes");
        ...

つまり、基本的には、今から XNUMX 分後にこのオブジェクトを期限切れにするようキャッシュに指示していることになります。 XNUMX 分後にそのオブジェクトがキャッシュから削除されるので、それが必要かどうかは関係ありません。 なぜ? キャッシュに XNUMX 分以上保存しておくのは不安だからです。 そして、なぜ快適に感じませんか? なぜなら、データベース内で変更されると考えられるからです。 キャッシュに保存しておくと安全ではありません。

スライド式有効期限

と呼ばれる別の種類の有効期限があります スライド式の有効期限、まったく異なる目的を果たします。 これはキャッシュを最新の状態に保つためのものではなく、クリーンアップのためのものです。 したがって、たとえばセッションの場合、 NCache スライド有効期限を使用します。これは、基本的に、間隔を指定して、10 分、20 分、5 分と言います。 つまり、誰もそのオブジェクトに触れない限り、 NCache その項目をキャッシュから削除します。

つまり、スライド式有効期限は、名前は依然として有効期限ですが、まったく異なる目的を果たします。 これは、アプリケーション データのキャッシュを最新の状態に保つために必要な絶対有効期限です。 ほぼすべてのキャッシュには絶対有効期限があります。 含む Redis、誰でも持っています。

キャッシュをデータベースと同期する

ただし、絶対有効期限の問題は、推測にすぎないことです。 その推測が間違っていて、実際にデータベース内のデータが変更された場合はどうなるでしょうか。 それで何が起こるでしょうか? 仕組みを考え出さなければなりません。 それで、もしあなたにその能力があるなら、 キャッシュをデータベースと同期する ここで、この非常に特定のデータセットが何であれ、データベースを監視して変更を監視するようにキャッシュに指示できます。

NCacheたとえば、この ADO.NET SQL キャッシュ依存関係機能を使用します。 この機能を使用する場合、どこで使用するかを指定する場合は、その使用方法を説明します。 この機能を使用すると、 NCache データベースを監視し、データベースに通知を要求します。 NCache そのデータが変更されたとき。 たとえば、SQL 依存関係の例があるとします。 そこで、もう一度同じキャッシュを実行しています。ここに追加します。 そこで、同じようにcache.Addを行っています。 鍵を持っています。 ここでは、オブジェクトの代わりに、実際のオブジェクトとその他のいくつかのものを含む構造であるキャッシュ項目があります。 したがって、たとえば、product テーブル内の単一行の SQL ステートメントが含まれます。 製品を Northwind データベースにキャッシュしているので、この SQL ステートメントは、 NCache それからそれを使ってください。

private static void AddProductToCacheWithDependency(Product product)
    {
        // Any change to the resultset of the query will cause cache to invalidate the dependent data
        string queryText = String.Format("SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice FROM dbo.PRODUCTS WHERE PRODUCTID = {0}", product.Id);

        // Let's create SQL depdenency
        CacheDependency sqlServerDependency = new SqlCacheDependency(_connectionString, queryText);

        CacheItem cacheItem = new CacheItem(product);
        cacheItem.Dependency = sqlServerDependency;

        // Inserting Loaded product into cache with key: [item:1]
        string cacheKey = GenerateCacheKey(product);
        _cache.Add(cacheKey, cacheItem);
    }

そこで、 SQLCacheDependency クラスイン NCache これは独自のクラスですが、舞台裏で ADO.NET SQL キャッシュの依存関係にマップされます。 さて、この電話は実際に電話をかけているので、ここに電話する必要があります。 そして、その呼び出しはキャッシュ サーバーに届き、キャッシュ サーバーは SQL サーバー データベースに対して ADO.NET 呼び出しを行います。 そして、キャッシュ サーバーがデータベースのクライアントになります。 そして、データベースに、このデータセットが変更された場合は通知してくださいと伝えます。

分散キャッシュの導入 (NCache)

また、SQL サーバーには、Oracle のようなデータベース通知メカニズムがあります。 少なくともこれら XNUMX つのデータベースに対しては、この機能を使用できます。 また、SQL キャッシュの依存関係により、推測できない場合でも、データがデータベースと一貫性を保っていることを基本的に確認できます。

これに関して何か質問はありますか? これで、フレームワーク コンポーネントが完成しました。 それで、 NCache EF、EF6、そして EF Core までの EF Core 用のプラグインもあります。 EF Core が登場する前、EF には実際にはプラグイン可能なアーキテクチャがありませんでした。 そのため、カスタム ADO.NET プロバイダーを実装し、SQL クエリをキャッシュする必要がありました。

SQL Core は、より柔軟なアーキテクチャです。 したがって、L2 キャッシュを提供できるようになりました。 Hibernate は、長い間存在していました。 Hibernate は非常に長い間そのアーキテクチャを採用してきました。 NCache NHibernate と Java クライアントの Hibernate に L2 キャッシュを提供しました。 しかし、現在 EF Core にはそのアーキテクチャが採用されています。 したがって、EF Core の利点は、これらの呼び出しを行う必要がないことです。 もちろん、欠点は、機能の点で、使用するキャッシュのサブセットが非常に小さいことです。 なぜなら、他のすべてのこと、たとえば SQL 依存関係の部分は、 NCache が提供しており、構成ファイルを介して構成できますが、これから説明する他の多くの機能も使用する必要があり、プラグイン可能なアーキテクチャを通過するだけの場合は、最小公倍数のアプローチを使用する必要があります。 そのため、API は、何を使用するとしても、多くの高度な機能を使用することはできませんが、現在ではすべてのキャッシュがこれらの機能を提供しています。 したがって、誰に対しても柔軟である必要があります。 一方、たとえば Java 側でメリットを享受したい場合は、ほぼすべてのキャッシュに、ここで説明したすべての機能が備わっています。 .NET 側では、それ以外のものはほとんどありません。 NCache。 だから、それは実際にはそうではありません NCache問題は、ご存知のとおり、これらのベスト プラクティスの使用に関して、.NET が Java コミュニティほど進んでいない、または成熟していないという事実です。 ということで、どんどん増えてきています。 今という事実 .NET Core これほど大きな変化を経験したことは、状況がどのように改善されるかを示す非常に良い兆候です。

ただし、現時点では、キャッシュをデータベースと同期させたい場合は、有効期限が切れるだけでは十分ではありません。 有効期限を超えなければなりません。 キャッシュをデータベースと同期する必要があります。 また、データベースが通知をサポートしていない場合は、ポーリング アプローチを検討することができます。 NCache を実装しました。

XNUMX 番目のアプローチは、CLR ストアド プロシージャを使用してデータベースからキャッシュにデータを直接追加する方法です。 つまり、パラダイム全体を逆転させているようなものです。 現在、データベースはキャッシュをフィードしています。 たとえば、次のようなトリガーがあるとします。スピードアップします。そうしないと、すべてのトピックを完了できなくなります。 したがって、これは非常に重要な機能であり、これなしではメリットを得ることができず、非リレーショナル データ ソースに対してキャッシュを同期することもできます。 たとえば、次の場合 NCache 呼び出しを行うことができるコードであるカスタム依存関係機能があります。 データ ソースがクラウドであり、実際にデータが何であるかを知るために毎回呼び出される Web メソッドだとします。 その後、どれも機能せず、このカスタム依存関係が機能します。 したがって、カスタム依存関係はキャッシュ上に存在し、データ ソースをチェックするためにキャッシュによって呼び出されるコードです。

したがって、この目標を達成すると、より多くのデータをキャッシュできるようになり、大きなメリットが得られます。 DB 依存関係、現在メインフレームで作業しているため、SQL 依存関係または Oracle 依存関係は機能しません。 では、ポーリングの頻度はどれくらいであるべきかというと、私は XNUMX 分間に数百万レコードのトランザクションが発生する運用データを扱っているからです。 それで、どのくらいの頻度で。 では、どのくらいの頻度でポーリングを行うかなど、どうやって知ることができるのでしょうか? ポーリングは構成可能な間隔であり、呼び出されるのはコードです。 したがって、各投票でどのくらいの量のデータを調べるかを決定します。 なぜなら、カスタム依存関係の場合、実際に特定のキーと照合して、そのキーがレガシー メインフレームで更新されたかどうかを確認することになるからです。 つまり、「このキーを確認してください、このキーを確認してください」という場合は、基本的にキーごとに行われます。 カスタム依存関係の場合。 DB 依存関係の場合、それは XNUMX つのキーではなく、データセット全体であり、別の機能があります。 NCache データアップデーターと呼ばれます。 キャッシュ ローダーと、コードが存在する別のサービスであるキャッシュ アップデータがあります。 つまり、キャッシュローダーと呼ばれる機能があります NCacheここでは実際にはすべての機能について言及しませんでしたが、キャッシュ ローダーと呼ばれる機能があります。これは、キャッシュを開始するときにキャッシュをロードしたり、データ ソースからキャッシュをプリロードしたりできるコードです。 つまり、メインフレームでもそうなる可能性があります。 ただし、設定可能な間隔ごとにコードを自動的に呼び出すキャッシュ アップデーターと呼ばれる機能もあり、そのコードはデータ ソース全体をチェックし、カスタム ロジックや変更されたデータ、または新しいデータに基づいて更新を探すことができます。発生したデータや削除されたデータは、キャッシュを更新することもできます。 したがって、キャッシュはデータ ソースと同期したままになります。 デフォルトでは、これらは約 15 秒間隔で呼び出されます。 ただし、より高速な場合もあります。 ニーズに応じて、頻度を増やすことも、減らすこともできます。 私はあなたの質問に答えましたか? 他にもありますが、それは省略します。 それについては後で話しましょう。

リードスルーとライトスルー

したがって、その目標を達成すると、より多くのデータをキャッシュし始めることになります。 次に、他にどのようなメリットが得られるでしょうか? 次に重要なことは、 リードスルー、ライトスルー。 既読スルーとは何ですか? キャッシュ サーバー上に存在するのはやはりコードです。 したがって、cache.Get を実行するとき、つまり、次の場合、リードスルーがコードであるとします。 NCache このインターフェイスを実装すると、 IReadThruProvider。 それにはXNUMXつの方法があります。

...
// Perform tasks like allocating resources or acquiring connections
public void Init(IDictionary parameters, string cacheId)
{
    object connString = parameters["connstring"];
    sqlDatasource = new SqlDatasource();
    sqlDatasource.Connect(connString == null ? "" : connString.ToString());
}

// Perform tasks associated with freeing, releasing, or resetting resources.
public void Dispose()
{
    sqlDatasource.DisConnect();
}

// Responsible for loading an object from the external data source.
public ProviderCacheItem LoadFromSource (string key)
{
    ProviderCacheItem cacheItem = new ProviderCacheItem(sqlDatasource.LoadCustomer(key));
    cacheItem.ResyncOptions.ResyncOnExpiration = true;
    // Resync provider name will be picked from default provider.
    return cacheItem;
}
...

キャッシュの開始時に呼び出され、キャッシュの停止時に破棄される Init がありますが、最も重要なのはこのロードです。 それで、負荷が通過するといいます。 したがって、キャッシュはこのメソッドを呼び出します。 NCache このメソッドを呼び出してキーを渡します。 そして、そのキーに基づいてデータベースにアクセスし、その項目を取得します。 したがって、これを実行すると、クライアント、つまりアプリケーションは、実行するたびに最終的な影響を受けます。 キャッシュ.取得、キャッシュには常にデータが含まれています。 もちろん、リードスルーを呼び出したくない場合は、そうすることもできます。詳細を指定することもできます。 ただし、キャッシュには常にデータが含まれています。 つまり、それが利点の XNUMX つです。 つまり、永続化レイヤーをキャッシュ層に統合することになります。 したがって、同じキャッシュ層を使用する複数のアプリケーションがある場合、同じ永続化コードを保持する必要がなくなるため、アプリケーションはよりシンプルになります。 彼らはただ、 キャッシュ.取得 そして、キャッシュからドメイン オブジェクトまたはエンティティ オブジェクトを取得します。 したがって、キャッシュは EF にかなり似てきました。 リードスルー自体は EF ベースにすることができます。

リードスルーで実行できるもう XNUMX つのことは、これを有効期限やデータベースの同期と組み合わせることができることです。 では、これら XNUMX つのことが起こった場合、そのデータをキャッシュから削除するのではなく、リロードしないのはなぜでしょうか? なぜなら、削除すると、アプリケーションは次にそれを必要とするときに、とにかくそれを再ロードする必要があるからです。 そして、多くの場合、そのデータは非常に頻繁に使用される可能性があります。 したがって、実際にはそれをキャッシュに再ロードする必要があります。 したがって、リードスルーによりコードが統合されるだけでなく、データベースがアクセスされなくなるためパフォーマンスも向上します。 電子商取引の多くの状況では、同じデータが頻繁にアクセスされる可能性があるため、キャッシュからデータを削除するとすぐに、同じデータに対して何千ものリクエストがデータベースにヒットすることになり、お客様がそのことについて不満を抱いているのを見てきました。 何百万ものデータ項目があり、各データ項目の有効期限が切れるとデータベースがヒットするため、この問題は頻繁に発生し続けます。 そのため、キャッシュを取得した後でも、全体的にはデータベースに多くのヒットが見られました。 したがって、それに対する答えは、期限切れではなくリロードでした。 したがって、リロードとは、データがキャッシュから離れることはなく、更新されるだけであることを意味します。 したがって、キャッシュによる XNUMX 回のデータベース呼び出しを除いて、データベースは決して操作されません。 そういった意味でも既読は非常に重要です。

もう XNUMX つはライトスルーで、書き込みを行う点を除いてリードスルーと同じように機能します。 また、書き込みは、追加、更新、または削除のいずれかを行うことができることを意味します。 さて、書き込みには別の機能があります。 ライトスルーの利点の XNUMX つはリードスルーと同じで、コードが統合されることです。

後書き

XNUMX 番目の利点はライトビハインドと呼ばれます。 データベースの更新は、データベースの読み取りと同様に高速ではありません。 データベースの更新も高速ではありません。 したがって、データの機密性がそれほど高くなく、データベースが更新されるまで待つ必要がない場合は、キャッシュを更新するだけで済みます。 そのため、すべてのアプリケーション インスタンスが同じデータを持つようになり、キャッシュによって非同期方式でデータがデータベースに更新されます。 また、キャッシュが更新されるのを待たなくなるため、アプリケーションのパフォーマンスが突然向上します。 したがって、後書きにはこの追加の利点があります。 したがって、キューが構築されます。 の場合には NCache このキューは複数のサーバーにレプリケートされますが、やはりリードスルー ライトスルーは非常に重要な機能です。 そして、これはキャッシュ サーバー上に存在するコードでもあります。

このキャッシュ ローダー、アップデーター、カスタム依存関係、リードスルー、ライトスルーなど、すべてその上に存在するサーバー コードであることを念頭に置いてください。 これは、…やはりこれらの機能は Java 側にも存在します。 ですから、それだけではありません NCache 発明されましたが、他の .NET 基本キャッシュではこれらの機能を利用できません。

したがって、開始し、すべてを準備し、これを実行したら、大量のデータをキャッシュに入れることになります。 本当に恩恵を受け始めています。 そして、キャッシュがキー値アクセスのみである場合、それはあまりフレンドリーではありません。 したがって、キャッシュはデータを取得するための使いやすい方法に対応する必要があります。

データのグループ化

したがって、次の場合には、 NCache できるデータはたくさんあります グループとサブグループ、タグ、ネームタグ。 SQL または LINQ に基づいて検索することもできます。 したがって、次のようなことができます。CUSTOMER.CITY = NEW YORK の顧客を選択してください'。 そして、突然、多くのデータセット、特によりフィルタリングされた方法で何度も読み取る必要がある参照データを、キャッシュから直接フェッチできるようになりました。 そして、今、あなたはやりたいデータを手に入れることができます。

留意すべき点は、SQL 検索を実行するときは常に、データ セット全体がキャッシュ内に存在する必要があるということです。 なぜなら、これはデータベースに保存されないからです。 したがって、キャッシュのみを検索します。 たとえば、ニューヨークに拠点を置くすべての顧客を私にくれと言ったとしましょう。 すべての顧客がキャッシュにない場合、すべてのニューヨークの顧客がキャッシュにない場合、 NCache そうしないと、キャッシュによって正しいデータ セットが返されなくなります。 したがって、これは覚えておくべき重要なことですが、検索すると、キャッシュにない場合はデータベースから取得することになるため、人々はよく混乱するということです。 ただし、SQL クエリはデータベース SQL クエリではありません。 これらはキャッシュ独自のクエリです。

大量のデータが存在するため、データ セット全体、特に参照データをキャッシュに保持できるようになり、そこでこれらを使用できるようになります。 ただし、少なくともトランザクション データ内には、完全にキャッシュに保持できるサブセットがあります。 それで、そうして待つのです。 以上のことを念頭に置くことで、キャッシュの恩恵を受けることができるようになります。

クライアントキャッシュ

もう XNUMX つ説明します。この機能は次のとおりです。 クライアントキャッシュ。 分散キャッシュを使い始めると人々が本当にショックを受けることの XNUMX つは、特に以前にスタンドアロンのインプロセス キャッシュを使用していた場合、パフォーマンスが実際に低下することです。 それで、多くのお客様が私たちに電話して、パフォーマンスが向上し、スケーラビリティが向上すると言っていたのに、実際にはパフォーマンスが低下したと言います。 その理由は、当初はスタンドアロンのキャッシュしかなかったからです。 サイズは制限されていましたが、キャッシュはオブジェクト形式であり、オブジェクトはヒープ上に保持されていましたが、今度はキャッシュ クラスターに移動する必要があり、シリアル化、逆シリアル化があり、ネットワーク トリップがあり、はるかに遅くなります。

クライアントキャッシュ

したがって、その問題を解決するために、多くのキャッシュ、つまりすべての Java 側キャッシュ、.NET 側キャッシュに多くのキャッシュがあるため、ここでも「多く」という言葉を使用します。 NCache それはあります。 クライアントキャッシュと呼ばれるこの機能があります。 Java 側ではニアキャッシュと呼ばれます。 これは以前に持っていたのと同じスタンドアロン キャッシュであり、同じ意味は似ていますが、現在はこのクラスター化されたキャッシュの一部であるという事実が認識されています。 したがって、保持しているデータが何であれ、キャッシュ クラスターとの同期が維持されます。 したがって、プログラミングを行わなくても接続するだけです。

したがって、クライアント キャッシュを使用すると、インプロセス スタンドアロン キャッシュのパフォーマンスを実現でき、書き込みよりも読み取りの方が多い多くのデータに対して非常に優れています。 これをセッションなどには使用したくないでしょう。 なぜなら、セッションでは読み取りと書き込みが XNUMX 回ずつ行われるからです。 したがって、メリットを得るには、書き込みよりも読み取りをはるかに多く行う必要があります。

動的キャッシュクラスター

したがって、アーキテクチャ的には、キャッシュがデータベースのようなものであることを理解する必要があります。 これはデータセンターや運用環境に存在し、アプリケーションに高可用性が必要な場合、キャッシュも高可用性である必要があります。そうでない場合は、問題が発生します。 そして、それを実現する唯一の方法は、キャッシュによって 100% の稼働時間が保証される場合です。 したがって、次のような場合に備えて、適切なキャッシュが必要です NCache それは持って 動的キャッシュクラスター。 それはピアツーピアアーキテクチャです。 任意のサーバーを追加または削除しても、すべて問題なく、何も停止しません。 キャッシュもアプリケーションも停止しません。

動的キャッシュクラスター

レプリケーションによる線形スケーラビリティ

そこで、パーティションについて話しました。 トポロジ すでに。 レプリケーションはインテリジェントに実行する必要があります。 したがって、パーティションレプリカの場合、コピーは XNUMX つだけ作成されます。 したがって、コピーを作成するたびに時間や労力がかかるため、データは XNUMX か所にのみ存在し、それを超えてはなりません。 が鈍くなるにもほどがあります。

キャッシングトポロジ

分散キャッシュの WAN レプリケーション

という機能もあります WANレプリケーション。 現在、多くの人が複数のデータセンターを持っています。 データベースが複数のデータセンターを処理できることが期待される場合、なぜキャッシュを使用しないのでしょうか? これはほとんどの Java キャッシュに備わっている機能です。 NCache にもありますが、.NET側のみです。

分散キャッシュの WAN レプリケーション

NCache 対 Redis

最後にもう XNUMX つだけ簡単に説明します。.NET 側には、実際には XNUMX つのオプションしかありません。 XNUMXつは NCache、XNUMXつは Redis. Redis 実際には Linux ベースのキャッシュに基づいていますが、Microsoft が Azure で提携して以来、確かに、はるかに人気が高まっています。 そこで、公平な比較をしたいと思いました。

ちなみに、私たちのウェブサイトにアクセスすると、 比較ページ そしてに行く 機能ごとの詳細な比較 彼らのドキュメントと私たちのドキュメントに基づいて、すべてを参照してください。 そして、これは、ご存知のとおり、私たちはこれをまったく吐き出しているわけではありません。それについてはあなた自身が適切に判断してください。 仕事の準備を容易にするためです。

ただし、どちらもオープンソースですが、 NCache .NET の人にとってはネイティブ .NET です。スタック全体が .NET です。 NCache サーバー側で実行できない .NET コードを使用できるようになります。 Redis。 そして、ご存知のとおり、Azure を使用している場合は、 Redis はサービスとしてのキャッシュとしてのみ利用可能ですが、私たちは意図的にそのモデルを選択しませんでした。 サービスとしてのキャッシュでは、キャッシュはブラックボックスであるためです。 つまり、先ほど説明したサーバー側の機能はまったくありません。 VM モデルを使用すると、完全に制御できます。

Redis 対 NCache - .NETアプリケーションの機能レベルの比較

私たちの顧客のほとんどは、自らのコントロールを手放したくないハイエンド企業です。 これは SQL データベースと SQL サーバーのようなものです。 それで、 NCacheご存知のとおり、環境全体を制御することになります。これはご覧のとおり、非常に簡単です。 ただし、これらのサーバー側の機能はすべて次のコマンドで取得できます。 NCache、それはできません。 Redis アクセス権がないからです。

Redis 対 NCache - クラウドサポート

したがって、やはり自分で決めてください。ただし、少なくともアーキテクチャでは分散キャッシュを使用してください。 スケーリングの準備ができていることを確認してください。 それが全体の目標です。 どうもありがとうございます。

次はどうする?

 

最新のアップデートを入手するには、月刊の電子メールニュースレターにサインアップしてください。

お問い合わせ(英語)

電話
©著作権 Alachisoft 2002 - . All rights reserved. NCache はダイヤテック株式会社の登録商標です。