Penembolokan terdistribusi di ASP.NET Core

Oleh Mohsin Nasir dan smandia

Catatan

Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Penting

Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Cache terdistribusi adalah cache yang dibagikan oleh beberapa server aplikasi, biasanya dipertahankan sebagai layanan eksternal ke server aplikasi yang mengaksesnya. Cache terdistribusi dapat meningkatkan performa dan skalabilitas aplikasi ASP.NET Core, terutama ketika aplikasi dihosting oleh layanan cloud atau farm server.

Cache terdistribusi memiliki beberapa keunggulan dibandingkan skenario penembolokan lainnya di mana data cache disimpan di server aplikasi individual.

Saat data yang di-cache didistribusikan, data:

  • Koheren (konsisten) di seluruh permintaan ke beberapa server.
  • Bertahan hidupkan ulang server dan penyebaran aplikasi.
  • Tidak menggunakan memori lokal.

Konfigurasi cache terdistribusi spesifik implementasi. Artikel ini menjelaskan cara mengonfigurasi cache terdistribusi SQL Server dan Redis. Implementasi pihak ketiga juga tersedia, seperti NCache (NCache di GitHub). Terlepas dari implementasi mana yang dipilih, aplikasi berinteraksi dengan cache menggunakan IDistributedCache antarmuka .

Melihat atau mengunduh kode sampel (cara mengunduh)

Prasyarat

Tambahkan referensi paket untuk penyedia cache terdistribusi yang digunakan:

Antarmuka IDistributedCache

Antarmuka IDistributedCache menyediakan metode berikut untuk memanipulasi item dalam implementasi cache terdistribusi:

  • Get, GetAsync: Menerima kunci string dan mengambil item yang di-cache sebagai byte[] array jika ditemukan di cache.
  • Set, SetAsync: Menambahkan item (sebagai byte[] array) ke cache menggunakan kunci string.
  • Refresh, RefreshAsync: Merefresh item dalam cache berdasarkan kuncinya, mengatur ulang batas waktu kedaluwarsa gesernya (jika ada).
  • Remove, RemoveAsync: Menghapus item cache berdasarkan kunci stringnya.

Menetapkan layanan penembolokan terdistribusi

Daftarkan implementasi IDistributedCache di Program.cs. Implementasi yang disediakan kerangka kerja yang dijelaskan dalam topik ini meliputi:

Cache Redis Terdistribusi

Sebaiknya aplikasi produksi menggunakan Cache Redis Terdistribusi karena ini adalah yang paling berkinerja. Untuk informasi selengkapnya, lihat Rekomendasi.

Redis adalah penyimpanan data dalam memori sumber terbuka, yang sering digunakan sebagai cache terdistribusi. Anda dapat mengonfigurasi Azure Cache for Redis untuk aplikasi ASP.NET Core yang dihosting Azure, dan menggunakan Azure Cache for Redis untuk pengembangan lokal.

Aplikasi mengonfigurasi implementasi cache menggunakan RedisCache instans, dengan memanggil AddStackExchangeRedisCache. Untuk penembolokan output, gunakan AddStackExchangeRedisOutputCache.

  1. Buat Azure Cache for Redis.
  2. Salin string koneksi Utama (StackExchange.Redis) ke Konfigurasi.
    • Pengembangan lokal: Simpan string koneksi dengan Secret Manager.
    • Azure: Simpan string koneksi di App Service Configuration atau penyimpanan aman lainnya.

Kode berikut mengaktifkan Azure Cache for Redis:

builder.Services.AddStackExchangeRedisCache(options =>
 {
     options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
     options.InstanceName = "SampleInstance";
 });

Kode sebelumnya mengasumsikan string koneksi Utama (StackExchange.Redis) disimpan dalam konfigurasi dengan nama MyRedisConStrkunci .

Untuk informasi selengkapnya, lihat Azure Cache for Redis.

Lihat masalah GitHub ini untuk diskusi tentang pendekatan alternatif ke cache Redis lokal.

Singgahan Memori Terdistribusi

Singgahan Memori Terdistribusi (AddDistributedMemoryCache) adalah implementasi IDistributedCache yang disediakan kerangka kerja yang menyimpan item dalam memori. Singgahan Memori Terdistribusi bukan cache terdistribusi aktual. Item yang di-cache disimpan oleh instans aplikasi di server tempat aplikasi berjalan.

