Spring Boot Redis Cache
In diesem Beitrag werden wir eine Beispielspring-Boot-Anwendung einrichten und sie mit dem Redis-Cache integrieren. Obwohl Redis ein Open-Source-In-Memory-Datenspeicher ist, der als Datenbank, Cache und Nachrichtenmakler verwendet wird, wird diese Lektion nur die Caching-Integration demonstrieren. Wir werden das Spring Initializr-Werkzeug verwenden, um das Projekt schnell einzurichten.
Einrichtung des Spring Boot Redis Projekts
Wir werden das Spring Initializr-Werkzeug verwenden, um das Projekt schnell einzurichten. Wir verwenden 3 Abhängigkeiten wie unten gezeigt: Laden Sie das Projekt herunter und entpacken Sie es. Wir haben die H2-Datenbankabhängigkeit verwendet, da wir eine eingebettete Datenbank verwenden werden, die alle Daten verliert, sobald die Anwendung gestoppt wurde.
Spring Boot Redis Cache Maven Abhängigkeiten
Obwohl wir die Einrichtung bereits mit dem Tool abgeschlossen haben, wenn Sie es manuell einrichten möchten, verwenden wir das Maven-Build-System für dieses Projekt, und hier sind die Abhängigkeiten, die wir verwendet haben:
<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>
Stellen Sie sicher, dass Sie die stabile Version für Spring Boot aus dem Maven Central verwenden.
Modell definieren
Um ein Objekt in die Redis-Datenbank zu speichern, definieren wir ein Person-Modellobjekt mit grundlegenden Feldern:
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;
}
// Standard-Getter und Setter
@Override
public String toString() {
return String.format("User{id=%d, name='%s', followers=%d}", id, name, followers);
}
}
Es handelt sich um eine Standard-POJO mit Gettern und Settern.
Redis-Cache konfigurieren
Mit Spring Boot und der erforderlichen Abhängigkeit, die bereits mit Maven funktioniert, können wir eine lokale Redis-Instanz mit nur drei Zeilen in unserer application.properties-Datei konfigurieren, wie folgt:
# Redis-Konfiguration
spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379
Verwenden Sie außerdem die Annotation @EnableCaching
in der Spring Boot-Hauptklasse:
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) {
// Einbetten der Datenbank hier
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());
}
}
Wir haben einen CommandLineRunner hinzugefügt, da wir einige Beispieldaten in der eingebetteten H2-Datenbank bereitstellen möchten.
Definition des Repositories
Bevor wir zeigen, wie Redis funktioniert, definieren wir einfach ein Repository für JPA-bezogene Funktionalität:
package com.journaldev.rediscachedemo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository { }
Es hat derzeit keine Methodenaufrufe, da wir keine benötigen.
Definition des Controllers
Controller sind der Ort, an dem die Redis-Cache aufgerufen wird. Tatsächlich ist dies der beste Ort dafür, weil eine Cache direkt damit verbunden ist. Die Anfrage muss nicht einmal in den Service-Code eintreten, um auf gecachte Ergebnisse zu warten. Hier ist das Gerüst des Controllers:
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;
}
...
}
Um etwas in den Cache zu legen, verwenden wir die Annotation @Cacheable
:
@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 der obigen Zuordnung wird die Methode getUser
eine Person in einen Cache mit dem Namen „Benutzer“ legen, diese Person anhand des Schlüssels „Benutzer-ID“ identifizieren und nur einen Benutzer mit mehr als 12000 Followern speichern. Dies stellt sicher, dass der Cache mit Benutzern bevölkert ist, die sehr beliebt sind und häufig abgefragt werden. Außerdem haben wir absichtlich eine Protokollmeldung im API-Aufruf hinzugefügt. Lassen Sie uns in diesem Moment einige API-Aufrufe von Postman aus machen. Dies sind die Aufrufe, die wir gemacht haben:
localhost:8090/1
localhost:8090/1
localhost:8090/2
localhost:8090/2
Wenn wir die Protokolle beachten, werden sie folgendermaßen sein:
... : Getting user with ID 1.
... : Getting user with ID 1.
... : Getting user with ID 2.
Beachte etwas? Wir haben vier API-Aufrufe gemacht, aber es gab nur drei Protokolleinträge. Dies liegt daran, dass der Benutzer mit der ID 2 29000 Follower hat und daher seine Daten zwischengespeichert wurden. Dies bedeutet, dass bei einem API-Aufruf für ihn die Daten aus dem Cache zurückgegeben wurden und kein DB-Aufruf für ihn erfolgte!
Aktualisiere Cache
Cache-Werte sollten auch aktualisiert werden, wenn die tatsächlichen Objektwerte aktualisiert werden. Dies kann mit der @CachePut-Annotation erreicht werden:
@CachePut(value = "users", key = "#user.id")
@PutMapping("/update")
public User updatePersonByID(@RequestBody User user) {
userRepository.save(user);
return user;
}
Mit diesem wird eine Person erneut durch ihre ID identifiziert und mit den Ergebnissen aktualisiert.
Cache leeren
Wenn einige Daten aus der tatsächlichen Datenbank gelöscht werden sollen, macht es keinen Sinn, sie weiter im Cache zu behalten. Wir können Cache-Daten mit der @CacheEvict
-Annotation löschen:
@CacheEvict(value = "users", allEntries=true)
@DeleteMapping("/{id}")
public void deleteUserByID(@PathVariable Long id) {
LOG.info("deleting person with id {}", id);
userRepository.delete(id);
}
In der letzten Zuordnung haben wir nur Cache-Einträge entfernt und nichts weiter gemacht.
Spring Boot Redis Cache-Anwendung ausführen
Wir können diese App einfach durch Verwendung eines einzigen Befehls ausführen:
mvn spring-boot:run
Redis-Cache-Grenzen
Auch wenn Redis sehr schnell ist, hat es auf einem 64-Bit-System immer noch keine Grenzen für die Speicherung beliebiger Datenmengen. Auf einem 32-Bit-System können nur 3 GB Daten gespeichert werden. Mehr verfügbare Speicher können zu einer höheren Trefferquote führen, aber dies hört auf, sobald Redis zu viel Speicher belegt. Wenn die Cache-Größe das Speicherlimit erreicht, werden alte Daten entfernt, um Platz für neue zu schaffen.
Zusammenfassung
In dieser Lektion haben wir uns angesehen, welche Leistung der Redis-Cache uns durch schnelle Dateninteraktion bietet und wie wir ihn mit minimaler und dennoch leistungsstarker Konfiguration in Spring Boot integrieren können. Fühlen Sie sich frei, unten Kommentare zu hinterlassen.
Source:
https://www.digitalocean.com/community/tutorials/spring-boot-redis-cache