Не тот Redis (а)

Redis

Разные Redis

Когда дело доходит до Redis, о чем каждый должен думать?

Высокий уровень параллелизма, хранилище KV, база данных в памяти, богатая структура данных, один поток (до версии 6)

Затем, далее, я отвечу на вышеперечисленные вещи один за другим и покажу вам прелесть Redis.Статья будет длинной и с какой-то ерундой, пожалуйста, пропустите ее, спасибо! ~

Почему возникает кэш?

Как правило, данные находятся в базе данных, а прикладная система непосредственно управляет базой данных. Когда количество посещений исчисляется десятками тысяч и увеличивается нагрузка на базу, что делать?

Небольшой партнер скажет, суб-библиотека подсуди, отдельный чтение и запись. Действительно, это действительно относительно высокие решения трафика, однако, если больше посещений, 100 000, 1 миллион из него? Как разделить его, похоже, не решает проблему, поэтому нам нужно использовать другие способы решения высокой базы данных параллелизма, приносит давление.

В это время появляется кеш. Кэш, как следует из названия, должен сначала кэшировать данные в памяти. При доступе мы сначала получим доступ к данным в памяти. Если данные в памяти не существуют, в на этот раз мы прочитаем его снова.Выберите базу данных, а затем создайте резервную копию данных в базе данных в памяти, чтобы в следующий раз, когда придет запрос на чтение, к нему сначала обращались непосредственно из памяти, а данные будут возвращены непосредственно после доступа к данным в памяти. Это отлично снижает нагрузку на базу данных.Может приходит 100 000 запросов, и все они обращаются к данным, зарезервированным в памяти, не обращаясь к базе данных, или только небольшое количество запросов обращается к базе данных, что действительно значительно сокращается. давление на базу данных, а это также улучшает реакцию системы. Подумайте об этом, скорость чтения и записи памяти намного быстрее, чем скорость чтения и записи жесткого диска. Память, считанная запросом, может быть намного быстрее, чем чтение жесткого диска.Удобство пользователя также будет высоким.

Что такое кеш?

Кэш изначально относится к высокоскоростной памяти на ЦП.Он обменивается данными с ЦП перед памятью, и скорость очень высокая.

Теперь обычно относится к набору копий исходных данных, хранящихся на компьютере для быстрого доступа.

В интернет-технологиях кэш-память является одной из ключевых технологий для быстрого отклика системы.

Кэшированный режим чтения-записи

Есть три режима чтения-записи кеша

Шаблон кэширования в сторону (обычно используется)

Cache Aside Pattern (побочный кеш), самый классический кеш + режим чтения и записи базы данных

При чтении сначала прочитайте кеш, если кеша нет, прочитайте базу, затем выньте данные и поместите их в кеш, и заодно верните ответ.

При обновлении сначала обновить базу, а потом удалить кеш

Зачем удалять кеш вместо обновления кеша?

1. Кэшированное значение представляет собой структуру, хеш, список и обновление данных, которые необходимо пройти.

2. Ленивая загрузка, кеш обновляется по мере использования, либо кеш может заполняться асинхронно

Три случая большого количества одновременных грязных чтений

1. Сначала обновите базу данных, затем обновите кеш.

Между обновлением и фиксацией, если кеш обновляется, а фиксация не удалась, БД несовместима с кэшированными данными.

2. Сначала удалите кэш, затем обновите базу данных.

Между обновлением и фиксацией происходит новое чтение, кеш пуст, данные БД считываются в кеш, данные старые

БД - это новые данные после фиксации

Тогда БД несовместима с кешированными данными

3. Сначала обновить базу, а потом удалить кеш (рекомендуется)

Между обновлением и фиксацией происходит новое чтение, кеш пуст, данные БД считываются в кеш, данные старые

БД - это новые данные после фиксации

Тогда БД несовместима с кешированными данными

Используйте стратегию отложенного двойного удаления

Read/Write Through Pattern

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

Read-Through (режим проникающего чтения/режим прямого чтения): приложение читает кеш, в кеше его нет, кеш возвращается источнику в базу данных, а кеш записывается