Singgahan Memori Terdistribusi adalah implementasi yang berguna:

  • Dalam skenario pengembangan dan pengujian.
  • Ketika satu server digunakan dalam produksi dan konsumsi memori bukanlah masalah. Menerapkan penyimpanan data cache Singgahan Memori Terdistribusi yang di-cache. Ini memungkinkan untuk menerapkan solusi penembolokan terdistribusi sejati di masa depan jika beberapa simpul atau toleransi kesalahan menjadi diperlukan.

Aplikasi sampel menggunakan Cache Memori Terdistribusi saat aplikasi dijalankan di lingkungan Pengembangan di Program.cs:

builder.Services.AddDistributedMemoryCache();

Singgahan SQL Server Terdistribusi

Implementasi Singgahan SQL Server Terdistribusi (AddDistributedSqlServerCache) memungkinkan cache terdistribusi menggunakan database SQL Server sebagai penyimpanan cadangannya. Untuk membuat tabel item cache SQL Server dalam instans SQL Server, Anda dapat menggunakan alat ini sql-cache . Alat ini membuat tabel dengan nama dan skema yang Anda tentukan.

Buat tabel di SQL Server dengan menjalankan sql-cache create perintah . Berikan instans SQL Server (Data Source), database (Initial Catalog), skema (misalnya, dbo), dan nama tabel (misalnya, TestCache):

dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache

Pesan dicatat untuk menunjukkan bahwa alat berhasil:

Table and index were created successfully.

Tabel yang sql-cache dibuat oleh alat ini memiliki skema berikut:

Tabel Cache SqlServer

Catatan

Aplikasi harus memanipulasi nilai cache menggunakan instans IDistributedCache, bukan SqlServerCache.

Aplikasi sampel diterapkan SqlServerCache di lingkungan non-Pengembangan di Program.cs:

builder.Services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString(
        "DistCache_ConnectionString");
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

Catatan

( ConnectionString dan opsional, SchemaName dan TableName) biasanya disimpan di luar kontrol sumber (misalnya, disimpan oleh Secret Manager atau dalam appsettings.json/appsettings.{Environment}.json file). string koneksi mungkin berisi kredensial yang harus dijaga dari sistem kontrol sumber.

Singgahan NCache Terdistribusi

NCache adalah cache terdistribusi sumber terbuka dalam memori yang dikembangkan secara asli di .NET dan .NET Core. NCache berfungsi baik secara lokal maupun dikonfigurasi sebagai kluster cache terdistribusi untuk aplikasi ASP.NET Core yang berjalan di Azure atau di platform hosting lainnya.

Untuk menginstal dan mengonfigurasi NCache di komputer lokal Anda, lihat Panduan Memulai untuk Windows (.NET dan .NET Core).

Untuk mengonfigurasi NCache:

  1. Instal NCache sumber terbuka NuGet.
  2. Konfigurasikan kluster cache di client.ncconf.
  3. Tambahkan kode berikut ke Program.cs:
builder.Services.AddNCacheDistributedCache(configuration =>
{
    configuration.CacheName = "democache";
    configuration.EnableLogs = true;
    configuration.ExceptionsEnabled = true;
});

Cache Azure CosmosDB terdistribusi

Azure Cosmos DB dapat digunakan di ASP.NET Core sebagai penyedia status sesi dengan menggunakan IDistributedCache antarmuka . Azure Cosmos DB adalah database NoSQL dan relasional yang dikelola sepenuhnya untuk pengembangan aplikasi modern yang menawarkan ketersediaan tinggi, skalabilitas, dan akses latensi rendah ke data untuk aplikasi misi penting.

Setelah menginstal paket NuGet Microsoft.Extensions.Caching.Cosmos , konfigurasikan cache terdistribusi Azure Cosmos DB sebagai berikut:

Menggunakan kembali klien yang sudah ada

Cara term mudah untuk mengonfigurasi cache terdistribusi adalah dengan menggunakan kembali klien Azure Cosmos DB yang ada. Dalam hal ini, CosmosClient instans tidak akan dibuang saat penyedia dibuang.

services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
    cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
    cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
    cacheOptions.CosmosClient = existingCosmosClient;
    cacheOptions.CreateIfNotExists = true;
});

Membuat klien baru

Atau, buat instans klien baru. Dalam hal ini, CosmosClient instans akan dibuang ketika penyedia dibuang.

