DEV交差点 2016

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

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

.NETアプリケーションでは、トランザクションの負荷が増大するため、データベースまたはストレージのボトルネックが発生する可能性があります。 ボトルネックを取り除き、分散キャッシングを使用して.NETアプリケーションをスケーリングする方法を学びます。 この講演の内容は次のとおりです。

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

概要

みなさん、こんにちは。 私の名前はイクバル・カーンです。 私はテクノロジーエバンジェリストです。 Alachisoft。 当社はサンフランシスコ ベイエリアに拠点を置くソフトウェア会社です。 NCache は分散キャッシュである当社の主力製品であり、これが今日の私のトピックです。 私の話題はそれについてではありません NCache 今日はそのキャッシュ全般について説明します。 NosDB これは私たちが所有する別の製品であり、オープンソースです NoSQL database .NET用。 Azure を使用して分散キャッシュをデモンストレーションし、実際にどのように使用されるかを見ていきます。

したがって、今日のトピックは、分散キャッシュ用の .NET アプリケーションのスケーリングです。 もっとインタラクティブな議論をしたいと思っています。 それでは、私が話している間に、質問がある方は手を挙げてください。 したがって、最後まで待つのではなく、その時点ですぐにそれについて話すことができます。 そうすることで、より有意義な会話ができるようになると思います。

それでは、始めましょう。 わかった! そこで、いくつかの定義を見ていきます。 すでにご存知の方も多いと思いますが、これは完了を目的としています。

スケーラビリティ

最初の定義はスケーラビリティです。 スケーラビリティとは、ピーク負荷時のアプリケーションの高いパフォーマンスです。 したがって、たとえば 5,000 人のユーザーがいる、ASP.NET アプリケーションや超高速に実行する .NET アプリケーションがある場合、必ずしもスケーラブルであるとは限りません。 もちろん、50,000 人のユーザーで高速に動作しない場合は、これ以外の問題が発生します。 しかし、ほとんどのアプリケーションはユーザーが 500,000 人であれば超高速に動作しますが、ユーザーが XNUMX、XNUMX、XNUMX 人になると、実際に問題が発生し始めます。 したがって、アプリケーションをスケーラブルにするには、ピーク負荷下でもアプリケーションを実行する必要があります。

線形スケーラビリティ

線形スケーラビリティとは、アプリケーション アーキテクチャや展開戦略が、サーバーを追加することで、線形スケーラブルよりも多くのトランザクションを処理する能力が増加するような方法で行われることを意味します。

線形スケーラビリティ

つまり、1500 台のサーバーがあり、さらに XNUMX 台のサーバーで XNUMX 人のユーザーを追加すると、XNUMX 人程度のユーザー数になるはずです。

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

ただし、アプリケーションのアーキテクチャやデプロイメントが直線的にスケーラブルではない場合、それは上下する対数曲線のようになります。これは、ある時点を過ぎると、サーバーを追加してもあまり問題にならないことを意味します。

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

が鈍くなるにもほどがあります。 これ以上のトランザクションがあると、そこから抜け出すことができなくなります。 その問題から身を守ることはできません。 したがって、スケーラビリティだけでなく、線形スケーラビリティも必要になります。

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

次のアプリケーションでは、この種の問題がよく発生します。 これらは ASP.NET Web アプリケーション、これらは Web サービス、これらは通常 Web サービスでもあるインターネット IOT バックエンドです。.NET では通常あまり一般的ではないビッグ データ処理があるかもしれませんが、ビッグ データ処理もまた何かですスケーリングが必要なサーバー アプリケーションやその他のサーバー アプリケーション。 あなたは、一定数の取引を処理するためのコンプライアンス要件がある金融機関である可能性があります。

したがって、サーバー アプリケーションには、たとえば銀行振込アプリケーションの場合、翌営業日または特定の時間までに資金を送金する必要があるというコンプライアンス要件がある場合があります。 したがって、より多くのトランザクションを処理できるようにする必要があります。 したがって、これらのアプリケーションのいずれかを持っている場合は、正しい話に到達したことになります。

スケーラビリティの問題

そこで、スケーラビリティの問題を定義しましょう。 現在、ASP.NET または Web サービス アプリケーションを使用しているアプリケーション アーキテクチャでは、アプリケーション層のスケールのアーキテクチャが直線的に変化していることをほとんどの人が知っています。 したがって、通常は問題なくサーバーを追加できます。 問題は実際にはデータ ストレージにあり、私がデータ ストレージという言葉を使用するときは、リレーショナル データベースとメインフレームを意味します。 レガシーデータがあります。 従来使用していたデータ ストアがボトルネックになり、それがボトルネックになると、この問題が発生します。 の NoSQL databases、私はそれらが常に答えであるとは限らないと言うはずでした。 しかし NoSQL この運動が一部の理由で始まりました。 リレーショナル データベースは拡張性がなかったため、 NoSQL databaseはスケーラブルですが、すべてのデータを既存のデータベースから別のデータベースに移動する必要があるため、あらゆる状況に適しているわけではありません。 NoSQL database 多くの新しいデータに対してはこれを行うことができますが、従来のビジネス データ、顧客、アカウントなどのすべてのデータは、ビジネス目的と技術的な理由の両方でリレーショナルな状態を維持する必要があります。 もちろん技術的な理由は、リレーショナル データベースには他のどのデータベースにも匹敵しないエコシステムがあるためです。 NoSQL database もちろんビジネス上の理由も同じ性質のものです。

だから、 NoSQL database 必ずしも答えがあるわけではありません。 NoSQL database 私たちが販売している製品はと呼ばれます NosDB、リレーショナル データベースの拡張としてのみ使用されます。 したがって、リレーショナル データベースから抜け出すことはできません。 リレーショナル データベースは今後も存続します。 したがって、その現実を受け入れて生きなければなりません。 したがって、依然として問題となっているリレーショナル データベースでのスケーラビリティを解決する必要があります。

スケーラビリティソリューション

もちろん、解決策はインメモリ分散キャッシュを使用することです。 NCache もそのような解決策の 10 つです。 オープンソースの分散キャッシュです。 当社は市場で最も古い .NET 分散キャッシュです。 私たちは過去 11 年間、実際には XNUMX 年間活動してきました。 そして、真にネイティブな .NET キャッシュは私たちだけです。

ほとんどの人が聞いたことがあるでしょう Redis、 右? つまり、2年以上前には聞いたこともありませんでした Redis 彼らは本当にそこに焦点を当てていなかったからだ。 Microsoft が Azure に関して提携するまでは至りませんでした。

分散キャッシュの展開

インメモリ分散キャッシュの利点は、既存のデータベースで使用できることです。 したがって、リレーショナル データベースがメモリ内の分散キャッシュを通じて提供している問題を解決できます。 では、その問題をどのように解決しますか? この問題を解決するには、次の図を見てみましょう。

分散キャッシュの展開
分散キャッシュアーキテクチャ

