基于async/non-blocking高性能redis组件库BeetleX.Redis

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 基于async/non-blocking高性能redis组件库BeetleX.RedisBeetleX.Redis是基于async/non-blocking模式实现的高性能redis组件库,组件支持redis基础指令集,并封装更简便的List,Hashset和Subscribe操作。

基于async/non-blocking高性能redis组件库BeetleX.Redis
BeetleX.Redis是基于async/non-blocking模式实现的高性能redis组件库,组件支持redis基础指令集,并封装更简便的List,Hashset和Subscribe操作。除了在基础操作功能上,组件还提供多服务备份方式和多连接池机制,从而让组件提供高可用和高性能的访问方案;在数据格式上组件默认集成了json和protobuf可以根据自己的需求来选择相应的存储格式。接下来大概看一下组件的性能和应用功能。

性能
针对Order结构进行一个GET/SET性能测试,分别测试BeetleX和StackExchange在这两个操作下不同线程的压测,由于在8以上线程数测试StackExchange经常抛timeout错误....,所以只测了1,2和4线程情况。详细测试代码:https://github.com/IKende/BeetleX.Redis/tree/master/PerformanceTest(代码里集成了一个轻巧的性能测试功能类,用起来非常方便,只需要简单编写测试用例就可以列表出测试时间和并发等相关数据,以下测试结果列表由这个测试类输出。)

测试数据结构
{"OrderID":10255,"CustomerID":"RICSU","EmployeeID":9,"OrderDate":"1996-07-12T00:00:00","RequiredDate":"1996-08-09T00:00:00","ShippedDate":"1996-07-15T00:00:00","ShipVia":3,"Freight":148.33,"ShipName":"Richter Supermarkt","ShipAddress":"Starenweg 5","ShipCity":"Genève","ShipPostalCode":"1204","ShipCountry":"Switzerland"}
Beetlex
1 await RedisDB.Set(item.OrderID.ToString(), item);
2 await RedisDB.Get(i.ToString());
StackExchange
1 await RedisDB.StringSetAsync(item.OrderID.ToString(), Newtonsoft.Json.JsonConvert.SerializeObject(item));
2 var data = await RedisDB.StringGetAsync(i.ToString());
3 var item = Newtonsoft.Json.JsonConvert.DeserializeObject(data);
测试结果

复制代码

|Name | Round| Threads| Count| Use time(s)| Sec|

|BeetleX_SET | 1| 1| 100000| 5.22| 19157|

|StackExchange_SET | 1| 1| 100000| 6.97| 14357|

|StackExchange_Sync_SET | 1| 1| 100000| 6.62| 15103|

|BeetleX_GET | 1| 1| 100000| 5.41| 18487|

|StackExchange_GET | 1| 1| 100000| 7.48| 13378|

|StackExchange_Sync_GET | 1| 1| 100000| 7.09| 14105|

|BeetleX_MGET | 1| 1| 100000| 7.03| 14216|

|StackExchange_MGET | 1| 1| 100000| 8.69| 11504|

|StackExchange_Sync_MGET | 1| 1| 100000| 8.36| 11963|

|BeetleX_SET | 1| 2| 100000| 2.55| 39246|

|StackExchange_SET | 1| 2| 100000| 3.97| 25199|

|StackExchange_Sync_SET | 1| 2| 100000| 3.56| 28069|

|BeetleX_GET | 1| 2| 100000| 2.78| 35946|

|StackExchange_GET | 1| 2| 100000| 4.1| 24364|

|StackExchange_Sync_GET | 1| 2| 100000| 3.72| 26907|

|BeetleX_MGET | 1| 2| 100000| 3.59| 27871|

|StackExchange_MGET | 1| 2| 100000| 4.75| 21035|

|StackExchange_Sync_MGET | 1| 2| 100000| 4.55| 21976|

|BeetleX_SET | 1| 4| 100000| 2.04| 48956|

|StackExchange_SET | 1| 4| 100000| 2.37| 42220|

|StackExchange_Sync_SET | 1| 4| 100000| 2.15| 46541|

|BeetleX_GET | 1| 4| 100000| 2.14| 46822|

|StackExchange_GET | 1| 4| 100000| 2.58| 38789|

|StackExchange_Sync_GET | 1| 4| 100000| 2.24| 44619|

|BeetleX_MGET | 1| 4| 100000| 2.49| 40238|

|StackExchange_MGET | 1| 4| 100000| 3.06| 32708|

|StackExchange_Sync_MGET | 1| 4| 100000| 2.76| 36264|

复制代码
组件使用
组件默认就支持数据对象操作,而数据存储的格式则由相应创建的DB数据类型决定,所以在使用和处理数据上都比较方便。

创建数据库
RedisDB DB = new RedisDB();
DB.AddWriteHost("192.168.2.19");
// set password
DB.AddWriteHost("192.168.2.19").Password="123456";
Json 数据库
RedisDB DB = new RedisDB(0, new JsonFormater());
Protobuf 数据库
RedisDB DB = new RedisDB(0, new ProtobufFormater());
基础操作
复制代码
await DB.Decr("mykey")
await DB.Decrby("mykey", 5);
await DB.Del("mykey");
await DB.Dump("mykey");
await DB.Exists("mykey", "order");
await DB.Expire("mykey", 10);
await DB.Expireat("mykey", 1293840000);
await DB.Get("mykey");
await DB.GetBit("mykey", 0);
await DB.GetRange("mykey", -3, -1);
await DB.GetSet("mycounter", 0);
await DB.Incr("mykey");
await DB.Incrby("mykey", 10);
await DB.IncrbyFloat("mykey", 0.1f);
await DB.Keys("t??");
await DB.MGet("key1", "key2");
await DB.MGet("key1", "aaa", "key2");
await DB.MSet(m => m"key1", "hello");
await DB.MSetNX(m => m"key1", "hello");
await DB.Move("one", 9);
await DB.PSetEX("mykey", 1000, "hello");
await DB.Persist("mykey");
await DB.Pexpire("mykey", 1500);
await DB.Pexpireat("mykey", 1555555555005);
await DB.Ping();
await DB.PTtl("mykey");
await DB.Randomkey();
await DB.Rename("mykey", "myotherkey");
await DB.Renamenx("mykey", "myotherkey");
await DB.Set("test", "henryfan");
await DB.SetBit("mykey", 7, false);
await DB.SetEX("mykey", 10, "hello");
await DB.SetNX("mykey", "hello");
await DB.SetRange("key1", 6, "redis");
await DB.Strlen("key1");
await DB.Type("key2");
复制代码
列表操作
创建列表