services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
    cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
    cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
    cacheOptions.ClientBuilder = new CosmosClientBuilder(Configuration["CosmosConnectionString"]);
    cacheOptions.CreateIfNotExists = true;
});

Menggunakan cache terdistribusi

Untuk menggunakan IDistributedCache antarmuka, minta instans IDistributedCache di aplikasi. Instans disediakan oleh injeksi dependensi (DI).

Saat aplikasi sampel dimulai, IDistributedCache disuntikkan ke dalam Program.cs. Waktu saat ini di-cache menggunakan IHostApplicationLifetime (untuk informasi selengkapnya, lihat Host Generik: IHostApplicationLifetime):

app.Lifetime.ApplicationStarted.Register(() =>
{
    var currentTimeUTC = DateTime.UtcNow.ToString();
    byte[] encodedCurrentTimeUTC = System.Text.Encoding.UTF8.GetBytes(currentTimeUTC);
    var options = new DistributedCacheEntryOptions()
        .SetSlidingExpiration(TimeSpan.FromSeconds(20));
    app.Services.GetService<IDistributedCache>()
                              .Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
});

Aplikasi sampel dimasukkan IDistributedCache ke IndexModel dalam untuk digunakan oleh halaman Indeks.

Setiap kali halaman Indeks dimuat, cache diperiksa untuk waktu yang di-cache di OnGetAsync. Jika waktu yang di-cache belum kedaluwarsa, waktu akan ditampilkan. Jika 20 detik telah berlalu sejak terakhir kali waktu cache diakses (terakhir kali halaman ini dimuat), halaman menampilkan Waktu Singgahan Kedaluwarsa.

Segera perbarui waktu yang di-cache ke waktu saat ini dengan memilih tombol Reset Waktu Singgahan. Tombol memicu OnPostResetCachedTime metode handler.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

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

    public string? CachedTimeUTC { get; set; }
    public string? ASP_Environment { get; set; }

    public async Task OnGetAsync()
    {
        CachedTimeUTC = "Cached Time Expired";
        var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

        if (encodedCachedTimeUTC != null)
        {
            CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
        }

        ASP_Environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
        if (String.IsNullOrEmpty(ASP_Environment))
        {
            ASP_Environment = "Null, so Production";
        }
    }

    public async Task<IActionResult> OnPostResetCachedTime()
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

        return RedirectToPage();
    }
}

Tidak perlu menggunakan masa pakai Singleton atau Cakupan untuk IDistributedCache instans dengan implementasi bawaan.

Anda juga dapat membuat IDistributedCache instans di mana pun Anda mungkin memerlukannya alih-alih menggunakan DI, tetapi membuat instans dalam kode dapat membuat kode Anda lebih sulit untuk menguji dan melanggar Prinsip Dependensi Eksplisit.

Rekomendasi

Saat memutuskan implementasi IDistributedCache mana yang terbaik untuk aplikasi Anda, pertimbangkan hal berikut:

  • Infrastruktur yang ada
  • Persyaratan performa
  • Biaya
  • Pengalaman tim

Solusi penembolokan biasanya mengandalkan penyimpanan dalam memori untuk menyediakan pengambilan data yang di-cache dengan cepat, tetapi memori adalah sumber daya terbatas dan mahal untuk diperluas. Hanya simpan data yang umum digunakan dalam cache.

Untuk sebagian besar aplikasi, cache Redis menyediakan throughput yang lebih tinggi dan latensi yang lebih rendah daripada cache SQL Server. Namun, tolok ukur disarankan untuk menentukan karakteristik performa strategi penembolokan.

Ketika SQL Server digunakan sebagai penyimpanan cadangan cache terdistribusi, penggunaan database yang sama untuk cache dan penyimpanan dan pengambilan data biasa aplikasi dapat berdampak negatif pada performa keduanya. Sebaiknya gunakan instans SQL Server khusus untuk penyimpanan backing cache terdistribusi.

Sumber Daya Tambahan:

Cache terdistribusi adalah cache yang dibagikan oleh beberapa server aplikasi, biasanya dipertahankan sebagai layanan eksternal ke server aplikasi yang mengaksesnya. Cache terdistribusi dapat meningkatkan performa dan skalabilitas aplikasi ASP.NET Core, terutama ketika aplikasi dihosting oleh layanan cloud atau farm server.