したがって、Web アプリケーション、Web サービス、その他のサーバー アプリケーションであるアプリケーション層があり、ここにさらにサーバーを追加できます。 Web アプリケーションと Web サービスの場合、通常はロード バランサーが存在しますが、ここでは描きませんでした。 したがって、この層にさらにサーバーを追加できます。 データベース層にサーバーを追加することはできません。 はい! さらにサーバーを追加できます。 NoSQL しかし、先ほども言ったように、それが常に答えであるとは限りません。 したがって、これら XNUMX つのボックスを解決する必要があります。 そこで、アプリケーション層とデータベースの間にインメモリ分散キャッシュを配置します。

分散キャッシュは通常、クラスターを形成します。 したがって、すべての分散キャッシュがクラスターを形成するわけではありません。 Memcached 分散キャッシュであってもクラスタリングを形成しませんでした。 Redis クラスターを形成しているのですが、 NCache 間違いなくクラスターを形成しています。 ここで、分散キャッシュは XNUMX つ以上のサーバーのクラスターを形成します。 XNUMX つとした理由は、冗長性、レプリケーション、その他の多くの目的、そしてスケーラビリティの目的です。 キャッシュ サーバーが XNUMX つだけ必要な場合は、おそらく分散キャッシュは必要ありません。 したがって、ここでは少なくとも XNUMX つのキャッシュ サーバーが必要であり、このキャッシュ クラスターは実際にすべてのキャッシュ サーバーのメモリと CPU リソースを XNUMX つの論理容量にプールします。 つまり、サーバーを追加すると、メモリ、CPU 処理、ネットワーク カードの容量が増加します。 これらがスケーラビリティの XNUMX つのボトルネックです。 メモリ、CPU、ネットワークカード。 最近のネットワーク カードは、XNUMX ギガビットまたは XNUMX ギガビットがほぼ標準です。 オブジェクトのサイズが大きくない限り、XNUMX ギガビット カードまたは XNUMX ギガビットを最大化するのはかなり困難です。 ただし、オブジェクトのサイズが大きい場合 (大きいとはオブジェクトごとに数百キロバイトを意味します)、トラフィックが多いとネットワーク カードを限界まで使い切るのは非常に簡単です。 ただし、より多くのサーバーがあり、もちろんネットワーク カードも多くなり、メモリも同様になります。

インメモリ分散キャッシュである理由は、メモリがディスクよりもはるかに高速であり、それが真の価値をもたらすためです。 より高速で、よりスケーラブルです。 したがって、ここでの目標は、分散キャッシュに送られるアプリケーション アクセスの約 80% をキャプチャすることです。 したがって、データベースに保存されるのは 20% だけになります。

多くの人は当初、キャッシュをパフォーマンスの向上と考えていました。 はい! インメモリはこれよりも高速であるため、パフォーマンスが向上します。 しかし、より重要なのは、インフラストラクチャにこのようなものがなければ拡張できないため、拡張性が必要であるということです。 実際、ますます多くの企業が、アプリケーション環境にデータベースを導入するのと同じように、分散キャッシュを導入することをほぼ標準にしつつあります。 Java 側のインメモリ データ グリッドと呼ぶ人もいますが、これは用語です。 これをデータ ファブリックの一種と呼ぶ人もいますが、分散キャッシュは .NET エコシステムの最も一般的な名前です。 つまり、これはインフラです。 一度導入すれば、非常に強力なツールとして使用できます。 アプリケーション サーバーとキャッシュ層の比率は、トランザクションに関してかなり負荷の高いサーバーであると仮定すると、通常は約 4:1、5:1 です。 これらの性質によっては、5:1 を超える場合もあります。 また、一般的なキャッシュ サーバーは、メモリが約 16 ギガから 32 ギガで、デュアル CPU クアッド コア タイプの構成です。 したがって、それほど高級なボックスではありません。 実際、この層には非常にハイエンドのボックスは必要ありません。 いくつかの非常に高級なボックスよりも多くのボックスが必要です。 メモリを追加すると、最大 128 ギガまたは 256 ギガ メモリに増やすことができますが、メモリを増やすには、より強力な CPU が必要になります。 何故ですか? なぜなら、メモリが多いほどヒープが大きくなり、ガベージ コレクションのタスクがさらに大きくなり、ガベージ コレクションは .NET では最速の処理ではなく、CPU を消費してしまうからです。 つまり、あなたはますますデータベースのように見えます。 したがって、キャッシュ サーバーあたり 16 ~ 32 ギガがかなり良いスイート スポットであることが望ましいでしょう。 今まで何か質問はありますか?

NCache スケーラビリティの数値

スケーラビリティの数値は次のとおりです。 NCache。 キャッシュが異なれば数値も異なりますが、目標はこれをスケーラブルにすることです。 したがって、読み取りはこの方法でスケーリングされ、書き込みはこれをスケーリングします。 読み取りではレプリケーションが発生するため、読み取りは書き込みよりも遅くなります。 それらの機能について説明します。

NCache スケーラビリティの数値

レプリケーションが必要な理由は、メモリが揮発性であるためです。 したがって、いずれかのサーバーがダウンすると、そのデータが失われます。 したがって、多くの場合、そのデータを失いたくないでしょう。

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

これまでの話の目的は、なぜ分散キャッシュが必要なのかを示すことでした。 そして、そのケースが確立したので、分散キャッシュを何に使用するかについて話しましょう。

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

最も一般的な使用例は、私が話したアプリケーション データのキャッシュです。 データベースに存在するデータをここにキャッシュします。 したがって、できる限り多くのデータをキャッシュすると、パフォーマンスとスケーラビリティが向上します。

アプリケーション データ キャッシュの使用例で注目すべき主な点は、データが XNUMX つの場所に存在するということです。 XNUMX つはデータベースに、もう XNUMX つはキャッシュにあります。 それが起こるたびに、XNUMX つの場所が存在した場合に何が問題になる可能性があるかという最初の懸念は何ですか? はい、一貫性があります!

したがって、優れた分散キャッシュがこれを処理することが非常に重要です。 なぜなら、キャッシュが両方の場所でデータの一貫性が必要であるという事実を処理できない場合、より多くの読み取り専用データをキャッシュする必要があるからです。 読み取り専用データはデータの約 10% ~ 15%、または 20% です。 データの大部分は、私がトランザクション データと呼んでいるものです。 これらはあなたの顧客であり、あなたのアカウントです。 それは変化しているデータです。 数秒ごとに変化する場合もありますが、ほとんどの場合は 30 分ごとに変化します。 したがって、たとえ XNUMX 分または XNUMX 秒間キャッシュできたとしても、それを複数回読み取ることでメリットが得られ、これに XNUMX 日に発生するトランザクションの総数を掛けると、トランザクションは数百万件になります。データベースに保存されなくなります。 したがって、アプリケーション データ キャッシュでは、優れた分散キャッシュがこの一貫性を処理する必要があることが非常に重要です。その一貫性を保つために非常に重要な機能について説明します。 したがって、アプリケーション データ キャッシュは永続的なデータをキャッシュします。 永続データとは、データベースに永続的に存在することを意味します。

ASP.NET固有のキャッシュ

XNUMX 番目の使用例は、ASP.NET アプリケーションがある場合、これはもちろん他の Web アプリケーションにも当てはまりますが、ここでは .NET に焦点を当てます。 MVC フレームワークを使用していない場合は、セッション状態やビュー状態をキャッシュしたり、出力 (ページ出力) をキャッシュしたりできます。 これらのデータはすべて、本質的に一時的なものです。 それは永続的なものではありません。 永続的でないデータは実際にはデータベースに存在すべきではありません。 一時的なデータです。

データが一時的なもので、データベースに存在せず、キャッシュ内にのみ存在する場合、何が問題になる可能性があるかという最大の懸念は何でしょうか? 粘り強さ…あるいはそれが欠けている。 したがって、継続しないとデータが失われます。 このキャッシュ サーバーがダウンし、ショッピング バスケットか何かがあり、たとえば、あなたが航空会社で、顧客がこのフライト検索を行ったところ、少なくとも 10 ドル相当の 5,000 枚または XNUMX 枚のチケットを購入しようとしているとします。最後のページを送信したり、最後のページを送信したりすると、キャッシュサーバーがダウンしたために突然セッションが失われ、最初からやり直す必要があります。 アクティビティ全体が失われます。 その顧客を失う可能性があります。 あまり良い経験ではありません。

したがって、キャッシュする一時的なものはすべて、キャッシュを複製する必要があります。 レプリケーションを行わないキャッシュは、実行可能なキャッシュではありません。 また、レプリケーションにはコストがかかるため、キャッシュは効果的かつ効率的なレプリケーションを実行する必要があります。 ASP.NET ではセッションが非常に一般的であるため、セッション状態は分散キャッシュの非常に一般的な使用例です。

イベントを通じたランタイムデータ共有

XNUMX 番目の一般的な使用例、または実際にはあまり知られていない XNUMX 番目の使用例は、ランタイム データ共有と呼ばれます。 これは、共有する必要があるアプリケーションが複数ある場合に当てはまります。 あるアプリケーションは、別のアプリケーションまたはそのアプリケーションの別のインスタンスが使用する必要があるものを生成または更新します。 通常、これには伝統的にメッセージ キューを使用するか、そのデータをデータベースに置くだけで他のアプリケーションがプルします。 ただし、分散キャッシュはそのようなユースケースには非常に適しています。 メッセージキューを置き換えるためにあるわけではありません。 メッセージ キューには別の用途もありますが、アプリケーションが同じデータセンターで実行されており、すべてのインスタンスでデータを共有する必要がある場合、すべてのアプリケーションが同じプラットフォームに接続されているため、これはよりスケーラブルなデータまたはデータ共有プラットフォームになります。プラットフォームは Pub/Sub モデルでイベントを起動できます。 パブリッシュとは、XNUMX つのアプリケーションがパブリッシャーであり、何かをパブリッシュし、イベントを起動することを意味します。 そのすべての加入者に通知が送信され、そのデータが消費されます。

他の種類の通知もあります。 特定の項目が変更されると、アプリケーションは特定の項目に関心を示し、この項目が変更された場合は通知することができます。 あるいは、 継続的なクエリ その特徴 NCache のようなものがあります SQLの依存関係 SQL サーバーの機能。ここで、 NCache 次のような SQL タイプのクエリを言うことができます。 SELECTS Customers WHERE Customers.City = "ニューヨーク"。 したがって、この基準を満たす顧客がキャッシュに追加、更新、またはキャッシュから削除したことがある場合は、通知されます。

したがって、これはキャッシュへの変更を監視するはるかにインテリジェントな方法です。 したがって、これらすべてにより、実行時に非常に高速かつスケーラブルな方法でアプリケーション間でデータを共有できるようになります。 また、これも一時的なデータです。そのデータの多くはデータベースに存在しますが、共有している形式には存在しない可能性があります。 つまり、それは一過性のものなのです。 したがって、これも複製する必要があります。 これまでに何か質問はありますか? 皆さんがすでにこのことを完全に知っているか、私が非常に優れているかのどちらかです。

アプリデータキャッシュの概要

それでは、どのように使用する必要がある機能とその使用方法について、ソース コードをいくつか見てみましょう。 使うつもりです NCache 例として挙げましたが、前述したように、私の焦点は実際の機能にあります。

ここでは、キャッシュを使用する一般的な方法を示します。

Customer Load(string customerId)
{
    // Key format: Customer:PK:1000
    string key = "Customers:CustomerID:" + customerId;
    
    Customer cust = (Customer) _cache[key];
    
    if (cust == null)
    {
        // Item not in cache so load from db
        LoadCustomerFromDb(cust);
        // Add item to cache for future reference
        _cache. Insert(key, cust);
    }
    return cust;
}

データベースから顧客をロードします。 データベースにアクセスする前に、キャッシュを確認し、文字列ベースのキーを使用します。 言ってみましょう 顧客:顧客ID そして、実際の顧客 ID は 1000 か何かである可能性があり、キャッシュを確認すると言います。 キャッシュにそれがあれば、データベースにアクセスする必要はありません。 キャッシュにない場合は、データベースにアクセスしてその顧客をロードし、キャッシュに入れます。 それをキャッシュに入れると、次にあなたまたは他の人が来たときに、キャッシュ内でそれを見つけることができます。 これは非常に単純なパラダイムです。 これを実行すると、誰もがキャッシュよりも価値のあるものを見つけることができます。

もちろん、必要になったほうが良いと思われる大量のデータをキャッシュに事前に設定できる機能は他にもたくさんあります。 そのため、データベース ヒットの多くを事前に保存し、その後もキャッシュ内に見つからないデータを段階的にキャッシュに追加し続けます。 たとえば、これはビジュアル スタジオ プロジェクトです。 もし使うとしたら NCache これらのアセンブリのうち XNUMX つをリンクします。 XNUMXつは NCache。ランタイム そしてXNUMXつは NCache。ウェブ。 ここで XNUMX つの名前空間を同様に使用します NCache。ランタイム & NCache.Web.キャッシング。 名前空間には、ASP.NET キャッシュにかなり近い名前を付けました。 それで、ご存知のとおり、いつ NCache 利用可能なキャッシュは ASP.NET キャッシュだけでした。 これができました。アプリケーションの開始時点では、これはもちろんコンソール アプリケーションであり、あなたのものは異なるものになります。 キャッシュに接続すると、キャッシュ ハンドルが取得されます。 すべてのキャッシュには名前が付けられ、キャッシュ ハンドルを取得してから、オブジェクトをキャッシュに追加します。 それで、今追加したとしましょう。 キャッシュ.追加 ここ。 キーを指定します。 ただし、これはおそらく David Jones ではなく、ある種の顧客 ID である必要があり、実際のオブジェクトがあり、有効期限が指定されています。 また、絶対有効期限を XNUMX 分に指定します。 XNUMX分後にこのアイテムがキャッシュから期限切れになると言っています。 それ以外はすべてデフォルトのままにします。 そして、後でできることは、 キャッシュ.取得 そして同じ顧客を別の場所から獲得します。 したがって、単純なキャッシュ操作だけです。

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、すべてのキャッシュに名前が付けられます。 ここで、キャッシュがどのようなものかを簡単に説明してから、コードに戻ります。 Azure に多数の VM をセットアップしました。 それで、あなたは走ることができます NCache Azure、Amazon、オンプレミス。 いずれの場合も、キャッシュ サーバー自体は単なる VM です。 これは Windows 2008、2012 VM のみです。 Azure のキャッシュ クライアントは、VM、Web ロール、ワーカー ロール、Web サイトのいずれかになります。

デモキャッシュAzure

クラスター化キャッシュの作成

ここでデモクライアントにログインしました。 早速キャッシュを作成してみます。 したがって、キャッシュがどのように見えるかを示すことができます。 と呼ばれるこのツールを使用します。 NCache マネージャー、グラフィカル ツールを使用して、次のことを行うことができます。ここでは、「新しいクラスター化キャッシュ」を作成すると言います。

クラスター化キャッシュの作成

すべてのキャッシュ NCache と名付けられています。 したがって、キャッシュに名前を付けることにします。 現時点では、その他すべてをデフォルトとして使用します。

キャッシュ名の指定

パーティション化されたレプリカのトポロジを選択します。 この話の最後にそれについて簡単に説明します。 パーティション化されたレプリカ 私のトポロジーです。

キャッシングトポロジ

非同期レプリケーションを使用します。

レプリケーション戦略

最初のキャッシュ サーバーとして、demo2 を選択します。 つまり、これらは私のキャッシュ ノード XNUMX つです。

キャッシュノードの追加

「次へ」をクリックします。 すべてデフォルトのままにします。 このキャッシュに割り当てるメモリの量を指定します。 したがって、この方法では、キャッシュがこれ以上のメモリを消費することはありません。 私はまだ XNUMX つのギグを行ったばかりですが、もちろんあなたのギグはもっと大きくなるでしょう。 それがパーティションのサイズです。

メモリー容量

したがって、キャッシュが大量のメモリを使用すると、キャッシュはいっぱいになります。 したがって、新しいアイテムを拒否するか、既存のアイテムの一部を削除することになります。 したがって、このキャッシュの 5% を削除し、最も最近使用したアルゴリズムが使用するアルゴリズムであり、キャッシュを作成したところだと言います。

先に進み、これにクライアントを追加します。

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

キャッシュを作成したので、キャッシュを開始します。

キャッシュを開始する

ストレスのシミュレーションとキャッシュ統計の監視

統計を選択するので、PerfMon 統計を使用できます。 クラスターの監視も行うつもりです。 ということで、キャッシュを開始しました。 このキャッシュはデモ キャッシュと呼ばれます。 早速テストしてみます。 そこで、付属のストレス テスト ツールを実行しました。 NCache また、独自の環境でキャッシュをすばやくテストできます。

ストレステストツール

したがって、このキャッシュは現在機能しています。 つまり、クライアント ボックス上で何が起こっているのかというと、クライアントとはアプリケーション サーバー ボックスを意味します。ここに構成ファイルがあります。 それで、キャッシュを作成したところ、キャッシュサーバーが何であるかを認識できるようになりました。 さて、コードに戻りましょう。 それで、実際にこのキャッシュ名を選択すると、実際に何が起こったかというと、アプリケーションがクラスター内のすべてのキャッシュ サーバーに接続し、キャッシュ ハンドルを与えてくれたので、 キャッシュ.追加、実際にはキャッシュ内の適切な場所に追加され、レプリケーションもすべて行われ、すべてが完了します。

したがって、API はその詳細をすべて隠していますが、そのキャッシュが舞台裏でどのように見えるか、そしてそのキャッシュがどれほど簡単に使用できるかを示したかったのです。 NCache その状況で。 それでは、本題に戻りましょう。 API は次のようになります。

  • キャッシュ接続
    ICache cache = CacheManager.GetCache(“myDistributedCache”);
    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");

あなたは cache.Get、cache.Contains、cache.Add、Insert、Remove。 挿入とは、存在しない場合は追加し、存在しない場合は更新することを意味します。

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

さて、キャッシュがどのようなものかを理解したところで、単純な API とは何なのかを理解しました。 先ほど説明した機能に移りましょう。 これらは分散キャッシュにとって重要です。

キャッシュを最新に保つ

したがって、私たちが最初に述べたことは、分散キャッシュはデータを最新の状態に保つ必要があり、キャッシュも最新の状態に保つ必要があるということです。 したがって、それを行うには XNUMX つの方法があります。 XNUMX番は 期限切れ、多くのキャッシュには、ほとんどすべてのキャッシュで期限切れにすることができます。

そこで、 絶対有効期限 そしてあります スライド式の有効期限。 絶対有効期限とは、先ほど示したものです。つまり、何が起こっても 24 分後にこのアイテムを期限切れにするというものです。 そして、私がこれを言う理由は、私が言ったように、このデータはデータベースに存在しており、データベース内で変更されないことを信頼できるのは XNUMX 分間だけだからです。 データベース内で変更される可能性があるため、それ以上キャッシュに保持したくありません。 つまり、データの性質について推測していることになります。 データによっては、何時間も何日もキャッシュできるものもあります。 ご存知のとおり、これはルックアップ テーブルかもしれません。 価格は XNUMX 日に XNUMX 回程度変更される可能性があります。 したがって、これを XNUMX 時間キャッシュできます。

その他のデータはトランザクション データです。 快適に感じる程度の時間なので、おそらく 30 秒または XNUMX 分間だけキャッシュしても構いません。 したがって、絶対有効期限は永続データに対するものであり、データをキャッシュ内に保持しておくのが安全な期間を推定または推測する XNUMX つの方法です。 それは非常に重要です。 絶対期限切れとスライディングの区別をつけたい。

スライド有効期限とは、基本的に、この期間、誰もそのアイテムに触れなくなったときに、このアイテムをキャッシュから削除することを意味します。 タッチするということは、取得または更新することを意味します。 たとえば、セッション状態です。 ログアウトすると、セッション状態は誰からも操作されなくなります。 したがって、20 分ほど経過したら、キャッシュから削除する必要があります。

通常、スライド有効期限は一時的なデータに使用されます。 それはむしろ浄化作戦です。 データを最新の状態に保つこととは何の関係もありません。 要らなくなったから処分するだけです。 ただし、絶対的な有効期限はデータを最新の状態に保つために必要です。 次に、有効期限は非常に重要です。 すべてのキャッシュにはそれが必要であり、ほとんどのキャッシュには、少なくとも絶対的な有効期限があり、実際にはすべてのキャッシュにあると思います。

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

XNUMX 番目の機能は、ほとんどの企業がやらないことです。 ここで、キャッシュをデータベースと同期します。

データベースの依存関係の使用

データベース内でこれがどのくらいの頻度でいつ更新されるのか、まったく予測できません。 データベース内のデータがいつ更新されるかわかりません。 なぜなら、複数のアプリケーションが更新されているからです。 他の人がデータに直接触れている可能性があります。 したがって、キャッシュでデータベースを監視したいだけです。 したがって、キャッシュはデータベース内のこの変更を認識する必要があります。 これは、 NCache もっている。 これは SQL 依存関係と呼ばれます。 実際には、SQL 依存関係と呼ばれる SQL サーバー機能を使用します。 NCache データベースのクライアントになります。

