Обзор
Большинство методов развертывания кластера Redis развертываются в стиле Twemproxy. То есть ключ redis сегментируется через Twemproxy, а ключ redis сегментируется и назначается одному из нескольких экземпляров redis. Схема архитектуры tewmproxy выглядит следующим образом:
Поскольку несколько экземпляров Redis, стоящих за Twemproxy, согласованы в конфигурации памяти и конфигурации ЦП, как только объем доступа или объем данных перекошены, это может привести к тому, что экземпляр Redis достигнет узкого места в производительности, что приведет к тому, что весь кластер достигнет узкого места в производительности. .
Возникновение горячей клавиши приводит к перекосу трафика кластера.
Горячий новостной контент в новостных приложениях;
Конфигурация действия, в котором пользователь активно участвует в системе действий;
В системе seckill торгового центра самая привлекательная и рентабельная информация о продукте;
...
решение
1. Используйте локальный кеш
Использование локального кеша на стороне клиента уменьшает количество обращений к горячему ключу со стороны redis-кластера, но в то же время приносит две проблемы: 1. Если все ключи, которые могут стать горячими ключами, кэшируются локально, будет ли локальный кеш слишком большой?Таким образом, это влияет на накладные расходы кэша, требуемые самим приложением. 2. Как обеспечить согласованность срока действия локального кеша и данных кластера Redis.
В ответ на эти две проблемы я не буду сначала говорить о втором решении.
2. Используйте характеристики алгоритма сегментирования, чтобы разбить ключ
Мы знаем, что горячая клавиша — это горячая клавиша, потому что у нее всего одна клавиша, которая приходится на один экземпляр. Следовательно, мы можем добавить префикс или суффикс к горячей клавише и изменить номер одной горячей клавиши на кратное M количеству экземпляров redis N, чтобы доступ к одному ключу redis стал доступом к N * M ключей redis.
N*M ключей redis распределяются по разным экземплярам посредством сегментирования, а объем доступа равномерно распределяется по всем экземплярам.
код показывает, как показано ниже:
//redis 实例数
const M = 16
//redis 实例数倍数(按需设计,2^n倍,n一般为1到4的整数)
const N = 2
func main() {
//获取 redis 实例
c, err := redis.Dial("tcp", "127.0.0.1:6379")
if err != nil {
fmt.Println("Connect to redis error", err)
return
}
defer c.Close()
hotKey := "hotKey:abc"
//随机数
randNum := GenerateRangeNum(1, N*M)
//得到对 hot key 进行打散的 key
tmpHotKey := hotKey + "_" + strconv.Itoa(randNum)
//hot key 过期时间
expireTime := 50
//过期时间平缓化的一个时间随机值
randExpireTime := GenerateRangeNum(0, 5)
data, err := redis.String(c.Do("GET", tmpHotKey))
if err != nil {
data, err = redis.String(c.Do("GET", hotKey))
if err != nil {
data = GetDataFromDb()
c.Do("SET", "hotKey", data, expireTime)
c.Do("SET", tmpHotKey, data, expireTime + randExpireTime)
} else {
c.Do("SET", tmpHotKey, data, expireTime + randExpireTime)
}
}
}
В этом коде ключ tmp получается через случайное число больше или равное 1 и меньше M*N, и программа отдаст приоритет доступу к ключу tmp.Содержимое записывается обратно в ключ tmp. Стоит отметить, что время истечения ключа tmp — это время истечения срока действия горячего ключа плюс небольшое случайное положительное целое число, чтобы гарантировать, что по истечении срока действия горячего ключа срок действия всех ключей tmp не истечет одновременно и вызовет кеширование. лавина. Это идея, чтобы избежать лавин за счет истечения срока действия склона, в то же время более совершенным является использование атомарных блокировок для записи данных и снижения нагрузки на БД.
Еще одна вещь, о которой стоит упомянуть, это то, что по умолчанию, когда мы генерируем ключ tmp, мы будем использовать случайное число в качестве суффикса горячей клавиши, что соответствует пространству имен Redis и облегчает сбор ключей и управление ими. Однако существует крайняя ситуация, то есть длина горячей клавиши очень велика.В это время случайное число не может быть добавлено в качестве суффикса.Причина в том, что в процессе расчета алгоритма шардинга Twemproxy, чем выше вес символов спереди, тем выше вес символов сзади.Вес меньше. То есть для имени ключа чем больше разница между предыдущими символами, тем больше разница в вычисленном значении сегмента и тем больше вероятность того, что он будет присвоен разным экземплярам (конкретный алгоритм здесь обсуждаться не будет). ). Таким образом, для горячей клавиши с длинным именем случайный номер следует размещать с осторожностью, например, располагая его перед последней командной областью (например, от исходного пробела1:пробел2:пробел3_rand до пробела1:пробел2:rand_space3) .
Большой ключ приводит к искажению объема данных кластера.
Масштабная долгосрочная строительная деятельность на форуме;
Список сообщений популярных чатов в системе чатов;
...
решение
разбить на большой ключ
Разделите данные (большое значение), хранящиеся в большом ключе, на значение1, значение2… значениеN,
Если большое значение представляет собой большой json, содержимое ключа распределяется по каждому экземпляру с помощью mset, чтобы уменьшить влияние большого ключа на искаженный объем данных.
//存
mset key1, vlaue1, key2, vlaue2 ... keyN, valueN
//取
mget key1, key2 ... keyN
Если большое значение представляет собой большой список, его можно разделить на разделенные списки. = список_1, список_2, список3, списокN
То же самое справедливо и для других типов данных.
И большая клавиша, и горячая клавиша
В процессе разработки некоторые ключи не только имеют большой объем доступа, но и имеют большой объем данных.В это время мы должны рассмотреть использование ключа, разумно ли хранить его в кластере Redis, и целесообразнее ли использовать другие компоненты для хранения; если вы настаиваете на использовании Redis для хранения, вы можете рассмотреть возможность миграции из кластера и принять один главный-один-резервный (или один-главный-несколько-резервных) ) архитектура для хранения.
разное
Как найти горячую клавишу, большой ключ
1. Предварительное предсказание
На этапе развития бизнеса необходимо заранее оценивать и обрабатывать данные, которые могут стать горячими и большими ключами, для этого требуется понимание продуктового бизнеса, понимание ритма работы и опыт проектирования данных.
2. На лету – мониторинг и автоматическая обработка
монитор
На стороне приложения собирайте и сообщайте о работе каждого запроса к redis; это не рекомендуется, но может быть рассмотрено в сценариях, где не хватает ресурсов для эксплуатации и обслуживания. Разработка может осуществляться в обход эксплуатации и обслуживания);
На уровне прокси собирайте и сообщайте о каждом запросе redis (рекомендуется, эксплуатация и обслуживание, естественно, являются лучшим решением);
Используйте команду монитора для подсчета горячих клавиш на экземпляре Redis (не рекомендуется, существует риск взрыва памяти Redis в условиях высокой параллелизма);
На уровне машины клиент Redis использует протокол TCP для взаимодействия с сервером, а протокол связи использует RESP. С точки зрения машины вы можете завершить статистику горячих клавиш, захватив TCP-пакеты всех портов Redis на машине (не рекомендуется, на каждой машине в компании уже есть много базовых компонентов, поэтому не добавляйте никаких больше путаницы);
автоматическая обработка
После мониторинга программа может получить большой ключ и горячую клавишу, и одновременно с тревогой программа автоматически обрабатывает большой ключ и горячую клавишу. Или сообщить программисту, чтобы он использовал определенный инструмент для настройки (выполнить вышеупомянутое решение для определенного ключа в программе)
3. По факту
Постарайтесь не думать задним числом, это все уроки крови и слез, так что я не буду об этом говорить.
Спасибо за чтение и добро пожаловать в общение.