Cache terdistribusi memiliki beberapa keunggulan dibandingkan skenario penembolokan lainnya di mana data cache disimpan di server aplikasi individual.

Saat data yang di-cache didistribusikan, data:

  • Koheren (konsisten) di seluruh permintaan ke beberapa server.
  • Bertahan hidupkan ulang server dan penyebaran aplikasi.
  • Tidak menggunakan memori lokal.

Konfigurasi cache terdistribusi spesifik implementasi. Artikel ini menjelaskan cara mengonfigurasi cache terdistribusi SQL Server dan Redis. Implementasi pihak ketiga juga tersedia, seperti NCache (NCache di GitHub). Terlepas dari implementasi mana yang dipilih, aplikasi berinteraksi dengan cache menggunakan IDistributedCache antarmuka .

Melihat atau mengunduh kode sampel (cara mengunduh)

Prasyarat

Tambahkan referensi paket untuk penyedia cache terdistribusi yang digunakan:

Antarmuka IDistributedCache

Antarmuka IDistributedCache menyediakan metode berikut untuk memanipulasi item dalam implementasi cache terdistribusi:

  • Get, GetAsync: Menerima kunci string dan mengambil item yang di-cache sebagai byte[] array jika ditemukan di cache.
  • Set, SetAsync: Menambahkan item (sebagai byte[] array) ke cache menggunakan kunci string.
  • Refresh, RefreshAsync: Merefresh item dalam cache berdasarkan kuncinya, mengatur ulang batas waktu kedaluwarsa gesernya (jika ada).
  • Remove, RemoveAsync: Menghapus item cache berdasarkan kunci stringnya.

Menetapkan layanan penembolokan terdistribusi

Daftarkan implementasi IDistributedCache di Program.cs. Implementasi yang disediakan kerangka kerja yang dijelaskan dalam topik ini meliputi:

Cache Redis Terdistribusi

Sebaiknya aplikasi produksi menggunakan Cache Redis Terdistribusi karena ini adalah yang paling berkinerja. Untuk informasi selengkapnya, lihat Rekomendasi.

Redis adalah penyimpanan data dalam memori sumber terbuka, yang sering digunakan sebagai cache terdistribusi. Anda dapat mengonfigurasi Azure Redis Cache untuk aplikasi ASP.NET Core yang dihosting Azure, dan menggunakan Azure Redis Cache untuk pengembangan lokal.

Aplikasi mengonfigurasi implementasi cache menggunakan RedisCache instans (AddStackExchangeRedisCache).

  1. Buat Azure Cache for Redis.
  2. Salin string koneksi Utama (StackExchange.Redis) ke Konfigurasi.
    • Pengembangan lokal: Simpan string koneksi dengan Secret Manager.
    • Azure: Simpan string koneksi di App Service Configuration atau penyimpanan aman lainnya.

Kode berikut mengaktifkan Azure Cache for Redis:

builder.Services.AddStackExchangeRedisCache(options =>
 {
     options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
     options.InstanceName = "SampleInstance";
 });

Kode sebelumnya mengasumsikan string koneksi Utama (StackExchange.Redis) disimpan dalam konfigurasi dengan nama MyRedisConStrkunci .

Untuk informasi selengkapnya, lihat Azure Cache for Redis.

Lihat masalah GitHub ini untuk diskusi tentang pendekatan alternatif ke cache Redis lokal.

Singgahan Memori Terdistribusi

Singgahan Memori Terdistribusi (AddDistributedMemoryCache) adalah implementasi IDistributedCache yang disediakan kerangka kerja yang menyimpan item dalam memori. Singgahan Memori Terdistribusi bukan cache terdistribusi aktual. Item yang di-cache disimpan oleh instans aplikasi di server tempat aplikasi berjalan.

Singgahan Memori Terdistribusi adalah implementasi yang berguna:

  • Dalam skenario pengembangan dan pengujian.
  • Ketika satu server digunakan dalam produksi dan konsumsi memori bukanlah masalah. Menerapkan penyimpanan data cache Singgahan Memori Terdistribusi yang di-cache. Ini memungkinkan untuk menerapkan solusi penembolokan terdistribusi sejati di masa depan jika beberapa simpul atau toleransi kesalahan menjadi diperlukan.

Aplikasi sampel menggunakan Cache Memori Terdistribusi saat aplikasi dijalankan di lingkungan Pengembangan di Program.cs:

