Ухудшение производительности Twemproxy (Щелкунчика) с .NET Servicestack.redis Client

StackOverflow https://stackoverflow.com//questions/20014030

Вопрос

Настройка Redis и Щелкунчик на Centos 6.4.И пытаясь подключить использование ServiceStack.redis Client.Нашел основной выпуск производительности.

Для тестирования осталось только 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 через NutCracker.

[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);
            });
        }

    }
}
.

На первых нескольких прогонах после Щелкунчика перезапустил Addrangetolist работает с 1-2 сек.Но с последующими прогонами Addrangetolist производительность значительно падает с нескольких минут даже более 20 минут (если нет настройки тайм-аута).Я не могу воспроизвести же при использовании Redis напрямую.Я еще не пробовал другого клиента.Любые идеи почему?

Это то, что я вижу в консоли после прогона модуля Run:

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

Это было полезно?

Решение

Если utlcracker проводит несколько десятков тысяч соединений или отправка многокомпонентного запроса с несколькими тысячами клавиш, вы должны использовать размер MBUF 512

Следующая ссылка говорит о том, как интерпретировать размер MBUF? - https://github.com/twitter/twemproxy/issues/141 >

Каждое клиентское соединение потребляет хотя бы один MBUF. Для обслуживания запроса нам нужны два подключения (один из клиента к прокси и другому от прокси-сервера). Таким образом, нам понадобятся два MBUFS.

Фрагментарный запрос, такой как «Get Foo Bar \ R \ N», который, кстати, на котором можно фрагментировать, чтобы «получить Foo \ R \ n» и «Получить BAR \ R \ N» потреблять два MBUF для запроса и два MBUF для ответа Отказ Таким образом, фрагментарный запрос с N-фрагментами нуждается в N * 2 MBUFS

Хорошая вещь о MBUF заключается в том, что память исходит из пула повторного использования. Как только MBUF выделяется, он никогда не освобождается, а просто наденьте в пул повторного использования. Плохая вещь, что, как только MBUF выделен, он никогда не освобождается, так как освобожденный MBUF всегда возвращается в пул повторного использования - https://github.com/twitter/twemproxy/blob/master/src/nc_mbuf.c#l23-l24 (это может быть исправлено Пороговой параметр на пул повторного использования)

Итак, если utlcracker обрабатывает, скажем, 1k Client Connections и 100 подключений сервера, это будет потреблять (MAX (1000, 100) * 2 * MBUF-Size) память для MBUF. Если мы предположим, что клиенты отправляют неработающий запрос, то с по умолчанию MBUF-размером 16K это будет в общем потреблении 32M.

Кроме того, если в среднем все запросы имеют 10 фрагментов, то потребление памяти будет 320 м. Вместо того, чтобы обращаться с 1K клиентскими соединениями, давайте скажем, вы обрабатывали 10k, то потребление памяти будет 3,2 г. Теперь вместо того, чтобы использовать MBUF-размер по умолчанию 16k, вы использовали 512 байт, то потребление памяти для одного и того же сценария упадет до 1000 * 2 * 512 * 10= 10 м

Это причина, почему для «большого количества» подключения вы хотите выбрать небольшое значение для размера MBUF, например, 512

Другие советы

Похоже, проблема связана с высоким использованием памяти при передаче этого объема данных.

По умолчанию Nutcracker выделяет размер буфера 16K для каждого ключа.В моем случае это будет 16k * 100000= 1,5 ГБ .Я видел около 2 ГБ пика при просмотре процесса Щелкунчика.My Cent OS VM был перегружен, и не было достаточно памяти, чтобы справиться с этим шипом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top