关于redis:Redis一原理与基本使用

@[toc]

一、Redis的外围概念

  1. 概念

    Redis就是分布式缓存,也能够了解成过程外的缓存。

    如图:

二、Redis的利用场景

  • 利用场景

    次要是利用在集群零碎中。

    • 单体我的项目就没必要用分布式缓存,应用本地缓存就能够;如图:

当客户端发动申请到零碎,零碎先去到本地缓存查问数据,没有查问到数据则到数据库查问,将查到的数据保留到本地缓存在返回到客户端;当第二次申请到零碎,零碎先去到本地缓存查问数据,则将缓存中的数据返回到客户端【第一次申请曾经将数据保留到本地缓存中】;那他本地缓存的命中率为 50%;
  • 应用本地缓存做分布式会有缓存命中率降落缺点;如图:

客户端发动申请到Nginx,Nginx将申请代理到零碎1,零碎1查看本地缓存没有符合条件的数据,再到数据库获取数据存到本地缓存再返回到客户端;当客户端在一次发动申请到Nginx,Nginx将申请代理到零碎2,零碎2查看本地缓存没有符合条件的数据,再到数据库获取数据存到本地缓存再返回到客户端,那么发动了两次申请都没有到本地缓存中获取到数据,那它缓存命中率为 0/2=0;缓存命中率降落那就表明整体查问性能降落。
  • 解决缓存命中率的计划

    将缓存数据集中到一起,应用Redis分布式缓存,如图:

