docker搭建redis哨兵集群并且整合springboot的實現(xiàn)
1、創(chuàng)建兩個文件夾redis和sentinel文件夾用于存放docker-compose.yml文件
2、redis下的docker-compose.yml
version: "3" services: master: image: redis:latest container_name: my_redis_master command: redis-server --requirepass root # 在連接容器時需要密碼 ports: - 6379:6379 slave1: image: redis:latest depends_on: # 這里目的是需要先啟動master,隨后再啟動slave節(jié)點 - master container_name: my_redis_slave1 command: redis-server --slaveof my_redis_master 6379 --requirepass root --masterauth root # 再容器啟動后,通過這里命令來指定主節(jié)點ip地址 ports: - 6380:6379 slave2: image: redis:latest depends_on: - master container_name: my_redis_slave2 ports: - 6381:6379 command: redis-server --slaveof my_redis_master 6379 --requirepass root --masterauth root networks: # 這里是配置網(wǎng)絡(luò)環(huán)境,目的是讓容器之間能夠相互連接,如果不配置,哨兵將獲取不到從節(jié)點的信息,并且無法轉(zhuǎn)換master節(jié)點 default: external: name: redis_net
3、sentinel下的docker-compose.yml文件以及sentinel.conf配置文件
version: '3' services: ? sentinel1: ? ? image: redis ? ? container_name: redis-sentinel-1 ? ? networks: ? ? ? - redis_net ? ? ports: ? ? ? - 26379:26379 ? ? command: redis-sentinel /usr/local/etc/redis/sentinel.conf ?# 啟動哨兵,并且指定配置文件 ? ? volumes: ? ? ? - ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf ? sentinel2: ? ? image: redis ? ? container_name: redis-sentinel-2 ? ? networks: ? ? ? - redis_net ? ? ports: ? ? ? - 26380:26379 ? ? command: redis-sentinel /usr/local/etc/redis/sentinel.conf ? ? volumes: ? ? ? - ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf ? sentinel3: ? ? image: redis ? ? container_name: redis-sentinel-3 ? ? networks: ? ? ? - redis_net ? ? ports: ? ? ? - 26381:26379 ? ? command: redis-sentinel /usr/local/etc/redis/sentinel.conf ? ? volumes: ? ? ? - ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf networks: ?# 這里指定網(wǎng)絡(luò)跟redis在同一個網(wǎng)絡(luò)環(huán)境下 ? redis_net: ? ? external: ? ? ? name: redis_net sentinel配置文件,將下面的配置文件 cp成三分就行 port 26379 dir /tmp sentinel monitor mymaster 192.168.16.2 6379 2 ?#指定集群的名字以及集群中master的ip地址,這里是容器地址,如果是用的虛擬機地址我這邊會導(dǎo)致master轉(zhuǎn)換不了。2就是指哨兵有多少個哨兵認為失效master就失效,保證超過50%就行 sentinel auth-pass mymaster root # 重點:我就是在這里忘了配置master需要密碼登陸 導(dǎo)致一直獲取不到master節(jié)點下的從信息 sentinel down-after-milliseconds mymaster 30000 #這里是指定master在失效之后多久就認為失效 sentinel parallel-syncs mymaster 1 # failover進行主備切換時最多可以有多少個slave對新的master進行同步,值越小完成failover的時間就越長,設(shè)置為1就是每次只有一個slave處于不能處理命令的狀態(tài) sentinel failover-timeout mymaster 180000? sentinel deny-scripts-reconfig yes
4、spring boot整合redis哨兵
依賴
<dependency> ? ? ? <groupId>org.springframework.boot</groupId> ? ? ? <artifactId>spring-boot-starter-data-redis</artifactId> ? ? ? <!-- 排除lettuce包,使用jedis代替--> ? ? ? <exclusions> ? ? ? ? <exclusion> ? ? ? ? ? <groupId>io.lettuce</groupId> ? ? ? ? ? <artifactId>lettuce-core</artifactId> ? ? ? ? </exclusion> ? ? ? </exclusions> ? ? </dependency> ? ? <dependency> ? ? ? <groupId>redis.clients</groupId> ? ? ? <artifactId>jedis</artifactId> ? ? ? <version>3.0.1</version> ? ? </dependency>
配置
spring: redis: sentinel: master: mymaster nodes: 192.168.16.5:26379,192.168.16.6:26380,192.168.16.7:26381 # 這里是連接的docker容器中哨兵的ip jedis: pool: max-idle: 8 min-idle: 0 max-wait: -1 max-active: 8 password: root
如果使用的虛擬機中的docker ip地址 先配置路由表,這樣宿主機才能訪問docker容器中的哨兵
route add -p 容器的網(wǎng)絡(luò)地址 mask 子網(wǎng)掩碼 虛擬機ip地址 切記一定要關(guān)閉虛擬機的防火墻
配置bean
@Bean ? ? public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){ ? ? ? ? RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); ? ? ? ? redisTemplate.setConnectionFactory(redisConnectionFactory); ? ? ? ? Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ? ? ? ? ObjectMapper om = new ObjectMapper(); ? ? ? ? om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); ? ? ? ? om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); ? ? ? ? jackson2JsonRedisSerializer.setObjectMapper(om); ? ? ? ? StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); ? ? ? ? // key采用String的序列化方式 ? ? ? ? redisTemplate.setKeySerializer(stringRedisSerializer); ? ? ? ? // hash的key也采用String的序列化方式 ? ? ? ? redisTemplate.setHashKeySerializer(stringRedisSerializer); ? ? ? ? // value序列化方式采用jackson ? ? ? ? redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); ? ? ? ? // hash的value序列化方式采用jackson ? ? ? ? redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); ? ? ? ? redisTemplate.afterPropertiesSet(); ? ? ? ? return redisTemplate; ? ? }
5、哨兵工作方式
1、特點:
- 每個哨兵進程會每秒一次向集群中的所有redis發(fā)送ping命令
- 如果距離最近的一次ping命令的時間超過了 down-after-milliseconds設(shè)置的時間,那么當(dāng)前哨兵就會將起標(biāo)記為主觀下線(SDOWN)
- 如果Master被標(biāo)記為了主觀下線,那么其余的哨兵會以每秒一次的頻率確認Master是否進入了主觀下線狀態(tài)
- 如果有足夠的哨兵(配置文件中配置)進程在指定的范圍內(nèi)確認Master進入主觀下線,則Master就會被改為客觀下線(ODWON)
- 如果沒有的哨兵同意Master主服務(wù)器下線,master的客觀下線狀態(tài)就會被移除
2、故障轉(zhuǎn)移(Raft算法):
- 先選擇優(yōu)先級最高的(slave-priority)
- 復(fù)制偏移量大的從節(jié)點(數(shù)據(jù)最新的)
- runid最小的
3、缺點:
- redis較難支持在線擴容,如果集群容量達到上限時在線擴容會變的很復(fù)雜
- 每個節(jié)點存入的數(shù)據(jù)都是相同的,容器造成資源的浪費
- 容易導(dǎo)致數(shù)據(jù)的丟失
- redis配置文件中
- min-slaves-to-write 1
- min-slaves-max-lag 10 表示至少要有1個salve節(jié)點與master數(shù)據(jù)同步超過10秒,就拒絕其它的請求
- 腦裂 (網(wǎng)絡(luò)分區(qū)變化時,master和slave出現(xiàn)無法通信時,sentinel會選擇新的master,那么此時client一直在向之前的master發(fā)送數(shù)據(jù),將原master進行恢復(fù)成新master的slave時,就會丟失后來發(fā)送的數(shù)據(jù))
6、Redis-Cluster集群
1、特點:
- 節(jié)點連接是使用二進制連接的
- 節(jié)點fail是超過半數(shù)的節(jié)點檢測時才會失效
- 客戶端只需要連接集群中任何一個節(jié)點即可
2、工作方式
每個節(jié)點上都有slot槽的概念,取值范圍是0-16383,還有一個就是cluster用于集群管理的插件。當(dāng)存取的key值到達時 redis會根據(jù)crc16進行計算,然后把計算的結(jié)果對16384取余數(shù),這樣就每個key就會有對應(yīng)的編號在0-16383之間的哈希槽,通過這個值跳轉(zhuǎn)到對應(yīng)的節(jié)點中。
redis-cluster引入了主從模式,一個主節(jié)點對應(yīng)多個從節(jié)點,當(dāng)超過半數(shù)的從節(jié)點ping主節(jié)點超時時,就會認為主節(jié)點宕機了。
3、缺點:
- 數(shù)據(jù)通過異步復(fù)制,不保證數(shù)據(jù)的強一致性
- 不支持多數(shù)據(jù)庫空間,集群模式下只能使用1個數(shù)據(jù)庫空間 0
7、redis常見問題
1、緩存雪崩
描述:在同一時間段,緩存集中過期。所有的請求都去查詢數(shù)據(jù)庫
解決方案:
解鎖或者隊列的方式防止大量線程對數(shù)據(jù)庫的一次性獨寫
協(xié)調(diào)redis的過期時間,隨機時間
做二級緩存,一級緩存為短期,二級緩存為長期
依賴隔離組件為后端限流并且降級
2、緩存穿透
描述:在redis中沒有查詢到并且數(shù)據(jù)庫中也沒有查詢到,下一次進來還是會到redis中查詢,就沒有查詢的意義了
解決方案:
布隆過濾器
將空對象記錄在緩存中
3、緩存擊穿
描述:查詢的某個key恰好失效,剛好又有大量的并發(fā)過來,造成DB壓力
解決方案:
通過加鎖或者隊列防止大量請求透過redis到DB中
對于熱點key可以無限調(diào)長
也可以做二級緩存
4、緩存降級
描述:訪問量劇增、服務(wù)出現(xiàn)問題,非核心的服務(wù)影響到核心流程的性能,但是仍需要服務(wù)還是可用
5、緩存預(yù)熱
描述:先將數(shù)據(jù)直接加載到redis中,防止用戶在請求時先查數(shù)據(jù)庫
解決方案:
定時刷新緩存
6、緩存更新
描述:維護大量緩存,自定義緩存淘汰的策略
解決方案:定時清理過期的緩存,先判斷緩存是否過期,如果過期就去數(shù)據(jù)庫獲取新的數(shù)據(jù)然后再更新
到此這篇關(guān)于docker搭建redis哨兵集群并且整合springboot的實現(xiàn)的文章就介紹到這了,更多相關(guān)docker搭建redis哨兵集群內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。