builder.Services.AddDistributedMemoryCache();

Singgahan SQL Server Terdistribusi

Implementasi Singgahan SQL Server Terdistribusi (AddDistributedSqlServerCache) memungkinkan cache terdistribusi menggunakan database SQL Server sebagai penyimpanan cadangannya. Untuk membuat tabel item cache SQL Server dalam instans SQL Server, Anda dapat menggunakan alat ini sql-cache . Alat ini membuat tabel dengan nama dan skema yang Anda tentukan.

Buat tabel di SQL Server dengan menjalankan sql-cache create perintah . Berikan instans SQL Server (Data Source), database (Initial Catalog), skema (misalnya, dbo), dan nama tabel (misalnya, TestCache):

dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache

Pesan dicatat untuk menunjukkan bahwa alat berhasil:

Table and index were created successfully.

Tabel yang sql-cache dibuat oleh alat ini memiliki skema berikut:

Tabel Cache SqlServer

Catatan

Aplikasi harus memanipulasi nilai cache menggunakan instans IDistributedCache, bukan SqlServerCache.

Aplikasi sampel diterapkan SqlServerCache di lingkungan non-Pengembangan di Program.cs:

builder.Services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString(
        "DistCache_ConnectionString");
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

Catatan

( ConnectionString dan opsional, SchemaName dan TableName) biasanya disimpan di luar kontrol sumber (misalnya, disimpan oleh Secret Manager atau dalam appsettings.json/appsettings.{Environment}.json file). string koneksi mungkin berisi kredensial yang harus dijaga dari sistem kontrol sumber.

Singgahan NCache Terdistribusi

NCache adalah cache terdistribusi sumber terbuka dalam memori yang dikembangkan secara asli di .NET dan .NET Core. NCache berfungsi baik secara lokal maupun dikonfigurasi sebagai kluster cache terdistribusi untuk aplikasi ASP.NET Core yang berjalan di Azure atau di platform hosting lainnya.

Untuk menginstal dan mengonfigurasi NCache di komputer lokal Anda, lihat Panduan Memulai untuk Windows (.NET dan .NET Core).

Untuk mengonfigurasi NCache:

  1. Instal NCache sumber terbuka NuGet.
  2. Konfigurasikan kluster cache di client.ncconf.
  3. Tambahkan kode berikut ke Program.cs:
builder.Services.AddNCacheDistributedCache(configuration =>
{
    configuration.CacheName = "democache";
    configuration.EnableLogs = true;
    configuration.ExceptionsEnabled = true;
});

Menggunakan cache terdistribusi

Untuk menggunakan IDistributedCache antarmuka, minta instans IDistributedCache di aplikasi. Instans disediakan oleh injeksi dependensi (DI).

Saat aplikasi sampel dimulai, IDistributedCache disuntikkan ke dalam Program.cs. Waktu saat ini di-cache menggunakan IHostApplicationLifetime (untuk informasi selengkapnya, lihat Host Generik: IHostApplicationLifetime):

app.Lifetime.ApplicationStarted.Register(() =>
{
    var currentTimeUTC = DateTime.UtcNow.ToString();
    byte[] encodedCurrentTimeUTC = System.Text.Encoding.UTF8.GetBytes(currentTimeUTC);
    var options = new DistributedCacheEntryOptions()
        .SetSlidingExpiration(TimeSpan.FromSeconds(20));
    app.Services.GetService<IDistributedCache>()
                              .Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
});

Aplikasi sampel dimasukkan IDistributedCache ke IndexModel dalam untuk digunakan oleh halaman Indeks.

Setiap kali halaman Indeks dimuat, cache diperiksa untuk waktu yang di-cache di OnGetAsync. Jika waktu yang di-cache belum kedaluwarsa, waktu akan ditampilkan. Jika 20 detik telah berlalu sejak terakhir kali waktu cache diakses (terakhir kali halaman ini dimuat), halaman menampilkan Waktu Singgahan Kedaluwarsa.