三、Redis的我的项目落地

  • 条件

    • Demo我的项目
    • Redis 【在linux中部署】

      • Linux装置

        #装置 wget 命令
        yum -y install wget
        #下载
        wget http://download.redis.io/releases/redis-6.2.6.tar.gz
        #解压
        tar xzf redis-6.2.6.tar.gz
        #进入解压文件夹
        cd redis-6.2.6
        #装置 gcc
        yum install gcc
        #编译
        make
        #进入解压后的src目录,运行服务
        src/redis-server
  • Demo 我的项目配置

    • 步骤

      1. 装置Redis Nuget包

        StackExchange.Redis
      2. 定义一个扩大类

        public static IServiceCollection AddRedis(this IServiceCollection serviceCollection) 
                {
                    ConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect("IP:端口");
                    serviceCollection.AddSingleton(connectionMultiplexer);  
                    return serviceCollection;    
                }
      3. StateUp类注册【写了个扩大办法】

        services.AddRedis();
      4. Redis 存储和获取

        //注入
        public readonly ConnectionMultiplexer connectionMultiplexer; 
        public HomeController(ConnectionMultiplexer _connectionMultiplexer)
        { 
          connectionMultiplexer = _connectionMultiplexer;
        }
        // 获取Redis值
        obj = connectionMultiplexer.GetDatabase(0).StringGet(Key).ToString();
        //存储Redis值  Key:Value
        connectionMultiplexer.GetDatabase(0).StringSet(Key, Value);
      5. Redis 存储汇合

        //获取Redis是否存在
        RedisValue[] redisValues = connectionMultiplexer.GetDatabase(0).SetMembers("list");
         //Redis中不存在此数据
         if (redisValues.Length == 0)
        {
        //数据库中获取
         list = demoDbContext.Set<User>().ToList();
         List<RedisValue> rvList = new List<RedisValue>();
         foreach (User user in list)
         {
            obj = JsonConvert.SerializeObject(user);
            rvList.Add(obj);
         }
         //将数据增加到Redis中
          connectionMultiplexer.GetDatabase(0).SetAdd("list", rvList.ToArray());       
         } 
      6. Redis Hash字典存储

        应用场景:对数据库某个字段做批改或者某个int字段数据加一

        //获取HASH字段中的数据
         connectionMultiplexer.GetDatabase(0).HashGet(类型, key).ToString();
         if (string.IsNullOrEmpty(obj))
         {
           //到数据库获取数据
           u = demoDbContext.Set<User>().Where(p => p.useid == useid).FirstOrDefault();
           //将数据增加到Redis Hash字典中
           connectionMultiplexer.GetDatabase(0).HashSet(类型, key,Value);
           //设置过期工夫
           connectionMultiplexer.GetDatabase(0).KeyExpire(类型,TimeSpan.FromSeconds(10));
        
          }
          //字典中的Value值加1
          connectionMultiplexer.GetDatabase(0).HashIncrement(类型, key);
      7. Redis 事务

        //查问获取值
        connectionMultiplexer.GetDatabase(0).HashGet(类型, key).ToString();
        //创立事务
        ITransaction transaction = connectionMultiplexer.GetDatabase(0).CreateTransaction();
        //增加值
        transaction.HashSetAsync(类型, key, value);
        //批改值
        // transaction.HashSetAsync(类型, key,批改后Value);
        //提交事务
         bool commit = transaction.Execute();
      8. Redis 批量存储数据

         //创立批量对象
          var bach = connectionMultiplexer.GetDatabase(0).CreateBatch();
          //获取数据
          List<User> list = new List<User>();
          list = demoDbContext.user.ToList();
          //批量增加
          for (int i = 0; i < list.Count; i++)
          {
            bach.HashSetAsync("bach_User_"+i, "state", list[i].usestate);
          }
          //数据提交
          bach.Execute();
      9. Redis汇合排序

        //获取数据
        RedisValue[] rv = connectionMultiplexer.GetDatabase(0).SetMembers("User");
         if (rv.Length == 0)
         {
           list = demoDbContext.Set<User>().ToList();
           List<RedisValue> rvList = new List<RedisValue>();
           //批量增加数据
           foreach (User u in list) 
           {
              var  data = JsonConvert.SerializeObject(u);  
              rvList.Add(data);
               //数据排序
               connectionMultiplexer.GetDatabase(0).SortedSetAdd("User", data, u.usestate);  // User :key  data:Value值  u.usestate:排序字段  升序
          } 
      10. Redis分页查问

         List<User> list = new List<User>();
         //获取分页数据  100为行数,1为页数
         RedisValue[] rv = connectionMultiplexer.GetDatabase(0).SetScan("User",100,0,1).ToArray();
         if (rv.Length == 0)
           {
              list = demoDbContext.Set<User>().ToList();
              List<RedisValue> rvList = new List<RedisValue>();
              foreach (User u in list) 
              { 
                 var  data = JsonConvert.SerializeObject(u); 
                 rvList.Add(data); 
               }
               //增加数据到Redis中
              connectionMultiplexer.GetDatabase(0).SetAdd("User", rvList.ToArray());
            }

四、Redis的通信原理

Redis处理事件的简略模型:多路复用机制【一个线程解决多个连贯】【订阅公布机制】;

  • 原理

    默认通过Socket协定建设连贯的,服务端通过Socket的通过四层,在通过链路层再通过四层达到Redis建设连贯;链路层【硬件层面】收到申请后,操作系统【生产者】通过同步转换成异步将申请发给事件收集器【MQ】而后Redis【订阅者】用一个线程通过轮询的形式处理事件,这就是多路复用机制。

    Redis做的三件事:

    1、建设连贯

    2、存储数据到本地缓存

    3、长久化数据到文件中(开启新线程)

    如图:

五、Redis的数据结构原理

  • 原理

    Redis 建设连贯后,通过接口将数据存储到内存中。

    如图:

  • 数据长久化

    • 目标

      为了避免数据失落。默认寄存在AOP 文件中。

  • Redis Set原理图

    数组+HASH表,如图:

HASH的作用:避免数据反复,应用HASH碰撞。

  • Redis HASH字典原理

    数组+HASH表+单项列表。

    • 原理

      字典存储的字段通过hash失去一个数组的索引,依据索引将key \ value存储到数组中,如果失去的索引曾经存在key\value 了,不会笼罩掉,会造成一个单项链表的模式持续存储。

      如图:



![在这里插入图片形容](https://img-blog.csdnimg.cn/3e4a1a23c7a34ef1b8c2c16e34abf72d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQEDnpZ7lhpzlhpnku6PnoIE=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)

  • 缺点

    齐全基于内存,会导致内存溢出。不适宜存储海量数据。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理