Сквозная запись (режим сквозной записи/режим сквозной записи): приложение записывает в кеш, а кеш записывает в базу данных. В этом режиме необходимо предоставить обработчик для базы данных, а разработка более сложная.

Write Behind Caching Pattern

Приложение только обновляет кеш

Кэш обновляет данные пакетами или объединяет их с БД асинхронно.

Невозможно синхронизировать все время, да еще и данные теряются

А что такое Редис?

Redis — это высокопроизводительная NoSQL (нереляционная база данных) с открытым исходным кодом, написанная на языке C, также называемая кэш-базой данных, где данные хранятся в памяти. Redis хранится в форме ключ-значение, которая отличается от традиционных реляционных баз данных. Эти основные требования традиционных баз данных не обязательно соблюдаются. Например, не следуйте стандарту SQL, транзакциям, структуре таблиц и т. д. Redis имеет очень богатые типы данных, такие как String, list, set, zset, hash и т. д.

Что может Редис?

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

  2. Разделить сеанс

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

    Redis решает эту проблему и сохраняет информацию о сеансе после успешного входа в Redis, чтобы несколько котов могли обмениваться информацией о сеансе.

  1. Сделать распределенную блокировку

    Как правило, блокировки в Java являются многопоточными блокировками, которые находятся в процессе. Несколько процессов также вызовут проблемы, если они выполняются одновременно, и время также должно контролироваться. В настоящее время Redis можно использовать для распределенных блокировок, используя Команда Redis setnx для достижения

У использования Redis в качестве кэша так много преимуществ, но много ли соответствующих недостатков?

  1. Дополнительные расходы на оборудование

    Кэширование — это технология пространства-времени в программных системах, которая требует дополнительного дискового пространства и памяти для хранения данных.

  2. Инвалидация кеша с высоким параллелизмом

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

  3. Синхронизация данных кэша и базы данных

    Кэш и база данных не всегда могут синхронизировать данные

  4. Соревнование по параллельному кэшированию

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

Установка Redis здесь обсуждаться не будет. В Интернете есть множество руководств по установке на Mac, Windows и Linux. Вы можете найти их в Интернете и следить за ними. Это относительно просто. Далее я предлагаю вам проанализировать некоторые из них. Общие типы данных Redis.

Структура данных Redis

Redis — это система хранения «ключ-значение», а тип ключа — строка.

В Redis существует пять распространенных типов данных значений: строка, список, хеш, набор, zset.

строка тип строки

Строка подходит для кеша с одним значением, кеша объектов, распределенной блокировки и т. д.

Имя команды формат команды описание команды
set set key value назначать
get get key ценность
getset getset key value принять значение и присвоить
setnx setnx key value использовать присваивание, когда значение не существует
установить значение ключа NX PX 3000 атомарной операции, px устанавливает количество миллисекунд
append append key value добавить значение в конец
strlen strlen key получить длину строки
incr incr key Увеличение числа
incrby incrby key increment Увеличить указанное целое число
decr decr key Уменьшение числа
decrby decrby key decrement Уменьшить указанное целое число
mset mset key value key value массовое присвоение
mget mget key key стоимость партии

Далее мы выполняем эти команды для Redis ниже

установить команду:

127.0.0.1:6379> set name liuxixi
OK

получить команду:

127.0.0.1:6379> set name liuxixi
OK
127.0.0.1:6379> get name
"liuxixi"

команда getset:

127.0.0.1:6379> getset name lixixi
"liuxixi"
127.0.0.1:6379> get name
"lixixi"

команда setnx:

127.0.0.1:6379> setnx age 12
(integer) 1 //第一次返回1代表设置成功
127.0.0.1:6379> setnx age 13
(integer) 0 //第二次返回0代表没有设置成功

Применение команды:

127.0.0.1:6379> append name xi
(integer) 8 //返回的8是value的长度
127.0.0.1:6379> get name
"lixixixi"

команда стрлен:

127.0.0.1:6379> strlen name
(integer) 8

команда увеличения:

127.0.0.1:6379> incr age //可以用来做点赞功能
(integer) 14
127.0.0.1:6379> get age
"14"

incrby команда:

127.0.0.1:6379> incrby age 3
(integer) 17
127.0.0.1:6379> get age
"17"

команда декр:

127.0.0.1:6379> decr age
(integer) 16
127.0.0.1:6379> get age
"16"

Команда расшифровки:

127.0.0.1:6379> decrby age 3
(integer) 13
127.0.0.1:6379> get age
"13"

хэш тип хэша

имя команды формат команды описание команды
hset hset key field value Назначение, не делается различия между добавлением или изменением
hmset hmset field1 value1 field2 value2 массовое присвоение
hsetnx hsetnx key field value Назначение, ничего не делать, если поле существует
hexists hexists key filed Проверить, существует ли поле
hget hget key field получить значение поля
hmget hmget key field1 field2 ... Получить несколько значений поля
hgetall hgetall key
hdel hdel key field1 field2.. удалить указанное поле
hincrby hincrby key field increment Указанное поле увеличивается само по себе
hlen hlen key получить количество полей

Сценарий применения: может использоваться как корзина для покупок в электронной коммерции.

Корзина электронной коммерции:

  1. Идентификатор пользователя как ключ
  2. идентификатор продукта является полем
  3. Количество товаров является ценностью

Работа с корзиной:

  1. Добавить товар: hset в корзину: 1001 10088 1
  2. Увеличить количество: корзина hincrby: 1001 10088 1
  3. Общее количество товаров: hlen cart: 1001
  4. Удалить Продукт: Тележка для гун: 1001 10088
  5. Gets cart Все товары: hgetвсей корзины: 1001

Преимущества и недостатки хэш-структуры

преимущество
  1. Однотипные данные классифицируются и объединяются для хранения, что удобно для управления данными
  2. По сравнению со строковыми операциями он потребляет меньше памяти и процессора.
  3. Экономит место по сравнению со строковым хранилищем

недостаток

  1. Функции истечения срока действия нельзя использовать на поле, только на ключе.
  2. Архитектура кластера Redis не подходит для крупномасштабного использования.

список тип списка

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

Получение записей возле головы или хвоста происходит очень быстро

Количество элементов в списке не более 2^31-1 (4 миллиарда).

Общие рабочие команды следующие:

имя команды формат команды описание команды
lpush lpush key v1 v2 v3 ... Вставить список слева
lpop lpop key Возьмите его слева от списка
rpush rpush key v1 v2 v3 ... Вставить список справа
rpop rpop key Возьмите его с правой стороны списка
lpushx lpushx key value Вставить значение в начало списка
rpushx rpushx key value вставить значение в конец списка
blpop blpop key timeout Выньте из левой части списка, заблокируйте, когда список пуст, вы можете установить максимальное время блокировки, единица измерения - секунды
brpop blpop key timeout Выньте из правой части списка, заблокируйте, когда список пуст, вы можете установить максимальное время блокировки, единица измерения - секунды
llen llen key Получить количество элементов в списке
lindex lindex key index Получить элемент с индексом index в списке index начинается с 0
lrange lrange key start end Возвращает элементы указанного диапазона в списке, диапазон задан по началу и концу
lrem lrem key count value Удалить элементы из списка, которые равны значению
Когда count>0, lrem удалит слева списка; когда count
lset lset key index value Установите элементы местоположения индекса списка на значение
ltrim ltrim key start end Обрежьте список, оставив только диапазон от начала до конца.
rpoplpush rpoplpush key1 key2 Вставьте справа от списка key1 и вставьте слева от списка key2
brpoplpush brpoplpush key1 key2 Выталкивание из правой части списка key1 и вставка его в левую часть списка key2 заблокирует
linsert linsert key BEFORE/AFTER pivot value Вставить значение в список до или после поворота значения

Общие структуры данных

Стек(стек)=LPUSH+LPOP

Очередь (очередь) = lpush + rpop

BlockingMQ (очередь блокировки) = LPUSH+BRPOP

список сценариев применения:

Поток новостей официального аккаунта Weibo и WeChat

Weibo и официальный аккаунт - все новые новости, которые в топе

  1. MacTalk отправил Weibo с идентификатором сообщения 10018

    LPUSH msg:{ID} 10018

  2. Запаска сказала, что машина размещена на Weibo, ID сообщения 10086

    LPUSH msg:{ID} 10086

  3. Просматривайте последние новости Weibo

    LRANGE msg:{ID} 0 4

Если Weibo big V или WeChat big V уделяют больше внимания, несколько тысяч, десятков тысяч можно распространять партиями, например, сначала отправлять их в онлайн, это будет очень быстро.

установить тип коллекции

набор: неупорядоченные, уникальные элементы

Максимальное количество элементов в наборе 2^32-1.

Общие рабочие команды следующие:

имя команды формат команды описание команды
sadd sadd key mem1 mem2 .... Добавить нового участника в коллекцию
srem srem key mem1 mem2 .... Удалить указанный элемент из коллекции
smembers smembers key Получить все элементы в коллекции
spop spop key Возвращает случайный элемент в коллекции и удаляет этот элемент
srandmember srandmember key Возвращает случайный элемент в коллекции, не удаляя элемент
scard scard key Получить количество элементов в коллекции
sismember sismember key member Проверить, находится ли элемент в коллекции
sinter sinter key1 key2 key3 Найдите пересечение нескольких множеств
sdiff sdiff key1 key2 key3 Найдите разницу нескольких наборов
sunion sunion key1 key2 key3 найти объединение нескольких множеств

Сценарии применения:

Подходит для структур данных, которые не могут повторяться и не требуют упорядочения

Например: подписчики также могут проводить случайную лотерею через spop.

Лотерейный апплет WeChat:

  1. Нажмите, чтобы принять участие в розыгрыше, чтобы присоединиться к коллекции

    SADD key {userId}

  2. Посмотреть всех пользователей, участвовавших в лотерее

    SMEMBERS key

  3. Победители розыгрыша

    SRANDMEMBER key [count] / SPOP key [count]

Wechat Weibo Нравится, Избранное, Тег

  1. как

    Sadd Alke: {ID сообщений} {ID пользователя}

  2. в отличие

    SREM, например: {идентификатор сообщения} {идентификатор пользователя}

  3. Проверить, понравилось ли пользователю

    SISMEMBMR, например: {идентификатор сообщения} {идентификатор пользователя}

  4. Получить список понравившихся пользователей

    УЧАСТНИКИ любят: {идентификатор сообщения}

  5. Получайте лайки от пользователей

    SCARD типа: {идентификатор сообщения}

Операция сбора реализует следующую модель Weibo и WeChat.

  1. люди, на которых вы подписаны

    хх -> {х, ххх}

  2. люди, на которых я подписан

    Ll -> {xx , xxx}

  3. я и люди, на которых вы подписаны

    SINTER xx LI -> {xxx}

  4. Я обеспокоен людьми, также обеспокоен им:

    SISMEMBER xx LI

  5. Люди, которых я могу знать:

    SDIFF xx LI -> {xx}

zset упорядоченный тип коллекции

Сами элементы неупорядочены и не повторяются

Каждый элемент связан с оценкой (score)

Сортировка по баллам, баллы можно повторить

Общие рабочие команды следующие:

имя команды формат команды описание команды
zadd zadd key score1 member1 score2 member2 ... Добавить новый элемент в отсортированный набор
zrem zrem key mem1 mem2 .... удаляет указанный элемент из упорядоченного набора
zcard zcard key Получить количество элементов в отсортированном наборе
zcount zcount key min max Возвращает количество элементов в коллекции, значение оценки которых находится в интервале [мин, макс]
zincrby zincrby key increment member На члене плюсового приращения набора баллов
zscore zscore key member Получить оценку участников в коллекции
zrank zrank key member Получить ранг участников в наборе (от малого к большому)
zrevrank zrevrank key member Получить ранг участников в наборе (в порядке убывания баллов)
zrange zrange key start end Получить элементы указанного интервала в наборе, отсортированные по возрастанию оценки
zrevrange zrevrange key start end Получить элементы указанного интервала в наборе, отсортированные по убыванию оценки

Сценарии применения:

Поскольку его можно сортировать по количеству очков, он подходит для различных списков лидеров. Например: рейтинги, рейтинги продаж, рейтинги подписчиков и т. д.

Пример:

