zoukankan      html  css  js  c++  java
  • .net core 2.0 redis驱动性能比拼

    今天来了三位主角,他们分别是大名鼎鼎的 StackExchange.Redis,无敌轻巧的 CSRedis,中通日处理80亿访问的 NewLife.Redis。

    作者从2016年学习.netcore以来,接触StackExchange.Redis遇到Timeout,这个问题坑了好多人。有人说2.0重构会解决了这个问题,碰巧本次测试发现2.0版本已经发布,本次测试版本为:2.0.505,期待StackExchange.Redis2.0重构版的测试表现。

    CSRedis 已经很出名就不讲了,开源地址:https://github.com/2881099/csredis

    NewLife.Redis 号称日处理80亿访问,代码简洁功能不多,能解决特定的业务场景,看看性能到底有多强劲。

    ps: NewLife.Redis 不支持异步方法,所以本次只测试同步方法。

    测试代码

    CSRedis.CSRedisClient csredis = new CSRedis.CSRedisClient("127.0.0.1:6379,password=,defaultDatabase=0,poolsize=100,ssl=false,writeBuffer=20480,prefix=");
    StackExchange.Redis.ConnectionMultiplexer seredis = StackExchange.Redis.ConnectionMultiplexer.Connect("127.0.0.1:6379,password=");
    StackExchange.Redis.IDatabase seredisDb = seredis.GetDatabase();
    
    var nlredis = Redis.Create("127.0.0.1:6379", 4);
    nlredis.Password = "";
    var nlredisClient = nlredis.Pool.Get();
    
    Task.Run(() => {
    	var times = new[] { 1000, 10000, 100000 };
    
    	foreach (var time in times) {
    		var dt_csredis_set = DateTime.Now;
    		for (var a = 0; a < time; a++) {
    			csredis.Set($"benchmark_csredis_{a}", Guid.NewGuid().ToString());
    		}
    		var ts_csredis_set = DateTime.Now.Subtract(dt_csredis_set);
    
    		var dt_seredis_set = DateTime.Now;
    		for (var a = 0; a < time; a++) {
    			seredisDb.StringSet($"benchmark_seredis_{a}", Guid.NewGuid().ToString());
    		}
    		var ts_seredis_set = DateTime.Now.Subtract(dt_seredis_set);
    
    		var dt_nlredis_set = DateTime.Now;
    		for (var a = 0; a < time; a++) {
    			nlredisClient.Set($"benchmark_nlredis_{a}", Guid.NewGuid().ToString());
    		}
    		var ts_nlredis_set = DateTime.Now.Subtract(dt_nlredis_set);
    
    		var dt_csredis_get = DateTime.Now;
    		for (var a = 0; a < time; a++) {
    			csredis.Get($"benchmark_csredis_{a}");
    		}
    		var ts_csredis_get = DateTime.Now.Subtract(dt_csredis_get);
    
    		var dt_seredis_get = DateTime.Now;
    		for (var a = 0; a < time; a++) {
    			seredisDb.StringGet($"benchmark_seredis_{a}");
    		}
    		var ts_seredis_get = DateTime.Now.Subtract(dt_seredis_get);
    
    		var dt_nlredis_get = DateTime.Now;
    		for (var a = 0; a < time; a++) {
    			nlredisClient.Get<string>($"benchmark_nlredis_{a}");
    		}
    		var ts_nlredis_get = DateTime.Now.Subtract(dt_nlredis_get);
    
    		Console.WriteLine($@"
    循环次数: {time}
    csredis set: {ts_csredis_set.TotalMilliseconds}ms
    statckexchange.redis StringSet: {ts_seredis_set.TotalMilliseconds}ms
    newlife.redis set: {ts_nlredis_set.TotalMilliseconds}ms
    
    csredis get: {ts_csredis_get.TotalMilliseconds}ms
    statckexchange.redis StringGet: {ts_seredis_get.TotalMilliseconds}ms
    newlife.redis get: {ts_nlredis_get.TotalMilliseconds}ms
    ");
    	}
    });
    

    测试这段代码,对 csredis 其实不公平的,因为内部使用的连接池有一点消耗,支持单例定义使用,支持并发使用

    另外,StackExchange.Redis.IDatabase 事先就初始化了,循环内没有多次 GetDatabase()。

    测试结果


     

    优化指南

    上面的对比结果不难发现,几个驱动的性能大同小异,StackExchange.Redis 偏慢一点点。

    NewLife.Redis 高性能优化的方向之一PipeLine,redis-server 支持管道模式,即指将一批命令打包,一次提交给 redis-server,减少来往消耗。

    NewLife.Redis 通过 rds.AutoPipeLine = 100,设置 rds 集满 100 条命令时 flush 打包提交一次。需要注意这是特定场景优化,比如你的项目访问率低并且用到了缓存,集满 AutoPipeLine 条命令如果需要5秒,及有可能影响缓存更新时间。

    CSRedis 也支持 PipeLine 的,代码如下:

    var ret1 = RedisHelper.StartPipe().Set("a", "1").Get("a").EndPipe();
    var ret2 = RedisHelper.StartPipe(p => p.Set("a", "1").Get("a"));
    
    var ret3 = RedisHelper.StartPipe().Get("b").Get("a").Get("a").EndPipe();
    //与 RedisHelper.MGet("b", "a", "a") 性能相比,经测试差之毫厘
    
  • 相关阅读:
    Arch Linux中安装Anaconda
    Windows下使用Diskpart格式化U盘
    Jupyter Notebook的安装
    Docker的脚本安装
    pip无法正常使用卸载并重新安装
    Arch更新时failed to prepare transaction
    Privoxy将Socks代理转化HTTP代理
    Arch Linux下Visual Stdio Code在格式化C代码时报错
    GNOME 3.28 启用桌面图标
    Appium入门(8)__控件定位
  • 原文地址:https://www.cnblogs.com/kellynic/p/9650996.html
Copyright © 2011-2022 走看看