Segera perbarui waktu yang di-cache ke waktu saat ini dengan memilih tombol Reset Waktu Singgahan. Tombol memicu OnPostResetCachedTime metode handler.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

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

    public string? CachedTimeUTC { get; set; }
    public string? ASP_Environment { get; set; }

    public async Task OnGetAsync()
    {
        CachedTimeUTC = "Cached Time Expired";
        var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

        if (encodedCachedTimeUTC != null)
        {
            CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
        }

        ASP_Environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
        if (String.IsNullOrEmpty(ASP_Environment))
        {
            ASP_Environment = "Null, so Production";
        }
    }

    public async Task<IActionResult> OnPostResetCachedTime()
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

        return RedirectToPage();
    }
}

Tidak perlu menggunakan masa pakai Singleton atau Cakupan untuk IDistributedCache instans dengan implementasi bawaan.

Anda juga dapat membuat IDistributedCache instans di mana pun Anda mungkin memerlukannya alih-alih menggunakan DI, tetapi membuat instans dalam kode dapat membuat kode Anda lebih sulit untuk menguji dan melanggar Prinsip Dependensi Eksplisit.

Rekomendasi

Saat memutuskan implementasi IDistributedCache mana yang terbaik untuk aplikasi Anda, pertimbangkan hal berikut:

  • Infrastruktur yang ada
  • Persyaratan performa
  • Biaya
  • Pengalaman tim

Solusi penembolokan biasanya mengandalkan penyimpanan dalam memori untuk menyediakan pengambilan data yang di-cache dengan cepat, tetapi memori adalah sumber daya terbatas dan mahal untuk diperluas. Hanya simpan data yang umum digunakan dalam cache.

Untuk sebagian besar aplikasi, cache Redis menyediakan throughput yang lebih tinggi dan latensi yang lebih rendah daripada cache SQL Server. Namun, tolok ukur disarankan untuk menentukan karakteristik performa strategi penembolokan.

Ketika SQL Server digunakan sebagai penyimpanan cadangan cache terdistribusi, penggunaan database yang sama untuk cache dan penyimpanan dan pengambilan data biasa aplikasi dapat berdampak negatif pada performa keduanya. Sebaiknya gunakan instans SQL Server khusus untuk penyimpanan backing cache terdistribusi.

Sumber Daya Tambahan:

Cache terdistribusi adalah cache yang dibagikan oleh beberapa server aplikasi, biasanya dipertahankan sebagai layanan eksternal ke server aplikasi yang mengaksesnya. Cache terdistribusi dapat meningkatkan performa dan skalabilitas aplikasi ASP.NET Core, terutama ketika aplikasi dihosting oleh layanan cloud atau farm server.

Cache terdistribusi memiliki beberapa keunggulan dibandingkan skenario penembolokan lainnya di mana data cache disimpan di server aplikasi individual.

Saat data yang di-cache didistribusikan, data:

  • Koheren (konsisten) di seluruh permintaan ke beberapa server.
  • Bertahan hidupkan ulang server dan penyebaran aplikasi.
  • Tidak menggunakan memori lokal.

Konfigurasi cache terdistribusi spesifik implementasi. Artikel ini menjelaskan cara mengonfigurasi cache terdistribusi SQL Server dan Redis. Implementasi pihak ketiga juga tersedia, seperti NCache (NCache di GitHub). Terlepas dari implementasi mana yang dipilih, aplikasi berinteraksi dengan cache menggunakan IDistributedCache antarmuka .

Melihat atau mengunduh kode sampel (cara mengunduh)

Prasyarat

Untuk menggunakan cache terdistribusi SQL Server, tambahkan referensi paket ke paket Microsoft.Extensions.Caching.SqlServer .

Untuk menggunakan cache terdistribusi Redis, tambahkan referensi paket ke paket Microsoft.Extensions.Caching.StackExchangeRedis .

Untuk menggunakan cache terdistribusi NCache, tambahkan referensi paket ke paket NCache.Microsoft.Extensions.Caching.OpenSource .

Antarmuka IDistributedCache

Antarmuka IDistributedCache menyediakan metode berikut untuk memanipulasi item dalam implementasi cache terdistribusi:

  • Get, GetAsync: Menerima kunci string dan mengambil item yang di-cache sebagai byte[] array jika ditemukan di cache.
  • Set, SetAsync: Menambahkan item (sebagai byte[] array) ke cache menggunakan kunci string.
  • Refresh, RefreshAsync: Merefresh item dalam cache berdasarkan kuncinya, mengatur ulang batas waktu kedaluwarsa gesernya (jika ada).
  • Remove, RemoveAsync: Menghapus item cache berdasarkan kunci stringnya.