それがどのようなものかを早速お見せしましょう。 つまり、ここにキャッシュがあれば。 したがって、ここでもライブラリの場合と同じ方法で、キャッシュに接続します。 さて、ここでアイテムをキャッシュに追加します。 ここに来てこう言うとしたら、AddProductToCacheWithDependency' 定義に進みます。 つまり、このキャッシュに対して、これが私の SQL ステートメントであると言っていることになります。

private static void AddProductToCacheWithDependency (Product product)
{
// Any change to the resulset 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.ProductID);

//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);
}

private static string GenerateCacheKey (Product product)
{
string cacheKey = "Product#" + product.productID;
return cachekey;
}

したがって、SQL ステートメントは通常、テーブル内のその XNUMX 行を反映します。 したがって、製品を追加する場合は、製品 ID がこれに等しい SQL ステートメントである必要があります。 つまり、SQL Server 用にこの SQL ステートメントを作成していることになります。 これは、SQL 依存関係の一部として SQL Server に渡すものだからです。 あなたはそれをに渡します NCache。 したがって、クライアントボックス上のあなたはこれをに渡します NCache。 つまり、これを SQL ステートメントとして指定することになります。 「キャッシュ項目」オブジェクトを作成し、そのキャッシュ項目内で「SQLServer 依存関係」を指定します。 それで、 SQLCacheDependency のクラスです NCache、 実は。 これは SQL サーバーの依存関係とは異なります。 これは、SQL キャッシュの依存関係を除いて、ほぼ同じ名前です。 これにより、その SQL ステートメントが保持され、それを指定して項目をキャッシュに追加します。 それで、あなたはこれを完了し、今ここにあるこの箱の上に座っています。

分散キャッシュ

それで、あなたはこれを次の人に渡します NCache。 それはキャッシュ サーバーの XNUMX つに送られます。 このキャッシュ サーバーはデータベースのクライアントになります。 なぜなら、接続文字列情報も指定しているからです。 ここのどこかで、接続文字列を指定します。 それで、 NCache サーバーはデータベースのクライアントになります。 ここで、データベースは SQL サーバーである可能性があり、Oracle である可能性があります。 NCache SQL 依存関係接続を確立します。 SQL サーバーは、データ セットを監視するデータ構造を SQL サーバー内に作成します。

だから、ちょうどのように NCache 実行時のデータ共有について説明した継続的クエリ機能がありました。 NCache すべての顧客を監視していました。 都市=「ニューヨーク」。 現在、SQL サーバーは SQL サーバー内のこのデータセットを監視しており、その基準に一致する行が SQL データベースに追加、更新、または削除された場合、SQL サーバーはキャッシュ サーバーに通知します。 キャッシュ サーバーは、データベース内でこのデータが変更されたことを認識します。 したがって、XNUMX つのオプションがあります。 デフォルトの動作であるキャッシュからそれを削除することも、新しいコピーを再ロードすることもできます。

リードスルー/ライトスルーの使用

新しいコピーをリロードする方法は、次のとおりです。 NCache 呼ばれます 既読スルー。 これはスキップしますが、これに戻る必要があります。 つまり、コードにはリードスルーと呼ばれる機能があります。 リードスルー ハンドラーを実装します。リードスルー ハンドラーを示します。 それで、ここに、 IReadThroughProvided.

