Redis Hyperloglog - побочный эффект PFCOUNT
Redis недавно выпустил свою новую структуру данных под названием HyperLogLog. Это позволяет нам вести подсчет уникальных объектов и занимает только 12 Кбайт. Чего я не понимаю, так это того, что команда Redis PFCOUNT технически называется командой записи. Почему это так?
Примечание: в качестве побочного эффекта вызова этой функции возможно изменение HyperLogLog, поскольку последние 8 байтов кодируют последнюю вычисленную мощность для целей кэширования. Таким образом, PFCOUNT технически является командой записи.
1 ответ
Заголовок объекта HyperLogLog выглядит следующим образом:
struct hllhdr {
char magic[4]; /* "HYLL" */
uint8_t encoding; /* HLL_DENSE or HLL_SPARSE. */
uint8_t notused[3]; /* Reserved for future use, must be zero. */
uint8_t card[8]; /* Cached cardinality, little endian. */
uint8_t registers[]; /* Data bytes. */
};
Обратите внимание на поле карты: оно содержит последнюю мощность, оцененную алгоритмом. Вычисление оценки мощности является дорогостоящей операцией, поэтому Redis кэширует значение и сохраняет его в этом поле.
Когда вызывается PFADD, объект HyperLogLog может обновляться или нет (есть большая вероятность, что это не так). Если оно не обновлено, вызов PFCOUNT будет повторно использовать кэшированное значение (поле карты). Если оно обновлено, поле карты становится недействительным, поэтому следующий PFCOUNT выполнит алгоритм подсчета и запишет новое значение в поле карты.
Вот почему PFCOUNT может изменять объект HyperLogLog.