0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Работаете со Spring, но ни разу не касались<strong>Redis</strong>? Давайте рассмотрим, что такое NoSQL базы данных, в частности Key-Value NoSQL БД, и что представляет собой одна из самых популярных NoSQL БД - Redis.</p>
1
<p>Работаете со Spring, но ни разу не касались<strong>Redis</strong>? Давайте рассмотрим, что такое NoSQL базы данных, в частности Key-Value NoSQL БД, и что представляет собой одна из самых популярных NoSQL БД - Redis.</p>
2
<h2>NoSQL DB (нереляционные БД)</h2>
2
<h2>NoSQL DB (нереляционные БД)</h2>
3
<p>Термин NoSQL (обозначение нереляционных БД) стал примерно таким же многозначным, как и "облако". NoSQL базами данных сейчас называют то, что раньше даже базами данных и не являлось. Например, кэши! Как ни странно, некоторые NoSQL БД имеют SQL-интерфейс. Поэтому саму аббревиатуру NoSQL сейчас расшифровывают как "Not Only SQL".</p>
3
<p>Термин NoSQL (обозначение нереляционных БД) стал примерно таким же многозначным, как и "облако". NoSQL базами данных сейчас называют то, что раньше даже базами данных и не являлось. Например, кэши! Как ни странно, некоторые NoSQL БД имеют SQL-интерфейс. Поэтому саму аббревиатуру NoSQL сейчас расшифровывают как "Not Only SQL".</p>
4
<p>NoSQL базы данных могут показаться совсем "нечеловеческими": в некоторых данные могут пропадать, ACID-транзакции могут отсутствуют как класс, долговременного хранения (durability в ACID) может в принципе не быть. Поэтому решая вопрос о применении той или иной NoSQL БД в проекте, необходимо абсолютно точно понимать, что вы делаете и какую задачу решаете.</p>
4
<p>NoSQL базы данных могут показаться совсем "нечеловеческими": в некоторых данные могут пропадать, ACID-транзакции могут отсутствуют как класс, долговременного хранения (durability в ACID) может в принципе не быть. Поэтому решая вопрос о применении той или иной NoSQL БД в проекте, необходимо абсолютно точно понимать, что вы делаете и какую задачу решаете.</p>
5
<p>NoSQL базы данных можно условно (условно!) разделить на четыре типа:</p>
5
<p>NoSQL базы данных можно условно (условно!) разделить на четыре типа:</p>
6
<p><strong>Key-Value базы данных</strong>хранят данные в виде ключ-значение, самый просто пример in-memory non-clustered non persistent DB - это HashMap. В, действительности, они не так просто устроены, но некоторое представление HashMap может дать</p>
6
<p><strong>Key-Value базы данных</strong>хранят данные в виде ключ-значение, самый просто пример in-memory non-clustered non persistent DB - это HashMap. В, действительности, они не так просто устроены, но некоторое представление HashMap может дать</p>
7
<p><strong>Семейства столбцов или "столбчатые" БД</strong>Их стоит один раз увидеть, чтобы понять, чем они отличаются от реляционных (табличных). В действительности они похожи на школьный журнал - с различными предметами, разделами, но не с идеальной посещаемостью и зафиксированными классами, а с пропусками и новыми учениками, иначе это был бы отличный пример реляционных данных.</p>
7
<p><strong>Семейства столбцов или "столбчатые" БД</strong>Их стоит один раз увидеть, чтобы понять, чем они отличаются от реляционных (табличных). В действительности они похожи на школьный журнал - с различными предметами, разделами, но не с идеальной посещаемостью и зафиксированными классами, а с пропусками и новыми учениками, иначе это был бы отличный пример реляционных данных.</p>
8
<p><strong>Документ-ориентированные</strong>БД хранит документы, допустим для простоты - JSON-ы. Самый простой пример - описание товаров в каком-нибудь интернет-магазине. Описания двух разных телефонов могут разниться очень сильно (у одного телефона описание камеры - может быть полем, а у другого - массив). А теперь сравним описания утюга и телефона. А теперь представим, если мы хотим найти все устройства c зарядкой на 110 V, или найти информацию о всех производителях SSD-дисков. Вот такие задачи можно решить с помощью документ-ориентированные БД.</p>
8
<p><strong>Документ-ориентированные</strong>БД хранит документы, допустим для простоты - JSON-ы. Самый простой пример - описание товаров в каком-нибудь интернет-магазине. Описания двух разных телефонов могут разниться очень сильно (у одного телефона описание камеры - может быть полем, а у другого - массив). А теперь сравним описания утюга и телефона. А теперь представим, если мы хотим найти все устройства c зарядкой на 110 V, или найти информацию о всех производителях SSD-дисков. Вот такие задачи можно решить с помощью документ-ориентированные БД.</p>
9
<p><strong>Графовые БД</strong>Предназначены для хранения графов. Хранить граф в реляционной БД - это тот ещё квест (с разными вариантами решения) и отличная задача на собеседование</p>
9
<p><strong>Графовые БД</strong>Предназначены для хранения графов. Хранить граф в реляционной БД - это тот ещё квест (с разными вариантами решения) и отличная задача на собеседование</p>
10
<p>Иногда выделяют ещё Time Series БД для хранения временных рядов, например, значений котировок акций, серию измерений.</p>
10
<p>Иногда выделяют ещё Time Series БД для хранения временных рядов, например, значений котировок акций, серию измерений.</p>
11
<p>Это деление, повторюсь, достаточно условное. Key-Value БД Redis можно, в частности, отнести и к документ-ориентированным. А ещё если взять две похожих Key-Value БД, например, Redis или<strong>Memcached</strong>, то принципы, на которых они построены, и их возможности могут кардинально отличаться. Например, Memcached является чисто in-memory БД, а вот Redis умеет записывать данные на диск.</p>
11
<p>Это деление, повторюсь, достаточно условное. Key-Value БД Redis можно, в частности, отнести и к документ-ориентированным. А ещё если взять две похожих Key-Value БД, например, Redis или<strong>Memcached</strong>, то принципы, на которых они построены, и их возможности могут кардинально отличаться. Например, Memcached является чисто in-memory БД, а вот Redis умеет записывать данные на диск.</p>
12
<p>Key-Value БД ещё делятся на RAM и не RAM - в любой момент времени можно быстро получить любой элемент или нет. Некоторые Key-Value БД позволяют хранить только массивы байт, какие-то поддерживают различные структуры данных, а какие-то построены на достаточно хитрых<strong>CRDT</strong>. Таким образом, существует большое множество Key-Value баз данных.</p>
12
<p>Key-Value БД ещё делятся на RAM и не RAM - в любой момент времени можно быстро получить любой элемент или нет. Некоторые Key-Value БД позволяют хранить только массивы байт, какие-то поддерживают различные структуры данных, а какие-то построены на достаточно хитрых<strong>CRDT</strong>. Таким образом, существует большое множество Key-Value баз данных.</p>
13
<h2>Redis</h2>
13
<h2>Redis</h2>
14
<p>Это<strong>Redistributable Dictionary Server</strong>- одна из известных Key-Value БД и одна из самых производительных in-memory баз данных. Есть возможность работать не только в режиме in-memory, но и записывать данные на диск, причём достаточно гибко. Поддерживает различные структуры данных - строки, хэш-таблицы, списки и множества этих же объектов, упорядоченные множества и т.д.</p>
14
<p>Это<strong>Redistributable Dictionary Server</strong>- одна из известных Key-Value БД и одна из самых производительных in-memory баз данных. Есть возможность работать не только в режиме in-memory, но и записывать данные на диск, причём достаточно гибко. Поддерживает различные структуры данных - строки, хэш-таблицы, списки и множества этих же объектов, упорядоченные множества и т.д.</p>
15
<h3>Познакомимся с Redis поближе</h3>
15
<h3>Познакомимся с Redis поближе</h3>
16
<p>Для начала развернём Redis в Docker-контейнере: docker run --name our-redis -p 6379:6379 redis</p>
16
<p>Для начала развернём Redis в Docker-контейнере: docker run --name our-redis -p 6379:6379 redis</p>
17
<p>Подключимся к Redis c помощью консольного клиента, тоже завёрнутого в Docker-контейнер: docker run -it --network container:our-redis redis redis-cli -h 127.0.0.1</p>
17
<p>Подключимся к Redis c помощью консольного клиента, тоже завёрнутого в Docker-контейнер: docker run -it --network container:our-redis redis redis-cli -h 127.0.0.1</p>
18
<h3>Основные команды в Redis</h3>
18
<h3>Основные команды в Redis</h3>
19
<p>Итак, если вы увидели приглашение, то можно попробовать положить строчку по ключу:</p>
19
<p>Итак, если вы увидели приглашение, то можно попробовать положить строчку по ключу:</p>
20
127.0.0.1:6379> SET key value OK<p>Синтаксис команд Redis достаточно прост: <имя команды> <аргументы>. Список всех команд можно посмотреть по<a>ссылке</a>, рекомендую держать эту вкладку открытой при изучении Redis.</p>
20
127.0.0.1:6379> SET key value OK<p>Синтаксис команд Redis достаточно прост: <имя команды> <аргументы>. Список всех команд можно посмотреть по<a>ссылке</a>, рекомендую держать эту вкладку открытой при изучении Redis.</p>
21
<p>Мы можем получить список всех ключей в БД:</p>
21
<p>Мы можем получить список всех ключей в БД:</p>
22
127.0.0.1:6379> KEYS * 1) "key"<p>В действительности все команды можно писать строчными буквами, поэтому давайте перестанем использовать заглавные. Redis поддерживает различные типы данных. Попробуем получить тип значения, лежащего по этому ключу:</p>
22
127.0.0.1:6379> KEYS * 1) "key"<p>В действительности все команды можно писать строчными буквами, поэтому давайте перестанем использовать заглавные. Redis поддерживает различные типы данных. Попробуем получить тип значения, лежащего по этому ключу:</p>
23
127.0.0.1:6379> type key string<p>А потом получим значение по этому ключу:</p>
23
127.0.0.1:6379> type key string<p>А потом получим значение по этому ключу:</p>
24
127.0.0.1:6379> get key "value"<p>Также можно посмотреть, как хранится эта строчка в Redis. Для этого используется команда<strong>Dump</strong>:</p>
24
127.0.0.1:6379> get key "value"<p>Также можно посмотреть, как хранится эта строчка в Redis. Для этого используется команда<strong>Dump</strong>:</p>
25
127.0.0.1:6379> dump key "\x00\x05value\t\x00Q\x04\x90\xf4\x95,\xf8\xdf"<p>Оставлю вам удовольствие разобраться в этом формате самостоятельно.</p>
25
127.0.0.1:6379> dump key "\x00\x05value\t\x00Q\x04\x90\xf4\x95,\xf8\xdf"<p>Оставлю вам удовольствие разобраться в этом формате самостоятельно.</p>
26
<h2>Множества (Set) в Redis</h2>
26
<h2>Множества (Set) в Redis</h2>
27
<p>Попробуем создать ключ и положить в него множество (Set) значений. Это можно сделать одной командой:</p>
27
<p>Попробуем создать ключ и положить в него множество (Set) значений. Это можно сделать одной командой:</p>
28
127.0.0.1:6379> sadd ourset value1 value2 (integer) 2<p>Проверим, что по этому ключу действительно лежит множество:</p>
28
127.0.0.1:6379> sadd ourset value1 value2 (integer) 2<p>Проверим, что по этому ключу действительно лежит множество:</p>
29
127.0.0.1:6379> type ourset set<p>Посмотрим значения, лежащие в этом множестве:</p>
29
127.0.0.1:6379> type ourset set<p>Посмотрим значения, лежащие в этом множестве:</p>
30
127.0.0.1:6379> smembers ourset 1) "value2" 2) "value1"<p>И опять же можем посмотреть, как Redis хранит множество:</p>
30
127.0.0.1:6379> smembers ourset 1) "value2" 2) "value1"<p>И опять же можем посмотреть, как Redis хранит множество:</p>
31
127.0.0.1:6379> dump ourset "\x02\x02\x06value2\x06value1\t\x00\xf5C\x86\b\xe05\xef\xa4"<p>И, попробуем удалить одно из значений:</p>
31
127.0.0.1:6379> dump ourset "\x02\x02\x06value2\x06value1\t\x00\xf5C\x86\b\xe05\xef\xa4"<p>И, попробуем удалить одно из значений:</p>
32
127.0.0.1:6379> srem ourset value1 (integer) 1 127.0.0.1:6379> smembers ourset 1) "value2"<p>Множества могут быть очень большими в Redis. Многие операции с множествами, например, объединение<strong>SUNION</strong>, - реализованы отдельными командами. А ещё можно очистить то, что мы добавили:</p>
32
127.0.0.1:6379> srem ourset value1 (integer) 1 127.0.0.1:6379> smembers ourset 1) "value2"<p>Множества могут быть очень большими в Redis. Многие операции с множествами, например, объединение<strong>SUNION</strong>, - реализованы отдельными командами. А ещё можно очистить то, что мы добавили:</p>
33
127.0.0.1:6379> del key ourset (integer) 2 127.0.0.1:6379> type ourset none<h2>Хэш-таблицы (hash) в Redis</h2>
33
127.0.0.1:6379> del key ourset (integer) 2 127.0.0.1:6379> type ourset none<h2>Хэш-таблицы (hash) в Redis</h2>
34
<p>Более сложная структура данных - хэш-таблица (hash). Давайте попробуем создать что-то вроде JSON-документа на основе хэш таблиц. Представим, что у нас есть некий "адрес", представим его в табличном виде:</p>
34
<p>Более сложная структура данных - хэш-таблица (hash). Давайте попробуем создать что-то вроде JSON-документа на основе хэш таблиц. Представим, что у нас есть некий "адрес", представим его в табличном виде:</p>
35
Поле Значение City Omsk Street Lenina number 2<p>Запишем этот объект в хэш по полям и сразу увидим, что собой представляет хэш. Воспользуемся сначала командой добавления поля в хэш:</p>
35
Поле Значение City Omsk Street Lenina number 2<p>Запишем этот объект в хэш по полям и сразу увидим, что собой представляет хэш. Воспользуемся сначала командой добавления поля в хэш:</p>
36
127.0.0.1:6379> hset address city Omsk (integer) 1<p>Посмотрим, какого типа у нас получилось значение по ключу address:</p>
36
127.0.0.1:6379> hset address city Omsk (integer) 1<p>Посмотрим, какого типа у нас получилось значение по ключу address:</p>
37
127.0.0.1:6379> type address hash<p>Вот мы и получили хэш-таблицу состоящую из пар field-value. Посмотреть список всех полей можно так:</p>
37
127.0.0.1:6379> type address hash<p>Вот мы и получили хэш-таблицу состоящую из пар field-value. Посмотреть список всех полей можно так:</p>
38
127.0.0.1:6379> hkeys address 1) "city"<p>А все значения можно посмотреть с помощью команды:</p>
38
127.0.0.1:6379> hkeys address 1) "city"<p>А все значения можно посмотреть с помощью команды:</p>
39
127.0.0.1:6379> hvals address 1) "Omsk"<p>Добавим другие поля с помощью множественного<em>"задания"</em>полей:</p>
39
127.0.0.1:6379> hvals address 1) "Omsk"<p>Добавим другие поля с помощью множественного<em>"задания"</em>полей:</p>
40
127.0.0.1:6379> hmset address street Lenina number 2 OK<p>Посмотрим, что получилось с помощью другой команды:</p>
40
127.0.0.1:6379> hmset address street Lenina number 2 OK<p>Посмотрим, что получилось с помощью другой команды:</p>
41
127.0.0.1:6379> hgetall address 1) "city" 2) "Omsk" 3) "street" 4) "Lenina" 5) "number" 6) "2"<p>Да, здесь имя поля и его значение следуют друг за другом. Вот таким образом можно хранить более привычные объекты в Redis. Примерно таким образом и будут храниться объекты репозиториев Spring Data Redis.</p>
41
127.0.0.1:6379> hgetall address 1) "city" 2) "Omsk" 3) "street" 4) "Lenina" 5) "number" 6) "2"<p>Да, здесь имя поля и его значение следуют друг за другом. Вот таким образом можно хранить более привычные объекты в Redis. Примерно таким образом и будут храниться объекты репозиториев Spring Data Redis.</p>
42
<p>Вот мы и познакомились с консольным интерфейсом. В следующей части изучим, как подключаться к Redis с помощью Spring Data.</p>
42
<p>Вот мы и познакомились с консольным интерфейсом. В следующей части изучим, как подключаться к Redis с помощью Spring Data.</p>
43
<p><em>Есть вопрос? Напишите в комментариях!</em></p>
43
<p><em>Есть вопрос? Напишите в комментариях!</em></p>
44
44