Redis由浅入深系列(废弃,已经建新目录了)
一. 简介
1. 什么是Redis?
全称“Remote Dictionary Server”,基于内存管理数据,它有多种数据结构(常用的5种),分别应对不同场景;它是单线程模型的,所以不会存在并发问题,数据不会出现中间状态;对外提供:增删改查、固化、集群等功能,包含0-15个数据存储库。
PS:Redis主要用来提升性能的,尽量不要作为数据的最终依据(当然可以配置高并发架构持久化存储到硬盘)。
官网:https://redis.io/ 下载地址:https://download.redis.io/releases/
中文版:http://www.redis.cn/
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 }
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 }
1.直接通过Redis客户端操作
打开客户端【redis-cli.exe】, 默认存储的是0库,可以通过命令set和get指定进行存储和查询,比如:【set fristName Y】和【get firstName】,如果要选择2库或3库,可以通过指令【select 2】和【select 3】来进行。
补充:如果要连接别的服务器端,通过指令 【 redis-cli -h 192.168.137.201 -p 6379 -a 123456】,-a是密码。
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 }
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 }
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 }
三. 系列章节
旧版目录:
第二节: Set类型和SortedSet类型的介绍和案例应用
第三节: List类型的介绍、生产者消费者模式、发布订阅模式
第四节:Geo类型介绍以及Redis批量操作、事务、分布式锁
第五节:Redis架构演变历程和cluster集群模式架构的搭建
新版目录:(即将更新)
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。