[Azure] Redis 缓存的实施
为了提高性能,引入缓存。推荐用于处理大量读取的JSON数据。
例如,现在有一个显示全国地区的页面。都道府县存储在数据库中,虽然它们不会经常变化,但为了方便,我们将其存储在数据库中,并在缓存中存储对应数据。在页面显示时,会先查看缓存中的数据。我们预期的是这样的运作方式。
仅需一种选项:请以中文本地化地重新表述以下内容:
请参考以下内容
我从这里参考了实现方法。
首先,我们将创建一个管理缓存的客户端。我们可以使用Nuget上提供的库来实现此功能。
之前
现在的情况是这样的。我通过访问数据库,在指定的国家ID下,联接了区域列表和该区域内的都道府县,并将其输出。
/// <summary>
/// Get regions by area id.
/// </summary>
/// <param name="areaId"></param>
/// <param name="keyword"></param>
/// <param name="sort"></param>
/// <param name="currentPage"></param>
/// <param name="itemsPerPage"></param>
/// <returns></returns>
public PaginationModel<RegionModel> GetRegionsByAreaId(string areaId, string keyword, string sort, int currentPage, int itemsPerPage)
{
var regions = from r in _db.Regions
join c in _db.AreaRegions on r.Id equals c.RegionId
where c.AreaId == areaId
select r;
if (!string.IsNullOrEmpty(keyword))
{
regions = regions.Where(c => c.EnglishName.Contains(keyword));
}
if (string.IsNullOrEmpty(sort))
{
regions = regions.OrderBy(c => c.DisplayOrder);
}
int totalItems = regions.Count();
int totalPages = 0;
if (totalItems > 0)
{
totalPages = (totalItems / itemsPerPage) + 1;
}
var result = new PaginationModel<RegionModel>()
{
Items = regions.ToList(),
Sort = sort,
CurrentPage = currentPage,
ItemsPerPage = itemsPerPage,
Keyword = keyword,
TotalItems = totalItems,
TotalPages = totalPages
};
return result;
}
完成
本次,在预先存储搜索结果的缓存中,检查是否已经存储了具有相同条件的输出结果,如果有的话,则从缓存中获取,这种实现可以减轻对数据库的负载。
当相关地区或其所属的都道府县信息发生更新时,需要同时更新缓存,因此请注意这一点。
将以下代码添加到另一个类中。
public class CacheServices
{
private static readonly string connectionStringUs = "";
private static readonly Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
return ConnectionMultiplexer.Connect(connectionStringUs);
});
/// <summary>
/// Returns ConnectionMultiplexer object
/// </summary>
public static ConnectionMultiplexer Connection => lazyConnection.Value;
}
然后,我们将从缓存中获取信息并在获取实际区域的类中进行输出。
public async Task<PaginationModel<RegionModel>> GetRegionsByAreaIdAsync(string areaId, string keyword, string sort, int currentPage = 1, int itemsPerPage = 100)
{
// Only if keyword is null, let's try to find value in cahce.
if (string.IsNullOrEmpty(keyword))
{
IDatabase cache = CacheServices.Connection.GetDatabase();
var result = await cache.StringGetAsync("GetRegionsByAreaId-" + areaId);
if (result.HasValue)
{
var cacheReult = JsonSerializer.Deserialize<PaginationModel<RegionModel>>(result);
return cacheReult;
}
else
{
// There was no data in cache, so fetch.
var dbResult = GetRegionsByAreaIdFromDb(areaId, keyword, sort, currentPage, itemsPerPage);
// And want to cache this.
string jsonString = JsonSerializer.Serialize(dbResult);
await cache.StringSetAsync("GetRegionsByAreaId-" + areaId, jsonString);
return dbResult;
}
}
var dbresultWKeyword = GetRegionsByAreaIdFromDb(areaId, keyword, sort, currentPage, itemsPerPage);
// And don't want to cache this.
return dbresultWKeyword;
}