Redis数据库基础与ASP.NET Core缓存实现

目录
  • 基础
    • Redis库
    • 连接Redis
    • 能用redis干啥
    • Redis数据库存储
      • 字符串
    • 订阅发布
    • RedisValue
  • ASP.NETCore缓存与分布式缓存
    • 内存中的缓存
      • ASP.NETCore的内存缓存
      • 在内存中缓存、存储数据
      • IMemoryCache
      • MemoryCache
    • 分布式缓存
      • IDistributedCache
      • Redis缓存

基础

Redis 库

C# 下 Redis-Client 开源的库很多,有 BeetleX.Redis、csredis、Nhiredis、redis-sharp、redisboost、Rediska、ServiceStack.Redis、Sider、StackExchange.Redis、TeamDev Redis Client。

这里我们使用 StackExchange.Redis,另外 csredis 现在叶老板(Freesql作者)贡献了大量维护,并且叶老板新开了一个叫 FreeRedis 的框架,目前正在开发中,有兴趣可以参与开发或提出建议。

连接 Redis

创建一个 .NET Core 项目,Nuget 库添加引用 StackExchange.Redis ,使用最新版本。

Redis 默认端口为 6379,如果要连接本地 Redis 服务:

ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost:6379");
// ”{ip}:{port}“

如果使用 redis 集群,则使用 , 分隔地址:

ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("server1:port1,server2:port2,server3:port3");

可能要注意区分集群模式,多 redis 实例的地址,适合主从模式的集群或者 redis culster 集群,哨兵模式笔者还没有测试过。

能用 redis 干啥

redis 具有很多应用场景,一般使用到的场景有:

  • 存储数据(当数据库使用)
  • 利用 pub/sub 做消息队列

接下来将介绍这两种场景的使用方法。

Redis 数据库存储

访问 redis 数据库:

IDatabase db = redis.GetDatabase();

Redis 默认有 16 个数据库,可以 GetDatabase(int db ) 获取指定的数据库。

使用了 redis cluster 集群的 redis 节点,只有一个数据库,不能自由选择。这里我们只需要使用 redis.GetDatabase() 即可 。

Redis 使用比较简单的,大多时候,只要有相应的应用场景,我们查询文档很快就可以掌握,所以这里只介绍字符串的使用。

字符串

redis 的字符串参考:字符串string

IDatabase 中包含 string 类型的数据操作,其 API 使用 String 开头,辨识度高。

设置一个字符串数据:

            db.StringSet("A", "这是一条字符串数据的值");
            var value = db.StringGet("A");

如果字符串使用 byte[] (二进制)存储,也可以设置值:

            byte[] str=... ...
            db.StringSet("A", str;

Redis 里面,还有其它很多类型,这里我们只介绍字符串,因为 API 其实就那么些,用到的时候再学也可以的。先学字符串的使用,其它就是触类旁通了。

订阅发布

订阅某个 Topic,当其改变状态时,订阅者可以收到通知,做分布式消息队列也行。类似 MQTT 协议这样。

获取订阅器:

ISubscriber sub = redis.GetSubscriber();

选择订阅的 Topic,并设置回调函数:

sub.Subscribe("Message", (channel, message) => {
    Console.WriteLine((string)message);
});

当某一方订阅了 Message ,在另一个地方,有别的客户端(也可以是自己)推送 Topic :

sub.Publish("Message","你有一条新的消息,请注意查收");

Topic 推送后,订阅方可以收到推送的消息。

测试代码

            ISubscriber sub = redis.GetSubscriber();

            sub.Subscribe("Message", (channel, message) => {
                Console.WriteLine((string)message);
            });

            Thread.Sleep(1000);

            sub.Publish("Message","你有一条新的消息,请注意查收");

channel :Topic 的名称,即上面的 Message。

message:推送的消息内容。

RedisValue

使用 API 设置值的时候,都会有这个参数。因为 Redis 中的值只能是 “字符串”,因此 C# 中也要遵守这种规则,但是 C# 是强类型语言,而且有那么多值类型,只使用 string ,编写代码时会有诸多不便。

因此,就创建了 RedisValue 这个类型,里面有大量的隐式转换重载,所以我们可以使用 C# 的简单类型存储数据以及获取数据,避免手工转换。

当然这个说法不是很准确,使用 RedisValue 主要考虑转换方便。

入门的知识就介绍到这里,更多的 Redis 知识可以查看官方文档。下面开始介绍 AS.NET Core 使用分布式缓存。

ASP.NET Core 缓存与分布式缓存

ASP.NET Core 里面有很多定义的标准接口,例如日志、缓存等,这些接口为开发者设置了统一的定义和功能,上层服务不需要变更代码就能切换类库,底层使用哪种库对上层没有影响。

ASP.NET Core 中的缓存,可以使用多种方式完成,例如 Redis,内存,关系型数据库,文件缓存等。而且根据拓展性,可以分为本机缓存,分布式缓存。

本机缓存常见的是内存缓存,内存缓存可以存储任何对象。 分布式缓存最常见的是 Redis,分布式缓存接口仅限 byte[](指参数,继续看到后面的小节就明白了) 。 内存缓存和分布式缓存都使用键值对来存储缓存项。

内存中的缓存

ASP.NET Core 的内存缓存

ASP.NET Core 内存缓存是指一般是单机(本机)使用的,一般这种内存缓存框架是 System.Runtime 或 Microsoft 包提供的,因为不需要考虑分布式或者复杂的结构,所以一般不需要第三方库。这里的内存缓存并不只是指数据在内存中,所以需要区分 Redis 这类专业的缓存框架。且这里缓存只是作为提高性能而用。

这种缓存主要有两种功能比较丰富的实现 System.Runtime.Caching 和MemoryCache。

在内存中缓存、存储数据

在 ASP.NET Core 的内存缓存之外,我们来讨论一下,编写代码时,自己设置的内存缓存是否合理。

我们都知道,使用内存缓存是为了提高代码性能而用的

这里笔者个人认为可以从两个层次来对这种缓存归类讨论。

第一种,对于要多次使用、而每次使用都需要计算、源数据相同则结果相同的,可以使用内存缓存。例如反射就比较消耗时间(速度慢),可以使用内存缓存起来,下次直接取得信息而不需要重新计算。

下面笔者说一下理由。

内存缓存用在反射缓存这类缓存上,缓存的数据源是可确定的、可计算总量的,而且这部分内存不需要频繁增加或者减少,不仅提高了性能,对 GC 来说也可以一定程度上减少回收压力,更重要的是开发者可以降低缓存的复杂程度。

这种缓存主要为了避免重复计算,或者重复导入(例如加载程序集、从文件加载数据)等。如果数据最近出现过,而且后面一段时间不会变化,使用内存来缓存也很实在,例如 MVC 的视图、每15分钟刷新一次的排行榜等。

第二种是使用内存存储数据,很多人单纯是因为内存存储数据特别快,把内存当作数据库来玩,因此很容易导致内存泄露。最常见的就是使用静态字典、静态列表等,然后编写方法增删查改数据,这一类在压力测试下或者请求量大一些、变动比较频繁的时候,内存堆积特别厉害。

需要频繁变化或需要实时变化的数据,存储在内存中确实速度非常快,如何确定数据失效、去除无用数据等需要有很深的考虑。

另外,在内存中如使用字典大量存储数据,数据量很多的情况下,每次索引数据的时间都会变长,如果使用了 Linq 或者 for 或者 foreach 等检索数据,也很容易出现耗时长的时间复杂度。这种情况下,你是相信自己的代码,还是相信 Mysql、SqlServer 等数据库? Hash 算法和红黑树都了解了嘛?

如果实在有需求需要使用内存缓存数据,并且可能动态增加或移除数据的话,可以使用 WeakReference 弱引用,即在引用对象的同时仍然允许 GC 回收该对象。缺点是数据可能丢失,不适合需要持久化的数据。

但无论情况,我们可以确定:

  • 缓存都是副本
  • 缓存丢失不影响程序的使用
  • 缓存不能无限增长
  • 缓存避免复杂结构
  • ... ...

IMemoryCache

IMemoryCache 提供的接口太少了:

        ICacheEntry CreateEntry(object key);
        void Remove(object key);
        bool TryGetValue(object key, out object value);

适合单一的键值缓存。

此接口在 Microsoft.Extensions.Caching.Memory 中有实现,例如 MemoryCache 。适合 ASP.NET Core 中使用。

MemoryCache

这里的 MemoryCache 并不是指 IMemoryCache 的实现,而是指 System.Runtime.Caching.MemoryCache,需要安装 Nuget 包。

可以实现对实例对象的缓存,请查看查看官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.caching.memorycache?view=dotnet-plat-ext-3.1

另外内存缓存还有一个分布式内存缓存,但不是真正的分布式,信息可以参考:https://docs.microsoft.com/zh-cn/aspnet/core/performance/caching/distributed?view=aspnetcore-3.1#distributed-memory-cache

分布式缓存

ASP.NET Core 分布式缓存,则使用了 IDistributedCache 这个统一的接口。如果你在 Nuget 搜索 IDistributedCache ,会发现相关的库非常多。

分布式缓存的使用,除了最常见的 Redis,SQLServer 也行,只要实现了 IDistributedCache 就ok。

IDistributedCache

IDistributedCache 接口提供的方法实在太少了,有四个异步方法四个同步方法,这里只介绍异步方法。

方法 说明
GetAsync(String, CancellationToken) 获取一个键的值
RefreshAsync(String, CancellationToken) 基于缓存中某个值的键刷新该值,并重置其可调到期超时(如果有)
RemoveAsync(String, CancellationToken) 删除一个键
SetAsync(String, Byte[], DistributedCacheEntryOptions, CancellationToken) 设置一个键的值

局限还是很大的,只能使用字符串。估计大家可能没怎么使用?

ASP.NET Core 官方支持的分布式缓存,目前主要有 NCache、Redis、SqlServer。本节只讨论 Redis。

Redis 缓存

StackExchange.Redis 是 ASP.NET Core 官方推荐的 Redis 框架,并且官方对其做了封装,可以到 Nuget 搜索 Microsoft.Extensions.Caching.StackExchangeRedis 。

RedisCache 继承了 IDistributedCache 接口。

Startup.ConfigureServices 中配置服务注册:

            services.AddStackExchangeRedisCache(options =>
            {
                options.Configuration = "ip:端口,ip1:端口,ip2:端口";	// redis 集群或单机
                options.InstanceName = "mvc";						// 实例 名称
            });

依赖注入:

        private readonly IDistributedCache _cache;

示例:

        public async Task<string> Test(string key,string value)
        {
            await _cache.SetStringAsync(key, value);
            return await _cache.GetStringAsync(key);
        }

设置缓存时间:

            var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
            await _cache.SetStringAsync(key, value, options);

到此这篇关于Redis数据库基础与ASP.NET Core缓存实现的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解如何在ASP.NET Core中使用Redis

    Redis 是一个开源的内存中的数据结构存储系统,可以用作数据库.缓存和消息中间件.它支持多种类型的数据结构:字符串,哈希表,列表,集合,有序集等等. Redis 官方没有推出Windows版本,倒是由Microsoft Open Tech提供了Windows 64bit 版本支持. 如何在Windows机器上安装Redis=>下载安装文件Redis-x64-3.2.100.msi,安装完毕之后,打开service管理器,找到Redis服务,并将其启动.  前期准备: 1.推荐使用Visual

  • Asp.net core中RedisMQ的简单应用实现

    最近一个外部的项目,使用到了消息队列,本来是用rabbitmq实现的,但是由于是部署到别人家的服务器上,想尽量简化一些,项目中本来也要接入了redis缓存,就尝试使用redis来实现简单的消息队列. 使用redis做消息队列有两种方法,一种是使用pub/sub,另一种是使用list结构,配合brpop来消费.这两种方式各有特点,这里简述一下: pub/sub模式,支持多客户端消费,但是不支持持久化,这就意味着客户端断开的时间内发布的消息将会全部舍弃掉. list配合brpop,默认不支持多客户端

  • 详解ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁

    引言:最近回头看了看开发的.Net Core 2.1项目的复盘总结,其中在多处用到Redis实现的分布式锁,虽然在OnResultExecuting方法中做了防止死锁的处理,但在某些场景下还是会发生死锁的问题,下面我只展示部分代码: 问题: (1)这里setnx设置的值"1",我想问,你最后del的这个值一定是你自己创建的吗? (2)图中标注的步骤1和步骤2不是原子操作,会有死锁的概率吗? 大家可以思考一下先,下面让我们带着这两个问题往下看,下面介绍一下使用Redis实现分布式锁常用的

  • .NET Core中使用Redis与Memcached的序列化问题详析

    前言 在使用分布式缓存的时候,都不可避免的要做这样一步操作,将数据序列化后再存储到缓存中去. 序列化这一操作,或许是显式的,或许是隐式的,这个取决于使用的package是否有帮我们做这样一件事. 本文会拿在.NET Core环境下使用Redis和Memcached来当例子说明,其中,Redis主要是用StackExchange.Redis,Memcached主要是用EnyimMemcachedCore. 先来看看一些我们常用的序列化方法. 常见的序列化方法 或许,比较常见的做法就是将一个对象序列

  • .net core如何使用Redis发布订阅

    Redis是一个性能非常强劲的内存数据库,它一般是作为缓存来使用,但是他不仅仅可以用来作为缓存,比如著名的分布式框架dubbo就可以用Redis来做服务注册中心.接下来介绍一下.net core 使用Redis的发布/订阅功能. Redis 发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的通道. 下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 -- client2 .

  • .net core使用redis基于StackExchange.Redis

    .net core使用redis基于StackExchange.Redis教程,具体如下 一.添加引用包 StackExchange.Redis Microsoft.Extensions.Configuration 二.修改配置文件 appsettings.json { "RedisConfig": { "Redis_Default": { "Connection": "127.0.0.1: 6379", "Inst

  • 详解Asp.net Core 使用Redis存储Session

    前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储Session来做一个简单的测试,或者叫做中间件(middleware). 对于Session来说褒贬不一,很多人直接说不要用,也有很多人在用,这个也没有绝对的这义,个人认为只要不影什么且又可以方便实现的东西是可以用的,现在不对可不可用做表态,我们只关心实现. 类库引用 这个相对于之前的.net是方便了不少,需要在project.json中的dependencies节点中添加如下内容: "StackExc

  • ASP.NET Core扩展库ServiceStack.Redis用法介绍

    给大家安利一款 ServiceStack.Redis 的 ASP.NET Core 扩展库,它是基于 ServiceStack.Redis.Core 开发的. 简单易用,开源免费,使用ASP.NET Core自身提供的DI容器来实现针对服务的注册和消费.直接在程序启动时注册到服务中即可完成全部配置,对于小白用户也可快速上手Redis缓存和Redis分布式缓存. Install Package https://www.nuget.org/packages/ServiceStack.Redis.Ex

  • .NET Core实现简单的Redis Client框架

    目录 0,关于RedisRESP 1,定义数据类型 2,定义异步消息状态机 3,定义命令发送模板 4,定义RedisClient 5,实现简单的RESP解析 6,实现命令发送客户端 7,如何使用 8,更多客户端 9,更多测试 10,性能测试 0,关于 Redis RESP RESP 全称 REdis Serialization Protocol ,即 Redis 序列化协议,用于协定客户端使用 socket 连接 Redis 时,数据的传输规则. 官方协议说明:https://redis.io/

  • Redis数据库基础与ASP.NET Core缓存实现

    目录 基础 Redis库 连接Redis 能用redis干啥 Redis数据库存储 字符串 订阅发布 RedisValue ASP.NETCore缓存与分布式缓存 内存中的缓存 ASP.NETCore的内存缓存 在内存中缓存.存储数据 IMemoryCache MemoryCache 分布式缓存 IDistributedCache Redis缓存 基础 Redis 库 C# 下 Redis-Client 开源的库很多,有 BeetleX.Redis.csredis.Nhiredis.redis-

  • ASP.NET Core缓存静态资源示例详解

    背景 缓存样式表,JavaScript或图像文件等静态资源可以提高您网站的性能.在客户端,总是从缓存中加载一个静态文件,这样可以减少对服务器的请求数量,从而减少获取页面及其资源的时间.在服务器端,由于它们的请求较少,服务器可以处理更多的客户端而无需升级硬件. 虽然缓存是一件好事,但您必须确保客户端始终运行最新版本的应用程序.当您部署下一个版本的网站时,您不希望客户端使用过时的缓存版本的文件. 方案: 为确保用户始终使用最新版本的文件,我们必须为每个文件版本提供一个唯一的URL.有很多策略: 使用

  • 详解Asp.Net Core 2.1+的视图缓存(响应缓存)

    响应缓存Razor 页与 ASP.NET 核心 2.0 中不支持. 此功能将支持ASP.NET 核心 2.1 版本. 在老的版本的MVC里面,有一种可以缓存视图的特性(OutputCache),可以保持同一个参数的请求,在N段时间内,直接从mvc的缓存中读取,不去走视图的逻辑. [OutputCache(Duration =20)]//设置过期时间为20秒 public ActionResult ExampleCacheAction() { var time=DateTime.Now.ToStr

  • ASP.NET Core MVC缓存Tag Helpers到内存

    简介 缓存可以大大提高应用程序加载时间和响应速度.我们可以使用缓存Tag Helpers缓存不会频繁更改的HTML内容. 在上一篇文章中,我们谈到了Tag Helpers,演示Tag Helpers能做什么.如何使用它们以及一些最常用的Tag Helpers. 今天,我们将看看如何使用缓存Tag Helpers和它们的益处. Cache Tag Helper 首先说一下 <cache> Tag Helper.与其它Tag Helper不同,其它Tag Helper被当作属性使用,缓存Tag H

  • 详解ASP.NET Core 中间件之压缩、缓存

    前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是Microsoft.AspNetCore.ResponseCompression 和 Microsoft.AspNetCore.ResponseCaching , 下面让我们一起看看的功能以及如何去使用吧. Getting Started Microsoft.AspNetCore.ResponseCompression Microsoft.AspNetCo

  • ASP.NET Core WebSocket集群实现思路详解

    目录 前言 实现 nginx配置 一对一发送 群组发送 发送所有人 整合到一起 一对一处理 群组处理 全员消息处理 示例源码 总结 前言 提到WebSocket相信大家都听说过,它的初衷是为了解决客户端浏览器与服务端进行双向通信,是在单个TCP连接上进行全双工通讯的协议.在没有WebSocket之前只能通过浏览器到服务端的请求应答模式比如轮询,来实现服务端的变更响应到客户端,现在服务端也可以主动发送数据到客户端浏览器.WebSocket协议和Http协议平行,都属于TCP/IP四层模型中的第四层

  • ASP.NET Core中使用Redis实现缓存

    目录 一.前言 二.安装StackExchange.Redis 三.添加配置 四.Redis帮助类 五.添加服务依赖项 六.在控制器中使用 七.测试 一.前言 我们这里以StackExchange.Redis为例,讲解如何在ASP.NET Core中如何使用Redis实现缓存.首先需要安装Redis和RedisDesktopManager.RedisDesktopManager用来查看Redis缓存里面的数据.如何安装Redis这里不在讲述. 二.安装StackExchange.Redis 在N

  • ASP.NET Core MVC/WebApi基础系列1

    >前言 最近发表的EF Core貌似有点多,可别误以为我只专攻EF Core哦,私下有时间也是一直在看ASP.NET Core的内容,所以后续会穿插讲EF Core和ASP.NET Core,别认为你会用ASP.NET Core就自认为你很了解ASP.NET Core,虽说是基础系列但也是也有你不知道的ASP.NET Core. UseStaticFiles.UseDefaultFiles.UseDirectoryBrowser.UseFileServer 当我们创建默认.NET Core We

  • 如何在ASP.Net Core使用分布式缓存的实现

    ASP.Net Core 提供了多种类型的缓存,除了内存缓存和响应缓存之外,还提供了对 分布式缓存 的支持.在之前的一篇文章中,我讨论了 ASP.Net Core 的内存缓存.在本文中,我们将讨论如何在 ASP.Net Core 中使用分布式缓存,本篇就拿 Redis 和 SQL Server 作为演示. 什么是分布式缓存 分布式缓存 可用于提高应用程序的性能和可伸缩性,通常 分布式缓存 被多个应用服务器共享,在分布式缓存中,缓存的数据不会落在某些个别的web服务器内存中,这些缓存数据采用集中化

随机推荐