首页 > 数据库 >(八).NET6.0添加通用的Redis功能

(八).NET6.0添加通用的Redis功能

时间:2024-12-27 11:31:52浏览次数:4  
标签:string redisConnection Redis value public 添加 key NET6.0

1.添加包:StackExchange.Redis

2.在配置文件里面,新建Redis的有关配置信息

Name是别名,可以任意起。Ip是Redis的服务端地址,例如安装本地,就是127.0.0.1,端口号Port默认是6379,密码可以通过Redis安装的根目录下的配置文件进行设置,Timeout是连接的超时时间,Db是使用Redis的DB区,一般Redis的DB区默认是0到15。注意:此处的配置使用的是数组,用于将来进行Redis分布式操作的可拓展。
注:我是本地部署的Redis,所以在本地有服务端和客户端,在初始情况下,Redis还没有密码,需要我们自己去设置,找到Redis的安装文件

进入图中的.conf文件去编辑
把#requirepass的#注释去掉 然后重新设置密码,设置完成后保存

cmd运行该文件夹,启动服务端并且指定配置文件

然后开启服务端,就可以进行本地redis开发调试了

3.Ysq.Core.Entity,然后新建一个实体类,叫RedisConfig,用于读取到配置文件的Redis信息进行赋值使用

4.在Common工具文件夹下,新建 Ysq.Core.Redis类库项目,并新建 RedisManage 类和对应接口 IRedisManage,如下图。然后,在该项目里面,引用共用包项目Ysq.Core.Package,用以使用Redis有关功能。

点击查看代码
public interface IRedisManage
{
    /// <summary>
    /// 设置一个 键值对
    /// </summary>
    /// <param name="key"></param>
    /// <param name="value"></param>
    /// <param name="ts"></param>
    void SetValue(string key, object value, TimeSpan ts);
    /// <summary>
    ///  //获取 Reids 缓存值
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    string GetValue(string key);
    /// <summary>
    /// 获取序列化值
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="key"></param>
    /// <returns></returns>
    TEntity Get<TEntity>(string key);
    /// <summary>
    /// 判断Key是否存在
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    bool Get(string key);
    /// <summary>
    /// 移除某个Key和值
    /// </summary>
    /// <param name="key"></param>
    void Remove(string key);
    /// <summary>
    /// 清空Redis
    /// </summary>
    void Clear();
    /// <summary>
    /// 异步获取 Reids 缓存值
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    Task<string> GetValueAsync(string key);
    /// <summary>
    /// 异步获取序列化值
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="key"></param>
    /// <returns></returns>
    Task<TEntity> GetAsync<TEntity>(string key);
    Task SetAsync(string key, object value, TimeSpan cacheTime);
    Task<bool> GetAsync(string key);
    /// <summary>
    /// 异步移除指定的key
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    Task RemoveAsync(string key);
    /// <summary>
    /// 异步移除模糊查询到的key
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    Task RemoveByKey(string key);
    /// <summary>
    /// 异步全部清空
    /// </summary>
    /// <returns></returns>
    Task ClearAsync();
}
点击查看代码
public class RedisManage : IRedisManage
{
    public volatile ConnectionMultiplexer _redisConnection;
    private readonly object _redisConnectionLock = new object();
    private readonly ConfigurationOptions _configOptions;
    private readonly ILogger<RedisManage> _logger;

    public RedisManage(ILogger<RedisManage> logger)
    {
        _logger = logger;
        ConfigurationOptions options = ReadRedisSetting();
        if (options == null)
        {
            _logger.LogError("Redis数据库配置有误");
        }
        this._configOptions = options;
        this._redisConnection = ConnectionRedis();
    }

    private ConfigurationOptions ReadRedisSetting()
    {
        try
        {
            List<RedisConfigInfo> config = AppHelper.Instance.ReadAppSettings<RedisConfigInfo>(new string[] { "Redis" }); // 读取Redis配置信息
            if (config.Any())
            {
                ConfigurationOptions options = new ConfigurationOptions
                {
                    EndPoints =
                        {
                            {
                                config.FirstOrDefault().Ip,
                                config.FirstOrDefault().Port
                            }
                        },
                    ClientName = config.FirstOrDefault().Name,
                    Password = config.FirstOrDefault().Password,
                    ConnectTimeout = config.FirstOrDefault().Timeout,
                    DefaultDatabase = config.FirstOrDefault().Db,
                };
                return options;
            }
            return null;
        }
        catch (Exception ex)
        {
            _logger.LogError($"获取Redis配置信息失败:{ex.Message}");
            return null;
        }

    }

    private ConnectionMultiplexer ConnectionRedis()
    {
        if (this._redisConnection != null && this._redisConnection.IsConnected)
        {
            return this._redisConnection; // 已有连接,直接使用
        }
        lock (_redisConnectionLock)
        {
            if (this._redisConnection != null)
            {
                this._redisConnection.Dispose(); // 释放,重连
            }
            try
            {
                this._redisConnection = ConnectionMultiplexer.Connect(_configOptions);
            }
            catch (Exception ex)
            {
                _logger.LogError($"Redis服务启动失败:{ex.Message}");
            }
        }
        return this._redisConnection;
    }

    public string GetValue(string key)
    {
        return _redisConnection.GetDatabase().StringGet(key);
    }

    public void SetValue(string key, object value,TimeSpan time)
    {
        if (value!=null)
        {
            _redisConnection.GetDatabase().StringSet(key,JsonConvert.SerializeObject(value),time);
        }
    }

    public void Clear()
    {
        foreach (var endPoint in this.ConnectionRedis().GetEndPoints())
        {
            var server = this.ConnectionRedis().GetServer(endPoint);
            foreach (var key in server.Keys())
            {
                _redisConnection.GetDatabase().KeyDelete(key);
            }
        }
    }

    public bool Get(string key)
    {
        return _redisConnection.GetDatabase().KeyExists(key);
    }


    public TEntity Get<TEntity>(string key)
    {
        var value = _redisConnection.GetDatabase().StringGet(key);
        if (value.HasValue)
        {
            //需要用的反序列化,将Redis存储的Byte[],进行反序列化
            return JsonConvert.DeserializeObject<TEntity>(value);
        }
        else
        {
            return default(TEntity);
        }
    }

    public void Remove(string key)
    {
        _redisConnection.GetDatabase().KeyDelete(key);
    }

    public bool SetValue(string key, byte[] value)
    {
        return _redisConnection.GetDatabase().StringSet(key, value, TimeSpan.FromSeconds(120));
    }



    public async Task ClearAsync()
    {
        foreach (var endPoint in this.ConnectionRedis().GetEndPoints())
        {
            var server = this.ConnectionRedis().GetServer(endPoint);
            foreach (var key in server.Keys())
            {
                await _redisConnection.GetDatabase().KeyDeleteAsync(key);
            }
        }
    }

    public async Task<bool> GetAsync(string key)
    {
        return await _redisConnection.GetDatabase().KeyExistsAsync(key);
    }

    public async Task<string> GetValueAsync(string key)
    {
        return await _redisConnection.GetDatabase().StringGetAsync(key);
    }

    public async Task<TEntity> GetAsync<TEntity>(string key)
    {
        var value = await _redisConnection.GetDatabase().StringGetAsync(key);
        if (value.HasValue)
        {
            return JsonConvert.DeserializeObject<TEntity>(value);
        }
        else
        {
            return default;
        }
    }

    public async Task RemoveAsync(string key)
    {
        await _redisConnection.GetDatabase().KeyDeleteAsync(key);
    }

    public async Task RemoveByKey(string key)
    {
        var redisResult = await _redisConnection.GetDatabase().ScriptEvaluateAsync(LuaScript.Prepare(
            //模糊查询:
            " local res = redis.call('KEYS', @keypattern) " +
            " return res "), new { @keypattern = key });

        if (!redisResult.IsNull)
        {
            var keys = (string[])redisResult;
            foreach (var k in keys)
                _redisConnection.GetDatabase().KeyDelete(k);

        }
    }

    public async Task SetAsync(string key, object value, TimeSpan cacheTime)
    {
        if (value != null)
        {
            await _redisConnection.GetDatabase().StringSetAsync(key, JsonConvert.SerializeObject(value), cacheTime);
        }
    }

    public async Task<bool> SetValueAsync(string key, byte[] value)
    {
        return await _redisConnection.GetDatabase().StringSetAsync(key, value, TimeSpan.FromSeconds(120));
    }
}

5.启动项目新增对Ysq.Core.Redis项目的引用,并且注入Redis类库中的接口

6.在控制器中设置一对key/value,然后进行读取并返回

Redis客户端有内容

另外:
Redis分布式锁是一种利用Redis单线程特性以及操作原子性实现分布式系统中锁功能的机制,以下我来详细解释这张图和Redis分布式锁的原理:
分布式锁的基本概念:
●使用 SET key value EX seconds NX 命令:key: 锁的名称。
○value: 锁的值(可以用来区分客户端)。
○EX seconds: 锁的过期时间(秒),保证锁不会无限存在。
○NX: 表示“仅在键不存在时设置”(即防止重复设置锁)。
●原理:当某个客户端成功设置了锁后,其他客户端如果尝试设置同样的锁(同样的 key),会失败,直到锁过期或者被释放。

左侧客户端操作:
1.set lock true ex 60 nx:尝试创建一个名为 lock 的锁,值为 true,过期时间为 60 秒。返回 OK,说明锁成功创建。
2.尝试 set lock true ex 60 nx 再次设置锁,返回 (nil),说明锁已经存在,无法再次创建。
3.删除锁:del lock,返回 (integer) 1,表示成功删除锁。
4.再次尝试创建锁:set lock true ex 60 nx,返回 OK,锁被重新创建。
5.删除锁:del lock,返回 (integer) 1。
右侧客户端操作:
1.set lock true ex 60 nx:尝试设置锁。如果锁不存在,返回 OK,锁被设置。
2.再次设置锁:set lock true ex 60 nx,返回 (nil),说明锁已存在,当前客户端无法设置。
3.删除锁:del lock,返回 (integer) 1,锁被成功删除。
观察:
●当锁存在时,其他客户端的 SET lock ... NX 操作会失败。
●但删除锁是无条件的,任何客户端都可以执行 DEL lock 操作,这种情况下存在并发删除的风险。
Redis分布式锁的主要目的是在分布式系统中,确保同一时刻只有一个客户端对某一关键资源进行操作,避免“同时修改”导致数据不一致的问题。例如:
●限制同一资源的并发访问(如用户订单、库存操作)。
●避免定时任务的多次重复执行。
使用锁的伪代码分析:
以下伪代码演示了Redis分布式锁的使用过程:

