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
- await RedisDB.Set(item.OrderID.ToString(), item);
- await RedisDB.Get<Order>(i.ToString());
- StackExchange
- await RedisDB.StringSetAsync(item.OrderID.ToString(), Newtonsoft.JSON.JsonConvert.SerializeObject(item));
- var data = await RedisDB.StringGetAsync(i.ToString());
- var item = Newtonsoft.JSON.JsonConvert.DeserializeObject<Northwind.Data.Order>(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<string>("mykey");
- await DB.GetBit("mykey", 0);
- await DB.GetRange("mykey", -3, -1);
- await DB.GetSet<string>("mycounter", 0);
- await DB.Incr("mykey");
- await DB.Incrby("mykey", 10);
- await DB.IncrbyFloat("mykey", 0.1f);
- await DB.Keys("t??");
- await DB.MGet<string, string>("key1", "key2");
- await DB.MGet<string, string, string>("key1", "aaa", "key2");
- await DB.MSet(m => m["key1", "hello"]["key2", "world"]);
- await DB.MSetNX(m => m["key1", "hello"]["key2", "there"]);
- 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<Employee>("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<Employee>("emp1");
- await table.Keys();
- await table.Len();
- await table.Get<Employee, Order>("emp", "order");
- await table.Get<Employee, Order, Customer>("emp", "order", "customer");
- await table.MSet(m => m["field1", GetEmployee(1)]["field2", GetCustomer(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