Автор: Линь Гуаньхун / Призраки под рукой
Самородки:Талант /user/178526…
Гитхаб:GitHub.com/afan913337456…
Облачная колонка Tencent:cloud.Tencent.com/developer/U…
Колонка блокчейна червоточины:woohoo.impulsecommunity.com/article/153…
содержание
- Прототип проблемы
- Условный выбор
- HyperLogLog
- тест Бернулли
- Расчетная оптимизация
- втягиваться
- битовая строка
- ведро
- соответствовать
- Применение HyperLogLog в Redis
- Принцип HyperLogLog в Redis
- Коррекция смещения
- плечи гигантов
PS: Моя техническая книга: «Практика разработки блокчейн-приложений Ethereum» опубликована, и ее можно приобрести онлайн.
Прототип проблемы
Если вы хотите добиться такой функции:
Подсчитайте, сколько пользователей нажимают, чтобы войти на страницу приложения или веб-страницу каждый день. Повторные клики одного и того же пользователя засчитываются как 1 раз.
Умный вы можете сразу подумать, сHashMap
Этой структуры данных достаточно, и она также удовлетворяет дедупликации. Действительно, это обходной путь, и есть и другие решения.
Хотя задача несложная, когда переменные, участвующие в задаче, достигают определенного порядка величины, самая простая задача становится сложной. Предположим, что количество ежедневных активных пользователей в приложении достигает百万
или千万以上级别
, мы используемHashMap
Это приведет к тому, что программа будет занимать много памяти.
Попробуем оценитьHashMap
Использование памяти при решении вышеуказанных проблем. Гипотетическое определениеHashMap
серединаKey
заstring
тип,value
заbool
.key
соответствующий пользователюId
,value
да是否点击进入
. Очевидно, когда к нему обращаются миллионы разных пользователей. этоHashMap
Отпечаток памяти:100万 * (string + bool)
.
Условный выбор
Можно сказать, что в существующих на данный момент решениях вышеуказанных проблем,HashMap
Это тот, у которого наибольшее использование памяти. Если статистики не много, то этот метод можно использовать для решения задачи и он также прост в реализации.
Кроме тогоB+ 树
,Bitmap 位图
, а статья в основном знакомитHyperLogLog
Алгоритмические решения.
При определенных условиях, если коэффициент ошибок статистики перед огромным объемом данных находится в допустимом диапазоне, а 10 миллионов просмотров страниц позволяют получить итоговую статистику меньше 10 000 или 20 000, то ее можно использовать.HyperLogLog
Алгоритм решения аналогичной задачи подсчета выше.
HyperLogLog
HyperLogLog
, именуемый в дальнейшемHLL
,этоLogLog
Обновленная версия алгоритма, которая может обеспечивать неточный подсчет дедупликации. Существуют следующие функции:
- Реализация кода затруднена.
- Может использовать очень мало памяти для подсчета огромных объемов данных, в
Redis
реализовано вHyperLogLog
,нужно всего лишь12K
Память можно считать2^64
данные. - Существует определенная ошибка в подсчете, и частота ошибок, как правило, низкая. Стандартная ошибка составляет 0,81%.
- ошибка может быть установлена
辅助计算因子
уменьшить.
Учащимся, которые имеют небольшое представление об использовании памяти для основных типов данных в программировании, достаточно12K
Память можно считать2^64
удивлен данными. Почему вы так говорите? Давайте возьмем пример:
ВыбиратьJava
язык, вообщеlong
Занимает 8 байт, а байт имеет 8 бит, то есть: 1 байт = 8 бит, то естьlong
Наибольшее число, которое может быть представлено типом данных:2^63-1
. соответствующий вышеизложенному2^64
число, при условии, что есть2^63-1
так много цифр, от0 ~ 2^63-1
,в соответствии сlong
а также1k = 1024字节
Правила подсчета общей памяти таковы:((2^63-1) * 8/1024)K
, что является огромным числом, а место для хранения намного больше, чем12K
. иHyperLogLog
но можно использовать12K
Статистику можно заполнить.
тест Бернулли
зная, почемуHyperLogLog
Прежде чем вы сможете использовать очень мало памяти для подсчета огромных объемов данных, вы должны сначала понять伯努利试验
.
伯努利试验
это математика概率论
частью содержания, его аллюзии исходят из抛硬币
.
У медали две стороны, одна подбрасывается к другой, и вероятность окончательного появления орла и решки составляет 50%. Предполагая, что монета подбрасывается до тех пор, пока не выпадет орел, мы записываем это как полное испытание с одним броском и четырьмя орлами. Независимо от количества бросков, пока выпадает решка, это записывается как испытание. Этот тест伯努利试验
.
Тогда для нескольких伯努利试验
, предполагая, что это кратноеn
Второсортный. значит естьn
следующий фронт. Предположим, каждый раз伯努利试验
Количество опытных бросков равноk
. первый раз伯努利试验
, количество раз установлено наk1
, и так далее,n
следующий соответствуетkn
.
Среди них для этогоn
второсортный伯努利试验
, должно быть максимальное количество бросковk
, например подбрасывание 12 раз, прежде чем выпадет орел, то назовите это какk_max
, что представляет собой максимальное количество бросков.
伯努利试验
Нетрудно сделать следующие выводы:
- Количество бросков для n процессов Бернулли не превышает k_max.
- n процессов Бернулли с хотя бы одним броском, равным k_max
Наконец, в сочетании с методом оценки максимального правдоподобия обнаруживается, что вn
иk_max
Есть предполагаемые ассоциации в:n = 2^(k_max)
. Этот метод оценки характеристик общего потока данных через локальную информацию, по-видимому, находится за пределами нашего базового понимания.Для вывода и проверки этой связи необходимы вероятностные и статистические методы.
Например, это выглядит так:
第一次试验: 抛了3次才出现正面,此时 k=3,n=1
第二次试验: 抛了2次才出现正面,此时 k=2,n=2
第三次试验: 抛了6次才出现正面,此时 k=6,n=3
第n 次试验:抛了12次才出现正面,此时我们估算, n = 2^12
Предполагая, что в приведенном выше примере есть 3 экспериментальные группы, тогда k_max = 6 и, наконец, n = 3, мы подставляем это в формулу оценки, очевидно: 3 ≠ 2^6 . То есть, когда количество испытаний невелико, ошибка этого метода оценки очень велика.
Расчетная оптимизация
В приведенных выше трех наборах примеров мы называем это одним раундом оценки. Если выполняется только один раунд, когда n достаточно велико, предполагаемая частота ошибок будет относительно снижена, но все же недостаточно мала.
Так можно ли делать несколько раундов? Например, провести 100 и более раундов испытаний, затем взять k_max каждого раунда, а затем взять среднее значение, а именно:k_mx/100
. Наконец, оценивается n. НижеLogLog
Формула оценки для:
вышеприведенной формулыDVLL
соответствуетn
,constant
является поправочным коэффициентом, его конкретное значение не определено и может быть разветвлено и установлено в соответствии с реальной ситуацией.m
представляет количество раундов испытания. крест на головеR
это среднее:(k_max_1 + ... + k_max_m)/m
.
Это достигается за счет увеличения количества тестовых раундов, а затем взятияk_max
Алгоритм оптимизации среднегоLogLog
способ сделать. иHyperLogLog
иLogLog
Отличие в том, что он использует не平均数
, но调和平均数
.调和平均数
Сравнивать平均数
Преимущество состоит в том, что на него не так легко воздействуют большие значения. Вот пример:
Найдите среднюю заработную плату:
А - 1000 в месяц, Б - 30000 в месяц. Как использовать среднее значение: (1000 + 30000) / 2 = 15500
Способ использования среднего гармонического: 2/(1/1000 + 1/30000) ≈ 1935,484.
очевидно,调和平均数
Сравнивать平均数
Эффект должен быть лучше. Ниже调和平均数
метод расчета,∑
является символом накопления.
втягиваться
Мы уже знаем из вышеизложенного, что в примере с подбрасыванием монеты она может пройти опыт Бернулли.k_max
чтобы оценитьn
.
Так как же этот метод оценки относится к следующему вопросу?
Подсчитайте, сколько пользователей нажимают, чтобы войти на страницу приложения или веб-страницу каждый день. Повторные клики от одного и того же пользователя засчитываются как 1.
HyperLogLog
это сделать. Для входных данных выполните следующие действия:
1. Битовая строка
пройти черезhash
функция преобразования данных в比特串
, например, введите 5, оно будет преобразовано в: 101. Зачем так конвертировать?
Это потому, что это соответствует подбрасыванию монеты,比特串
, 0 представляет решку, а 1 представляет решку, если данные окончательно преобразованы10010000
, то справа налево, снизу вверх, мы можем думать, что первое появление 1 положительно.
Затем на основе приведенного выше оценочного вывода мы можем оценить общее количество экспериментов, проведенных максимальным количеством раз, когда эксперимент с подбрасыванием монеты подбрасывается орлом. Аналогичным образом, согласно сохраненным данным, максимальное значение 1 появляется после Преобразование.позиция k_max, чтобы оценить, сколько данных хранится.
2. Ведро
Ведро делится на сколько раундов. Абстрагировавшись в память компьютера, он хранит большой массив S с единицей измерения бит (бит) и длиной L. Разделим S в среднем на m групп, обрати внимание на эту m группу, скольким раундам она соответствует, и затем количество раундов в каждой группе.Количество занятых битов является средним и устанавливается равным P. Легко вывести следующую зависимость:
- L = S.length
- L = m * p
- В K память, занятая S = L/8/1024
существуетRedis
середина,HyperLogLog
Настройки: m=16834, p=6, L=16834*6. Занятая память = 16834 * 6/8/1024 = 12К
визуализируется как:
第0组 第1组 .... 第16833组
[000 000] [000 000] [000 000] [000 000] .... [000 000]
3. Переписка
Теперь вернемся к вопросу подсчета пользователей на нашей исходной странице приложения.
- Установите ключ домашней страницы приложения как: main
- Идентификатор пользователя: idn , n->0,1,2,3....
В этой статистической задаче разные идентификаторы пользователей идентифицируют пользователя, тогда мы можем использовать идентификатор пользователя в качестве пользователя.hash
ввод. который:
хэш (идентификатор) = битовая строка
Разные идентификаторы пользователей должны иметь разные比特串
. Каждый比特串
, также должна быть хотя бы одна позиция 1. Мы сравниваем каждый比特串
однажды伯努利试验
.
в настоящее время分轮
, это,分桶
. Таким образом, мы можем установить, что каждый比特串
После преобразования первого числа цифр в десятичное его значение соответствует метке корзины. Предположение比特串
Нижние два бита используются для вычисления флага под ведром, в это время есть идентификатор пользователя比特串
Да: 1001011000011. Его индекс ведра:11(2) = 1*2^1 + 1*2^0 = 3
, в третьем ведре, третий тур.
В приведенном выше примере после расчета номера ведра оставшаяся часть比特串
Да: 10010110000, от младшего к старшему, первое вхождение 1 равно 5. То есть третий ствол в это время, в третьем раунде испытаний,k_max = 5
. 5 соответствует двоичному коду: 101, опять же, потому что в каждой корзине есть p бит. Когда p>=3, можно сохранить 101.
Имитируя описанный выше процесс, несколько разных идентификаторов пользователей разбросаны по разным корзинам, и каждая корзина имеет свой k_max. Потом, когда статистикаmian
Когда количество кликов пользователя на странице является оценочным. Наконец, объединив k_max во всех сегментах и подставив его в формулу оценки, можно получить оценочное значение.
НижеHyperLogLog
Формула оценки, которая сочетает в себе гармоническое среднее, переменную интерпретацию иLogLog
такой же как:
Применение HyperLogLog в Redis
Во-первых, в Redis HyperLogLog — это одна из высокоуровневых структур данных. Есть две команды, включая, но не ограничиваясь следующими:
- значение ключа pfadd, сохраните значение, соответствующее ключу в
- ключ pfcount, подсчитайте, сколько значений ключа есть
Напомним, что исходная страница APP подсчитывает проблемы пользователей. Если ключ соответствует имени страницы, значение соответствует идентификатору пользователя. Тогда проблема правильная.
Принцип HyperLogLog в Redis
Ранее мы узнали, что в его реализации имеется 16384 корзины, то есть: 2^14 = 16384, каждая корзина имеет 6 бит, и максимальное число, которое может выражать каждая корзина, равно: 2^5+2^4+.. .+1 = 63 в двоичном формате:111 111
.
Для команды:pfadd key value
При сохранении значение будет хэшировано в 64 бита, то есть в 64-битную строку, первые 14 бит используются для группирования, а первые 14 бит двоичного кода преобразуются в десятичное число, которое является меткой сегмента.
Почему выбирают14位
Причина для выражения числа ведра состоит в том, что 16384 ведра разделены, и 2^14 = 16384, в самый раз, ведро может быть израсходовано за максимальное время, не вызывая потерь. Предположим, что первые 14 цифр строки: 00 0000 0000 0010, а ее десятичное значение равно 2. Затем индекс будет преобразован и помещен в корзину номер 2.
Правило преобразования для индекса:
Во-первых, поскольку полная строка битов значения находится в 64-битной форме, после вычитания 14 остается бит 50. В крайнем случае позиция, где появляется 1, находится на 50-й позиции, то есть позиция равна 50. . На данный момент индекс = 50. На этом этапе сначала преобразуйте индекс в двоичный, то есть: 110010.
Из-за 16384 сегментов каждый сегмент состоит из 6 бит. Так уж получилось, что 110010 было установлено на ведро номер 2. Обратите внимание, что 50 — это уже наихудший случай, и все это приспособлено. Тогда остальные точно можно разместить не задумываясь.
Потому что ключ fpadd может устанавливать несколько значений. Например следующий пример:
pfadd lgh golang
pfadd lgh python
pfadd lgh java
В соответствии с описанным выше методом разные значения будут установлены для разных сегментов.Если они появляются в одном и том же сегменте, первое 14-битное значение будет одинаковым, но позиция, в которой 1 появится позже, будет другой. Затем сравните, больше ли исходный индекс, чем новый индекс. Если да, замените. Нет, никаких изменений.
Наконец, 16384 корзины, соответствующие ключу, имеют множество значений, и каждая корзина имеетk_max
. При вызове pfcount в это время по описанному выше методу оценки можно вычислить, сколько раз установлено значение ключа, то есть статистическое значение.
Значение преобразуется в 64-битную строку и, наконец, записывается в каждую корзину в соответствии с описанным выше методом. Преобразование 64 бит в десятичное: 2 ^ 64,HyperLogLog
Используется только:16384 * 6 /8 / 1024 K
Место для хранения может насчитывать до 2^64 чисел.
Коррекция смещения
В предполагаемой расчетной формулеconstant
Переменная не является фиксированным значением, она будет разветвляться в зависимости от фактической ситуации, как показано ниже.
Допущения: m — количество ведер, p — логарифм по основанию 2 от m.
// m 为桶数
switch (p) {
case 4:
constant = 0.673 * m * m;
case 5:
constant = 0.697 * m * m;
case 6:
constant = 0.709 * m * m;
default:
constant = (0.7213 / (1 + 1.079 / m)) * m * m;
}
плечи гигантов
Простой эксперимент с подбрасыванием монеты может привести к такому шокирующему алгоритму, силе математики.
Благодарим за руководство в следующих двух сообщениях в блоге:
Все изображения в этой статье взяты из:
woo woo Краткое описание.com/afraid/55 разработали 6-е…
Содержание этой статьи относится к:
woohoo.дождливый лук E.com/blog/2017/0…
Ручное визуальное наблюдениеLogLog
иHyperLogLog
Измененный сайт: