分散式快取綜合指南:Kubernetes + Redis + Spring Boot
本文的範圍是提供全面的指南,以在 Kubernetes 叢集上啟動 Redis 主從叢集並實現支援分散式快取的 Sprinboot 應用程式。對 Kubernetes/Redis/Spring boot 的全面介紹超出了本文的範圍。
先決條件
- 啟動並執行 Kubernetes 叢集
- Node.js v16.15.0 或本地最新版本
- 本地首選 IDE 或文字編輯器
- Java 8 或本地最新版本
在 Kubernetes 上部署 Redis 叢集
以下步驟描述瞭如何在 Kubernetes 上設定 Redis 主從叢集。我強烈建議在部署到生產環境之前對 K8S Storage Class/Persistent Volume/ConfigMap 物件進行一些研究。如果您需要全面瞭解以下步驟,請閱讀本教程。
1、建立名稱空間
在您的 K8S 叢集上執行流動命令以建立名稱空間,這將允許更有效地管理您在 K8S 叢集上的物件。
kubectl create ns redis
2、定義一個儲存類
現在我們將建立一個應用於整個叢集的儲存類。在您的 K8S 叢集上執行流動命令以建立儲存類。storage-class.yaml包含配置。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true reclaimPolicy: Delete |
kubectl apply -f storage-class.yaml
3.建立一個持久卷
在這個解決方案中,我們在 Redis 叢集上建立了 3 個節點,所以我們需要 3 個持久卷。在您的 K8S 叢集上執行流動命令以建立持久卷。persistent-volume.yaml包含配置。
apiVersion: v1 kind: PersistentVolume metadata: name: local-pv1 spec: storageClassName: local-storage capacity: storage: 1Gi accessModes: - ReadWriteOnce hostPath: path: "/storage/data1" --- apiVersion: v1 kind: PersistentVolume metadata: name: local-pv2 spec: storageClassName: local-storage capacity: storage: 1Gi accessModes: - ReadWriteOnce hostPath: path: "/storage/data2" --- apiVersion: v1 kind: PersistentVolume metadata: name: local-pv3 spec: storageClassName: local-storage capacity: storage: 2Gi accessModes: - ReadWriteOnce hostPath: path: "/storage/data3" |
kubectl apply -f persistent-volume.yaml
4.建立配置圖
您可以在此處獲取 ConfigMap 清單的配置。請確保更改masterauth&requirepass 值。這兩個變數是 Redis 叢集主從節點的密碼。如果您對兩者使用相同的值將很容易維護。
kubectl apply -n redis -f redis-config.yaml
5.使用StatefulSet部署Redis
StatefulSet 在需要控制主從行為時管理 pod。在您的 K8S 叢集上執行流動命令以建立持久卷。persistent-volume.yaml 包含配置。
redis-statefulset.yaml
apiVersion: apps/v1 kind: StatefulSet metadata: name: redis spec: serviceName: redis replicas: 3 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: initContainers: - name: config image: redis:6.2.3-alpine command: [ "sh", "-c" ] args: - | cp /tmp/redis/redis.conf /etc/redis/redis.conf echo "finding master..." MASTER_FDQN=`hostname -f | sed -e 's/redis-[0-9]\./redis-0./'` if [ "$(redis-cli -h sentinel -p 5000 ping)" != "PONG" ]; then echo "master not found, defaulting to redis-0" if [ "$(hostname)" == "redis-0" ]; then echo "this is redis-0, not updating config..." else echo "updating redis.conf..." echo "slaveof $MASTER_FDQN 6379" >> /etc/redis/redis.conf fi else echo "sentinel found, finding master" MASTER="$(redis-cli -h sentinel -p 5000 sentinel get-master-addr-by-name mymaster | grep -E '(^redis-\d{1,})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})')" echo "master found : $MASTER, updating redis.conf" echo "slaveof $MASTER 6379" >> /etc/redis/redis.conf fi volumeMounts: - name: redis-config mountPath: /etc/redis/ - name: config mountPath: /tmp/redis/ containers: - name: redis image: redis:6.2.3-alpine command: ["redis-server"] args: ["/etc/redis/redis.conf"] ports: - containerPort: 6379 name: redis volumeMounts: - name: data mountPath: /data - name: redis-config mountPath: /etc/redis/ volumes: - name: redis-config emptyDir: {} - name: config configMap: name: redis-config volumeClaimTemplates: - metadata: name: data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "local-storage" resources: requests: storage: 500Mi |
kubectl apply -n redis -f redis-statefulset.yaml
6.建立負載均衡服務
在 Kubernetes 部署的最後一步,我們將通過公共 IP 公開 Redis 伺服器。為此,我們部署了 Loadbalancer 服務。
apiVersion: v1 kind: Service metadata: name: redis-service labels: app: redis spec: selector: app: redis ports: - port: 80 targetPort: 6379 protocol: "TCP" name: redis type: LoadBalancer |
kubectl apply -n redis -f redis-lb.yaml
6.1 檢查外部IP
部署負載均衡器後,幾分鐘後叢集將提供公共外部 IP。為了檢查在幾分鐘內執行以下命令。
kubectl get service -n redis
從本地訪問 Redis 叢集
對於此步驟,您應該必須在本地計算機上安裝 Node.js v16.15.0 或最新版本。此步驟是可選的,但為了檢查日誌/驗證連線性,最好有辦法通過redis-cli. 為此,您無需在本地計算機上安裝 Redis 伺服器。
1、安裝redis-cli
npm install -g redis-cli
2.訪問Redis叢集
一旦 npm 安裝成功,您可以redis-cli在終端上執行以下命令之後的任何支援的命令。
rdcli -h {host} -a {password} -p {port}
3.使用redis-cli監控Redis叢集
我將分享一些有用的命令來對 Redis 叢集進行基本級別的維護。您可以使用以下命令重新整理所有鍵並檢查叢集上儲存的值。
3.1檢查Redis叢集中儲存的值
rdcli -h {ip} -a {password} -p {port} xxx.xxx.xxx.xxx:xx> KEYS * |
3.2 在 Redis 叢集上重新整理快取
rdcli -h {ip} -a {password} -p {port} FLUSHALL
實現 Springboot 應用程式
現在我們要實現具有分散式快取功能的 Springboot 應用程式。此應用程式包含一個 GET 服務返回字串值,但使用Thread.sleep. 讓我們看看分散式快取解決方案如何幫助我們克服這種緩慢。
1. 將以下依賴項新增到 POM
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>io.pivotal.cfenv</groupId> <artifactId>java-cfenv-boot</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> |
2.Redis配置
要訪問 Redis 遠端伺服器,我們需要在屬性檔案中新增一些屬性,並在根包上實現 RedisConfiguration 類。
application.properties 檔案
spring.redis.host=xxx.xxx.xxx.xxx spring.redis.port=xx spring.redis.password=xxxxxxxx spring.cache.redis.time-to-live=10000 |
package com.booking; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; @Configuration public class RedisConfiguration { @Value("${spring.redis.host:xxx.xxx.xxx.xxx}") private String redisHost; @Value("${spring.redis.port:xx}") private int redisPort; @Value("${spring.redis.password:xxxxxxxx}") private String redisPassword; @Bean public JedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(redisHost, redisPort); redisStandaloneConfiguration.setPassword(redisPassword); return new JedisConnectionFactory(redisStandaloneConfiguration); } @Bean public <T> RedisTemplate<String, T> redisTemplate() { RedisTemplate<String, T> redisTemplate = new RedisTemplate<String, T>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.afterPropertiesSet(); return redisTemplate; } } |
3. 建立 RESTful Web API
至此,我們討論了屬於遠端 Redis 叢集的配置。現在我們將實現一個典型的 Spring Boot Rest API,唯一的變化是我們在主類和服務類中提供了一些註釋來配置快取啟用。
BookingServiceApplication.java(主類)
package com.booking; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableCaching public class BookingServiceApplication { public static void main(String[] args) { SpringApplication.run(BookingServiceApplication.class, args); } } |
BookingController.java(控制器類)
package com.booking.contraller; import com.booking.model.Booking; import com.booking.service.BookingService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("booking") public class BookingController { @Autowired private BookingService bookingService; @GetMapping public String getServiceDetails(@RequestParam(name = "scope", required = false, defaultValue = "N/A") String scope){ return bookingService.getServiceDetails(scope); } } |
BookingService.java(服務類)
package com.booking.service; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service public class BookingService { @Cacheable("echoCacheWithParam") public String getServiceDetails(String level) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } if(level.equals("ALL")){ return "Book Service v.1.0 \n Developed By Denuwan"; }else { return "Book Service v.1.0"; } } } |
curl -X GET \ http://localhost:8080/booking
一旦你完成了 spring boot Rest 服務的實現,你就可以啟動伺服器並嘗試上面的 GET 方法。由於Thread sleep. 但是當您嘗試第二次響應時,應該需要 < 1Seconds,因為響應過程來自 Redis 快取伺服器,而不是命中服務層。
另外,請注意,我們將快取時間設定為application.properties檔案中的實時屬性, 因此當您在 10 秒內再次執行 GET 請求時,您會注意到該請求再次從服務層處理並花費 > 5 秒。
原始碼:這裡
相關文章
- 在Kubernetes上使用Spring Boot實現Hazelcast分散式快取 – PiotrSpring BootAST分散式快取
- 搞懂分散式技術14:Spring Boot使用註解整合Redis快取分散式Spring BootRedis快取
- Spring Boot Cache Redis快取Spring BootRedis快取
- redis→分散式快取Redis分散式快取
- SmartSql Redis 分散式快取SQLRedis分散式快取
- 分散式快取架構綜述分散式快取架構
- 結合Hazelcast和Spring的分散式快取 - reflectoringASTSpring分散式快取
- Spring Boot + Redis 快取方案深度解讀Spring BootRedis快取
- Redis——快取穿透、快取擊穿、快取雪崩、分散式鎖Redis快取穿透分散式
- Spring Boot Redis 實現分散式鎖,真香!!Spring BootRedis分散式
- Spring Boot redis分散式session快速配置Spring BootRedis分散式Session
- spring-boot-route(十二)整合redis做為快取SpringbootRedis快取
- spring boot使用Jedis整合Redis實現快取(AOP)Spring BootRedis快取
- Spring Boot整合Hazelcast實現叢集與分散式記憶體快取Spring BootAST分散式記憶體快取
- 5、Spring Boot快取Spring Boot快取
- WEB 應用快取解析以及使用 Redis 實現分散式快取Web快取Redis分散式
- Spring-Boot專案中配置redis註解快取SpringbootRedis快取
- Spring Security安全綜合大全指南Spring
- 分散式快取分散式快取
- 10、Spring Boot分散式Spring Boot分散式
- Spring Boot(二):Web 綜合開發Spring BootWeb
- redis分散式鎖-spring boot aop+自定義註解實現分散式鎖Redis分散式Spring Boot
- 如何在SPRING中同時管理本地快取和分散式快取? - techblogSpring快取分散式
- 聊聊分散式快取分散式快取
- 分散式快取方案分散式快取
- 聊聊本地快取和分散式快取快取分散式
- Spring boot學習(八)Spring boot配置ehcache快取框架Spring Boot快取框架
- Spring AOP單元測試綜合指南Spring
- Spring Boot(十一)Redis整合從Docker安裝到分散式Session共享Spring BootRedisDocker分散式Session
- 分散式快取NCache使用分散式快取
- 分散式快取擊穿分散式快取
- 同為分散式快取,為何 Redis 更勝一籌?分散式快取Redis
- 在Spring Boot快取API - Code FactorySpring Boot快取API
- 從零搭建Spring Boot腳手架(6):整合Redis作為快取Spring BootRedis快取
- Spring Boot 2.x基礎教程:使用集中式快取RedisSpring Boot快取Redis
- spring配置redis註解快取SpringRedis快取
- 【Azure Redis 快取】示例使用 redisson-spring-boot-starter 連線/使用 Azure Redis 服務Redis快取Springboot
- 分散式快取 - 快取簡介,常用快取演算法分散式快取演算法