127.0.0.1:6379> zadd hit:1 100 item1 20 item2 45 item3
(integer) 3
127.0.0.1:6379> zcard hit:1
(integer) 3
127.0.0.1:6379> zscore hit:1 item3
"45"
127.0.0.1:6379> zrevrange hit:1 0 -1
1) "item1"
2) "item3"
3) "item2"
127.0.0.1:6379>

zset установить операцию для достижения таблицы лидеров

  1. Нажмите, чтобы узнать новости

    ZINCRBY горячие новости:20190819 1 гвардеец Гонконг

  2. 10 лучших в выставочный день

    ZREVRANGE hotNews:20190819 0 9 WITHSCORES

  3. Список поиска за семь дней

    ZUNIONSTORE hotNews:20190813-20190819 7

    hotNews:20190813 hotNews:20190814... hotNews:20190819

  4. Показать семь из первой десятки рейтинга

    ZREVRANGE hotNews:20190813-201908109 0 9 WITHSCORES

Однопоточность и высокая производительность для Redis

Является ли Redis однопоточным?

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

Почему Redis работает в однопоточном режиме так быстро?

Здесь мы тестируем параллелизм, поддерживаемый Redis локально.

执行这条命令: ./redis-benchmark get
结果:
====== get ======
  100000 requests completed in 1.02 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1
  host configuration "save": 900 1 300 10 60 10000
  host configuration "appendonly": no
  multi-thread: no

0.00% <= 0.1 milliseconds
13.00% <= 0.2 milliseconds
55.85% <= 0.3 milliseconds
80.60% <= 0.4 milliseconds
92.57% <= 0.5 milliseconds
97.12% <= 0.6 milliseconds
99.06% <= 0.7 milliseconds
99.68% <= 0.8 milliseconds
99.86% <= 0.9 milliseconds
99.90% <= 1.0 milliseconds
99.90% <= 1.1 milliseconds
99.90% <= 1.2 milliseconds
99.91% <= 1.3 milliseconds
99.93% <= 1.4 milliseconds
99.95% <= 1.5 milliseconds
99.97% <= 1.6 milliseconds
99.98% <= 1.7 milliseconds
99.99% <= 1.8 milliseconds
99.99% <= 1.9 milliseconds
100.00% <= 2 milliseconds
100.00% <= 2 milliseconds
98328.42 requests per second

Здесь мы видим, что если секунд нет, он может поддерживать почти 100 000 concurrency, что уже является очень страшными данными.

Поскольку все данные находятся в памяти, все операции являются операциями на уровне памяти, но также и для того, чтобы избежать однопотокового переключения производительности проблемы многопоточного потребления. Поскольку Redis является однопоточным, будьте осторожны при использовании команд Redis, эти команды (например, ключи) отнимают много времени, их следует использовать с осторожностью, поскольку они могут привести к Redis Caton.

Как один поток Redis обрабатывает такое количество одновременных клиентских подключений?

Мультиплексирование операций ввода-вывода в Redis: Redis использует epoll для реализации мультиплексирования операций ввода-вывода, помещая информацию о соединении и события в очередь и одновременно помещая их в диспетчер событий файлов, а диспетчер событий распределяет события обработчику событий.

Некоторые другие расширенные команды Redis

keys

Полный обход ключей используется для получения списка всех ключей, которые удовлетворяют определенным правилам обычных строк.Когда объем данных Redis относительно велик, производительность относительно низкая, и этого следует избегать.

сканирование: клавиша прогрессивного обхода

SCAN cursor [MATCH pattern] [COUNT count]

Параметр сканирования предоставляет три параметра: первый — целочисленное значение курсора (значение индекса хэш-контейнера), второй — обычный шаблон ключа, а третий — количество ключей, пройденных за один раз (эталонное значение, количество базовых обходов не обязательно), а не количество подходящих результатов. При первом обходе значение курсора равно 0, а затем первое целочисленное значение в возвращаемом результате используется в качестве курсора для следующего обхода. Перемещайтесь до тех пор, пока возвращаемое значение курсора не станет равным 0.

