ASPでの作業NCacheのためのNet Core I DistributedCacheプロバイダー


私はもともとこの投稿を公開on my blog 数週間前.これは、Alachisoft、NCacheのクリエイターとのコンテンツコラボレーションの一部です.
前回学んだ時、私がカバーした時in-memory caching with ASP.NET Core , キャッシュは、アプリケーションと外部リソース(例えばデータベース)間のストレージ層であり、そのリソースへの将来の要求をスピードアップするために使用されます.このポストでは、ASPを使いましょう.ネットコアIDistributedCache 抽象化はncacheを使用してデータキャッシュ層を書く.

Ncacheとは


からNCache official page , Ncacheは. NET、Java、およびnode . jsアプリケーション用のメモリ分散キャッシュのオープンソースです
とりわけ、キャッシュをデータベースキャッシュ、NHibernate 2レベルキャッシュ、Entity Frameworkキャッシュ、およびセッション用のWebキャッシュとして使用できます.
ncacheは3つのエディションで開きます:オープンソース、プロフェッショナル、および企業.オープンソースバージョンは2つのノードをサポートし、そのキャッシュサーバは利用可能です.NET Framework Version 4.8 .違いの完全なリストのために、チェックしてくださいNCache edition comparison .
Ncacheキー機能の一つはパフォーマンスです.に基づいてtheir own benchmarks , NCACHEは、5サーバキャッシュクラスタを使用して、毎秒200万稼動を達成するために線形的にスケールすることができます

WindowsマシンでNcacheをインストールする方法は?


WindowsマシンにNcacheサーバーをインストールする方法を見ましょう.このためには、Windowsインストーラが必要ですtrial license key . ncacheエンタープライズバージョン5.2 SP 1をインストールしましょう.
インストーラを実行した後、キャッシュサーバー、リモートクライアント、開発者/QAの3種類からインストールタイプを選択する必要があります.キャッシュサーバを選びましょう.

ncacheインストールタイプ
次に、ライセンスキーを入力する必要があります.我々がインストールしている同じバージョンのために、ライセンスキーを持っているようにしましょう.そうでなければ、“無効なライセンスキー”エラーを取得します.登録中に使用したメールアドレスに送信されたライセンスキーを受け取ります.

ncacheライセンスキー
次に、我々は完全な名前、電子メールを入力する必要がありますし、私たちは自分自身を登録するために使用した組織は、裁判所のライセンスを要求します.

ユーザー情報
それから、私たちは、我々のNCacheサーバーを縛るIPアドレスを選択する必要があります.デフォルトに固執しましょう.

結合の設定
次に、ncacheを実行するアカウントを選択する必要があります.ローカルシステムアカウントを使いましょう.

キャッシュを実行するアカウント
インストールが完了すると、デフォルトのブラウザはWebマネージャで開きます.デフォルトでは、ncachedemoCache .

ウェブマネージャ
次回は、ウェブマネージャを起動することによってhttp://localhost:8251 .
Ncacheの公式サイトは、冗長目的のために最低2台のサーバを推薦します.しかし、我々のサンプルアプリは、テスト目的のために単一のノードサーバーを使用してみましょう.
これまでWindowsマシンのインストール手順を扱っています.しかし、LinuxとDockerコンテナでncacheをインストールすることもできます.また,ncacheをazureやwsで仮想マシンとして利用できる.

キャッシュは高速な記憶装置です.写真でJezael Melgoza on Unsplash

Ncacheキャッシュからデータを加えて、取り出す方法?


今、私たちは私たちのncacheサーバーを使用してから始める準備ができています.NETアプリケーション.Visual Studioで、ソリューションを作成します.NCACHEで基本的なキャッシュ操作を学習するためのクラス6“MSTestテストプロジェクト”とクラスファイル.

ncacheキャッシュへの接続


ncacheサーバに接続する前に、まずクライアントnugetパッケージをインストールする必要があります.Alachisoft.NCache.SDK . 最新版を使いましょう.5.2.1 .
接続を開始するには、GetCache() キャッシュ名のメソッド.サンプルアプリケーションの場合は、デフォルトのキャッシュを使用します.demoCache .
キャッシュからムービーを追加して取得するテストを書き始めましょう.
using Alachisoft.NCache.Client;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace NCacheDemo.Tests;

