.net core 2.0 redis驅動性能比拼

今天來了三位主角,他們分別是大名鼎鼎的 StackExchange.Redis,無敵輕巧的 CSRedis,中通日處理80億訪問的 NewLife.Redis。git

做者從2016年學習.netcore以來,接觸StackExchange.Redis遇到Timeout,這個問題坑了好多人。有人說2.0重構會解決了這個問題,碰巧本次測試發現2.0版本已經發布,本次測試版本爲:2.0.505,期待StackExchange.Redis2.0重構版的測試表現。github

CSRedis 已經很出名就不講了,開源地址:https://github.com/2881099/csredisredis

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") 性能相比,經測試差之毫釐
相關文章
相關標籤/搜索