zoukankan      html  css  js  c++  java
  • .Net Core 缓存方式(二)分布式缓存及MemoryDistributedCache 实现(1)

    .Net Core 缓存方式(二)分布式缓存

    官方文档

    分布式缓存是由多个应用服务器共享的缓存,通常作为外部服务在访问它的应用服务器上维护。 分布式缓存可以提高 ASP.NET Core 应用程序的性能和可伸缩性,尤其是在应用程序由云服务或服务器场托管时。
    与其他缓存方案相比,分布式缓存具有多项优势,其中缓存的数据存储在单个应用服务器上。
    当分布式缓存数据时,数据将:
    (一致性) 跨多个服务器的请求。
    置服务器重启和应用部署。
    不使用本地内存。

    IDistributedCache

    IDistributedCache接口提供以下方法:
    GetGetAsync:接受字符串键,并检索缓存项作为 byte[] 数组(如果在缓存中找到)。
    SetSetAsync:使用字符串键将项 (作为 byte[] 数组) 添加到缓存中。
    Refresh, RefreshAsync :基于其键刷新缓存中的项,如果有任何) ,则重置其可调过期超时 (。
    RemoveRemoveAsync:根据缓存项的字符串键删除缓存项。

    源码地址:https://github.com/dotnet/runtime/blob/master/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/IDistributedCache.cs

    分布式内存缓存使用方式

    Startup.ConfigureServices :

    services.AddDistributedMemoryCache();
    
        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();
            }
        }
    

    实现方式

    Microsoft.Extensions.Caching.Abstractions/src/IDistributedCache.cs

    // Licensed to the .NET Foundation under one or more agreements.
    // The .NET Foundation licenses this file to you under the MIT license.
    
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace Microsoft.Extensions.Caching.Distributed
    {
        /// <summary>
        /// Represents a distributed cache of serialized values.
        /// </summary>
        public interface IDistributedCache
        {
            /// <summary>
            /// Gets a value with the given key.
            /// </summary>
            /// <param name="key">A string identifying the requested value.</param>
            /// <returns>The located value or null.</returns>
            byte[] Get(string key);
    
            /// <summary>
            /// Gets a value with the given key.
            /// </summary>
            /// <param name="key">A string identifying the requested value.</param>
            /// <param name="token">Optional. The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
            /// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the located value or null.</returns>
            Task<byte[]> GetAsync(string key, CancellationToken token = default(CancellationToken));
    
            /// <summary>
            /// Sets a value with the given key.
            /// </summary>
            /// <param name="key">A string identifying the requested value.</param>
            /// <param name="value">The value to set in the cache.</param>
            /// <param name="options">The cache options for the value.</param>
            void Set(string key, byte[] value, DistributedCacheEntryOptions options);
    
            /// <summary>
            /// Sets the value with the given key.
            /// </summary>
            /// <param name="key">A string identifying the requested value.</param>
            /// <param name="value">The value to set in the cache.</param>
            /// <param name="options">The cache options for the value.</param>
            /// <param name="token">Optional. The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
            /// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
            Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken));
    
            /// <summary>
            /// Refreshes a value in the cache based on its key, resetting its sliding expiration timeout (if any).
            /// </summary>
            /// <param name="key">A string identifying the requested calue.</param>
            void Refresh(string key);
    
            /// <summary>
            /// Refreshes a value in the cache based on its key, resetting its sliding expiration timeout (if any).
            /// </summary>
            /// <param name="key">A string identifying the requested value.</param>
            /// <param name="token">Optional. The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
            /// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
            Task RefreshAsync(string key, CancellationToken token = default(CancellationToken));
    
            /// <summary>
            /// Removes the value with the given key.
            /// </summary>
            /// <param name="key">A string identifying the requested value.</param>
            void Remove(string key);
    
            /// <summary>
            /// Removes the value with the given key.
            /// </summary>
            /// <param name="key">A string identifying the requested value.</param>
            /// <param name="token">Optional. The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
            /// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
            Task RemoveAsync(string key, CancellationToken token = default(CancellationToken));
        }
    }
    

    AddDistributedMemoryCache 的实现

    • Microsoft.Extensions.Caching.Memory/src/MemoryCacheServiceCollectionExtensions.cs 依赖注入 IDistributedCache与 MemoryDistributedCache实现
            public static IServiceCollection AddDistributedMemoryCache(this IServiceCollection services)
            {
                if (services == null)
                {
                    throw new ArgumentNullException(nameof(services));
                }
    
                services.AddOptions();
                services.TryAdd(ServiceDescriptor.Singleton<IDistributedCache, MemoryDistributedCache>());
    
                return services;
            }
    
    
    • MemoryDistributedCache : IDistributedCache

    Microsoft.Extensions.Caching.Memory/src/MemoryDistributedCache.cs

    namespace Microsoft.Extensions.Caching.Distributed
    {
        public class MemoryDistributedCache : IDistributedCache
        {
            private readonly IMemoryCache _memCache;
    
            public MemoryDistributedCache(IOptions<MemoryDistributedCacheOptions> optionsAccessor)
                : this(optionsAccessor, NullLoggerFactory.Instance) { }
    
            public MemoryDistributedCache(IOptions<MemoryDistributedCacheOptions> optionsAccessor, ILoggerFactory loggerFactory)
            {
                if (optionsAccessor == null)
                {
                    throw new ArgumentNullException(nameof(optionsAccessor));
                }
    
                if (loggerFactory == null)
                {
                    throw new ArgumentNullException(nameof(loggerFactory));
                }
    
                _memCache = new MemoryCache(optionsAccessor.Value, loggerFactory);
            }
    
            public byte[] Get(string key)
            {
                if (key == null)
                {
                    throw new ArgumentNullException(nameof(key));
                }
    
                return (byte[])_memCache.Get(key);
            }
    
            public Task<byte[]> GetAsync(string key, CancellationToken token = default(CancellationToken))
            {
                if (key == null)
                {
                    throw new ArgumentNullException(nameof(key));
                }
    
                return Task.FromResult(Get(key));
            }
    
            public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
            {
                if (key == null)
                {
                    throw new ArgumentNullException(nameof(key));
                }
    
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(value));
                }
    
                if (options == null)
                {
                    throw new ArgumentNullException(nameof(options));
                }
    
                var memoryCacheEntryOptions = new MemoryCacheEntryOptions();
                memoryCacheEntryOptions.AbsoluteExpiration = options.AbsoluteExpiration;
                memoryCacheEntryOptions.AbsoluteExpirationRelativeToNow = options.AbsoluteExpirationRelativeToNow;
                memoryCacheEntryOptions.SlidingExpiration = options.SlidingExpiration;
                memoryCacheEntryOptions.Size = value.Length;
    
                _memCache.Set(key, value, memoryCacheEntryOptions);
            }
    
            public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken))
            {
                if (key == null)
                {
                    throw new ArgumentNullException(nameof(key));
                }
    
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(value));
                }
    
                if (options == null)
                {
                    throw new ArgumentNullException(nameof(options));
                }
    
                Set(key, value, options);
                return Task.CompletedTask;
            }
    
            public void Refresh(string key)
            {
                if (key == null)
                {
                    throw new ArgumentNullException(nameof(key));
                }
    
                _memCache.TryGetValue(key, out object value);
            }
    
            public Task RefreshAsync(string key, CancellationToken token = default(CancellationToken))
            {
                if (key == null)
                {
                    throw new ArgumentNullException(nameof(key));
                }
    
                Refresh(key);
                return Task.CompletedTask;
            }
    
            public void Remove(string key)
            {
                if (key == null)
                {
                    throw new ArgumentNullException(nameof(key));
                }
    
                _memCache.Remove(key);
            }
    
            public Task RemoveAsync(string key, CancellationToken token = default(CancellationToken))
            {
                if (key == null)
                {
                    throw new ArgumentNullException(nameof(key));
                }
    
                Remove(key);
                return Task.CompletedTask;
            }
        }
    }
    
  • 相关阅读:
    1033 To Fill or Not to Fill (25分)(贪心)
    CentOS(五)--Linux系统的分区概念
    Linux安装Oracle 11G过程(测试未写完)
    【VMware虚拟化解决方案】设计和配置VMware vCenter 5.5
    CentOS(四)--Linux系统的启动级别
    CentOS(三)--初识linux的文件系统以及用户组等概念
    CentOS(二)--初识linux的一些常用命令
    CentOS(一)--CentOS6.4环境搭建
    Linux c/c++图片传输功能(中级版)
    remote uptime 服务器程序
  • 原文地址:https://www.cnblogs.com/WNpursue/p/13498220.html
Copyright © 2011-2022 走看看