• .Net Redis 入门到熟练


    内存缓存主要有两种,一种是应用服务自己的memcache,类似于 webapi的session 其实都是服务自己的应用级内存,另外一种是分布式的缓存服务,此服务在另外的机器上,耗费的都是此机器的内存资源。

    分布式缓存服务,在.Net技术栈下,我所知的有两种,第一个是Redis支持内存又支持保存到本地。第二个是Memcached 应该只支持内存服务。

    所以,这种内存型的缓存,内存是越大越好,我是见过几百G的内存做的缓存服务,更大的,目前我还没有见到。

    Redis的安装

    网上有教程,可以参考,安装地址 : https://github.com/MicrosoftArchive/redis/releases

    也可以注册官网的 https://redis.com/try-free/ 免费资源,大概一百M左右好像,支持的功能多,测试用很方便。

    我安装此类服务直接就是Docker Desktop ,直接就部署了。方便的很。

    所以,建议,可以搜一下,安装个Docker Desktop,安装,卸载都很方便。

    Docker命令如下:

    docker run --name redis  -p 6379:6379 -d redis
    
    • 1

    就一行代码,就可以了,大致如下图,下载完就OK,直接自己启动服务了

    可以看到 服务已经启动了。

    接下来,就是连接到服务,看看效果如何

    Redis Desktop Manager

    现在此服务是收费的,果然好的东西,就会收费。

    但是可以下载早期版本。

    https://github.com/uglide/RedisDesktopManager/releases/tag/0.9.3

    下载后,直接安装

    基本都是下一步,下一步。

    直接打开就是这个样子

    然后,把刚才的redis的服务地址给搞上去,我这边都是默认就可以用了。

    也可以点击测试连接,我这边直接就连上了。


    双击连接,就看到了我们的16个redis的数据库了

    至此,redis的服务安装完毕,也能看到里面是啥子了。

    这个 Redis Desktop Manager 就能做很多的操作,读啊,写数据,但是,我们还是用程序来搞,更加的深入。

    redis 新建项目

    新建一个控制台项目

    Nuget包

    Install-Package StackExchange.Redis -Version 2.6.45
    
    • 1

    只需要一个包就可以了,也挺方便的

    代码连接服务

    挺简单的

    var _connMultiplexer = ConnectionMultiplexer.Connect("127.0.0.1");
    Console.WriteLine($"redis连接状态:{_connMultiplexer.IsConnected}"); 
    var _db = _connMultiplexer.GetDatabase(1);//可以选择指定的db,0-15
    
    • 1
    • 2
    • 3

    就获取了服务的状态,以及获取了指定的db 了。

    默认的db 为 第0个db ,如果是集群模式(1主多从,基本都用的第0个DB)

    redis 有几个数据类型

    其实我们不仅仅可以从官网了解到,还可以从这个_db对象上看到有哪些类型的

    1. GEO (地里位置)
    2. Hash (哈希)
    3. HyperLogLog (大数据的统计,类似于UV统计)
    4. List(可重复集合,有序,先进先出,可作为队列使用)
    5. Set (不重复集合,无序)
    6. SortedSet (不重复集合,有序,自带score 列)
    7. Stream (新版消息队列,推荐)
    8. String (键值对)

    而我们常用的有

    1. String
    2. Hash
    3. List
    4. Set
    5. Zset(SortedSet)

    下面就基于常见类型与不常见类型,来一个案例

    redis String

    //String
    db.StringSet("str1", "123");
    var stringValue = db.StringGet("str1");
    Console.WriteLine($"获取到string 类型的值:{stringValue}");
    
    • 1
    • 2
    • 3
    • 4

    可以清晰的看到它的结构,简单明了的 key,value 结构

    redis Hash

    //hash 就是一个key 下面  有一个集合的hash  key,value
    db.HashSet("hash", 123, 123);
    db.HashSet("hash", 123, 456);
    
    var HashValue = db.HashGet("hash", 123);
    Console.WriteLine($"获取到hash 类型的值:{HashValue}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    redis List

    // List ,就是一个有序的集合,可以选择push和pop,左右都可以
    db.KeyDelete("list");
    db.ListLeftPush("list", "123");
    db.ListLeftPush("list", "456");
    
    var listValue = db.ListLeftPop("list");
    Console.WriteLine($"获取到list 类型的值:{listValue}");
    listValue = db.ListLeftPop("list");
    Console.WriteLine($"获取到list 类型的值:{listValue}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    redis set

    // Set 一个无序不重复集合
    db.SetAdd("set", 123);
    db.SetAdd("set", 456);
    db.SetAdd("set", 789);
    db.SetAdd("set", 789);
    var setValue = db.SetScan("set");
    Console.WriteLine($"获取到set 类型的值:{string.Join(",",setValue)}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Zset(SortedSet)

    // Zset(SortedSet)
    db.SortedSetAdd("SortedSet", 123, 1);
    db.SortedSetAdd("SortedSet", 123, 2);
    db.SortedSetAdd("SortedSet", 456, 2);
    var sortedSetValue = db.SortedSetScan("SortedSet");
    Console.WriteLine($"获取到sortedSetValue 类型的值:{string.Join(",", sortedSetValue)}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    redis GEO 地里位置类型

    // geo
    db.GeoAdd("geo", 104.056257, 30.651897, "成都锦里");
    db.GeoAdd("geo", 104.063684, 30.663607, "成都人民公园");
    var Distance = db.GeoDistance("geo", "成都锦里", "成都人民公园");
    Console.WriteLine($"获取到 geo 地理类型 距离{Distance}");
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这样的类型存储

    还挺准的。

    redis HyperLogLog (大数据的统计,类似于UV统计)

    // HyperLogLog 它是一种算法
    db.HyperLogLogAdd("HyperLogLog1", 123);
    db.HyperLogLogAdd("HyperLogLog1", 123);
    db.HyperLogLogAdd("HyperLogLog1", 456);
    var HyperLogLogLength = db.HyperLogLogLength("HyperLogLog1");
    Console.WriteLine($"HyperLogLogLength 长度:{HyperLogLogLength}");
    
    db.HyperLogLogAdd("HyperLogLog2", 789);
    db.HyperLogLogAdd("HyperLogLog2", 789);
    db.HyperLogLogAdd("HyperLogLog2", 123);
    
    //可以合并集合
    db.HyperLogLogMerge("HyperLogLog3", "HyperLogLog1", "HyperLogLog2");
    HyperLogLogLength = db.HyperLogLogLength("HyperLogLog3");
    Console.WriteLine($"HyperLogLogLength 长度:{HyperLogLogLength}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15


    存储的是个二进制。好吧,也看不到是啥玩意儿

    但是功能是记录 去重后的数据量,用极少的内存存储大数据量的数据。对比set来讲,降低了set的重复性,
    hash存的话好点,但是,没有这个算法好,毕竟是二进制的,也类似于bitmap算法,求交集。

    redis Stream (新版消息队列)

    // Stream 新版消息队列
    db.StreamDeleteConsumerGroup("stream", "消费者组");
    //消费者组创建
    var result = db.StreamCreateConsumerGroup("stream", "消费者组");
    if (result)
    {
        Console.WriteLine("创建消费者组成功");
    }
    else
    {
        Console.WriteLine("创建消费者1失败");
    }
    //生产者
    Task.Run(() =>
    {
        int i = 0;
        while (true)
        {
            var result = db.StreamAdd("stream", "123", i.ToString());
            Thread.Sleep(1000);
            i++;
        }
    });
    //消费者1
    Task.Run(() =>
    {
        while (true)
        {
            var result = db.StreamReadGroup("stream", "消费者组", "消费者1");
            if (result?.Any() == true)
            {
                foreach (var item in result)
                {
                    Console.WriteLine($"消费者1:{item.Id} {item["123"]}");
                }
            }
        }
    });
    //消费者2
    Task.Run(() =>
    {
        while (true)
        {
            var result = db.StreamReadGroup("stream", "消费者组", "消费者2");
            if (result?.Any() == true)
            {
                foreach (var item in result)
                {
                    Console.WriteLine($"消费者2:{item.Id} {item["123"]}");
                }
            }
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    Redis Desktop Manager 里看不到,是个二进制

    代码运行结果如下:

    总结

    我们基于redis来了一个从入门到熟练,现在各种类型都已熟悉。还学习了一些新的类型,以前我都没搞过。

    用到特殊地方肯定有奇效。

    代码地址

    https://github.com/kesshei/redisDemo.git

    https://gitee.com/kesshei/redisDemo.git

  • 相关阅读:
    回归与聚类算法系列②:线性回归
    DHorse v1.3.0 发布,基于k8s的发布平台
    多人协作多版本开发冲突的正确解决姿势
    Nginx+rtmp+ffmpeg搭建视频转码服务
    Java PipedOutputStream类简介说明
    47.(前端)用户列表的数据填充
    使用JAVA-api读取HDFS下文件内容,出现报错信息
    Jemeter实现多用户登录的两种方式
    HTML CSS 网页设计作业「动漫小站」
    Xilinx ISE系列教程(5):查看模块级资源占用率和综合报告
  • 原文地址:https://blog.csdn.net/kesshei/article/details/125401731