var list = DB.CreateList("employees");
列表操作

复制代码
await list.BLPop();
await list.BRPop();
await list.BRPopLPush("List2");
await list.Index(0);
await list.Insert(true, GetEmployee(2), GetEmployee(3));
await list.Len();
await list.Pop();
await list.Push(GetEmployee(1));
await list.Push(GetEmployee(1), GetEmployee(2));
await myotherlist.PushX(GetEmployee(2));
await list.Rem(-2, GetEmployee(1));
await list.Set(-2, GetEmployee(5));
await list.Trim(1, -1);
await list.RPop();
await list.RPopLPush("myotherlist");
await list.RPush(GetEmployee(3));
await list.RPush(GetEmployee(1), GetEmployee(2));
await list.RPushX(GetEmployee(2));
await list.Range(-3, 2);
复制代码
HashTable结构
创建

var table = DB.CreateHashTable("myhash");
相关操作

复制代码
await table.Del("emp1");
await table.Exists("emp1");
await table.Get("emp1");
await table.Keys();
await table.Len();
await table.Get("emp", "order");
await table.Get("emp", "order", "customer");
await table.MSet(m => m"field1", GetEmployee(1));
await table.Set("field1", GetEmployee(1));
await table.SetNX("field", GetEmployee(1));
复制代码
订阅
创建订阅

复制代码

        var sub = db.Subscribe();
        sub.Register<Employee>("test1");
        sub.Receive = (o, e) =>
        {
            Console.WriteLine($"[{DateTime.Now}]{e.Channel}-{e.Type}:{e.Data}");
        };
        sub.Listen();

复制代码
通过Retister方法注册订阅频道,在注册的时候必须指定数据类型,对象反序列化的格式依据库数据的格式类型。

await DB.Publish("test1", GetEmployee(i));
以上是发布消息到频道

总结
以上是BeetleX.Redis现有版本的功能,集群功能暂没有实现;但提供主备功能可以根据自己的需要添加多个WriteHost或ReadHost,默认连接池机制随意应对高并发应用;组件希望打造一个高性能简便的Redis .net core组件,但要发挥组件的性能特色就要适应完全基于await的方法进行组件操作。 项目开源地址:https://github.com/IKende/BeetleX.Redis
原文地址https://www.cnblogs.com/smark/p/10639573.html

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
77 6
|
3月前
|
缓存 NoSQL Java
Redis深度解析:解锁高性能缓存的终极武器,让你的应用飞起来
【8月更文挑战第29天】本文从基本概念入手,通过实战示例、原理解析和高级使用技巧,全面讲解Redis这一高性能键值对数据库。Redis基于内存存储,支持多种数据结构,如字符串、列表和哈希表等,常用于数据库、缓存及消息队列。文中详细介绍了如何在Spring Boot项目中集成Redis,并展示了其工作原理、缓存实现方法及高级特性,如事务、发布/订阅、Lua脚本和集群等,帮助读者从入门到精通Redis,大幅提升应用性能与可扩展性。
75 0
|
1月前
|
存储 消息中间件 NoSQL
Redis 入门 - C#.NET Core客户端库六种选择
Redis 入门 - C#.NET Core客户端库六种选择
60 8
|
2月前
|
存储 缓存 NoSQL
Redis的高性能之谜
Redis的高性能之谜
41 5
|
1月前
|
NoSQL 网络协议 应用服务中间件
redis,memcached,nginx网络组件
redis,memcached,nginx网络组件
17 0
|
2月前
|
存储 消息中间件 NoSQL
Redis的单线程设计之谜:高性能与简洁并存
Redis的单线程设计之谜:高性能与简洁并存
44 0
|
5月前
|
NoSQL Go Redis
如何使用 Go 和 `go-redis/redis` 库连接到 Redis 并执行一些基本操作
如何使用 Go 和 `go-redis/redis` 库连接到 Redis 并执行一些基本操作
80 1
|
5月前
|
存储 缓存 NoSQL
Redis是一种高性能的内存数据库,常用于高并发环境下的缓存解决方案
【6月更文挑战第18天】**Redis摘要:** 高性能内存数据库,擅长高并发缓存。数据存内存,访问迅速;支持字符串、列表等多元数据类型;具备持久化防止数据丢失;丰富命令集便于操作;通过节点集群实现数据分片与负载均衡,增强可用性和扩展性。理想的缓存解决方案。
80 1
|
5月前
|
存储 运维 NoSQL
Redis 分区:构建高性能、高可用的大规模数据存储解决方案
Redis 分区:构建高性能、高可用的大规模数据存储解决方案
|
4月前
|
Java Redis 数据安全/隐私保护
Redis13的Java客户端-Jedis快速入门,建立连接的写法,ip地址,设置密码密码,选择库的写法
Redis13的Java客户端-Jedis快速入门,建立连接的写法,ip地址,设置密码密码,选择库的写法
下一篇
无影云桌面