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.

    Rate this post
    Etiquetas:

    Deja una respuesta

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