[TestClass]
public class NCacheTests
{
    [TestMethod]
    public void AddItem()
    {
        var cacheName = "demoCache";
        ICache cache = CacheManager.GetCache(cacheName);

        // We will fill in the details later
    }
}

If you're new to unit testing, start looking at how to write your first unit test in C# with MSTest.


我々のキャッシュに接続する接続文字列を使用する必要はありませんでした.キャッシュ名だけを使用します.Webマネージャと同じです.demoCache .
Ncacheはclient.ncconf 接続文字列の代わりにファイル.アプリケーションまたはインストールレベルでこのファイルを定義できます.テストのために、インストールレベルで設定ファイルに依存しています.そういうわけで、我々はキャッシュ名だけを必要としました.

アイテムの追加


新しいアイテムをキャッシュに追加するには、Add() and AddAsync() メソッドkeyCacheItem キャッシュする.キーは識別子で、項目はキャッシュするオブジェクトのラッパーです.
キャッシュへのすべてのアイテムは、満了を必要とします.The CacheItem を持っているExpiration プロパティ.
2つの基本的な呼出タイプがあります.Absolute and Sliding .
キャッシュされたアイテムAbsolute 呼気は与えられた時間の後に期限が切れる.数秒おきましょう.しかし、アイテムSliding 有効期限は、それがアクセスされるたびに更新されます.スライディング時間内では、アイテムを取得しません.
我々のテストを我々のキャッシュに映画を加えるために更新しましょう.
using Alachisoft.NCache.Client;
using Alachisoft.NCache.Runtime.Caching;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;

namespace NCacheDemo.Tests;

[TestClass]
public class NCacheTests
{
    private const string CacheName = "demoCache";

    [TestMethod]
    public async Task AddItem()
    {
        var movie = new Movie(1, "Titanic");
        var cacheKey = movie.ToCacheKey();
        var cacheItem = ToCacheItem(movie);

        ICache cache = CacheManager.GetCache(CacheName);
        // Let's add Titanic to the cache...
        await cache.AddAsync(cacheKey, cacheItem);

        // We will fill in the details later
    }

    private CacheItem ToCacheItem(Movie movie)
        => new CacheItem(movie)
        {
            Expiration = new Expiration(ExpirationType.Absolute, TimeSpan.FromSeconds(1))
        };
}

[Serializable]
public record Movie(int Id, string Name)
{
    public string ToCacheKey()
        => $"{nameof(Movie)}:{Id}";
}
注意:二つのヘルパーメソッドを使用しました.ToCacheKey() すべてのムービーからキーを作成するにはToCacheItem() ムービーからキャッシュアイテムを作成するには.
我々はrecords from C# 9.0 創造するMovie クラス.また、我々はそれと注釈を付ける必要があった[Serializable] 属性.

アイテムの取得


項目を追加した後、それらを取得しましょう.このためにはGet<T>() キーでメソッド.
我々が加えたオブジェクトを取り出すために、我々の最初の単位テストを完了しましょう.
using Alachisoft.NCache.Client;
using Alachisoft.NCache.Runtime.Caching;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;

namespace NCacheDemo.Tests;

[TestClass]
public class NCacheTests
{
    private const string CacheName = "demoCache";

    [TestMethod]
    public async Task AddItem()
    {
        var movie = new Movie(1, "Titanic");
        var cacheKey = movie.ToCacheKey();
        var cacheItem = ToCacheItem(movie);

        ICache cache = CacheManager.GetCache(CacheName);
        await cache.AddAsync(cacheKey, cacheItem);

        // Let's bring Titanic back...
        var cachedMovie = cache.Get<Movie>(cacheKey);
        Assert.AreEqual(movie, cachedMovie);
    }

    private CacheItem ToCacheItem(Movie movie)
        => new CacheItem(movie)
        {
            Expiration = new Expiration(ExpirationType.Absolute, TimeSpan.FromSeconds(1))
        };
}

[Serializable]
public record Movie(int Id, string Name)
{
    public string ToCacheKey()
        => $"{nameof(Movie)}:{Id}";
}

