Ухудшение производительности Twemproxy (Щелкунчика) с .NET Servicestack.redis Client
-
21-12-2019 - |
Вопрос
Настройка 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 был перегружен, и не было достаточно памяти, чтобы справиться с этим шипом.