簡體   English   中英

Redis是否是本地緩存的可行解決方案?

[英]Is Redis a viable solution for a local cache?

在我的場景中,我有一個連接到WebApi2的Winforms客戶端。 數據存儲在SQL Server數據庫中。

為了加快性能,我正在研究將數據存儲在本地緩存中是否是可行的解決方案。 優選地,本地高速緩存應該存儲在文件中而不是保存在存儲器中,因為RAM可能是個問題。 數據是所有POCO類,有些比其他類復雜得多,並且大多數類彼此相關。

我列出了哪些框架可行的候選名單:

  1. 的MemoryCache
  2. Memcached的
  3. 的CacheManager
  4. StackExchange.Redis
  5. 本地數據庫

使用MemoryCache ,我需要實現自己的解決方案,但它符合我的初始要求。

但是,我看到的一個常見問題是更新相關類。 例如,我在CustomerAddressPostCode之間存在關系。 如果我更改郵政編碼對象中的某些屬性,我可以輕松更新其本地緩存。 但是如何更新/無效使用此郵政編碼的任何其他類,在本例中為CustomerAddress

上面的任何框架是否都有幫助這種情況的方法,還是完全依賴於開發人員來處理這種緩存失效?

為了加快性能,我正在研究將數據存儲在本地緩存中是否是可行的解決方案。 優選地,本地高速緩存應該存儲在文件中而不是保存在存儲器中,因為RAM可能是個問題

整個問題是避免將其存儲在文件中,以避免緩慢的DISK操作,因此Redis是基於RAM的內存。

上面的任何框架是否都有幫助這種情況的方法,還是完全依賴於開發人員來處理這種緩存失效?

您可以將整個對象保存為JSON,而不是應用邏輯並反匯編對象,這在應用更改時也會很慢並且容易出錯。

CachingFramework.Redis庫提供了一種將標記與鍵和哈希相關聯的機制,以便您可以在單個操作中使它們無效。

我假設你會:

  • 使用“ 地址:{AddressId} ”等密鑰將客戶地址存儲在Redis中。
  • 使用“ PostCode:{PostCodeId} ”等密鑰將郵政編碼存儲在Redis中。

而且你的模型是這樣的:

public class CustomerAddress
{
    public int CustomerAddressId { get; set; }
    public int CustomerId { get; set; }
    public int PostCodeId { get; set; }
}
public class PostCode
{
    public int PostCodeId { get; set; }
    public string Code { get; set; }
}

我的建議是:

  • 使用“ Tag-PostCode:{PostCodeId} ”之類的標記在Redis上標記客戶地址對象。
  • 使用緩存模式從緩存/數據庫中檢索客戶地址和后代碼。
  • 更改郵政編碼時,按標簽使緩存對象無效。

這樣的事情應該可行:

public class DataAccess
{
    private Context _cacheContext = new CachingFramework.Redis.Context("localhost:6379");

    private string FormatPostCodeKey(int postCodeId)
    {
        return string.Format("PostCode:{0}", postCodeId);
    }

    private string FormatPostCodeTag(int postCodeId)
    {
        return string.Format("Tag-PostCode:{0}", postCodeId);
    }

    private string FormatAddressKey(int customerAddressId)
    {
        return string.Format("Address:{0}", customerAddressId);
    }

    public void InsertPostCode(PostCode postCode)
    {
        Sql.InsertPostCode(postCode);
    }

    public void UpdatePostCode(PostCode postCode)
    {
        Sql.UpdatePostCode(postCode);
        //Invalidate cache: remove CustomerAddresses and PostCode related
        _cacheContext.Cache.InvalidateKeysByTag(FormatPostCodeTag(postCode.PostCodeId));
    }

    public void DeletePostCode(int postCodeId)
    {
        Sql.DeletePostCode(postCodeId);
        _cacheContext.Cache.InvalidateKeysByTag(FormatPostCodeTag(postCodeId));
    }

    public PostCode GetPostCode(int postCodeId)
    {
        // Get/Insert the postcode from/into Cache with key = PostCode{PostCodeId}. 
        // Mark the object with tag = Tag-PostCode:{PostCodeId}
        return _cacheContext.Cache.FetchObject(
            FormatPostCodeKey(postCodeId),              // Redis Key to use
            () => Sql.GetPostCode(postCodeId),          // Delegate to get the value from database
            new[] { FormatPostCodeTag(postCodeId) });   // Tags related
    }

    public void InsertCustomerAddress(CustomerAddress customerAddress)
    {
        Sql.InsertCustomerAddress(customerAddress);
    }

    public void UpdateCustomerAddress(CustomerAddress customerAddress)
    {
        var updated = Sql.UpdateCustomerAddress(customerAddress);
        if (updated.PostCodeId != customerAddress.PostCodeId)
        {
            var addressKey = FormatAddressKey(customerAddress.CustomerAddressId);
            _cacheContext.Cache.RenameTagForKey(addressKey, FormatPostCodeTag(customerAddress.PostCodeId), FormatPostCodeTag(updated.PostCodeId));
        }
    }

    public void DeleteCustomerAddress(CustomerAddress customerAddress)
    {
        Sql.DeleteCustomerAddress(customerAddress.CustomerAddressId);
        //Clean-up, remove the postcode tag from the CustomerAddress:
        _cacheContext.Cache.RemoveTagsFromKey(FormatAddressKey(customerAddress.CustomerAddressId), new [] { FormatPostCodeTag(customerAddress.PostCodeId) });
    }

    public CustomerAddress GetCustomerAddress(int customerAddressId)
    {
        // Get/Insert the address from/into Cache with key = Address:{CustomerAddressId}. 
        // Mark the object with tag = Tag-PostCode:{PostCodeId}
        return _cacheContext.Cache.FetchObject(
            FormatAddressKey(customerAddressId),
            () => Sql.GetCustomerAddress(customerAddressId),
            a => new[] { FormatPostCodeTag(a.PostCodeId) });
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM