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


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

    性能

    针对Order结构进行一个GET/SET性能测试,分别测试BeetleXStackExchange在这两个操作下不同线程的压测,由于在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<Order>(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<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

  • 相关阅读:
    Jmeter运行badboy录制的脚本
    Bugfree安装与使用
    JMeter录制脚本
    第六天-linux系统优化初步讲解
    第五天-linux基础命令
    第四天-secureCRT-ssh客户端使用详解
    第三天-linux版本选择及安装
    第二天-计算机硬件基本知识和linux发展简史
    第一天-学习linux运维
    ubuntu15.04 无线上网问题
  • 原文地址:https://www.cnblogs.com/smark/p/10639573.html
Copyright © 2020-2023  润新知