アイテムの更新


同じキーでアイテムを追加しようとするとAdd() or AddAsync() メソッドは、OperationFailedException . それを証明するために単体テストを追加してみてください.
新しいアイテムを追加するか、既存のものを更新するには、Insert() or InserAsync() 代わりにメソッド.別のテストでそれらを使用しましょう.
using Alachisoft.NCache.Client;
using Alachisoft.NCache.Runtime.Caching;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;

namespace NCacheDemo.Tests;

[TestClass]
public class NCacheTests
{
    // Our previous test is the same

    [TestMethod]
    public async Task UpdateItem()
    {
        ICache cache = CacheManager.GetCache(CacheName);

        var movie = new Movie(2, "5th Element");
        var cacheKey = movie.ToCacheKey();
        var cacheItem = ToCacheItem(movie);
        // Let's add the 5th Element here...
        await cache.AddAsync(cacheKey, cacheItem);

        var updatedMovie = new Movie(2, "Fifth Element");
        var updatedCacheItem = ToCacheItem(updatedMovie);
        // There's already a cache item with the same key...
        await cache.InsertAsync(cacheKey, updatedCacheItem);

        var cachedMovie = cache.Get<Movie>(cacheKey);
        Assert.AreEqual(updatedMovie, cachedMovie);
    }

    // Rest of the file...
}
我々が使った通知InsertAsync() 同じキーで項目を追加する方法.我々がそれを検索すると、それはアイテムの更新されたバージョンを含んでいました.
もう一つの基本的な方法があります.Remove() and RemoveAsync() . 我々は彼らが何をするか推測できます.再び、それを証明するテストを書くようにしてください.

ASPの使い方.NCacheを使用したNet Core IsDistributedCache


ここまで、ncacheをインストールし、項目の追加、取得、更新、削除の方法を知っています.
我々のポストから我々のサンプルアプリケーションを再訪問しましょうusing a Redis-powered cache layer .
最後のポストの例を思い出しましょう.データベースにアクセスするためのサービスを使用するエンドポイントがありましたが、完了するには数秒かかります.複雑なオブジェクトグラフを取得したり、データを返したりする前にデータをいくつか計算してみましょう.
こんなものだ.
using DistributedCacheWithNCache.Responses;

namespace DistributedCacheWithNCache.Services;

public class SettingsService
{
    public async Task<SettingsResponse> GetAsync(int propertyId)
    {
        // Beep, boop...Aligning satellites...
        await Task.Delay(3 * 1000);

        return new SettingsResponse
        {
            PropertyId = propertyId,
            Value = "Anything"
        };
    }
}
注意3秒遅延でデータベースコールをエミュレートしました.
また、IDistributedCache キャッシュからオブジェクトを追加して取得するには.
前回書いた拡張方法がありました.
using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json;

namespace DistributedCacheWithNCache.Services;

public static class DistributedCacheExtensions
{
    public static readonly DistributedCacheEntryOptions DefaultDistributedCacheEntryOptions
        = new DistributedCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(60),
            SlidingExpiration = TimeSpan.FromSeconds(10),
        };

    public static async Task<TObject> GetOrSetValueAsync<TObject>(this IDistributedCache cache,
                                                                  string key,
                                                                  Func<Task<TObject>> factory,
                                                                  DistributedCacheEntryOptions options = null)
        where TObject : class
    {
        var result = await cache.GetValueAsync<TObject>(key);
        if (result != null)
        {
            return result;
        }

        result = await factory();

        await cache.SetValueAsync(key, result, options);

        return result;
    }

    private static async Task<TObject> GetValueAsync<TObject>(this IDistributedCache cache,
                                                              string key)
        where TObject : class
    {
        var data = await cache.GetStringAsync(key);
        if (data == null)
        {
            return default;
        }

        return JsonConvert.DeserializeObject<TObject>(data);
    }

    private static async Task SetValueAsync<TObject>(this IDistributedCache cache,
                                                     string key,
                                                     TObject value,
                                                     DistributedCacheEntryOptions options = null)
        where TObject : class
    {
        var data = JsonConvert.SerializeObject(value);

        await cache.SetStringAsync(key, data, options ?? DefaultDistributedCacheEntryOptions);
    }
}
注意:newtonsoftを使用しました.オブジェクトをシリアル化して逆シリアル化するJSON.

