相关文章推荐
玩篮球的铅笔  ·  Spring抛java.lang.Illeg ...·  3 周前    · 
胆小的毛衣  ·  SQL Server 和 MySQL 中的 ...·  1 年前    · 
伤情的豌豆  ·  Use the ...·  1 年前    · 
憨厚的手电筒  ·  如何在VC中使用7z ...·  1 年前    · 

StackExchange.Redis 命令扩展

Intro

在之前的文章中有简单介绍过 StackExchange.Redis 直接调用 Redis 命令来实现调用 Stream 的根据消息 Id 来控制消息长度,因为 StackExchange.Redis 目前还不支持根据消息 Id 控制 Stream 消息长度,目前有很多 6.2 以后带来的新特性大多还不支持。

前段时间,给 StackExchange.Redis 提了一个 PR 支持了一个 Redis 6.2 的新命令 GETDEL ,给大家分享一下,有想去蹭贡献的也可以尝试贡献一下

GETDEL

GETDEL 是 Redis 6.2 中引入的新功能中的其中一个,是针对 String 类型的数据的命令,如同命令名称一样,先 GET 并删除某一个 key,返回 key 的内容,如下面示例一样

redis> SET mykey "Hello"

redis> GETDEL mykey

"Hello"

redis> GET mykey

(nil)

Implement

命令比较简单,不会造成产生破坏性的变更,实现起来也是比较简单,主要是新增下面两个 API:

RedisValue StringGetDelete(RedisKey key, CommandFlags flags = CommandFlags.None);
Task<RedisValue> StringGetDeleteAsync(RedisKey key, CommandFlags flags = CommandFlags.None);

分别定义在 IDatabase / IDatabaseAsync

对于其实现来说,会增加一个 Redis 命令的枚举定义,需要在 RedisCommand 中增加一个新命令 GETDEL

enum RedisCommand:
+  GETDEL,

实现需要修改的地方有三个:

RedisDatabase ,新增的 API 实现如下

public RedisValue StringGetDelete(RedisKey key, CommandFlags flags = CommandFlags.None)
    var msg = Message.Create(Database, flags, RedisCommand.GETDEL, key);
    return ExecuteSync(msg, ResultProcessor.RedisValue);
public Task<RedisValue> StringGetDeleteAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
    var msg = Message.Create(Database, flags, RedisCommand.GETDEL, key);
    return ExecuteAsync(msg, ResultProcessor.RedisValue);
 

DatabaseWrapper:

public RedisValue StringGetDelete(RedisKey key, CommandFlags flags = CommandFlags.None)
    return Inner.StringGetDelete(ToInner(key), flags);
 

WrapperBase:

public Task<RedisValue> StringGetDeleteAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
    return Inner.StringGetDeleteAsync(ToInner(key), flags);
 

单元测试的变更如下:

tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs:

[Fact]
public void StringGetDelete()
    wrapper.StringGetDelete("key", CommandFlags.None);
    mock.Verify(_ => _.StringGetDelete("prefix:key", CommandFlags.None));
 

tests/StackExchange.Redis.Tests/WrapperBaseTests.cs:

[Fact]
public void StringGetDeleteAsync()
    wrapper.StringGetDeleteAsync("key", CommandFlags.None);
    mock.Verify(_ => _.StringGetDeleteAsync("prefix:key", CommandFlags.None));
 

tests/StackExchange.Redis.Tests/Strings.cs: 实际使用也可以参数这两个测试用例

[Fact]
public void GetDelete()
    using (var muxer = Create())
        Skip.IfMissingFeature(muxer, nameof(RedisFeatures.GetDelete), r => r.GetDelete);
        var conn = muxer.GetDatabase();
        var prefix = Me();
        conn.KeyDelete(prefix + "1", CommandFlags.FireAndForget);
        conn.KeyDelete(prefix + "2", CommandFlags.FireAndForget);
        conn.StringSet(prefix + "1", "abc", flags: CommandFlags.FireAndForget);
        Assert.True(conn.KeyExists(prefix + "1"));
        Assert.False(conn.KeyExists(prefix + "2"));
        var s0 = conn.StringGetDelete(prefix + "1");
        var s2 = conn.StringGetDelete(prefix + "2");
        Assert.False(conn.KeyExists(prefix + "1"));
        Assert.Equal("abc", s0);
        Assert.Equal(RedisValue.Null, s2);