127.0.0.1:6379> scan 0 match key* count 3
1) "12" //这个12代表返回下一次扫描的游标数,下一次scan就需要从这个数开始扫描
2) 1) "key4"
127.0.0.1:6379> scan 12 match key* count 3
1) "26"
2) 1) "key1"
   2) "key3"

Примечание: Но сканирование не является совершенным.Если в процессе сканирования происходит изменение ключа (добавление, удаление, изменение), эффект обхода может столкнуться со следующими проблемами: вновь добавленный ключ может не пройти, и обход повторяется. Другими словами, сканирование не гарантирует, что полный ключ проходит через все ключи, это то, что мы должны учитывать при разработке.

Основные принципы проектирования Redis

Redis как система хранения ключей и значений имеет следующую структуру данных:

Экземпляр Redis соответствует нескольким БД, а БД соответствует нескольким ключам. Ключи обычно представляют собой строки. Значение, стоящее за ним, называется RedisObject. Это не означает, что значение является строкой, списком, картой и т. д., но что все эти Типы используются Redis.Он инкапсулирован в RedisObjcet, какой это тип? Вот способ использования указателя, чтобы указать, к какому типу он относится.

Почему вы хотите это сделать, в основном для повышения производительности Redis

PS: Вставьте здесь предложение, почему способ использования указателей лучше, чем способ использования самого объекта?

Здесь есть две точки:

Во-первых, это динамическое размещение, и большая особенность указателей заключается в том, что вам нужно только объявить тип, на который он указывает впереди (и если вы хотите использовать фактический объект, вам также нужно его определить). Таким образом, вы можете уменьшить связь между вашими модулями компиляции и, таким образом, сократить время компиляции.

Структура RedisDB

В Redis нет понятия таблиц. БД, соответствующие экземплярам Redis, различаются по номерам. Сама БД является пространством имен ключа.

Например: user: 1000 в качестве значения ключа, указывающего на элемент с идентификатором 1000 в пользовательском пространстве имен, аналогично строке с идентификатором = 1000 в пользовательской таблице.

Строка паспорта безопасности

Как мы все знаем, Redis реализован на языке C. В языке C тип String на самом деле представляет собой массив символов, например char data[]="xxx\0". Однако клиент может отправить набор отправка произвольной строки не проверяется, поэтому, если мы отправим строку xx\0xx, то xx после \0 не будет прочитан, а только предшествующий xx (в языке C "\0" означает конец строки, если в самой строке есть символ "\0", строка будет усечена)

Таким образом, Redis реализовал строку с именем SDS, и SDS записал LEN и char buf[], len используется для записи длины buf, например, Char Buf[] = "xx \ 0xx", тогда Len равно 5 , SDS Так же есть более важный атрибут free, указывающий сколько там.

free вычисляется путем изменения len. Например, если «xxx1234» изменить на «xxx123456», емкость будет увеличена в соответствии с (len + addlen) * 2 = 18. В это время len становится 9, а free — 18. -9. 9

Например:

char buf[] = "xxx1234" 改成 "xxx123456" //这里的buf是柔性数组
free:12  变成free:10
len:8    变成len:10

Каковы преимущества Redis при разработке SDS следующим образом:

  1. Двоичные безопасные структуры данных
  2. Предоставляет механизм предварительного выделения памяти, чтобы избежать частого выделения памяти.
  3. Библиотека функций, совместимая с языком C
  4. Есть отдельные статистические переменные len и free, по которым можно легко получить длину строки, что позволяет избежать риска неполного чтения.
  5. Содержимое хранится в гибком массиве buf, а указатель, предоставляемый SDS верхнему уровню, является не указателем на структуру SDS, а указателем непосредственно на гибкий массив buf. Верхний уровень может читать содержимое SDS так же, как чтение строк C, и совместим с различными функциями языка C для обработки строк.

Вот объяснение того, что такое мягкий массив:

Гибкий массив — это массив, размер которого необходимо определить.Последним элементом структуры в языке C может быть массив неизвестного размера, который является так называемой нулевой длиной, поэтому мы можем использовать структуру для создания гибкого массива. множество. Основная цель гибких массивов — удовлетворить потребности структур переменной длины, чтобы решить проблему избыточности памяти и выхода массива за границы при использовании массивов.

Это также было достигнуто до Redis 3.2.