Третья пуля Redis, дающая вам 100 миллионов ключей, как считать эффективно?

Redis

предисловие

Я не знаю, использовали ли вы его в больших масштабах.Redis? Или это просто инструмент кэширования? Наиболее часто в Redis используются коллекции, например, следующие сценарии:

  1. В системе регистрации день соответствует серии записей регистрации пользователей.
  2. В системе электронной коммерции продукт соответствует серии отзывов.
  3. В системе знакомств ряд друзей пользователя.

Характеристики коллекций в Redis — это не что иное, какKeyСоответствует серии данных, но роль данных часто для статистики, например:

  1. В системе дружбы необходимо ежедневно считать новых друзей и общих друзей обеих сторон.
  2. В системе электронной коммерции необходимо учитывать последние комментарии в списке комментариев.
  3. В системе входа необходимо подсчитать количество пользователей, которые вошли в систему в течение непрерывного месяца.

В крупномасштабных интернет-приложениях объем данных огромен, не говоря уже о миллионах, десятках миллионов или даже 100 миллионах, таких как гигант электронной коммерции Taobao, гиганты знакомств WeChat и Weibo, офисный гигант Dingding и т.д. не имеет сотни миллионов пользователей?

Только подбирая подходящие наборы для разных сценариев, можно сделать статистику более удобной.

Сводная статистика

聚合统计Относится к результату агрегирования нескольких элементов, таких как статистика нескольких наборов.перекресток,союз,разница

Если вам нужно агрегировать статистику по нескольким множествам, хорошим выбором будет коллекция Set.Помимо данных без дубликатов, Redis также предоставляет соответствующий API

перекресток

В приведенном выше примере общие друзья обеих сторон учитываются в системе дружбы, что и является агрегированной статистикой.交集.

существуетRedisможетuseridв видеkey, друзьяuseridв видеvalue,Как показано ниже:

Нужно всего два, чтобы сосчитать общих друзей двух пользователейSetПересечение наборов, команда выглядит следующим образом;

SINTERSTORE userid:new userid:20002 userid:20003

После запуска вышеуказанной командыuserid:newВ этом ключе будет хранитьсяuserid:20002,userid:20003Пересечение двух множеств.

разница

Например: если предположить, что системе дружбы необходимо ежедневно подсчитывать новых друзей, то необходимо взять разностный набор наборов друзей за два дня, например2020/11/1друг дняset1,2020/11/2друг дняset2, то необходимо толькоset1иset2Сделайте разностный набор.

Как должна быть спроектирована структура в настоящее время? Как показано ниже:

userid:20201101этоkeyзаписаноuseridпользователи2020/11/1Коллекция друзей дня.

Набор различий очень прост, просто нужно выполнитьSDIFFSTOREкоманда, как показано ниже:

SDIFFSTORE  user:new  userid:20201102 userid:20201101  

После того, как выполнение будет завершено,user:newЭтот набор будет2020/11/2Новые друзья добавляются ежедневно.

Вот более подходящий пример.Есть функция людей, которых вы можете знать на Weibo.Вы можете использовать разностный набор, то есть друзья ваших друзей минус ваши общие друзья — это люди, которых вы можете знать.

союз

Или пример набора разностей, предполагая, что требуется статистика2020/11/01и2020/11/2总共新增的好友,此时只需要对这两日新增好友的集合做一个并集。 Команда выглядит следующим образом:

SUNIONSTORE  userid:new userid:20201102 userid:20201101

новая коллекция на данный моментuserid:newЭто два дня новых друзей.

Суммировать

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

Так как же избежать блокировки? предложения ниже:

  1. существуетRedisВыберите подчиненную библиотеку в кластере, которая будет отвечать за агрегированную статистику, чтобы основная библиотека и другие подчиненные библиотеки не были заблокированы.
  2. Данные передаются клиенту, и клиент выполняет сводную статистику.

Сортировать статистику

На некоторых сайтах электронной коммерции вы можете видеть, что обзоры товаров всегда актуальны, как это делается?

Список последних комментариев содержит все комментарии, т.е.Коллекции хранят элементы по порядку.也就是说集合中的元素必须按序存储,称之为有序集合。

Redisв четырех наборахListиSorted SetПринадлежит к упорядоченному множеству.

ноListиSorted SetКакая разница? Какой использовать?

Список отсортирован по порядку элементов, а отсортированный набор можно отсортировать по весу элементов.Например, вы можете определить вес в соответствии с временем набора элементов, сначала вставил вес элементов, а мощность элемента значительна.

Для этого примера очевидно, что обе они могут соответствовать требованиям.LRANGE иSorted SetКоманда запроса пейджингаZRANGEBYSCORE.

Но с точки зрения гибкости List точно не подходит, List можно сортировать только по порядку вставки, но в большинстве сценариев он может сортироваться не только по времени, но и по каким-то определенным условиям.Sorted SetЭто очень удобно, просто нужно сгенерировать соответствующие веса по уникальному алгоритму.

Бинарная статистика государства

Двоичное состояние относится к двум значениям 0 или 1; В сценарии регистрации и включения необходимо записать только два состояния регистрации (1) и отсутствия регистрации (0), что является типичной бинарной статистикой состояний.

Статистику для бинарных состояний можно сделать с помощьюRedisРасширенный тип данныхBitmap, нижний слой используетStringРеализация типа, вы можете думать об этом как оbitМножество. Для получения подробной информации о последующем введении .........

В статистике входов0и1только одинbit, даже если есть только данные о 365 регистрациях за один год.bitнемного. Значительно сокращает место для хранения.