[Fact]
public async Task GetDeleteAsync()
    using (var muxer = Create())
        Skip.IfMissingFeature(muxer, nameof(RedisFeatures.GetDelete), r => r.GetDelete);
        var conn = muxer.GetDatabase();
        var prefix = Me();
        conn.KeyDelete(prefix + "1", CommandFlags.FireAndForget);
        conn.KeyDelete(prefix + "2", CommandFlags.FireAndForget);
        conn.StringSet(prefix + "1", "abc", flags: CommandFlags.FireAndForget);
        Assert.True(conn.KeyExists(prefix + "1"));
        Assert.False(conn.KeyExists(prefix + "2"));
        var s0 = conn.StringGetDeleteAsync(prefix + "1");
        var s2 = conn.StringGetDeleteAsync(prefix + "2");
        Assert.False(conn.KeyExists(prefix + "1"));
        Assert.Equal("abc", await s0);
        Assert.Equal(RedisValue.Null, await s2);
 

主要的变更就是这些了,是不是看起来也简单的,除了上面的基本实现就是要增加一些测试用例以及本地进行一下测试,看是不是可以按预期工作,有一些功能可能会要求集成测试

除了上面还有一个小点,就是如果不是只读命令需要声明命令是 MasterOnly 的,在 src/StackExchange.Redis/Message.cs 中的 public static bool IsMasterOnly(RedisCommand command) 声明即可,除此之外,StackExchange.Redis 会建议增加 ReleaseNote

如果你愿意也可以尝试去贡献一下 https://github.com/StackExchange/StackExchange.Redis/issues

References

  • https://github.com/StackExchange/StackExchange.Redis/pull/1840

  • https://github.com/StackExchange/StackExchange.Redis/issues/1729

  • https://redis.io/commands/getdel

  • https://github.com/StackExchange/StackExchange.Redis/issues