Menetapkan layanan penembolokan terdistribusi

Daftarkan implementasi IDistributedCache di Startup.ConfigureServices. Implementasi yang disediakan kerangka kerja yang dijelaskan dalam topik ini meliputi:

Singgahan Memori Terdistribusi

Singgahan Memori Terdistribusi (AddDistributedMemoryCache) adalah implementasi IDistributedCache yang disediakan kerangka kerja yang menyimpan item dalam memori. Singgahan Memori Terdistribusi bukan cache terdistribusi aktual. Item yang di-cache disimpan oleh instans aplikasi di server tempat aplikasi berjalan.

Singgahan Memori Terdistribusi adalah implementasi yang berguna:

  • Dalam skenario pengembangan dan pengujian.
  • Ketika satu server digunakan dalam produksi dan konsumsi memori bukanlah masalah. Menerapkan penyimpanan data cache Singgahan Memori Terdistribusi yang di-cache. Ini memungkinkan untuk menerapkan solusi penembolokan terdistribusi sejati di masa depan jika beberapa simpul atau toleransi kesalahan menjadi diperlukan.

Aplikasi sampel menggunakan Cache Memori Terdistribusi saat aplikasi dijalankan di lingkungan Pengembangan di Startup.ConfigureServices:

services.AddDistributedMemoryCache();

Singgahan SQL Server Terdistribusi

Implementasi Singgahan SQL Server Terdistribusi (AddDistributedSqlServerCache) memungkinkan cache terdistribusi menggunakan database SQL Server sebagai penyimpanan cadangannya. Untuk membuat tabel item cache SQL Server dalam instans SQL Server, Anda dapat menggunakan alat ini sql-cache . Alat ini membuat tabel dengan nama dan skema yang Anda tentukan.

Buat tabel di SQL Server dengan menjalankan sql-cache create perintah . Berikan instans SQL Server (Data Source), database (Initial Catalog), skema (misalnya, dbo), dan nama tabel (misalnya, TestCache):

dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache

Pesan dicatat untuk menunjukkan bahwa alat berhasil:

Table and index were created successfully.

Tabel yang sql-cache dibuat oleh alat ini memiliki skema berikut:

Tabel Cache SqlServer

Catatan

Aplikasi harus memanipulasi nilai cache menggunakan instans IDistributedCache, bukan SqlServerCache.

Aplikasi sampel diterapkan SqlServerCache di lingkungan non-Pengembangan di Startup.ConfigureServices:

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = 
        _config["DistCache_ConnectionString"];
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

Catatan

( ConnectionString dan opsional, SchemaName dan TableName) biasanya disimpan di luar kontrol sumber (misalnya, disimpan oleh Secret Manager atau dalam appsettings.json/appsettings.{Environment}.json file). string koneksi mungkin berisi kredensial yang harus dijaga dari sistem kontrol sumber.

Cache Redis Terdistribusi

Redis adalah penyimpanan data dalam memori sumber terbuka, yang sering digunakan sebagai cache terdistribusi. Anda dapat mengonfigurasi Azure Redis Cache untuk aplikasi ASP.NET Core yang dihosting Azure, dan menggunakan Azure Redis Cache untuk pengembangan lokal.

Aplikasi mengonfigurasi implementasi cache menggunakan RedisCache instans (AddStackExchangeRedisCache).

  1. Buat Azure Cache for Redis.
  2. Salin string koneksi Utama (StackExchange.Redis) ke Konfigurasi.
    • Pengembangan lokal: Simpan string koneksi dengan Secret Manager.
    • Azure: Simpan string koneksi di App Service Configuration atau penyimpanan aman lainnya.

Kode berikut mengaktifkan Azure Cache for Redis:

public void ConfigureServices(IServiceCollection services)
{
    if (_hostContext.IsDevelopment())
    {
        services.AddDistributedMemoryCache();
    }
    else
    {
        services.AddStackExchangeRedisCache(options =>
        {
            options.Configuration = _config["MyRedisConStr"];
            options.InstanceName = "SampleInstance";
        });
    }

    services.AddRazorPages();
}

Kode sebelumnya mengasumsikan string koneksi Utama (StackExchange.Redis) disimpan dalam konfigurasi dengan nama MyRedisConStrkunci .

Untuk informasi selengkapnya, lihat Azure Cache for Redis.