Растровое изображение обеспечиваетGETBIT/SETBITоперация с использованием значения смещенияoffsetЧтение и запись битового массива BIT. Однако следует отметить, что смещение Bitmap начинается с 0, что означаетoffsetМинимальное значение равно 0. когда используешьSETBITКогда бит записывается, бит будет установлен в 1. Растровое изображение также предоставляетBITCOUNTОперация для подсчета всех битов в этом битовом массиве1количество.

Как спроектировать значение ключа? ключ может бытьuserid:yyyyMM, который представляет собой уникальный идентификатор плюс месяц. Предположим, что идентификатор сотрудника10001требуется статистика2020/11Ежемесячная запись регистрации.

Первым шагом является выполнение команды для установки значения.Предполагая, что карта включена 2 ноября, команда выглядит следующим образом:

SETBIT userid:10001:202011 1 1 

BitMap начинается с нижнего индекса 0, поэтому нижний индекс № 2 равен 1. Если установлено значение 1, это означает, что карта успешно синхронизирована.

Второй шаг - проверять, будет ли пользователь на 2 ноября. Команда выглядит следующим образом:

GETBIT userid:10001:202011 1 

Третий шаг – подсчет количества перфокарт в ноябре, команда выглядит следующим образом:

BITCOUNT userid:10001:202011

Таким образом, вопрос в том, нужно подсчитать общее количество пользователей, подписывающихся на Chunging 20 дней подряд, вы эту подпись системы, как с этим бороться? Предположим, пользователь миллион.

такие как статистика2020/11/01прибыть2020/11/20Как подсчитать количество людей, которые работают непрерывно в течение дня?

BitmapОн также поддерживает выполнение побитовых операций над несколькими растровыми изображениями одновременно.,,异或Операция, команда, как показано ниже:

Идея приходит, мы можем использовать дату каждого дня в качествеkey,соответствующийBitMapХраните статус врезки 100 миллионов пользователей в день. Как показано ниже:

В этот момент нам просто нужно2020/11/1прибыть2020/11/20номерBitmapПобитовое делатьоперацию, в результате чегоBitmapЗначение, соответствующее каждой битовой позиции, представляет ситуацию отсчета в течение 20 дней подряд.Только когда все часы отсчитываются в течение 20 дней подряд, значение бита, в котором он находится, равно 1. Как показано ниже:

наконец-то можно использоватьBITCOUNTкоманда для статистики.

Вы можете попытаться рассчитать накладные расходы на память, используя Bitmap со 100 миллионами битов в день, что составляет около12MBОбъем памяти (10^8/8/1024/1024), накладные расходы памяти для 20-дневного растрового изображения составляют около240MB, нагрузка на память не слишком велика. Однако на практике лучшеBitmapУстановите время истечения срока действия, чтобы позволить Redis автоматически удалять записи регистрации, которые больше не нужны для экономии памяти.

Если речь идет о двоичном статусе, например, существует ли пользователь, регистрация, регистрация, существует ли продукт и т. д., можно использовать растровое изображение, что может эффективно сэкономить место в памяти.

Статистика кардинальности

Статистика мощности относится к подсчету количества уникальных элементов в наборе.

Например, на веб-сайтах электронной коммерции обычно необходимо подсчитать количествоUVДля определения веса необходимо дедуплицировать UV веб-страницы в типе Redis.SetДля поддержки дедупликации первое, что приходит на ум, это Set.

Но тут есть проблема,SetНижний слой использует хеш-таблицы и целочисленные массивы.Если UV веб-страницы достигает десятков миллионов (на веб-сайте электронной коммерции более одной страницы), она будет потреблять много памяти.

Redis предоставляет расширенный тип HyperLogLog для статистики количества элементов, который требует всего около 12 КБ памяти для вычисления 2 ^ 64 элементов.

Ты взволнован? ноHyperLogLogдаОшибкаДа наверное в0.81%, если вам нужна точная статистика, вам все равно нужно использоватьSet. Для такого типа веб-страниц достаточно UV.

При подсчете UV веб-страницы вам нужно только сохранить уникальный идентификатор пользователя в HyperLogLog следующим образом:

PFADD p1:uv 10001 10002 10003 10004

Если есть повторяющиеся элементы, они будут автоматически дедуплицированы.

Статистика также очень проста, используйтеPFCOUNTкоманда, как показано ниже:

PFCOUNT p1:uv

Суммировать

В этой статье представлены несколько типов статистики и то, какое хранилище коллекций следует использовать.Чтобы облегчить понимание, автор суммирует поддержку, преимущества и недостатки в таблице, как показано на следующем рисунке:

SetиSorted SetОперации агрегирования, поддерживающие пересечение и объединение, поддерживаются, ноSorted SetОперация набора разностей не поддерживается.

BitmapОн также может выполнять операции AND, XOR и OR для нескольких растровых изображений.

ListиSortedSetОба поддерживают статистику сортировки, но List сортируется в соответствии с порядком вставки элементов, а Sorted Set поддерживает веса, что является более гибким, чем сортировка List.

Для статистики бинарного состояния, оценки существования элемента и т. д. рекомендуется использоватьBitmap, экономя место в памяти.

Для кардинальной статистики рекомендуется использовать в случае большого объема данных и отсутствия требований к точностиHyperLogLog, экономит место в памяти, для точной кардинальной статистики лучше всего использоватьSetсобирать.

Кроме того, авторы завершили два столбцаМибатис Продвинутый,Усовершенствованная весенняя загрузка, статьи колонки были организованы в книги, и при необходимости публичный аккаунт будет возвращен.码猿技术专栏несколько ключевых словMybatis 进阶,Spring Boot 进阶Получите это бесплатно.