StackExchange.Redis 命令扩展Intro在之前的文章中有简单介绍过 StackExchange.Redis 直接调用 Redis 命令来实现调用 Stream 的根据消息...
发现用StackExchange.Redis代替收费项目ServiceStack.Redis是个不错的选择,只有一个dll,并且代码开源,很不错。 代码只做简单演示用StackExchange.Redis操作Redis数据库。 测试写入100万个key用时43秒。
在C#中使用Redis,一般有两种方式: 1、ServiceStack.Redis,据说是Redis官方推荐使用的驱动类库,但是是收费的。 2、StackExchange.Redis,可能性能要比ServiceStack.Redis差点,但是是免费的。 经过多方调研,我选用StackExchange.Redis来实现Redis操作,
最近因项目需要在C#使用redis,在网上随意找一下看到挺多C#中使用ServiceStack.Redis 文章同时好像也是redis推介的C#客户端,就在没在仔细了解的情况下就直接使用了ServiceStack.Redis。在使用的过程中发现ServiceStack.Redis在频繁的读写后或运行一段时间后报错,后来在网上翻资料发现它已商业化,免费版每小时只能访问redis6000次。给出的解决方案有2个: StackExchange.Redis 使用方法及注意事项...
昨天上班的时候后端有一个delete请求,要求我把参数放在url的query string上面。于是我说其实可以放在请求的实体中,但是后端说delete和get是没有请求实体的。这和我的记忆不太一样。那么到底delete和post请求能有实体吗? 先看网上的资料 先通过简单的搜索在stack overflow找到一个类似的问题, Is an entity body allowed for an HTTP DELETE request?。回答中说到并没有禁止和不推荐在get和delete方法中使用实体。意
StackExchange.Redis是一款免费的操作Redis的客户端工具,我们使用这个库来简单的学习下Redis的一些基本操作 Redis默认安装好后的端口是6379 密码可以自己设置,使用命令修改 config get requirepass //获取当前密码 config set requirepass "yourpassword"//设置当前密码 代码里需引用StackExch...
使用StackExchange.Redisredis简单封装(一) 1.0 前言     参考一系列网上学习资料,自己尝试手写了一个有关redis的封装类。因为ServiceStack.Redis从4.0版本以后开始商业化,免费版有限制,故采用StackExchange.Redisredis进行简单封装。 1.1StackExchange.Redis引用     NuGet包里面搜索StackExchange.Redis,然
StackExchange.Redis中最重要的对象是ConnectionMultiplexer类, 它存在于StackExchange.Redis命名空间中。 这个类隐藏了Redis服务的操作细节,ConnectionMultiplexer类做了很多东西, 在所有调用之间它被设计为共享和重用的。 不应该为每一个操作都创建一个ConnectionMultiplexer 。 Connectio
上篇文章介绍了Redis服务器和客户端管理器的使用,接下来小编将介绍Redis的C#/.net代码客户端——StackExchange.Redis 一、为啥要使用它 应高性能目的的网站开发要求,多种缓存服务应运而生。Redis就是其中之一,而它的特点在于: Redis支持高并发访问; 客户端可以静态协调多redis服务维持健壮性和可用性; 方便访问redis所有的特性设置 异步同步使用...
public static bool Exists(string key){ key=MergeKey(key); return GetDatabase().KeyExists(key);//可以直接调用 关于如何使用调用接口实现redis缓存清除
完整的代码,使用vs2015创建。通过一个64位StackExchange.Redis.dll(开源,1.2.6版),创建客户端,管理和使用Redis的PUB/SUB功能,适合集成进项目使用。 (需正常配置Redis客户端后才可使用)
### 回答1: StackExchange.Redis 是一个.NET平台下的开源Redis客户端库,它提供了一种高性能、稳定和易于使用的方式来与Redis服务器进行通信。它支持异步和同步操作,并提供了一些高级特性,如管道、发布/订阅等。 StackExchange.Redis 具有以下特点: - 快速:通过使用高性能、低级别的Redis通信协议,StackExchange.Redis 可以实现高效的数据访问。 - 可扩展性:StackExchange.Redis 支持分区功能,使它能够在多个Redis节点上分布数据,并且可以在需要时轻松地添加或删除节点。 - 可靠性:StackExchange.Redis 有一个内置的连接池来管理与Redis服务器的连接,从而可以提高性能和可靠性,并避免了频繁的连接/断开开销。 - 易用性:StackExchange.Redis 提供了一个简单的API,使得开发人员能够轻松地与Redis进行交互。 总的来说,如果你在.NET平台上使用RedisStackExchange.Redis 应该是你的首选。 ### 回答2: StackExchange.Redis 是一个基于Redis的 .Net客户端库,由StackExchange团队开发和维护。Redis内存数据库是非常流行的键值对存储,支持复杂数据结构,速度快,有完善的集群方案,在web应用程序、消息系统等应用场景中被广泛使用。 StackExchange.Redis提供了方便易用、高性能、可扩展的API,可以直接向Redis发送命令、订阅和发布消息、连接Redis集群等。他进一步扩展Redis命令,使其更加简单易用,并支持事务、管道和多线程操作。同时,StackExchange.Redis支持Redis的高级特性,如SortedSet和Hash;而且,它还能够在运行时自动检测Redis服务状态,支持Redis Sentinel、Cluster和多节点环境。 此外,StackExchange.Redis还支持应用程序跟踪(application tracing),采用异步API调用,从而提高了性能和可伸缩性。与其他Redis客户端库不同,StackExchange.Redis实现了连接池、序列化和反序列化器等高级功能,使用起来更加方便和优雅,可以减少代码量和复杂性。 总的来说,StackExchange.Redis是一个很不错的Redis客户端库,它提供了强大而与Redis完全兼容的API,打破了语言壁垒,使得开发者可以在自己喜欢的语言环境(例如.Net)中使用 Redis 。 许多一流的公司如 StackOverflow和GitHub都使用 StackExchange.Redis,证明了它的可靠性和性能优势。 ### 回答3: StackExchange.RedisRedis数据库的一个适用于 .NET 编程语言的客户端。它提供了一组丰富的功能,用于在 .NET 框架内与Redis数据库进行交互。 StackExchange.Redis旨在为 .NET 开发人员提供最佳的Redis集成体验。StackExchange.Redis提供了许多优点,其中最主要的有: 高度优化的读写操作。StackExchange.Redis客户端库具有非常高的效率,用于从Redis服务器读取和写入数据时,可大大减少网络流量和延迟。这使得它成为处理高吞吐量负载的很好的选择。 支持许多复杂数据类型。除了提供基本的字符串和整数类型之外,StackExchange.Redis还支持许多复杂的数据类型,例如哈希表、排序集合和列表数据类型。这些数据类型将极大地帮助开发人员设计和实施高效的Redis应用程序。 易于使用和集成。StackExchange.Redis具有完美的适配性,可以很简单地与 .NET 中的 ASP.NET 应用程序、Windows 服务、控制台应用程序等相集成。此外,它具有丰富的文档、教程和API reference,可以让开发者轻松入手。 另外,StackExchange.Redis还包括许多其他特性,如:连接复用、事务支持、发布与订阅、管道等。这使得它成为在 .NET 编程语言中使用Redis数据库的非常好的选择。