本文是有關 Redis 的學習筆記的一部分,相關目錄請參考 Redis 學習筆記(1)-簡介。
- 上一篇 商用環境的 Redis
在上一篇我們說明如何架設高可用的Redis環境,在上篇實作中我們是採用Redis主從複製模式的架構,而在本次學習中我們將說明如何由Java客戶端,或者說Spring Boot連接到我們上次建立的Redis+Sentinel的環境中。
在本次的學習中,我們將會延用上次的Redis主從複製模式的高可用環境,在此我們假設該環境已備好且隨時可用。
在開始實作前,我們先解釋在客戶端和Redis伺服器端之間若有端口轉換時,會遇到的困擾。
在使用 Redis+Sentinel 環境下,Java 客戶端連入 Redis 的操作是分二段。第一段是先連入 Sentinel,詢問最近的 Master Redis 的 IP,第二段才是真正連到 Master Redis。如下圖:
Redis+Sentinel 在 Docker 和 NAT 環境的使用會有些限制,詳情請見High availability with Redis Sentinel。下面則是對該問題的簡單描述:
在上面的描述中,說明了客戶端和Sentinel+Redis的環境中間不可插入端口轉換單元,除非依照官網上的描述覆寫Sentinel回應的IP。在我的需求中,我會將服務放在Docker Swarm中,並且Redis的網路模式採用host模式,所以不會有端口轉換的狀況發生,下面開始說明測試架構。
計劃驗證的方式是將 App 也放在 Docker 中,因為若是將 App 放在 PC 上則會遇到類似 NAT 的問題。先確認 App 可以正常連入 Redis。 如下圖:
接下來停止 Redis Master,觸發 Sentinel 執行切換。即使切換後 App 也可正常連入 Redis Master。如下圖:
在之前的學習 客戶端整合 Redis有撰寫四個模組的程式,其中有個模組appWeb可以作為這次的測試程式使用。
我們先由打包appWeb模組開始。
之前我們需要連接的對像是Redis單機環境,但是此是我們將連接的環境是Redis和Sentinel環境,所以我們的連結環境要作些修改。
開啟 appWeb 模組,在 resources 下新增一個設定檔如下:
sentinelServersConfig:
password: mypwd
clientName: sentinelclient
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
sentinelAddresses:
- "redis://10.0.2.11:26379"
- "redis://10.0.2.12:26379"
- "redis://10.0.2.13:26379"
masterName: "mymaster"
codec: !<org.redisson.codec.JsonJacksonCodec> {}
將該模組打包,如下:
將打包好的 appWeb-1.0-SNAPSHOT.jar
上傳到 c7a1 的 /root/myApp 目錄下。準備建立容器用的image。
在 c7a1:/root/myApp 下新增一個 application.properties,Shell 指令如下:
cd
mkdir -p myApp
cat << EOF | tee ./myApp/application.properties
## 使用 redisson_sentinel.yml 作為 redisson 的設定檔
spring.redis.redisson.file: classpath:/redisson_sentinel.yml
EOF
在 c7a1:/root/myApp 下新增一個 Dockerfile,如下:
cd
cat << EOF | tee ./myApp/Dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=appWeb-1.0-SNAPSHOT.jar
WORKDIR /
COPY \${JAR_FILE} app.jar
COPY application.properties application.properties
ENTRYPOINT ["java","-jar","/app.jar"]
EOF
在 c7a1:/root/myApp 下建立名稱為 my_web:v1 的 image ,指令如下:
cd
cd myApp
## 建立名稱為 my_web:v1 的 image
docker build -t my_web:v1 .
在 c7a1 執行啟動指令,如下:
## 以背景模式啟動 my_web
docker run --rm -d --name my_web -p 8080:8080 my_web:v1
## 檢視 my_web 日誌
docker logs my_web -f
確認 Virtual box 有設定 PC:18080 轉導到 c7a1:8080 如下:
在測試程式啟動後,我們就可以開始驗證是否程式的運作符合我們的預期。
第一個要驗證的就是一般情況下是否可以正常寫入。
檢查目前 Redis Master 是在 c7a1。先登入任一個 Sentinel 執行指令如下:
## 進入 Sentinel 容器
docker exec -it `docker ps -q -f 'name=sentinel'` /bin/bash
## 進入 Sentinel
redis-cli -p 26379
## 詢問 Master
sentinel get-master-addr-by-name mymaster
透過 Postman 驗證可以新增 User,如下:
接下來我們透過Docker指令將Mater Redis強制停止,觸發Sentinel進行切換。
在 c7a1 停止 redis 容器,觸發切換,指令如下
## 在 c7a1 上停止 redis
docker stop `docker ps -q -f 'name=redis'`
檢查目前 Redis Master 是在 c7a2。先登入任一個 Sentinel 執行指令如下:
## 進入 Sentinel 容器
docker exec -it `docker ps -q -f 'name=sentinel'` /bin/bash
## 進入 Sentinel
redis-cli -p 26379
## 詢問 Master
sentinel get-master-addr-by-name mymaster
切換之後,再重新確認是否可以正常寫入。
透過 Postman 驗證可以新增 User,如下:
在本篇學習中,我們瞭解了如何連結Sentinel環境內的Redis,並擴展之前的測試程式,使其可以連上Sentinel環境內的Redis。
我們也透過實際切換操作來驗證這個架構具有高可用性能力。
學習到此,我們關於Redis的學習已全部完成。