Spring Boot Redis Cache

Lente Boot Redis Cache

In deze post zullen we een voorbeeld Spring-boottoepassing opzetten en integreren met Redis-cache. Hoewel Redis een Open source in-memory datastructuuropslag is, gebruikt als database, cache en berichtenmakelaar, zal deze les alleen de cache-integratie demonstreren. We zullen gebruikmaken van de Spring Initializr-tool om het project snel op te zetten.

Spring Boot Redis Project Setup

We zullen de Spring Initializr-tool gebruiken om het project snel op te zetten. We zullen 3 afhankelijkheden gebruiken zoals hieronder getoond: Download het project en pak het uit. We hebben de H2-database-afhankelijkheid gebruikt omdat we een ingebedde database zullen gebruiken die alle gegevens verliest zodra de toepassing is gestopt.

Lentekriebels Redis Cache Maven Afhankelijkheden

Hoewel we de installatie al hebben voltooid met de tool, als je het handmatig wilt instellen, gebruiken we het Maven-buildsysteem voor dit project en hier zijn de afhankelijkheden die we hebben gebruikt:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.9.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
</properties>
<dependencies>
  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
     <scope>test</scope>
  </dependency>

  <!-- for JPA support -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>

  <!-- for embedded database support -->
  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
  </dependency>

</dependencies>

<build>
  <plugins>
     <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
     </plugin>
  </plugins>
</build>

Zorg ervoor dat je de stabiele versie van Spring Boot gebruikt vanuit het maven central.

Het Model Definiëren

Om een object in de Redis-database op te slaan, definiëren we een Persoon-modelobject met basisvelden:

package com.journaldev.rediscachedemo;

import javax.persistence.*;
import java.io.Serializable;

@Entity
public class User implements Serializable {

    private static final long serialVersionUID = 7156526077883281623L;

    @Id
    @SequenceGenerator(name = "SEQ_GEN", sequenceName = "SEQ_USER", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GEN")
    private Long id;
    private String name;
    private long followers;

    public User() {
    }

    public User(String name, long followers) {
        this.name = name;
        this.followers = followers;
    }

    //standaard getters en setters

    @Override
    public String toString() {
        return String.format("User{id=%d, name='%s', followers=%d}", id, name, followers);
    }
}

Het is een standaard POJO met getters en setters.

Redis Cache Configureren

Met Spring Boot en de vereiste afhankelijkheid die al werkt met Maven, kunnen we een lokale Redis-instantie configureren met slechts drie regels in ons application.properties-bestand zoals:

# Redis Configuratie
spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379

Gebruik ook de @EnableCaching-annotatie op de Spring Boot hoofdklasse:

package com.journaldev.rediscachedemo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class Application implements CommandLineRunner {

  private final Logger LOG = LoggerFactory.getLogger(getClass());
  private final UserRepository userRepository;

  @Autowired
  public Application(UserRepository userRepository) {
    this.userRepository = userRepository;
  }

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

  @Override
  public void run(String... strings) {
    //Ingebedde database hier populieren
    LOG.info("Saving users. Current user count is {}.", userRepository.count());
    User shubham = new User("Shubham", 2000);
    User pankaj = new User("Pankaj", 29000);
    User lewis = new User("Lewis", 550);

    userRepository.save(shubham);
    userRepository.save(pankaj);
    userRepository.save(lewis);
    LOG.info("Done saving users. Data: {}.", userRepository.findAll());
  }
}

We hebben een CommandLineRunner toegevoegd omdat we wat voorbeeldgegevens willen toevoegen aan de ingebedde H2-database.

Het definiëren van de Repository

Voordat we laten zien hoe Redis werkt, zullen we gewoon een Repository definiëren voor JPA-gerelateerde functionaliteit:

package com.journaldev.rediscachedemo;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository { }

Er zijn op dit moment geen methodenoproepen omdat we deze niet nodig hebben.

Het definiëren van de Controller

Controllers zijn de plek waar de Redis-cache wordt aangeroepen voor actie. Eigenlijk is dit de beste plek om dit te doen omdat de cache er direct mee is verbonden, waardoor het verzoek zelfs niet naar de servicecode hoeft te gaan om op gecachte resultaten te wachten. Hier is het controllerskelet:

package com.journaldev.rediscachedemo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

@RestController
public class UserController {

