Spring Boot con Redis: funcionalidad CRUD de HashOperations

Introducción

REmote DIctionary Server (Redis) es un almacén de estructura de datos en memoria. Puede utilizarse como una base de datos simple, un intermediario de mensajes y para el almacenamiento en caché gracias a su soporte para varias estructuras de datos.

En este artículo, crearemos una aplicación CRUD simple e integraremos Redis con Spring Boot. Para lograr la funcionalidad CRUD, confiaremos en el HashOperations interfaz proporcionada por el Spring Data Redis proyecto.

Redis

Redis es un almacén de datos en memoria de código abierto escrito en C, lo que lo hace increíblemente rápido. Debido a sus operaciones de lectura / escritura más rápidas, se usa comúnmente para almacenar datos en caché. Los datos se almacenan en Redis en forma de pares clave-valor donde se usa una clave para extraer los valores.

Redis también puede conservar los datos en un disco, en lugar de mantenerlos en la memoria, mediante “instantáneas”, copiando su almacén de datos en la memoria a intervalos regulares.

Prerrequisitos

Instalación de Redis

Redis se puede instalar fácilmente en Linux y macOS. Sin embargo, Windows requiere un poco de piratería. Instalaremos Redis en una instancia AWS EC2 que ejecute Ubuntu 18.04 LTS:

$ sudo apt install redis-server

macOS, puedes instalarlo a través de brew:

$ brew install redis

Después de instalar con éxito el redis-server paquete, verifiquemos el estado del proceso de Redis para verificar la instalación:

$ systemctl status redis

El resultado muestra el estado del redis-server, la dirección de enlace y el puerto en el que redis-server está escuchando en:

● 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

De forma predeterminada, la configuración de Redis estará disponible en la /etc/redis/redis.conf archivo.

Habilitar la conexión remota a Redis

De forma predeterminada, solo se puede acceder a Redis desde localhost. Para habilitar la conexión remota a nuestro servidor Redis, actualice la dirección de enlace en la configuración de Redis a 0.0.0.0:

bind 0.0.0.0 ::1

Una vez actualizado, reinícielo:

$ systemctl restart redis

Configuración de Spring Boot

La forma más fácil de comenzar con una aplicación Spring Boot en blanco es usar Spring Initializr:

Alternativamente, también puede utilizar el Spring Boot CLI para arrancar la aplicación:

$ spring init --dependencies=spring-boot-starter-data-redis redis-spring-boot-demo

Empezamos con el spring-boot-starter-data-redis dependencia ya que incluye spring-data-redis, spring-boot-starter y lettuce-core.

Si ya tiene una aplicación Maven / Spring, agregue la dependencia a su pom.xml archivo:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
	<version>${version}</version>
</dependency>

O si está usando Gradle:

compile group: 'org.springframework.data', name: 'spring-data-redis', version: '${version}'

Conexión al servidor Redis

Como siempre, cuando trabajamos con servicios como Redis, queremos conectar nuestra aplicación al servicio. Hay disponibles varios conectores Redis basados ​​en Java: Jedis y Lechuga son dos opciones populares.

Conectando con Jedis

Para usar Jedis, tendremos que agregarlo a nuestro pom.xml archivo:

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>${version}</version>
</dependency>

O si está usando Gradle:

compile group: 'redis.clients', name: 'jedis', version: '${version}'

Una vez que las dependencias están en su lugar, necesitamos configurar el 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;
    }
}

No hace falta decir que esta configuración se realiza en un @Configuration clase. Si desea leer más sobre las anotaciones principales de Spring Framework, ¡lo tenemos cubierto!

Conectando con la lechuga

La lechuga es Netty-conector Redis de código abierto y basado en el paquete con la dependencia de inicio. La configuración de una fábrica de conexiones Lettuce es prácticamente la misma que la de 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;
    }
}

Aunque su configuración es prácticamente la misma, su uso es diferente. Lettuce permite operaciones asincrónicas y es seguro para subprocesos, a diferencia de Jedis, por ejemplo.

RedisTemplate

RedisTemplate es una clase de entrada proporcionada por Spring Data a través de la cual interactuamos con el servidor Redis.

Pasaremos un RedisConnectionFactory instancia a la RedisTemplate para establecer una conexión:

