• NoSql之Redis系列(.Net Core)


    一. 简介

    1. 什么是Redis?

      全称“Remote Dictionary Server”,基于内存管理数据,它有多种数据结构(常用的5种),分别应对不同场景;它是单线程模型的,所以不会存在并发问题,数据不会出现中间状态;对外提供:增删改查、固化、集群等功能,包含0-15个数据存储库。

    PS:Redis主要用来提升性能的,尽量不要作为数据的最终依据(当然可以配置高并发架构持久化存储到硬盘)。

    2. Redis优点

    (1).支持 string、hash、set、sortedset、list、geo 等复杂的数据结构。

    (2).高命中的数据运行时是在内存中,数据最终还是可以保存到磁盘中,这样服务器重启之后数据还在。

    (3).服务器是单线程的,来自所有客户端的所有命令都是串行执行的,因此不用担心并发修改(串行操作当然还是有并发问题)的问题,编程模型简单。

    (4).支持消息订阅/通知机制,可以用作消息队列。

    (5).Key、Value 最大长度允许512M。

      特别说明:Redis的单线程不用担心并发指定是每个单一操作之间是单线程,比如客户端同时发过来多个针对同一key的StringIncrement自增操作,Redis端是串行进行的,有先后,不会同时进行。 但是如果客户端每个请求是一个组合操作,比如:先KeyExists,再KeyDelete;这个时候很可能第一个客户端KeyExists的时候,数据是存在的,当它要KeyDelete,该数据已经被别的客户端删除了。

    3.Redis缺点

    (1) Redis 是单线程的,因此单个 Redis 实例只能使用一个CPU核,不能充分发挥服务器的性能。可以在一台服务器上运行多个 Redis 实例,不同实例监听不同端口,再互相组成集群。

    (2) 做缓存性能不如 Memcached;

    4. 常用工具说明和下载

    (1) Redis的Windows版本下载

      https://github.com/MicrosoftArchive/redis/tags, 目前最新版本【3.2.1】, .zip类型的是手动exe打开部署, .msi是自动部署成windows服务。

    PS:Linux下的Redis已经到了5.x版本了

    (2) .Net的两个程序集

      a. StackExchange.Redis:免费.【推荐】 (目前最新版本:2.0.601),里面的每类方法基本上都有对应的异步方法

      b. ServiceStack.Redis:收费(1小时3600次请求限制),但可以破解,后面介绍

    (3).可视化客户端程序:RedisDesktopManager

    5. 六大数据结构

    (1).String:典型的key-value集合。

    (2).Hash:一个key(hashid)对应,多个key-value集合。

    (3).Set:一个key对应多个value,且value值不重复,且无序。

    (4).SortedSet:一个key对应多个 member-score,member不重复。

    (5).List:是一个双向链表,可以左进、左出、右进、右出。

    (6).Geo:用来保存兴趣点(POI,point of interest)的坐标信息。可以实现计算两 POI 之间的距离、获取一个点周边指定距离的 POI。

    6.Windows版Redis包含文件介绍

    (1). redis-server.exe:Redis的服务程序

    (2). redis-cli.exe:连接当前Redis服务的客户端

    (3). redis.conf : redis相应配置

    (4). redis-check-aof.exe:更新日志检查

    (5). dump.rdb:持久化到本地保存的数据库文件

     

    二. 基本使用

     前提:

      ①.管理员身份启动Redis服务器【redis-server.exe】,打开可视化客户端RedisDesktopManager进行查看。

      ②.通过Nuget给Utils层安装程序集【StackExchange.Redis】,将Redis的两个帮助类RedisHelp和RedisHelp2也放到该类,这里我们使用RedisHelp类。

    分享RedisHelp相关类代码

     1     /// <summary>
     2     /// Redis帮助类(写法1)
     3     /// </summary>
     4     public class RedisHelp
     5     {
     6         private string _connectionString; //连接字符串
     7         private int _defaultDB; //默认数据库
     8         private readonly ConnectionMultiplexer connectionMultiplexer;
     9 
    10         /// <summary>
    11         /// 构造函数
    12         /// </summary>
    13         /// <param name="connectionString"></param>
    14         /// <param name="defaultDB">默认使用Redis的0库</param>
    15         public RedisHelp(string connectionString, int defaultDB = 0)
    16         {
    17             _connectionString = connectionString;
    18             _defaultDB = defaultDB;
    19             connectionMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
    20         }
    21 
    22         /// <summary>
    23         /// 获取数据库
    24         /// </summary>
    25         /// <returns></returns>
    26         public IDatabase GetDatabase()
    27         {
    28             return connectionMultiplexer.GetDatabase(_defaultDB);
    29         }
    30 
    31     }
    RedisHelp
     1      /// <summary>
     2     /// Redis帮助类(写法2)
     3     /// </summary>
     4     public class RedisHelp2 : IDisposable
     5     {
     6         private string _connectionString; //连接字符串
     7         private string _instanceName; //实例名称
     8         private int _defaultDB; //默认数据库
     9         private ConcurrentDictionary<string, ConnectionMultiplexer> _connections;
    10         public RedisHelp2(string connectionString, string instanceName, int defaultDB = 0)
    11         {
    12             _connectionString = connectionString;
    13             _instanceName = instanceName;
    14             _defaultDB = defaultDB;
    15             _connections = new ConcurrentDictionary<string, ConnectionMultiplexer>();
    16         }
    17 
    18         /// <summary>
    19         /// 获取ConnectionMultiplexer
    20         /// </summary>
    21         /// <returns></returns>
    22         private ConnectionMultiplexer GetConnect()
    23         {
    24             return _connections.GetOrAdd(_instanceName, p => ConnectionMultiplexer.Connect(_connectionString));
    25         }
    26 
    27         /// <summary>
    28         /// 获取数据库
    29         /// </summary>
    30         /// <param name="configName"></param>
    31         /// <param name="db">默认为0:优先代码的db配置,其次config中的配置</param>
    32         /// <returns></returns>
    33         public IDatabase GetDatabase()
    34         {
    35             return GetConnect().GetDatabase(_defaultDB);
    36         }
    37 
    38         public IServer GetServer(string configName = null, int endPointsIndex = 0)
    39         {
    40             var confOption = ConfigurationOptions.Parse(_connectionString);
    41             return GetConnect().GetServer(confOption.EndPoints[endPointsIndex]);
    42         }
    43 
    44         public ISubscriber GetSubscriber(string configName = null)
    45         {
    46             return GetConnect().GetSubscriber();
    47         }
    48 
    49         public void Dispose()
    50         {
    51             if (_connections != null && _connections.Count > 0)
    52             {
    53                 foreach (var item in _connections.Values)
    54                 {
    55                     item.Close();
    56                 }
    57             }
    58         }
    59     }
    RedisHelp2

    1.直接通过Redis客户端操作

      打开客户端【redis-cli.exe】, 默认存储的是0库,可以通过命令set和get指定进行存储和查询,比如:【set fristName Y】和【get firstName】,如果要选择2库或3库,可以通过指令【select 2】和【select 3】来进行。

    补充:如果要连接别的服务器端,通过指令【 redis-cli.exe -h 127.0.0.1 -p 6379】

    2.DotNet Core控制台操作

      实例化RedisHelp类,传入连接字符串和默认数据库,进行string类型的key-value存储和查询.

     (1). 客户端读取配置文件,并创建RedisHelp实例。 通过Nuget安装程序集:【Microsoft.Extensions.Configuration】和【Microsoft.Extensions.Configuration.Json】

    1 {
    2   "RedisStr": {
    3     "connectionString": "localhost:6379",
    4     "defaultDB": 0
    5   }
    6 }
    1             //读取Redis的相关配置
    2             var configurationBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
    3             var Configuration = configurationBuilder.Build();
    4             var _connectionString = Configuration["RedisStr:connectionString"]; //连接字符串
    5             int _defaultDB = Convert.ToInt32(Configuration["RedisStr:defaultDB"]);  //默认数据库
    6             RedisHelp redis = new RedisHelp(_connectionString, _defaultDB);
    7             var db = redis.GetDatabase();

     (2). 进行简单的插入和查询操作。

    1 db.StringSet("name", "fk");
    2 Console.WriteLine("插入成功");
    3 string d1 = db.StringGet("name");
    4 Console.WriteLine($"获取成功,name的值为{d1}");

    3.CoreMvc操作

      在类ConfigureServices中获取Redis的配置并注册RedisHelp单例类,然后在对应控制器中进行注入使用即可。RedisHelp注册成单例类,然后在对应的控制器中进行注入,使用即可。这里再补充一种读取配置文件的方式,利用IOptions<T>,详见下面RedisHelp_Test类的注入。

     1      /// <summary>
     2     /// Redis帮助类(写法1)
     3     /// </summary>
     4     public class RedisHelp
     5     {
     6         private string _connectionString; //连接字符串
     7         private int _defaultDB; //默认数据库
     8         private readonly ConnectionMultiplexer connectionMultiplexer;
     9 
    10         /// <summary>
    11         /// 构造函数
    12         /// </summary>
    13         /// <param name="connectionString"></param>
    14         /// <param name="defaultDB">默认使用Redis的0库</param>
    15         public RedisHelp(string connectionString, int defaultDB = 0)
    16         {
    17             _connectionString = connectionString;
    18             _defaultDB = defaultDB;
    19             connectionMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
    20         }
    21 
    22         /// <summary>
    23         /// 获取数据库
    24         /// </summary>
    25         /// <returns></returns>
    26         public IDatabase GetDatabase()
    27         {
    28             return connectionMultiplexer.GetDatabase(_defaultDB);
    29         }
    30 
    31     }
    RedisHelp
     1      /// <summary>
     2     /// 内容同RedisHelp相同,这里是为了测试另外一种配置文件读取的方式
     3     /// </summary>
     4     public class RedisHelp_Test
     5     {
     6         private readonly IOptions<RedisSetting> _redisSetting;
     7         private readonly ConnectionMultiplexer _connectionMultiplexer;
     8 
     9         /// <summary>
    10         /// 构造函数
    11         /// </summary>
    12         /// <param name="connectionString"></param>
    13         /// <param name="defaultDB">默认使用Redis的0库</param>
    14         public RedisHelp_Test(IOptions<RedisSetting> redisSetting)
    15         {
    16             this._redisSetting = redisSetting;
    17             _connectionMultiplexer = ConnectionMultiplexer.Connect(_redisSetting.Value.connectionString);
    18         }
    19 
    20         /// <summary>
    21         /// 获取数据库
    22         /// </summary>
    23         /// <returns></returns>
    24         public IDatabase GetDatabase()
    25         {
    26             return _connectionMultiplexer.GetDatabase(_redisSetting.Value.defaultDB);
    27         }
    28     }
    RedisHelp_Test
    1 {
    2   "RedisStr": {
    3     "connectionString": "localhost:6379",
    4     "defaultDB": 0
    5   }
    6 }
     1         public void ConfigureServices(IServiceCollection services)
     2         {
     3             //获取Redis配置,注入RedisHelp单例对象
     4             {
     5                 var connectionString = Configuration["RedisStr:connectionString"];
     6                 int defaultDB = Convert.ToInt32(Configuration["RedisStr:defaultDB"]);
     7                 services.AddSingleton(new RedisHelp(connectionString, defaultDB));
     8             }
     9             //另外一种读取Redis配置的方法
    10             {
    11                 services.AddOptions().Configure<RedisSetting>(Configuration.GetSection("RedisStr"));
    12                 services.AddSingleton<RedisHelp_Test>();
    13             }
    14             services.AddControllersWithViews();
    15         }
     1  public class HomeController : Controller
     2     {
     3         private readonly IDatabase _redis;
     4         private readonly IDatabase _redis2;
     5         public HomeController(RedisHelp redisHelp,RedisHelp_Test redisHelp_Test)
     6         {
     7             _redis = redisHelp.GetDatabase();
     8             _redis2 = redisHelp_Test.GetDatabase();
     9         }
    10         public IActionResult Index()
    11         {
    12                 _redis.StringSet("myName", "ypf");
    13                 var data = _redis.StringGet("myName");
    14                 var data2 = _redis2.StringGet("myName");
    15                  return View();
    16         }
    17     }
    HomeController

    三. 后续目录

              第一节: String类型和Hash类型的介绍和案例应用

              第二节: Set类型和SortedSet类型的介绍和案例应用

              第三节: List类型的介绍、生产者消费者模式、发布订阅模式

              第四节:Geo类型介绍以及Redis批量操作、事务、分布式锁

              第五节:Redis架构演变历程和cluster集群模式架构的搭建

              第六节:秒杀业务/超卖问题的几种解决思路

              第七节:

              第八节:

     

    !

    • 作       者 : Yaopengfei(姚鹏飞)
    • 博客地址 : http://www.cnblogs.com/yaopengfei/
    • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
    • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    云开发数据库 Firebase Firestore 零基础入门视频实战教程(7 个视频)
    在 2021 年你需要掌握的 7 种关于 JavaScript 的数组方法
    2021 年写 JavaScript 代码的 17 个优化技巧
    Redis 学习笔记系列文章之 Redis 的安装与配置 (一)
    selenium webdriver 删除元素
    FFT板子
    pytest一:运行几个简单的测试用例终端显示的信息
    JS 日期取年月日
    将博客搬至CSDN
    c语言编译器
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/11889700.html
Copyright © 2020-2023  润新知