  private final Logger LOG = LoggerFactory.getLogger(getClass());

  private final UserRepository userRepository;

  @Autowired
  public UserController(UserRepository userRepository) {
    this.userRepository = userRepository;
  }
   ...
}

Om iets in de cache te plaatsen, gebruiken we de @Cacheable-annotatie:

@Cacheable(value = "users", key = "#userId", unless = "#result.followers < 12000")
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
public User getUser(@PathVariable String userId) {
  LOG.info("Getting user with ID {}.", userId);
  return userRepository.findOne(Long.valueOf(userId));
}

In de bovenstaande mapping zal de methode getUser een persoon in een cache plaatsen met de naam ‘gebruikers’, die die persoon identificeert aan de hand van de sleutel ‘gebruikers-ID’ en alleen een gebruiker met meer dan 12000 volgers opslaan. Dit zorgt ervoor dat de cache wordt gevuld met gebruikers die zeer populair zijn en vaak worden bevraagd. Ook hebben we opzettelijk een logboekverklaring toegevoegd bij de API-oproep. Laten we op dit moment wat API-oproepen maken vanuit Postman. Dit zijn de oproepen die we hebben gedaan:

localhost:8090/1
localhost:8090/1
localhost:8090/2
localhost:8090/2

Als we naar de logs kijken, zullen deze het volgende zijn:

... : Getting user with ID 1.
... : Getting user with ID 1.
... : Getting user with ID 2.

Opgelet iets? We hebben vier API-oproepen gedaan maar er waren slechts drie logboekvermeldingen aanwezig. Dit komt doordat de Gebruiker met ID 2 29000 volgers heeft en dus zijn gegevens in de cache stonden. Dit betekent dat toen er een API-oproep voor werd gedaan, de gegevens uit de cache werden teruggegeven en er geen DB-oproep werd gedaan voor dit!

Cache bijwerken

Cache-waarden moeten ook worden bijgewerkt wanneer hun werkelijke objectwaarden worden bijgewerkt. Dit kan worden gedaan met behulp van de @CachePut-annotatie:

@CachePut(value = "users", key = "#user.id")
@PutMapping("/update")
public User updatePersonByID(@RequestBody User user) {
  userRepository.save(user);
  return user;
}

Met dit wordt een persoon opnieuw geïdentificeerd aan de hand van zijn ID en worden de resultaten bijgewerkt.

Cache wissen

Als sommige gegevens uit de werkelijke database moeten worden verwijderd, heeft het geen zin om ze nog in de cache te bewaren. We kunnen cachegegevens wissen met behulp van de @CacheEvict-annotatie:

@CacheEvict(value = "users", allEntries=true)
@DeleteMapping("/{id}")
public void deleteUserByID(@PathVariable Long id) {
  LOG.info("deleting person with id {}", id);
  userRepository.delete(id);
}

In de laatste toewijzing hebben we alleen cachevermeldingen verwijderd en verder niets gedaan.

Spring Boot Redis Cache-applicatie uitvoeren

We kunnen deze app eenvoudig uitvoeren door slechts één commando te gebruiken:

mvn spring-boot:run

Limieten voor Redis-cache

Hoewel Redis erg snel is, heeft het nog steeds geen limieten voor het opslaan van willekeurige hoeveelheden gegevens op een 64-bits systeem. Op een 32-bits systeem kan het slechts 3 GB aan gegevens opslaan. Meer beschikbaar geheugen kan resulteren in een hogere hitratio, maar dit zal neigen te stoppen zodra te veel geheugen wordt ingenomen door Redis. Wanneer de cache-grootte de geheugenlimiet bereikt, worden oude gegevens verwijderd om plaats te maken voor nieuwe.

Samenvatting

In deze les hebben we gekeken naar de kracht die Redis Cache ons biedt met snelle gegevensinteractie en hoe we het kunnen integreren met Spring Boot met minimale maar toch krachtige configuratie. Voel je vrij om hieronder opmerkingen achter te laten.

Project Spring Boot Redis Cache Downloaden

Source:
https://www.digitalocean.com/community/tutorials/spring-boot-redis-cache