我们正在尝试使用ServiceStack包装器在Redis中存储一些大缓冲区(每个8MB)。我们使用“RedisNativeClient.Set(string key,byte [] value)”API来设置缓冲区。 客户端和服务器都驻留在同一台机器上。 坚持残疾人。 我们目前正在使用ServiceStack的评估版。
问题是我们的性能非常差 - 大约60 MB /秒。 使用一些不同的c#包装器(" Sider"),我们可以获得更好的性能(~400 MB /秒)。
我用于测量的代码:
Stream
问题是什么?
谢谢, 埃坦。
答案 0 :(得分:3)
ServiceStack.Redis使用可重用的缓冲池,通过重用字节缓冲池来减少内存压力。默认byte[]
缓冲区的大小为 1450字节,以适应以太网MTU数据包大小。虽然这种默认配置对于较小有效载荷(<100k)的正常使用情况是最佳的,但对于较大的有效载荷(> 1MB +),它看起来最终变慢。
基于此,ServiceStack.Redis客户端现在已被修改,因此它不再将缓冲池用于大于 500k 的有效负载,现在可以使用RedisConfig.BufferPoolMaxSize
进行配置,例如:< / p>
RedisConfig.BufferPoolMaxSize = 500000;
byte[]
缓冲区的默认1450字节大小现在也可配置为:
RedisConfig.BufferLength = 1450;
此更改现在可以提高ServiceStack.Redis对较大有效负载的吞吐量性能,如RedisBenchmarkTests套件中所示,它使用不同有效负载大小的基准,例如:
public void Run(string name, int nBlockSizeBytes, Action<int,byte[]> fn)
{
Stopwatch sw;
long ms1, ms2, interval;
int nBytesHandled = 0;
int nMaxIterations = 5;
byte[] pBuffer = new byte[nBlockSizeBytes];
// Create Redis Wrapper
var redis = new RedisNativeClient();
// Clear DB
redis.FlushAll();
sw = Stopwatch.StartNew();
ms1 = sw.ElapsedMilliseconds;
for (int i = 0; i < nMaxIterations; i++)
{
fn(i, pBuffer);
nBytesHandled += nBlockSizeBytes;
}
ms2 = sw.ElapsedMilliseconds;
interval = ms2 - ms1;
// Calculate rate
double dMBPerSEc = nBytesHandled / 1024.0 / 1024.0 / (interval / 1000.0);
Console.WriteLine(name + ": Rate {0:N4}, Total: {1}ms", dMBPerSEc, ms2);
}
从我的MacBook Pro和在Ubuntu VirtualBox VM中运行的redis-server运行的结果:
ServiceStack.Redis 1K: Rate 4.7684, Total: 1ms
Sider 1K: Rate 0.4768, Total: 10ms
ServiceStack.Redis 10K: Rate 47.6837, Total: 1ms
Sider 10K: Rate 4.3349, Total: 11ms
ServiceStack.Redis 100K: Rate 26.4910, Total: 18ms
Sider 100K: Rate 20.7321, Total: 23ms
ServiceStack.Redis 1MB: Rate 103.6603, Total: 46ms
Sider 1MB: Rate 70.1231, Total: 68ms
ServiceStack.Redis 8MB: Rate 77.0646, Total: 495ms
Sider 8MB: Rate 84.3960, Total: 452ms
ServiceStack.Redis的性能对于较小的有效载荷更快,而现在更接近于大于8MB的有效载荷。
此更改可从 v4.0.41 + 获得,现在为available on MyGet。