{
    // <summary>
    // Contains methods used to read an object by its key from the master data source.
    // </summary>

    public class SqlReadThruProvider : Alachisoft.Ncache.Runtime.DatasourceProviders. IReadThruProvider
    {
        private SqlDatasource sqlDatasource;
        // <summary>
        // Responsible for loading the object from the external data source.
        // Key is passed as parameter.
        // <param name="key">item identifier; probably a primary key</param>
        // <param name="exh">Current expiration hint; you can modify the value and attach a new hint</param>
        // <param name="evh">Current eviction hint; you can modify the value and attach a new hint</param>
        // <returns></returns

        public void LoadFromSource(string key, out ProviderCacheItem cacheItem)
        {
            cacheItem = new ProviderCacheItem(sqlDatasource.LoadCustomer(key));
            cacheItem.ResyncItemonExpiration = true;
            cacheItem.ResyncProviderName = sqlDatasource.ConnString;
        }
        // <summary>
        // Perform tasks like allocating resources or acquiring connections
        // </summary>
        ...

これを実装するのはあなたです。 それを初期化する Init メソッドがあります。 Dispose メソッドで、実際には Get メソッドに似ています。 したがって、get はキーを渡し、それにキャッシュ項目を返します。 したがって、自分のデータ ソースに移動してその項目をロードし、有効期限などを指定して、それを元のデータ ソースに渡します。 NCache。 このコードはキャッシュ サーバー上で実行されます。 これは覚えておくべき重要なことです。

したがって、リードスルーは実際にはキャッシュ サーバー自体で実行されます。 実は別の図があります。

リードスルーキャッシュローダー

したがって、リードスルーはキャッシュ サーバー自体で実行されます。 つまり、.NET コードを実行するには、キャッシュ サーバーを .NET で開発する必要があります。 したがって、.NET ショップ、アプリケーションが .NET である場合、これらすべての利点を得るために、スタック全体を .NET にする必要があると私が言ったのはそのためです。

それで、例えば、 Redis, Redis Linux ベースのキャッシュです。 これは素晴らしいキャッシュです。私は彼らに反対するつもりはありません。しかし、あなたが .NET ショップの場合は、これらすべてのことを行う必要があり、キャッシュが同期できるようにするには、コードをキャッシュ サーバー上で実行する必要があります。データベースを削除し、その項目をデータベースから自動的に再ロードします。 したがって、必要に応じて、SQL 依存関係が発生したときに、リードスルー ハンドラーが呼び出されます。 それを望まない場合は、その項目をキャッシュから削除するだけです。 そして、キャッシュから削除されると、次回アプリケーションがそのファイルを検索するときに、そのファイルは見つからず、データベースから取得することになります。 たとえば、キャッシュした製品カタログで、価格を更新したばかりの場合などがあります。 価格を更新したばかりなのに、なぜキャッシュから商品を削除するのでしょうか? なぜなら、アプリケーションにはデータベースから情報を取得するロジックが必要になるからです。 自動でリロードした方が良いです。

したがって、大量のデータが何度も必要になると思われる場合は、期限切れになるか、データベースの同期が発生するときに、削除するよりも再ロードする方が良いでしょう。 そうすればアプリケーションはこれを行う必要がないからです。 このキャッシュが多ければ多いほど、アプリケーションはより簡単になります。 したがって、キャッシュ自体をデータベースと同期できる別の方法があります。 したがって、SQL サーバーや Oracle がない場合、たとえば MySQL または DB2 があれば、これら XNUMX つの機能が存在すれば、DB 依存関係を使用できます。これは、DBXNUMX のもう XNUMX つの機能です。 NCache それはどこで NCache 特定のテーブルをプールし、その行のフラグを更新するようにデータベース トリガーを変更します。 NCache それを手に取り、このアイテムには変化があると言いました。 したがって、削除するかリロードする必要があります。

CLR ストアド プロシージャの使用

CLR プロシージャは、キャッシュをデータベースと同期するもう XNUMX つの方法です。 実際に書くところは、 CLR手順。 テーブルトリガーから呼び出します。 たとえば、Add トリガー、Update トリガー、または Delete トリガーがあるとします。 この CLR プロシージャを呼び出すと、 NCache またはキャッシュを呼び出します。

CLR プロシージャの場合、キャッシュが非同期メソッドをサポートしていることを確認する必要があります。 NCache そうです。 したがって、挿入非同期呼び出しのようにキャッシュを作成すると、コントロールがすぐに戻ってきます。 非同期呼び出しを行わないと、データベース トランザクションがタイムアウトし始めるからです。 キャッシュ内の複数のサーバーを更新することになるため、データベース トランザクションの設計とは異なるネットワークを経由することになります。 したがって、非同期呼び出しが必要です。

以上が、キャッシュを同期できる XNUMX つの方法です。 したがって、お金を払ったキャッシュは、データを常に最新の状態に保つことができるようにする必要があります。 この XNUMX つの方法があります。

キャッシュを非リレーショナルと同期する

非リレーショナル データ ソースがある場合も同様です。たとえば、データがクラウドまたは他の場所にある場合です。 Web メソッド呼び出しを行うこともできます。 実際には、カスタム依存関係を実装することができます。これもまた、キャッシュ サーバーに登録して実行するコードであり、 NCache それを呼び出して、データソースが変更されているかどうかを確認してくださいと言います。 データソースを確認し、変更されている場合は通知します NCache そのデータとデータ ソースが変更されました。 それで、 NCache 削除するかリロードすることができます。

そこで、再びリレーショナル データベースを使用します。 NCache すべてあなたのためにやってくれます。 非リレーショナルの場合は、カスタム依存関係を行う必要があります。

リレーショナルデータの処理

キャッシュを最新の状態に保つための最後の側面は、依存関係機能です。 顧客と注文の間に XNUMX 対多の関係があり、両方をキャッシュしているとします。 顧客オブジェクトがキャッシュから削除されたらどうなるでしょうか? 注文はキャッシュに残すべきでしょうか? 実際にデータベースから顧客を削除した場合はどうなるでしょうか。 そうですね、XNUMX 対多と言っている場合、通常は顧客を削除しません。 たとえば、キャッシュから一方の側を削除するということは、実際にはデータベースからもその側を削除することを意味する場合はどうなるでしょうか。 つまり、多側面はもはや有効ではありません。 それでは、誰がこれらすべてを追跡すべきでしょうか? キャッシュがそれを代行してくれるなら、あなたの生活はずっとシンプルになります。

たとえば、ASP.NET キャッシュ オブジェクトには、と呼ばれるこの機能があります。 キャッシュの依存関係. NCache はこれを実装していますが、私の知る限り、この機能を備えた .NET キャッシュは他にありません。 ただし、基本的にはアイテム間の関係を登録し、これはこのアイテムに依存するというもので、このアイテムが更新または削除された場合は、このアイテムを自動的に削除してください。 したがって、キャッシュがクリーンアップを行います。

キャッシュの機能が多ければ多いほど、データが最新であることが保証されるため、より良い結果が得られます。 これに自信が持てるようになると、ほぼすべてのデータをキャッシュできるようになります。 データを最新の状態に保つためにどの戦略を使用するかが問題です。

データの検索

データが新しいという確信が持てたので、大量のデータのキャッシュを開始します。 すべてのデータのキャッシュを開始すると、次に起こるのは、キャッシュがますますデータベースのように見え始めることです。 これはデータベースではなく、常に一時的なストアです。 ただし、特に参照データの多くは、ほとんどのデータ セット全体をキャッシュに保存します。 そんなときは、検索できるようにしたいと思うでしょう。 常にキーに基づいて検索するのではなく、非常に不便です。 キーに基づいてアイテムを検索するのは必ずしも便利であるとは限りません。 他の手段でそれを検索できるようにしたいと考えています。

XNUMX つの方法は、 SQL検索。 再び、 SELECT Customers WHERE Customers.City = "ニューヨーク"。 あなたがそうするか、このカテゴリの私の製品をすべて私にくれと言うのと同じように。 したがって、これらのオブジェクトのコレクションはデータベースからではなくキャッシュから取得されます。 キャッシュから取得するということは、データベースがそのヒットを受ける必要がなくなり、すべてがメモリ内にあることを意味します。 複数のサーバーから同時に送信されるため、はるかに高速になります。

したがって、これらはすべて並列クエリです。 そして、これを行うには、キャッシュがインデックス作成をサポートしている必要があります。 NCache そうです。 他の製品がサポートしているかどうかはわかりませんが、キャッシュがインデックス作成をサポートしていることを確認してください。 そうしないと、クエリが非常に遅くなります。

データのグループ化

キャッシュで実行できないことの XNUMX つは、複数のオブジェクトまたは複数のテーブルを結合することですが、これはリレーショナル データベースでは実行できます。 したがって、これを回避する方法があります。それは、物事をグループ化し、特定の方法でタグ付けしてそれらを取得し、キャッシュ内の論理的な関連付けまたはグループ化に基づいてデータを取得できるようにすることです。 そこで、すべてをキャッシュする場合の例を示します。 たとえば、顧客のコレクションが戻ってきたとします。 そこで、オブジェクト タグのコレクションがあり、すべてのオブジェクトを個別にキャッシュにキャッシュしたいと考えています。 ただし、後で、XNUMX 回の呼び出しですべてを取得できるようにしたいと考えています。

//Caching Query Results (Collection)
//Cache Collection Objects Separately
static void CacheSupplierProducts(NorthwindEntities context, int supplierId)
{
    Tag[] productTags = new Tag[1];
    productTags[0] = new Tag("SupplierProducts:" + supplierId);
    
    IQueryable<Product> products = context.Products;
    
    var result = from product in products
                  where product.SupplierID == supplierId
                  select product;
                  
    foreach (Product p in result)
    {
        String key = "Products:ProductId:" + p.ProductID;
        _cache.Insert(key, p, productTags);
    }
}
...
ICollection productList = _cache.GetByAnyTag(productTags).Values;

したがって、同じクエリ、SQL クエリを発行して、すべてを返してくださいと言うのです。 ただし、これらのオブジェクトはデータベースから取得したものであり、キャッシュから取得したものではありません。 また、それらはデータセット全体ではありません。 たとえば、当時私が取得したいと思っていたセットを何でも考えてみましょう。 したがって、個別にアクセスする必要があるすべてのオブジェクトを個別にキャッシュしました。 ただし、すべてを XNUMX つのコレクションとして取得できるようにしたいと考えています。 そこで、タグの概念を使用します。 全部同じタグ付けしてみました。 そして、そのタグは任意の一意の文字列にすることができ、このタグが付いているアイテムをすべて教えてくださいと言います。 したがって、XNUMX 回の呼び出しで、コレクション全体を再び取得できます。 つまり、タグを使用して実行できるのは、キャッシュ内の結合の不足を補うようなタイプの処理です。

したがって、グループ化を行うことができます。 の グループとサブグループ。 できるよ タグ。 名前付きタグを付けることができます。 名前付きタグ 基本的にはキーがあり、次に値があります。 たとえば、テキスト、自由形式のテキストをキャッシュする場合。 これはテキストであるため、テキスト自体にインデックスを付ける方法はありません。 したがって、タグを自分で作成する必要があり、タグ自体だけでは不十分な場合があります。 すべてのタグに名前を付けられるようにしたいと考えています。

つまり、オブジェクトに属性名があるのと同じです。 つまり、ネームタグはオブジェクトの属性のようなものです。 したがって、名前は city であり、このテキストの値は New York または Las Vegas である可能性があります。 したがって、これらのことをすべて実行してから、後でそれらを取得することができます。 NCache 少なくとも、API または SQLクエリ。 したがって、SQL に基づいて何かを取得する場合は…

最初の質問、素晴らしいですね! 階層的な分類法を使用できますか? 実際にできることは…グループとサブグループでは XNUMX レベルの階層しか提供されません。 したがって、グループ内に複数のサブグループを持つことができますが、それを超えることはできません。

XNUMX つの項目に複数のタグを割り当てることができるため、さまざまなタイプのタグを使用して表すことができます。 したがって、たとえば、複数の階層がある場合、下に行くすべてのレベルに割り当てることができ、各レベルの最上位のすべてを個別のタグとして割り当てることができます。

もう一つ質問です。 キャッシュの内部表現を制御できますか? インデックスは、ハッシュ テーブルの組み合わせに基づいて構築されます。 NCache、そして赤黒い木。 インデックスは選択できますが、内部的に使用されるデータ構造は選択できません。 ただし、インデックスは使用の性質に基づいて構築されます。 したがって、たとえば、ハッシュ テーブルは特定のタイプのアクセスに適しており、範囲タイプの検索を実行する場合は、赤黒ツリーの方がはるかに優れています。 それで、 NCache そうなります。 他の製品がどうなるかは分かりませんが、 NCache かなりの量のインデックスを作成します。

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

早速見ていきましょう リードスルー、ライトスルー。 では、なぜリードスルーとライトスルーが必要なのでしょうか? 最後までお読みください。その一例として、内容を自動的にリロードできることが挙げられます。

リードスルーのもう XNUMX つの利点は、もちろん、多くのデータ アクセスをキャッシュ自体に統合できることです。 アクセスが増えれば増えるほど、キャッシュまたはキャッシュ層に入る量が増え、アプリケーション内でのアクセスが減り、アプリケーションがシンプルになります。 アプリケーションはただ次のことを行います キャッシュ.取得 そしてもちろん、そのもう XNUMX つの利点は、自動的にロードできることです。

ライトスルーも同様です。 利点の XNUMX つは、すべての書き込みを統合できることです。 XNUMX 番目の利点は、実際に書き込みを高速化できることです。 たとえば、ライトビハインドは、キャッシュを同期的に更新し、キャッシュがデータベースを非同期的に更新する機能です。 したがって、データベースの更新がキャッシュほど速くない場合は、実際にはキャッシュを更新するだけで、キャッシュはデータベースを更新するため、アプリケーションのパフォーマンスが突然向上します。

したがって、リードスルー、ライトスルー、ライトビハインドは、活用すべき非常に強力な機能です。 これは、キャッシュ クラスター上で実行されるサーバー側のコードでもあり、作業が簡素化されます。 そのため、アプリケーションはより多くのデータをキャッシュに保持し、キャッシュを通じて更新することもできます。

早速読んで、何か話しましょう。 詳細には立ち入らないが、 ASP.NETセッション状態のキャッシュ。 コードを変更せずにプラグインし、web.config に変更を加えるだけで自動的に処理され、同様のことが行われることを知っておいてください。 ビューステート & 出力キャッシュ.

高可用性 (100% 稼働率)

いくつかのことを簡単に説明します。 最初に話したいのは… 使用するキャッシュについてです。これはデータベースのようなもので、実稼働環境ではインメモリ データベースであるためです。 したがって、キャッシュは高可用性である必要があります。 可用性の高いキャッシュが必要です。

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

NCache は、いくつかの機能を通じて可用性が高くなります。 まず、それは 動的キャッシュクラスター。 実行時にサーバーを追加または削除でき、クラスターが自動的に再調整されます。 構成にサーバー名をハードコードする必要はなく、クライアントは自動的に設定されます。 クライアントがキャッシュ サーバーと通信すると、クラスターのメンバーシップ情報を取得します。 実行時にメンバーシップが変更された場合、たとえば、新しいノードを追加したり、ノードを削除したりすると、更新されたメンバーシップがクライアントに伝播されます。

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

したがって、それが最初に存在する必要がある部分です。 そういう風に見ることが本当に大切です。

キャッシングトポロジ

XNUMX つ目はキャッシュ トポロジです。 したがって、さまざまな方法があります NCacheたとえば、XNUMX つのキャッシュ トポロジが得られます。 最初のものはと呼ばれます ミラーリングされたキャッシュ。 アクティブ/パッシブの2ノードです。

ミラーリングされたキャッシュ

秒はと呼ばれます 複製されたキャッシュ、キャッシュ内のすべてのサーバーにはキャッシュ全体のコピーがあります。 したがって、サーバーが増えれば増えるほど、キャッシュのコピーも増えます。 読み取りに関してはスケーラブルですが、更新に関してはスケーラブルではありません。 ただし、ケースには独自の用途があります。

複製されたキャッシュ

XNUMX 番目のトポロジは次のように呼ばれます。 パーティション化されたキャッシュ、キャッシュ全体がパーティションに分割されます。 すべてのサーバーは XNUMX つのパーティションです。 そして、これらのパーティションは自動的に作成されます。

パーティション化されたキャッシュ

したがって、たとえば次の場合、 NCache 各パーティションには多数のバケットが含まれています。 したがって、クラスター全体には 1,000 個のバケットがあります。 したがって、パーティションが XNUMX つある場合、バケットの数は XNUMX/XNUMX、XNUMX/XNUMX になります。

パーティション化されたレプリカ パーティションの場合も同じですが、すべてのパーティションが別のサーバーにバックアップされ、すべてが自動的に行われます。 したがって、XNUMX ノードのクラスターを作成すると、XNUMX つのパーティション、つまり XNUMX つのレプリカが作成されることになります。 XNUMX 番目のサーバーを追加すると、自動的に XNUMX 番目のパーティションが作成されます。XNUMX 番目のパーティションが作成されると、一部のバケットを既存のパーティションから移動する必要があります。

パーティション化されたレプリカ

したがって、すべての作業が自動的に行われます。 新しいレプリカが自動的に作成されます。 実際、これでわかるのであれば、ここでそれをお見せしましょう。 たとえば、1 つのサーバー パーティションがあるとします。ただし、1 つのサーバー クラスタリングしかない場合は、パーティションが 2 つあるとします。 ここにパーティション 2 があり、レプリカ 2 がありました。パーティション 3、レプリカ XNUMX。さて、XNUMX 番目のサーバーを追加しました。突然 XNUMX 番目のパーティションが必要になり、バケットの一部をここから取得し、その他のバケットをここから取得することになります。これは XNUMX つのことです。 次に、レプリカ XNUMX はここには存在しなくなり、パーティション XNUMX のレプリカがここに存在する必要があるため、ここに移動します。

そのため、調整はすべて自動的に行われます。 NCache。 それで、それは一つのことです。 XNUMX 番目に、と呼ばれる機能があります。 クライアントキャッシュ これをニア キャッシュと呼ぶ人もいます。これは非常に強力なので、必ず使用する必要があります。 基本的に、これはクライアント アプリケーション内のローカル キャッシュです。 ただし、これには特別な点が XNUMX つあります。それは、このローカル キャッシュがキャッシュ クラスターから切断されていないことです。 キャッシュクラスターに接続されています。 それ自体の同期が保たれます。

クライアントキャッシュ

したがって、次の場合には、 NCacheたとえば、クライアント キャッシュは舞台裏で自動的に設定にプラグインされます。 これらの各アプリケーションから何を取得しても、サーバーはクライアント キャッシュに自動的に保持されます。 したがって、次回必要になったときに、クライアント キャッシュで見つけることができます。 また、キャッシュ クラスターは、どのデータがどのクライアント キャッシュにあるかを認識します。 したがって、そのデータが、たとえば別のクライアントによって変更された場合、クラスターは、そのデータを保持しているすべてのクライアント キャッシュに、自身を更新するよう通知します。 したがって、クライアント キャッシュは接続されたままですが、ローカル キャッシュになります。 インプロセスであっても構いません。 インプロセスとは、アプリケーションプロセス内を意味します。 したがって、パフォーマンスが大幅に向上しますが、同時に接続された分散キャッシュ全体の一部になります。

WANレプリケーション

時間がないので、多くのことを省略します。 それで、それもあります WANレプリケーション。 複数のデータセンターがある場合は、キャッシュを WAN 経由で複製できるようにする必要がありますが、WAN 経由でクラスターを構築することはできません。 これらのソケットが壊れると、レイテンシが非常に高くなるだけで機能しなくなるだけです。 したがって、XNUMX つのデータセンター間でキャッシュを接続する何らかの方法が必要です。

の場合 NCache 複数のデータセンターを接続するブリッジ トポロジと呼ばれるものがあります。 アクティブ/アクティブ、アクティブ/パッシブ、または XNUMX つ以上のデータセンターを構築できるようになりました。 そして、これはすべて非同期で行われ、競合解決も自動的に行われます。 ご覧のとおり、キャッシュは単なるキーと値のストアではありません。 したがって、舞台裏では覚えておくべきことがたくさんあります。

NCache 対 Redis

すぐに取り上げたいと思ったことの XNUMX つは、 NCache 対 Redis、ただ大まかなレベルで、これについて話したかったのです。 NCache ネイティブの .NET キャッシュです。 Windows 上で実行され、クライアント側とサーバー側の両方のキャッシュを実行できることが利点の XNUMX つです。 一方、 Redis 主に Linux ベースのキャッシュです。 Microsoft が提携する前は、.NET 側のほとんどの人は、Unix や PHP、その他の環境で非常に人気のあるキャッシュであったにもかかわらず、その存在さえ知りませんでした。

次に、Linux バージョンの NCache Azureで利用可能です、サービスとしてのキャッシュとして。 サービスとしてのキャッシュの理由は、.NET アプリケーションの場合、実際には Linux ベースのキャッシュでサーバー側のコードを実行できないためです。 実行するには .NET ベースのキャッシュが必要です。 したがって、これは大きな制限の XNUMX つです。

XNUMX 番目に、Azure の外で何かを行う場合は、 Redis Linux ベースのキャッシュとしてのみ使用できます。 Microsoft が行ったウィンドウ サポートは、Microsoft 自身が使用するものではありません。 Azure であっても、Windows での使用を選択しません。 あまり安定していません。 さらに詳しく見たい場合は、詳細もあります の比較 NCache & Redis、ここに来て比較を確認できます。 それで、私たちは持っています 比較 なぜなら、私たちは自分たちにとても自信を持っているからです。

ご覧のとおり、これは完全な比較です。 ただ通過してください。 分散キャッシュの使用を検討している場合は、そうすべきですが、スケーラビリティのニーズはすべて満たされています。 下調べをして、使用するものがすべて自分のニーズに合っていることを確認してください。 そして、これまでのところ、 NCache 心配な方のために、簡単に比較してみます NCache 他の人と一緒に。 私たちのウェブサイトにアクセスして、 ダウンロード NCache。 オープンソースです。 したがって、Enterprise Edition またはオープンソース版をここからダウンロードするか、次のリンクにアクセスしてください。 GitHubの そしてあなたは NCache ページ をご覧ください

私のプレゼンテーションはこれで終わりです。 質問は? ストアド プロシージャ呼び出しを渡すことができます。 SQL サーバー自体内で実行されるトランザクション SQL など、すべて SQL である必要があります。

はい。 したがって、キャッシュはアプリケーションと同じサーバー上に置くことができます。 お勧めしません。 これは良い展開戦略ではありませんが、小規模な構成の場合は、もちろん可能です。

パーティショニングを行うと、すべてのパーティショニングが自動的に行われます。 したがって、全体的な考え方は、すべてのパーティションの重み、データ サイズ、トランザクションの点で同じである必要があるということです。

あなたはパーティションを制御するのではなく、パーティションが存在することを知っているだけです。

データベースからキャッシュを直接呼び出すことができる CLR プロシージャがある場合、項目テーブルを更新するときに、データベース自体内からキャッシュを更新することを選択できます。 キャッシュを更新できる別のコードを作成することもできます。そのコードは、どれだけキャッシュに保存されているかに応じて異なります。

ご希望であれば、オフラインでさらに詳しくお話します。 ただし、アクセスする必要があるすべてのデータがキャッシュ内に確実に最新の状態に保たれるようにする方法は複数あります。

はい、実際にスライドを公開します。 それが私たちが全員のメールをスキャンした理由です。 それで、それを行うことができ、ビデオを録画してアップロードすることもできます。 つまり、あなただけでなく同僚も見ることができます。

実際には、アプリケーションごと、または…実際には複数のアプリケーションにわたってです。 したがって、すべてはトランザクション内の負荷に依存します。 クラスターを構成するために少なくとも 2 つのキャッシュ サーバーを使用できますが、サーバーの数は、アプリケーション サーバーの数、または基本的にアクティビティの量によって異なります。 キャッシュされるデータの量はどれくらいですか? どれくらいの読み取りと書き込みを行っていますか?

関係ないよ、そうだね。 はい、すべてが引き続き機能します。 君たちありがとう。

次はどうする?

 

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

お問い合わせ(英語)

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