بررسی Read-Through و Write-Through Cache در سناریوهای چندکاربره

کشینگ یکی از تکنیک‌های اصلی در معماری سیستم‌های نرم‌افزاری مدرن است که به بهبود عملکرد و مقیاس‌پذیری سیستم‌ها کمک می‌کند. به‌ویژه در سیستم‌هایی که بار زیادی از درخواست‌های خواندن و نوشتن دارند، استفاده از کش می‌تواند باعث کاهش فشار روی دیتابیس‌ها و تسریع در پاسخ‌دهی به درخواست‌ها شود.

در این مقاله به بررسی دو الگوریتم کش محبوب Read-Through و Write-Through پرداخته می‌شود. این دو الگوریتم با هدف بهینه‌سازی دسترسی به داده‌ها در سیستم‌های پیچیده و چندکاربره طراحی شده‌اند. الگوریتم Read-Through Cache بیشتر برای سیستم‌هایی مناسب است که نیاز به خواندن داده‌های زیاد و تغییرات کم دارند، در حالی که Write-Through Cache برای سیستم‌هایی که تغییرات داده‌ها به‌طور مداوم انجام می‌شود، کاربرد دارد.

الگوریتم Read-Through Cache

مفهوم Read-Through Cache

الگوی Read-Through Cache به این صورت عمل می‌کند که داده‌ها ابتدا از کش خوانده می‌شوند. در صورتی که داده‌ها در کش موجود نباشند، از دیتابیس خوانده شده و به کش اضافه می‌شوند. این الگوریتم مناسب برای سیستم‌هایی است که بیشترین درخواست‌ها برای خواندن داده‌ها هستند و تغییرات در داده‌ها کم است.

پیاده‌سازی Read-Through Cache

در این پیاده‌سازی، Redis به‌عنوان کش و Entity Framework Core به‌عنوان ابزار تعامل با دیتابیس انتخاب شده‌اند. در صورتی که داده‌ای در کش موجود نباشد، آن داده از دیتابیس خوانده شده و سپس به کش اضافه می‌شود.

            
public class ProductService
{
    private readonly RedisService _redisService;
    private readonly ApplicationDbContext _dbContext;

    public ProductService(RedisService redisService, ApplicationDbContext dbContext)
    {
        _redisService = redisService;
        _dbContext = dbContext;
    }

    public async Task GetProductAsync(int productId)
    {
        var cacheKey = $"product:{productId}";
        var cachedProduct = await _redisService.Database.StringGetAsync(cacheKey);

        if (cachedProduct.HasValue)
        {
            return JsonSerializer.Deserialize(cachedProduct);
        }

        var product = await _dbContext.Products.FindAsync(productId);
        if (product != null)
        {
            await _redisService.Database.StringSetAsync(cacheKey, JsonSerializer.Serialize(product), TimeSpan.FromMinutes(10));
        }

        return product;
    }

    public async Task UpdateProductAsync(Product product)
    {
        var cacheKey = $"product:{product.Id}";

        _dbContext.Products.Update(product);
        await _dbContext.SaveChangesAsync();

        await _redisService.Database.KeyDeleteAsync(cacheKey);
    }
}
            
        

نکات:

  • در این الگوریتم، داده‌ها زمانی که در دیتابیس تغییر می‌کنند، کلید کش حذف می‌شود.
  • این باعث می‌شود که در دفعات بعدی، داده‌ها از دیتابیس خوانده شده و در کش ذخیره شوند.

الگوریتم Write-Through Cache

مفهوم Write-Through Cache

الگوی Write-Through Cache به این صورت عمل می‌کند که هر بار که داده‌ای در کش نوشته می‌شود، همزمان در دیتابیس نیز ذخیره می‌شود. این الگوریتم مناسب برای سیستم‌هایی است که تغییرات داده‌ها زیاد است و همگام‌سازی دقیق داده‌ها بین کش و دیتابیس اهمیت دارد.

پیاده‌سازی Write-Through Cache

در این پیاده‌سازی، Redis به‌عنوان کش و Entity Framework Core برای ذخیره‌سازی داده‌ها در دیتابیس استفاده می‌شود. هر بار که داده‌ای در کش ذخیره می‌شود، همزمان در دیتابیس نیز ذخیره می‌شود.

            
public class ProductService
{
    private readonly RedisService _redisService;
    private readonly ApplicationDbContext _dbContext;

    public ProductService(RedisService redisService, ApplicationDbContext dbContext)
    {
        _redisService = redisService;
        _dbContext = dbContext;
    }

    public async Task GetProductAsync(int productId)
    {
        var cacheKey = $"product:{productId}";
        var cachedProduct = await _redisService.Database.StringGetAsync(cacheKey);

        if (cachedProduct.HasValue)
        {
            return JsonSerializer.Deserialize(cachedProduct);
        }

        var product = await _dbContext.Products.FindAsync(productId);
        if (product != null)
        {
            await _redisService.Database.StringSetAsync(cacheKey, JsonSerializer.Serialize(product), TimeSpan.FromMinutes(10));
        }

        return product;
    }

    public async Task UpdateProductAsync(Product product)
    {
        var cacheKey = $"product:{product.Id}";

        _dbContext.Products.Update(product);
        await _dbContext.SaveChangesAsync();

        await _redisService.Database.StringSetAsync(cacheKey, JsonSerializer.Serialize(product), TimeSpan.FromMinutes(10));
    }
}
            
        

نکات:

  • در این الگوریتم، داده‌ها همیشه همزمان در کش و دیتابیس ذخیره می‌شوند.
  • این روش باعث می‌شود که همواره داده‌ها در کش و دیتابیس همگام باشند.

نتیجه‌گیری

در این مقاله، الگوریتم‌های Read-Through و Write-Through Cache را بررسی کردیم که برای بهبود عملکرد سیستم‌های نرم‌افزاری و کاهش بار روی دیتابیس‌ها طراحی شده‌اند. با پیاده‌سازی این الگوریتم‌ها با استفاده از Redis به عنوان کش و Entity Framework Core برای تعامل با دیتابیس، می‌توان کارایی سیستم‌ها را بهبود بخشید و فشار بر روی دیتابیس‌ها را کاهش داد.

این مقاله با ارائه کدهای عملی، شما را در درک بهتر و پیاده‌سازی این الگوریتم‌ها در پروژه‌های واقعی یاری می‌کند.