public static RedisTemplate<String, User> redisTemplate() {
    RedisTemplate<String, User> redisTemplate = new RedisTemplate<String ,User>();
    redisTemplate.setConnectionFactory(redisConnectionFactory());
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

Una vez establecido, RedisTemplate se convierte en la principal abstracción de las operaciones de Redis que podemos controlar. También se encarga de la serialización y deserialización de objetos en matrices de bytes.

Por defecto, RedisTemplate usa el JdkSerializationRedisSerializer serializar y deserializar objetos.

El mecanismo de serialización de RedisTemplate puede cambiarse, y Redis ofrece varios serializadores en el org.springframework.data.redis.serializer paquete.

StringRedisTemplate es una extensión de RedisTemplate centrado en pares clave-valor basados ​​en cadenas, por ejemplo.

Para admitir varias operaciones en diferentes tipos de datos, RedisTemplate proporciona clases de operación como ValueOperations, ListOperations, SetOperations, HashOperations, StreamOperationsetc.

Para operaciones relacionadas con hash, que usaremos para almacenar datos en nuestro servidor Redis, usaremos el HashOperations clase.

HashOperations

Redis Hashes puede contener un n número de pares clave-valor y están diseñados para usar menos memoria, lo que lo convierte en una excelente manera de almacenar objetos en la memoria. A través de HashOperations ayudante, podemos manipularlos.

Para usar cualquiera de estos, empaquetamos las operaciones hash devueltas del RedisTemplate instancia en el HashOperations interfaz:

HashOperations hashOperations = redisTemplate.opsForHash();

Estas operaciones incluyen operaciones básicas de mapas hash como put(), get(), entries(), etc:

// 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);

Definición de un repositorio de usuarios

Ahora sigamos adelante y creemos un repositorio de usuarios que realmente manejará las operaciones CRUD:

@Repository
public class UserRepository {
    private HashOperations hashOperations;
    public UserRepository(RedisTemplate redisTemplate) {
        this.hashOperations = redisTemplate.opsForHash();
    }
}

Por el contrario, en un repositorio típico, el HashOperations sería algo así como un SessionFactory. Con Redis, también puede crear un repositorio ampliando la CrudRepository interfaz y configurar una conexión Jedis en un @Bean.

En el constructor, pasamos nuestro redisTemplate, que debe configurarse con una fábrica de conexiones de Redis.

Ahora, para poner una entrada, usaríamos:

hashOperations.put("USER", hashKey, value);

Una sola tecla, como la USER puede tener múltiples hashKey:value pares. Cada value se puede acceder a través de hashKeys para una clave determinada.

O para obtener una entrada, usaríamos:

value = hashOperations.get("USER", hashKey);

Definamos el User:

public class User {
    private int userId;
    private String name;
    
    // Constructor, getters and setters
}

Con eso en mente, implementemos el resto del repositorio:

@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));
	}
}

Ahora para probar la aplicación, usemos nuestro 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());

Ejecutar este fragmento de código producirá:

2020-03-30 11:34:11.260  INFO 8772 --- [           main] c.h.redistutorial.UserRepository       : User with ID 1 saved
2020-03-30 11:34:11.260  INFO 8772 --- [           main] c.h.redistutorial.UserRepository       : User with ID 1 updated
2020-03-30 11:34:11.260  INFO 8772 --- [           main] c.h.redistutorial.UserRepository       : User with ID 1 deleted

Usemos un cliente de Redis para ver los datos que se insertan, actualizan y eliminan.

  • Creando un usuario:
  • Actualización de un usuario:
  • Eliminar un usuario:

Conclusión

Spring Boot es cada vez más preferido por los desarrolladores de Java / Spring porque es liviano y fácil de usar. Simplifica enormemente el proceso de arranque de aplicaciones y le ayuda a concentrarse en la lógica empresarial real en lugar de conectar las cosas.

Redis, por otro lado, es una base de datos en memoria extremadamente popular que la convierte en un gran compañero para los microservicios.

Redis se usa a menudo para la administración de caché por microservicios para reducir la cantidad de llamadas de base de datos al servidor. En este nuevo mundo de sistemas de cobro de pago por uso, esto puede reducir efectivamente los costos operativos para empresas y empresas.

Etiquetas:

2 pensamientos sobre “Spring Boot con Redis: funcionalidad CRUD de HashOperations”

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *