แคชไฮบริด
แคชแบบไฮบริดคือไลบรารีแบบรวมสำหรับการแคชข้อมูลในหน่วยความจำและแหล่งข้อมูลภายนอก ซึ่งสามารถเรียกอีกอย่างว่าการแคชแบบหลายชั้น กล่าวอีกนัยหนึ่ง การแคชหลายระดับนี้มาแทนที่ IDistributedCache และ IMemoryCache นอกจากนี้ยังมีจุดมุ่งหมายเพื่อลดความซับซ้อนของการใช้แคชใน .NET วิธีการเก่าสำหรับ Distributed Caching จำเป็นต้องเขียนโค้ดเพิ่มเติมเพื่อให้แน่ใจว่าสิ่งต่างๆ ได้รับการแคชและดึงข้อมูลอย่างถูกต้อง แพ็คเกจนี้เป็นส่วนเสริมที่น่าทึ่งในการลดความซับซ้อนของการแคชใน .NET เพื่อสร้างโซลูชันการแคชที่มีประสิทธิภาพ เราใช้ Microsoft เพื่อใช้งานแพ็คเกจ nuget แคชแบบไฮบริด Extensions.Caching. ในบทความนี้ เราจะกล่าวถึงคุณลักษณะทั้งหมดของแพ็คเกจแคชแบบไฮบริด
คุณสมบัติของแพ็คเกจ
- โค้ดที่ขยายได้: รหัสที่เขียนสำหรับแคชในหน่วยความจำสามารถใช้ได้ตามที่เป็นอยู่โดยไม่ต้องแก้ไขเพื่อรวมกับเซิร์ฟเวอร์แคชภายนอก เช่น Redis, SQL Server ฯลฯ
- การจัดการภาวะพร้อมกัน: หากต้องการใช้แคชแบบไฮบริด เราต้องใช้คลาสแคชแบบไฮบริดเป็นบริการอ้างอิง คลาสนี้ช่วยให้แน่ใจว่ามีการใช้อินสแตนซ์เท่านั้นเพื่อรับข้อมูลสำหรับคีย์ใดๆ และไม่มีการร้องขอพร้อมกันสำหรับรายการเดียวกัน คำขอที่เกิดขึ้นพร้อมกันทั้งหมดรอให้คำขอนี้เสร็จสิ้น
- การแคชหลายแหล่งที่มา/การแคชแหล่งที่มาหลัก-รอง: หากแอปพลิเคชันได้กำหนดค่าแหล่งข้อมูลหลายแห่งสำหรับการแคช ข้อมูลจะถูกจัดเก็บไว้ในทุกตำแหน่ง
หากต้องการรับข้อมูล จะต้องตรวจสอบในแหล่งที่มาหลักก่อน หากไม่มีข้อมูลดังกล่าว คำขอจะถูกส่งต่อไปยังแหล่งที่มารอง ดังที่แสดงในแผนภาพด้านล่าง สถานการณ์ที่ 1 เป็นสีน้ำเงิน และสถานการณ์ที่ 2 เป็นสีแดง
ป>
การตั้งค่าโค้ด ป>
ในการเริ่มต้น ก่อนอื่นเราจะติดตั้งแพ็คเกจ Microsoft.Extensions.Caching.Hybrid
ใน Program.cs เราจะเขียนโค้ดด้านล่างเพื่อเพิ่มแคชไฮบริด
builder.Services.AddHybridCache(); ในการกำหนดค่าแคชไฮบริด เราจะเขียนโค้ดด้านล่างภายใน AddHybridCache เป็นการดำเนินการตั้งค่า ด้านล่างนี้คือตัวอย่าง
builder.Services.AddHybridCache(options =>
{
options.ReportTagMetrics = true;
options.DefaultEntryOptions = new Microsoft.Extensions.Caching.Hybrid.HybridCacheEntryOptions
{
Expiration = TimeSpan.FromSeconds(30),
LocalCacheExpiration = TimeSpan.FromSeconds(30),
};
});
ใช้งานแคชในหน่วยความจำ
การกำหนดค่าบริการอ้างอิงข้างต้นเพียงพอสำหรับเราในการแคชในหน่วยความจำ ด้านล่างนี้คือโค้ดตัวอย่างในตัวควบคุม API เพื่อตั้งค่าและรับคีย์และค่าในหน่วยความจำแอปพลิเคชัน
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Hybrid;
namespace HybridCacheDemoApplication.Controllers
{
[ApiController]
[Route("[controller]")]
public class CacheController : ControllerBase
{
private readonly HybridCache _cache;
const string cacheKey = "ping";
public CacheController(HybridCache cache)
{
_cache = cache;
}
[HttpGet(Name = "GetPingKey")]
public async Task<IActionResult> Get()
{
var keydata = await _cache.GetOrCreateAsync<string>(
cacheKey, // Unique key to the cache entry
async cancel => await Task.FromResult("pong from get")
);
return Ok(new {message = $"{cacheKey} data: {keydata}"});
}
[HttpGet("set",Name = "SetPingKey")]
public async Task<IActionResult> Set()
{
await _cache.SetAsync<string>(cacheKey, "ping");
return Ok(new { message = $"{cacheKey} is set" });
}
}
}
เพื่อทำความเข้าใจวิธีการทำงานของโค้ดนี้ โปรดดูตารางด้านล่างตามลำดับ
ตารางสาธิตการดำเนินการแคช
คำอธิบายเอาต์พุตจุดสิ้นสุดลำดับ 1 http://localhost:5154/cache/
{
"message": "ping data: pong from get"
} จุดสิ้นสุดนี้ตั้งค่าแคชเป็น "pong from get" เมื่อไม่ได้ตั้งค่า ดังนั้นมันจะพิมพ์ "pong from get" 2 http://localhost:5154/cache/set
{
"message": "ping is set"
} จุดสิ้นสุดนี้จะตั้งค่าในแคช 3 http://localhost:5154/cache/
{
"message": "ping data: ping"
} นี่เป็นจุดสิ้นสุดเดียวกันกับที่เราเรียกใช้ใน 1 ขั้นตอน แต่คราวนี้ ค่ามีอยู่แล้วในแคช ลบคีย์แคช:หากต้องการลบคีย์แคช เราใช้วิธีการด้านล่าง
[HttpGet("del",Name="DeletePingKey")]
public async Task<IActionResult> RemoveKey()
{
await _cache.RemoveAsync(cacheKey); //Removes data
return Ok(new {message=$"{cacheKey} removed"});
} แคชแบบกระจายโดยใช้เซิร์ฟเวอร์ Redis
หากต้องการใช้แคชแบบกระจาย เราจำเป็นต้องดำเนินการกำหนดค่าบริการการพึ่งพาเพิ่มเติม สำหรับตัวอย่างนี้ เราจะใช้แคช Redis เป็นแหล่งแคชภายนอก
ตอนนี้ เราจะกำหนดค่าแพ็คเกจ Redis โดยใช้ Microsoft.Extensions.Caching.StackExchangeRedis
เมื่อติดตั้งแล้ว เราจะต้องเพิ่มโค้ดด้านล่างเพื่อเพิ่ม Redis สตริงการเชื่อมต่อของเราจะอยู่ในรูปแบบ {HOST_NAME}:{PORT_NUMBER},password={PASSWORD}
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration =
builder.Configuration.GetConnectionString("RedisConnectionString");
}); ตอนนี้ เราจะเรียกใช้ http://localhost:5154/cache/set และข้อมูลจะถูกตั้งค่าในแคช Redis ได้อย่างราบรื่น ด้านล่างนี้คือลักษณะที่ปรากฏใน Redis