点击查看代码
If (exists(lock)) {
    return false; // 锁存在,返回失败
} else {
    set lock true ex 5 nx; // 设置锁(超时时间为5秒)
    // 开始操作关键资源
    set key1 100; // 资源操作,比如设置值为100
    del lock; // 删除锁
    return true; // 返回成功
}

标签:string,redisConnection,Redis,value,public,添加,key,NET6.0
From: https://www.cnblogs.com/sq1201/p/18635246

相关文章

  • (六).NET6.0通用读取配置文件功能
    1.新增Microsoft.Extensions.Configuration包在启动项目下,设置appsettings.json属性为始终复制2.新建一个文件夹Common,用于存放工具类项目。并且新建项目:Ysq.Core.AppSettings,引用package包项目,然后新建一个读取配置文件的通用类,叫AppHelper。目录结构如图3.AppHelper代码如......
  • Edge浏览器添加网址永久使用ie兼容模式
    参考https://bbs.pcbeta.com/viewthread-1990717-1-1.html实现下载文件解压后运行Install.cmdEdgeToIE.zipInstall.cmd@ECHOOFFSETLOCALEnableDelayedExpansionTITLE强制网站使用InternetExplorer打开PUSHD%~dp0&CD/d"%~dp0"%1%2mshtavbscript:createobject(......
  • (五).NET6.0使用Serilog进行配置和实现日志记录
    1.首先安装Serilog六件套神装包也可以对个别相应的包进行删除等,例如:1是读取配置文件的,如果不需要通过配置文件进行操作,就可以不使用这个包。2是打印到控制台的,如果不需要打印到控制台,也可以不引用。3是写入到文件的,如果不需要写入到文件,也是可以不提供的。我在此处全部引入,方便......
  • PHP语言laravel框架中基于Redis的异步队列使用实践与原理
    在Laravel中,基于Redis的异步队列是通过Laravel的队列系统与Redis服务结合来实现的。这种队列机制允许你将任务推送到队列中,并由后台工作进程异步处理这些任务。这样,你就可以将耗时的操作(如发送邮件、处理视频、数据同步等)推迟到后台处理,从而提高应用的响应速度。###1......
  • 添加SQL字段说明
    USE[xxx];GO;WITHcteColsAS(SELECTc.nameASColumnNameFROMsys.columnscINNERJOINsys.tablestONc.object_id=t.object_idINNERJOINsys.schemassONt.schema_id=s.schema_idWHEREt.name='SSLPDT'......
  • Redis 性能优化策略
    一、引言在当今数字化时代,Redis作为一款高性能的键值对存储数据库,在众多领域中发挥着关键作用。无论是应对高并发的Web应用场景,还是满足大数据量下的快速读写需求,Redis都展现出了卓越的性能优势。然而,随着业务的不断拓展和数据量的持续增长,如何进一步优化Redis的性能,使......
  • 中型项目中 Redis 的关键作用
    一、引言在中型项目的开发与运维过程中,随着业务量的增长和数据复杂度的提升,数据处理和存储面临着诸多挑战。例如,高并发场景下的数据读写压力、海量数据的快速查询需求以及数据一致性的保障等问题,都对项目的性能和稳定性提出了更高的要求。而Redis作为一款高性能的内存数据库......
  • Redis是什么,怎么安装使用
    ###Redis是什么?Redis(**RE**mote**DI**ctionary**S**erver)是一个开源的、基于内存的高性能键值数据库(key-valuestore)。它不仅支持简单的键值对,还支持多种复杂的数据结构,包括字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(SortedSet)等。Redis常被用作缓存、中间件......
  • OpenCV计算机视觉 03 椒盐噪声的添加与常见的平滑处理方式(均值、方框、高斯、中值)
    上一篇文章:OpenCV计算机视觉02图片修改图像运算边缘填充阈值处理添加椒盐噪声defadd_peppersalt_noise(image,n=10000):  result=image.copy()  h,w=image.shape[:2]  #获取图片的高和宽  foriinrange(n):  #生成n个椒盐噪声  ......
  • telegraf中获取出来的disk相关的监控,如何添加一个disk 序列号的tag
    查看telegraf关于diskio输出的文档https://github.com/influxdata/telegraf/tree/master/plugins/inputs/diskio##Devicemetadatatagstoaddonsystemssupportingit(Linuxonly)##Use'udevadminfo-qproperty-n<device>'togetalistofproper......