ncacheとiDistributedCacheインターフェイス


さあ、使いましょう.NET 6“ASP . NETコアWebアプリケーション、”これらの拡張メソッドの上にIDistributedCache , とncacheをスピードアップするSettingsService .
まず、nugetパッケージをインストールする必要がありますNCache.Microsoft.Extensions.Caching . このパッケージはIDistributedCache ncacheを使ったインターフェースです.
nugetパッケージをインストールした後、ASP . NETにキャッシュを追加する必要があります.NET依存関係コンテナProgram.cs ファイル.これを達成するためにはAddNCacheDistributedCache() メソッド.
// Program.cs
using Alachisoft.NCache.Caching.Distributed;
using DistributedCacheWithNCache;
using DistributedCacheWithNCache.Services;

var (builder, services) = WebApplication.CreateBuilder(args);

services.AddControllers();
// We add the NCache implementation here...
services.AddNCacheDistributedCache((options) =>
{
    options.CacheName = "demoCache";
    options.EnableLogs = true;
    options.ExceptionsEnabled = true;
});
services.AddTransient<SettingsService>();

var app = builder.Build();
app.MapControllers();
app.Run();
注意してください、私たちは同じキャッシュ名を使い続けました:demoCache . そして、私たちもDeconstruct メソッドbuilder and services 変数のコンストラクタ.私は、ハリドAbukhmehのものからこの考えをとりましたAdding Clarity To .NET Minimal Hosting APIs .
インザバックSettingsService , 私たちはIDistributedCache コンストラクタへのインタフェースとDistributedCacheExtensions クラス.このように.
using DistributedCacheWithNCache.Responses;
using Microsoft.Extensions.Caching.Distributed;

namespace DistributedCacheWithNCache.Services
{
    public class SettingsService
    {
        private readonly IDistributedCache _cache;

        public SettingsService(IDistributedCache cache)
        {
            _cache = cache;
        }

        public async Task<SettingsResponse> GetAsync(int propertyId)
        {
            var key = $"{nameof(propertyId)}:{propertyId}";
            // Here we wrap the GetSettingsAsync method around the cache logic
            return await _cache.GetOrSetValueAsync(key, async () => await GetSettingsAsync(propertyId));
        }

        private static async Task<SettingsResponse> GetSettingsAsync(int propertyId)
        {
            // Beep, boop...Aligning satellites...
            await Task.Delay(3 * 1000);

            return new SettingsResponse
            {
                PropertyId = propertyId,
                Value = "Anything"
            };
        }
    }
}
注意、私たちはGetSettingsAsync() におけるキャッシュ論理の周りのロジックを実際に取得するGetOrSetValueAsync() . いくつかの時点で、我々のキャッシュとストレージ層に同じデータがあります.
代わりにキャッシュを行うと、そのサービスを使用する1つのエンドポイントをヒットした場合、最初の呼び出しが3秒遅れた後、より高速な応答時間が表示されます.

ncacheから読んだいくつかのmiliseconds
また、私たちがncacheウェブマネージャに戻るならば、我々は若干の活動をサーバーで見なければなりません.

最初のリクエストを示すncacheダッシュボード
このシナリオでは、項目を追加して取得するすべてのロジックがIDistributedCache インターフェイス.だからこそ、我々は直接呼び出す必要はありませんでしたAdd() or Get<T>() メソッド.ncacheのソースコードを見てみると、それらのメソッドを見つけますhere and here .
ベール!これはncacheとどのように使用するにはIDistributedCache インターフェイス.ncacheでは,いくつかの構成とボックスからダッシュボードを持つ分散キャッシュサーバを持っている.また、すべてのキャッシュロジックを追加することができますdecorators そして、できるだけきれいに我々のサービスをしてください.
我々がこのポストで書いたコードとともに続くために、チェックしてくださいNcache Demo githubの上の倉庫.

より多くのコンテンツを読むにはUnit Testing 101 シリーズはどのように模擬に最初の単体テストを書くから学ぶために.
ハッピーコーディング!