在CentOS 6.4上设置Redis和Nutcracker。并尝试使用servicestack.redis客户端连接。发现了主要的性能问题。

用于测试只留下1个redis实例

beta:
  listen: 0.0.0.0:22122
  hash: fnv1a_64
  distribution: ketama
  auto_eject_hosts: true
  #timeout: 5000
  #server_retry_timeout: 2000
  #server_failure_limit: 3
  redis: true
  servers:
  #- 127.0.0.1:6379:1
   - 127.0.0.1:6380:1
.

在以下单元测试中,我试图通过胡桃钳发送100k字符串来redis。

[TestClass]
public class RedisProxyTest
{
    public string host = "192.168.56.112";
    //public int port = 6379;
    public int port = 22122;

    [TestMethod]
    public void TestMethod1()
    {
        var key = "l2";
        var count = 100000;
        using (var redisClient = new RedisClient(host, port))
        {
            var list = new List<string>();
            for (int i = 0; i < count; i++)
            {
                list.Add(Guid.NewGuid().ToString());
            }

            Utils.TimeLog("Remove", () => redisClient.Remove(key));

            Utils.TimeLog("AddRangeToList", () => redisClient.AddRangeToList(key, list));
        }

        using (var redisClient = new RedisClient(host, port))
        {
            redisClient.GetListCount(key);

            Utils.TimeLog("GetRangeFromList", () =>
            {
                var ret = redisClient.GetRangeFromList(key, count / 2, count - 1);
                Console.WriteLine(ret.Count);
            });
        }

    }
}
.

在Nutcracker重新启动Addrangetolist后,在前几次运行,用1-2秒适用。但随后运行AddRangetolist性能显着下降,几分钟即使超过20分钟(如果没有配置超时)。直接使用Redis时,我不能再现相同。我还没有尝试任何其他客户。任何想法为什么?

在单元测试运行后我在控制台中看到的内容:

Test Name:  TestMethod1
Test Outcome:   Passed  
Remove: 0.0331171
AddRangeToList: 806.8219166
50000
GetRangeFromList: 1.741737
.

有帮助吗?

解决方案

如果NUNCRACKER正在使用数千个连接或用几千键发送多个连接请求,则应使用512的MBUF大小>

以下链接谈论如何解释MBUF大小? - https://github.com/twitter/twemproxy/issues/141

每个客户端连接消耗至少一个MBUF。要为请求提供服务,我们需要两个连接(从客户端到代理,另一个从代理到服务器)。所以我们需要两个mbufs。

像'得到foo bar \ r \ n'这样的碎片要求,其中btw碎片化为'get foo \ r \ n',并且'get bar \ r \ n'将消耗两个mbuf来寻找请求和两个mbuf进行响应。因此,使用N片段的碎片请求需要n * 2 mbufs

MBUF的好处是存储器来自重用池。一旦分配了MBUF,它永远不会释放,但刚刚放回重用池中。坏事是,一旦分配了MBUF,它永远不会被释放,因为释放MBUF总是返回到重用池 - https://github.com/twitter/twemproxy/blob/master/src/nc_mbuf.c.c#l23-l24 (这可以通过放置来修复重用池上的阈值参数)

因此,如果Nutcracker正在处理1K客户端连接和100个服务器连接,它将消耗(MAX(1000,100)* 2 * MBuf大小)MBUF内存。如果我们假设客户端发送非流水线请求,那么默认MBUF大小为16k,这将总计32米。

此外,如果平均每个请求有10个碎片,那么内存消耗将是320米。而不是处理1K客户端连接,让我们说你正在处理10K,那么内存消耗将是3.2g。现在而不是使用默认的MBUF大小为16k,您使用了512字节,然后同一方案的内存消耗将掉到1000 * 2 * 512 * 10= 10m

这就是为什么要为您想要为MBUF大小选择一个小值的“大量”的原因,如512

其他提示

看起来当传送该数据量时,问题与高内存使用情况有关。

默认情况下,nutcracker为每个键分配16k缓冲区大小。在我的情况下,它将是 16k * 100000= 1.5gb 。我在观看胡桃夹子过程时看到了大约2GB的峰值。My Cent OS VM超载,没有足够的内存来处理该尖峰。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top