Lihat masalah GitHub ini untuk diskusi tentang pendekatan alternatif ke cache Redis lokal.

Singgahan NCache Terdistribusi

NCache adalah cache terdistribusi sumber terbuka dalam memori yang dikembangkan secara asli di .NET dan .NET Core. NCache berfungsi baik secara lokal maupun dikonfigurasi sebagai kluster cache terdistribusi untuk aplikasi ASP.NET Core yang berjalan di Azure atau di platform hosting lainnya.

Untuk menginstal dan mengonfigurasi NCache di komputer lokal Anda, lihat Panduan Memulai untuk Windows (.NET dan .NET Core).

Untuk mengonfigurasi NCache:

  1. Instal NCache sumber terbuka NuGet.

  2. Konfigurasikan kluster cache di client.ncconf.

  3. Tambahkan kode berikut ke Startup.ConfigureServices:

    services.AddNCacheDistributedCache(configuration =>    
    {        
        configuration.CacheName = "demoClusteredCache";
        configuration.EnableLogs = true;
        configuration.ExceptionsEnabled = true;
    });
    

Menggunakan cache terdistribusi

Untuk menggunakan IDistributedCache antarmuka, minta instans dari IDistributedCache konstruktor apa pun di aplikasi. Instans disediakan oleh injeksi dependensi (DI).

Saat aplikasi sampel dimulai, IDistributedCache disuntikkan ke dalam Startup.Configure. Waktu saat ini di-cache menggunakan IHostApplicationLifetime (untuk informasi selengkapnya, lihat Host Generik: IHostApplicationLifetime):

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    IHostApplicationLifetime lifetime, IDistributedCache cache)
{
    lifetime.ApplicationStarted.Register(() =>
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
    });

Aplikasi sampel dimasukkan IDistributedCache ke IndexModel dalam untuk digunakan oleh halaman Indeks.

Setiap kali halaman Indeks dimuat, cache diperiksa untuk waktu yang di-cache di OnGetAsync. Jika waktu yang di-cache belum kedaluwarsa, waktu akan ditampilkan. Jika 20 detik telah berlalu sejak terakhir kali waktu cache diakses (terakhir kali halaman ini dimuat), halaman menampilkan Waktu Singgahan Kedaluwarsa.

Segera perbarui waktu yang di-cache ke waktu saat ini dengan memilih tombol Reset Waktu Singgahan. Tombol memicu OnPostResetCachedTime metode handler.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

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

    public string CachedTimeUTC { get; set; }

    public async Task OnGetAsync()
    {
        CachedTimeUTC = "Cached Time Expired";
        var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

        if (encodedCachedTimeUTC != null)
        {
            CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
        }
    }

    public async Task<IActionResult> OnPostResetCachedTime()
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

        return RedirectToPage();
    }
}

Catatan

Tidak perlu menggunakan masa pakai Singleton atau Cakupan untuk IDistributedCache instans (setidaknya untuk implementasi bawaan).

Anda juga dapat membuat IDistributedCache instans di mana pun Anda mungkin memerlukannya alih-alih menggunakan DI, tetapi membuat instans dalam kode dapat membuat kode Anda lebih sulit untuk menguji dan melanggar Prinsip Dependensi Eksplisit.

Rekomendasi

Saat memutuskan implementasi IDistributedCache mana yang terbaik untuk aplikasi Anda, pertimbangkan hal berikut:

  • Infrastruktur yang ada
  • Persyaratan performa
  • Biaya
  • Pengalaman tim

Solusi penembolokan biasanya mengandalkan penyimpanan dalam memori untuk menyediakan pengambilan data yang di-cache dengan cepat, tetapi memori adalah sumber daya terbatas dan mahal untuk diperluas. Hanya simpan data yang umum digunakan dalam cache.

Umumnya, cache Redis memberikan throughput yang lebih tinggi dan latensi yang lebih rendah daripada cache SQL Server. Namun, tolok ukur biasanya diperlukan untuk menentukan karakteristik performa strategi penembolokan.

Ketika SQL Server digunakan sebagai penyimpanan cadangan cache terdistribusi, penggunaan database yang sama untuk cache dan penyimpanan dan pengambilan data biasa aplikasi dapat berdampak negatif pada performa keduanya. Sebaiknya gunakan instans SQL Server khusus untuk penyimpanan backing cache terdistribusi.

Sumber Daya Tambahan: