Привет, одноклассники, на прошлом уроке мы подробно представили базовую структуру хранения данных строк и списков в Redis, а сегодня мы сосредоточимся на принципах структуры hash, set и zset в Redis.
Redis — хеш-объект (хэш)
хэш базовой структуры данных хранится в двух: одна - ziplist, другая - Hashtable, две структуры данных, которые мы объяснили ранее, ziplist - это вышеупомянутая структура, объясненная перед структурой redis хеш-таблицы, хэш-объекты, только если они соответствуют следующим условия перед использованием кода ziplist:
- Длина строк ключа и значения, хранящихся в хеш-объекте, меньше 64 байт.
- Количество пар ключ-значение, хранящихся в хеш-объекте, меньше 512.
Структура хранилища ziplist выглядит следующим образом
Как видно на рисунке выше, когда количество данных относительно невелико, мы будем рассматривать все ключи и значения как один элемент и хранить их в ziplist для формирования заказа.
Структура хранилища хеш-таблиц
В чем разница между заданным значением ключа и хешем строк
- Срок действия, хэш не имеет срока действия
- Существует проблема с добавлением постоянного значения set.Один из атрибутов в dict — dictht ht[2], который в основном используется для расширения.Если ключ постоянно добавляется, необходимо расширить общую память Redis, а расширение должен быть основан на исходной памяти.Двойное потребление памяти
Объект Redis-коллекции (набор)
Set — это неупорядоченный, автоматически дедуплицированный тип данных коллекции.Нижний уровень Set хранится в двух структурах данных: одна — хэш-таблица, а другая — вставка.
Ключ хеш-таблицы — это значение элемента в наборе, а значение равно null.
Вставку можно понимать как массив, и использование структуры данных вставки должно соответствовать следующим двум условиям:
- Количество элементов не менее значения по умолчанию 512
set-max-inset-entries 512
- Элементы могут быть представлены как целые числа
Базовая структура intset
typedef struct intset {
// 编码类型
uint32_t encoding;
// 集合包含的元素数量
uint32_t length;
// 保存元素的数组
int8_t contents[];
} intset;
Метод запроса обычно использует двухточечный метод поиска, фактическая сложность запроса также является журналом (N)
Redis — отсортированный набор объектов (zset)
zset упорядочен (ограниченный порядок оценок, и элементы находятся в лексикографическом порядке, если оценки одинаковы), тип данных набора с автоматической дедупликацией, и его основная реализация представляет собой словарь (dict) + список пропуска (skiplist), когда данные относительно мал, используйте хранилище структуры кодировки ziplist.
Следующие два условия выполняются одновременно для использования хранилища ziplist:
- Количество элементов, хранящихся в отсортированном наборе, меньше значения по умолчанию, равного 128.
- Длина всех элементов, хранящихся в отсортированном наборе, меньше значения по умолчанию, равного 64 байтам.
метод хранения ziplist
Когда ziplist используется в качестве базовой структуры хранения zset, каждый элемент набора хранится с использованием двух сжатых узлов списка рядом друг с другом, первый узел содержит элементы элемента, а второй элемент содержит оценку элемента.
Способ хранения словарь (dict) + скиплист (skiplist)
Базовая структура хранения zset включает в себя ziplist или skiplist. ziplist используется, когда одновременно выполняются следующие два условия, а skiplist используется в других случаях. Эти два условия следующие:
Количество элементов, хранящихся в отсортированном наборе, меньше 128. Длина всех элементов, содержащихся в отсортированном наборе, меньше 64 байт.
пропустить структуру данных таблицы
Во-первых, давайте разберемся, что такое таблица пропуска.Это видно из того же вида, что мы запрашиваем от высшего уровня к более низкому уровню путем градации, и эффективность повышается, а его временная сложность logn (аналогично бинарному поиску)
Окончательная структура хранения dict+skiplist выглядит следующим образом.
Основываясь на приведенном выше рисунке, давайте посмотрим на структуру данных нескольких ключевых объектов в skiplist, которая удобна для понимания всем.
zset
/*
* 有序集合
*/
typedef struct zset {
// 字典,键为成员,值为分值
// 用于支持 O(1) 复杂度的按成员取分值操作
dict *dict;
// 跳跃表,按分值排序成员
// 用于支持平均复杂度为 O(log N) 的按分值定位成员操作
// 以及范围操作
zskiplist *zsl;
} zset;
Видно, что одна из них представляет собой структуру dict, основной ключ — ее элемент set, а значение — соответствующую оценку, а zkiplist используется как таблица переходов, отсортированная по оценке, что удобно для поиска членов.
zskiplist
/*
* 跳跃表
*/
typedef struct zskiplist {
// 表头节点和表尾节点
struct zskiplistNode *header, *tail;
// 表中节点的数量
unsigned long length;
// 表中层数最大的节点的层数
int level;
} zskiplist;
zskiplistNode
/*
* 跳跃表节点
*/
typedef struct zskiplistNode {
// 成员对象
robj *obj;
// 分值
double score;
// 后退指针
struct zskiplistNode *backward;
// 层
struct zskiplistLevel {
// 前进指针
struct zskiplistNode *forward;
// 跨度
unsigned int span;
} level[];
} zskiplistNode;
Указатель robj в zskiplistNode указывает на определенный элемент.Обратите внимание, что этот указатель и указатель ключа в dict указывают на один и тот же элемент, а обратный указатель ноги удобен для возврата.
Суммировать
В этом разделе в основном объясняется основной принцип Hash, SET, ZSET в REDIS, где в конце Hash используются два типа: Ziplist и Hashtable, а также два hashtable и INSET соответственно, где INSET также можно понимать как массивы, ZSET Нижний уровень – Ziplist и Dict + Skiplist, и мы видим превосходный дизайн с точки зрения экономии памяти и повышения эффективности запросов. Они могут быть использованы в качестве ценного опыта в нашем будущем проектировании и разработке. Мы перейдем к следующему разделу. Возможности REDIS в безопасность данных и защита производительности, выходите из класса!