สังเกตว่าโค้ดของเราทำงานได้อย่างราบรื่นเพียงเพิ่มการพึ่งพาสำหรับเซิร์ฟเวอร์แคชแบบกระจาย เช่น Redis ในสถานการณ์ของเรา
การทำให้เป็นอนุกรม
หากต้องการส่งข้อมูลไปยังเซิร์ฟเวอร์แคชภายนอก แพ็คเกจนี้ใช้ไบต์[] สตริง และ System.Text.Json ซึ่งสามารถปรับแต่งเพิ่มเติมได้โดยใช้เมธอด .AddSerializer() หรือ AddSerializerFactory() เพิ่มเติมด้วยบริการพึ่งพา AddHybridCache เมื่อเราใช้ซีเรียลไลเซอร์ที่ได้รับการปรับปรุงประสิทธิภาพมากขึ้น พวกมันจะปรับปรุงประสิทธิภาพของแอปพลิเคชัน
การปรับแต่งเพิ่มเติม
เราสามารถปรับแต่งพฤติกรรมของบริการแคชเพิ่มเติมได้โดยตั้งค่าสถานะเมื่อกำหนดค่าการขึ้นต่อกัน ด้านล่างนี้คือตัวอย่างแฟล็กหนึ่งรายการที่จะปิดใช้งานการบีบอัดแคช
หมายเหตุ นี่ไม่ใช่แนวทางปฏิบัติที่ดีที่สุด แต่อาจแตกต่างกันไปขึ้นอยู่กับสถานการณ์เมื่อไม่จำเป็นต้องใช้หรือใช้การบีบอัด
builder.Services.AddHybridCache(options =>
{
options.ReportTagMetrics = true;
options.DefaultEntryOptions = new Microsoft.Extensions.Caching.Hybrid.HybridCacheEntryOptions
{
Flags = Microsoft.Extensions.Caching.Hybrid.HybridCacheEntryFlags.DisableCompression
};
}); คุณลักษณะทดลอง:แท็ก - การทำงานกับคีย์ที่เกี่ยวข้องกัน
ในบางครั้ง เราอาจต้องรับมือกับคีย์ต่างๆ ที่เกี่ยวข้องกัน ตัวอย่าง: ในแอปพลิเคชันอีคอมเมิร์ซ เราได้แคชฟิลด์จำนวนมากที่สอดคล้องกับรายการในรถเข็นให้กับผู้ใช้ สำหรับสิ่งนี้ เราสามารถสร้างแท็กได้
ด้านล่างนี้คือโค้ด สำหรับการทำงานกับคีย์ที่เกี่ยวข้องกันซึ่งเราได้สร้างแท็กชื่อ "testdata" เราสามารถเพิ่มแท็กได้มากกว่าหนึ่งแท็ก ขึ้นอยู่กับประเภทของการจัดกลุ่มที่ใช้ได้กับสถานการณ์ที่แตกต่างกัน รหัสนี้อธิบายได้ในตัว แต่ในกรณีที่เกิดความสับสน โปรดระบุรหัสดังกล่าวในความคิดเห็น
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Hybrid;
namespace HybridCacheDemoApplication.Controllers
{
[ApiController]
[Route("[controller]")]
public class CacheController : ControllerBase
{
private readonly HybridCache _cache;
const string cacheKey = "ping";
public CacheController(HybridCache cache)
{
_cache = cache;
}
[HttpGet(Name = "GetPingKey")]
public async Task<IActionResult> Get()
{
var keydata = await _cache.GetOrCreateAsync<string>(
cacheKey, // Unique key to the cache entry
async cancel => await Task.FromResult("pong from get"),
tags: ["testdata"]
);
return Ok(new {message = $"{cacheKey} data: {keydata}"});
}
[HttpGet("set",Name = "SetPingKey")]
public async Task<IActionResult> Set()
{
await _cache.SetAsync<string>(cacheKey,
"ping",
tags: ["testdata"]
);
return Ok(new { message = $"{cacheKey} is set" });
}
[HttpGet("del",Name="DeletePingKey")]
public async Task<IActionResult> RemoveKey()
{
await _cache.RemoveAsync(cacheKey);
return Ok(new {message=$"{cacheKey} removed"});
}
[HttpGet("delbytag", Name = "DeleteByTestTags")]
public async Task<IActionResult> RemoveKeyByTags()
{
await _cache.RemoveByTagAsync(["testdata"]);
return Ok(new { message = $"{cacheKey} removed" });
}
}
}
ขอบคุณที่อ่านจนจบ การแคชแบบไฮบริดนี้ให้ประโยชน์ที่น่าทึ่ง และฉันหวังว่าคุณจะพบว่าสิ่งนี้มีประโยชน์เช่นกัน