Вступление
REmote DIctionary Server (Redis) - это хранилище структур данных в памяти. Его можно использовать в качестве простой базы данных, брокера сообщений и для кэширования за счет поддержки различных структур данных.
В этой статье мы создадим простое приложение CRUD и интегрируем Redis с
Spring Boot. Для достижения функциональности CRUD мы будем полагаться на
интерфейс HashOperations
предоставляемый проектом Spring Data
Redis.
Redis
Redis - это хранилище данных в памяти с открытым исходным кодом, написанное на C, что делает его невероятно быстрым. Из-за более быстрых операций чтения / записи он обычно используется для кэширования данных. Данные хранятся в Redis в виде пар " ключ-значение", где ключ используется для извлечения значений.
Redis также может сохранять данные на диске, а не хранить их в памяти, используя «моментальные снимки» - путем регулярного копирования своего хранилища данных в памяти.
Предпосылки
Установка Redis
Redis можно легко установить в Linux и macOS. Однако Windows требует небольшого взлома. Мы установим Redis на экземпляр AWS EC2 под управлением Ubuntu 18.04 LTS:
$ sudo apt install redis-server
macOS, вы можете установить его через brew
:
$ brew install redis
После успешной установки redis-server
давайте проверим статус процесса
Redis, чтобы проверить установку:
$ systemctl status redis
Результат показывает состояние redis-server
, адрес привязки и порт,
который redis-server
:
● redis-server.service - Advanced key-value store
Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)`
Active: active (running) since Tue 2020-03-10 10:06:30 UTC; 3min 2s ago
Docs: http://redis.io/documentation,
man:redis-server(1)
Main PID: 2227 (redis-server)
Tasks: 4 (limit: 1152)
CGroup: /system.slice/redis-server.service
└─2227 /usr/bin/redis-server 127.0.0.1:6379
По умолчанию конфигурация Redis будет доступна в файле
/etc/redis/redis.conf
Включить удаленное подключение к Redis
По умолчанию Redis доступен только с localhost
. Чтобы включить
удаленное подключение к нашему серверу Redis, обновите адрес привязки в
конфигурации Redis до 0.0.0.0
:
bind 0.0.0.0 ::1
После обновления перезапустите его:
$ systemctl restart redis
Настройка Spring Boot
Самый простой способ начать с пустого приложения Spring Boot - использовать Spring Initializr :
{.ezlazyload}
В качестве альтернативы вы также можете использовать Spring Boot CLI для начальной загрузки приложения:
$ spring init --dependencies=spring-boot-starter-data-redis redis-spring-boot-demo
Мы начинаем с spring-boot-starter-data-redis
поскольку она включает в
себя spring-data-redis
, spring-boot-starter
и lettuce-core
.
Если у вас уже есть приложение Maven / Spring, добавьте зависимость в
свой файл pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${version}</version>
</dependency>
Или, если вы используете Gradle:
compile group: 'org.springframework.data', name: 'spring-data-redis', version: '${version}'
Подключение к серверу Redis
Как всегда, при работе с такими сервисами, как Redis - мы хотим подключить наше приложение к сервису. Доступно несколько соединителей Redis на основе Java - два популярных варианта - Jedis и Lettuce.
Связь с джедаями
Чтобы использовать Jedis, нам нужно добавить его в наш файл pom.xml
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${version}</version>
</dependency>
Или, если вы используете Gradle:
compile group: 'redis.clients', name: 'jedis', version: '${version}'
После того, как зависимости установлены, нам нужно настроить
JedisConnectionFactory
:
@Configuration
public class Config {
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName("your_host_name_or_ip");
jedisConnectionFactory.setPort(6379);
jedisConnectionFactory.afterPropertiesSet();
return jedisConnectionFactory;
}
}
Излишне говорить, что эта настройка выполняется в классе
@Configuration
Если вы хотите узнать больше об аннотациях ядра Spring
Framework , мы вам
поможем!
Подключение к салату
Lettuce - это коннектор Redis с открытым исходным кодом на основе Netty, который поставляется с зависимостью для начинающих. Настройка фабрики соединений салата во многом такая же, как и для Jedis:
@Configuration
public class Config {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
LettuceConnectionFactory lcf = new LettuceConnectionFactory();
lcf.setHostName("your_host_name_or_ip");
lcf.setPort(6379);
lcf.afterPropertiesSet();
return lcf;
}
}
Хотя их настройка практически одинакова, их использование отличается. Салат-латук позволяет выполнять асинхронные операции и является поточно-ориентированным, в отличие, например, от Jedis.
RedisTemplate
RedisTemplate
- это входной класс, предоставляемый Spring Data, через
который мы взаимодействуем с сервером Redis.
Мы RedisConnectionFactory
экземпляр RedisTemplate
чтобы установить
соединение:
public static RedisTemplate<String, User> redisTemplate() {
RedisTemplate<String, User> redisTemplate = new RedisTemplate<String ,User>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
После установки RedisTemplate
становится основной абстракцией операций
Redis, которой мы можем управлять. Он также заботится о сериализации и
десериализации объектов в байтовые массивы.
По умолчанию RedisTemplate
использует
JdkSerializationRedisSerializer
для сериализации и десериализации
объектов.
Механизм сериализации RedisTemplate
можно изменить, и Redis предлагает
несколько сериализаторов в пакете
org.springframework.data.redis.serializer
StringRedisTemplate
- это расширение RedisTemplate
ориентированное,
например, на строковые пары ключ-значение.
Для поддержки различных операций с разными типами данных RedisTemplate
предоставляет классы операций, такие как ValueOperations
,
ListOperations
, SetOperations
, HashOperations
,
StreamOperations
и т. Д.
Для операций, связанных с хешем, которые мы будем использовать для
хранения данных на нашем сервере Redis, мы будем использовать класс
HashOperations
HashOperations
Хэши Redis могут содержать n
пар ключ-значение и предназначены для
использования меньшего объема памяти, что делает их отличным способом
хранения объектов в памяти. С HashOperations
вспомогательного класса
HashOperations мы можем управлять ими.
Чтобы использовать любого из них, мы упаковываем возвращенные хэш -
операцию из RedisTemplate
экземпляра в HashOperations
интерфейс:
HashOperations hashOperations = redisTemplate.opsForHash();
Эти операции включают в себя базовые операции хеш-карты, такие как
put()
, get()
, entries()
и т.
// Sets user object in USER hashmap at userId key
hashOperations.put("USER", user.getUserId(), user);
// Get value of USER hashmap at userId key
hashOperations.get("USER", userId);
// Get all hashes in USER hashmap
hashOperations.entries("USER");
// Delete the hashkey userId from USER hashmap
hashOperations.delete("USER", userId);
Определение пользовательского репозитория
Теперь давайте продолжим и создадим пользовательский репозиторий, который будет фактически обрабатывать операции CRUD:
@Repository
public class UserRepository {
private HashOperations hashOperations;
public UserRepository(RedisTemplate redisTemplate) {
this.hashOperations = redisTemplate.opsForHash();
}
}
Напротив, в типичном репозитории HashOperations
будет чем-то вроде
SessionFactory
. Используя Redis, вы также можете создать репозиторий,
расширив CrudRepository
и установив соединение Jedis в @Bean
.
В конструкторе мы передаем наш redisTemplate
, который должен быть
настроен с помощью фабрики соединений Redis.
Теперь, чтобы добавить запись, мы будем использовать:
hashOperations.put("USER", hashKey, value);
Один ключ, например USER
может иметь несколько hashKey:value
. К
каждому value
можно получить доступ через hashKey
для данного ключа.
Или, чтобы получить запись, мы использовали бы:
value = hashOperations.get("USER", hashKey);
Определим User
:
public class User {
private int userId;
private String name;
// Constructor, getters and setters
}
Имея это в виду, давайте реализуем остальную часть репозитория:
@Repository
public class UserRepository {
final Logger logger = LoggerFactory.getLogger(UserRepository.class);
private HashOperations hashOperations;
public UserRepository(RedisTemplate redisTemplate) {
this.hashOperations = redisTemplate.opsForHash();
}
public void create(User user) {
hashOperations.put("USER", user.getUserId(), user);
logger.info(String.format("User with ID %s saved", user.getUserId()));
}
public User get(String userId) {
return (User) hashOperations.get("USER", userId);
}
public Map<String, User> getAll(){
return hashOperations.entries("USER");
}
public void update(User user) {
hashOperations.put("USER", user.getUserId(), user);
logger.info(String.format("User with ID %s updated", user.getUserId()));
}
public void delete(String userId) {
hashOperations.delete("USER", userId);
logger.info(String.format("User with ID %s deleted", userId));
}
}
Теперь, чтобы протестировать приложение, воспользуемся нашим
userRepository
:
UserRepository userRepository = new UserRepository(redisTemplate());
userRepository.create(new User("1", "username", "emailid"));
User user = userRepository.get("1");
userRepository.update(user);
userRepository.delete(user.getUserId());
Выполнение этого фрагмента кода даст:
2020-03-30 11:34:11.260 INFO 8772 --- [ main] chredistutorial.UserRepository : User with ID 1 saved
2020-03-30 11:34:11.260 INFO 8772 --- [ main] chredistutorial.UserRepository : User with ID 1 updated
2020-03-30 11:34:11.260 INFO 8772 --- [ main] chredistutorial.UserRepository : User with ID 1 deleted
Давайте воспользуемся клиентом Redis, чтобы увидеть, какие данные вставляются, обновляются и удаляются.
-
Создание пользователя:
{.ezlazyload} -
Обновление пользователя:
{.ezlazyload} -
Удаление пользователя:
{.ezlazyload}
Заключение
Разработчики Java / Spring все чаще предпочитают Spring Boot, потому что он легкий и простой в использовании. Это значительно упрощает процесс начальной загрузки приложений и помогает сконцентрироваться на реальной бизнес-логике, а не связывать все вместе.
Redis, с другой стороны, является чрезвычайно популярной базой данных в памяти, что делает ее отличным компаньоном для микросервисов.
Redis часто используется микросервисами для управления кешем, чтобы уменьшить количество обращений к серверу из базы данных. В этом новом мире систем оплаты за использование это может эффективно снизить эксплуатационные расходы для предприятий и предприятий.