1. 程式人生 > 其它 >redis cli 刪除key 模糊_Redis叢集及雪崩

redis cli 刪除key 模糊_Redis叢集及雪崩

技術標籤:redis cli 刪除key 模糊redis 叢集redis叢集檢視redis叢集狀態

redis分散式叢集

上一篇 主從複製(哨兵),雖然主從能提升讀的併發,但是單個master節點的容量是有限的,記憶體資料達到一定程度就會有瓶頸,無論多少套主從,master的容量都是最終的瓶頸。這個時候我們需要水平擴充套件記憶體,而分散式叢集恰好能解決這點,redis叢集最少要求三組進行確立叢集,客戶端建立與叢集連線,只需要與其中的一個進行連線就可以,資料不具體儲存到叢集中的某個節點上,而是儲存到叢集的槽點上。

d115871012c743f84aa259e8fe9689c6.png
叢集能解決那些問題
  • 高併發
  • 高可用
  • 訪問/儲存水平擴充套件

redis叢集配置

13e4e81f2bdccdce1372926bca4af922.png
#解釋下,我主機上上redis是以埠來區別的,沒有分開部署到8臺機子上#叢集中單機配置 redis.confdaemonize yesdir /usr/local/redis-cluster/8001bind 0.0.0.0requirepass cqp1116  #因為redis是隨機分配主從,所以儘量密碼弄成一樣的方便記憶。masterauth cqp1116 #叢集建立會自動搭建主從關係,所以不要手工配置replicaofport 8001pidfile /var/run/redis_8001.pid# 開啟叢集配置cluster-enabled yes# 叢集每個節點都需要的配置檔案cluster-config-file nodes-8001.conf# master超時時間,超過後主備切換cluster-node-timeout 3000# 開啟AOFappendonly yes#因為我是在一臺伺服器上搭建叢集,可以用批命令的方式進行chmod 777 cluster.shredis-server /usr/local/redis-cluster/8001/redis.confredis-server /usr/local/redis-cluster/8002/redis.confredis-server /usr/local/redis-cluster/8003/redis.confredis-server /usr/local/redis-cluster/8004/redis.confredis-server /usr/local/redis-cluster/8005/redis.confredis-server /usr/local/redis-cluster/8006/redis.conf#執行./cluster.sh啟動

搭建叢集

# Redis 3.x開始有叢集,redis-trib.rb# Redis 5.x使用redis-cli就可以了# 叢集建立的命令# --cluster-replicas 1 每個master有幾個slaveredis-cli -a cqp1116 --cluster create 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 127.0.0.1:8006 --cluster-replicas 1# 檢視叢集資訊redis-cli -a cqp1116 --cluster check 127.0.0.1:8001# 檢視叢集命令幫助redis-cli -a cqp1116 --cluster help

資料儲存

當我們在叢集單一節點上儲存資料的時候,會一定儲存到當前登入節點麼?

# 單機登入節點redis-cli -a cqp1116 -p 8001# 叢集登入節點redis-cli -c -a cqp1116 -p 8001set key valueget key127.0.0.1:8001> cluster info127.0.0.1:8001> cluster nodeskeys * # 在叢集狀態下只能拿到當前節點的所有資料#-> Redirected to slot [12539] located at 127.0.0.1:8003

slot槽點

slot就是支援分散式儲存的核心,redis叢集建立後會建立16384個槽點,並且根據叢集的master資料平均分配給master

  • 如果有3個master,16384/3=(大約)5460個
  • 當你往redis叢集中插入資料時,資料只存一份,不一定在你登入節點上,redis叢集會使用crc16(key)mod16384來計算這個key應該放在那個hash slot中
  • 獲取資料的時候也會根據key來取模,就知道在哪個slot上了,也就能redirect了
  • 一個slot其實就是一個資料夾,就能存很多key

叢集如何實現分散式

  • 每個master只儲存mod後的slot資料
  • 如果要擴充套件,再加入一個,只需要給這個新節點再分一些slot就行了,但注意無論多少個node,slots總數不變都是16384
  • 8g(2460),8g(2460),8g(2460),這個時候加入一個16g(4000) 16g(5000):total-16384
  • slot移動,slot裡的資料也跟著移動
  • 一個master節點是否記憶體裝滿,是slots數量多少還是slot裡存放的檔案多少導致的?

叢集搭建簡易

  • 建議是奇數個,至少3個master節點
  • 主從切換:節點間會相互通訊,一半以上的節點ping不通某個節點,就認為這個master掛了,這個時候從節點頂上
  • 什麼時候整個叢集不可用
    • 如果叢集中任意master掛掉,且沒有slave頂上,叢集就進入fail狀態
    • 如果超半數以上的master掛掉,無論是否有slave,叢集都進入fail狀態
叢集新增節點
#add-node       new_host:new_port existing_host:existing_port#                 --cluster-slave#                 --cluster-master-id # 新增主節點redis-cli -a cqp1116 --cluster add-node 127.0.0.1:8007 127.0.0.1:8001# 加入後可以通過cluster nodes來檢視127.0.0.1:8001> cluster nodes# 給8007分配slot# --cluster-from 從哪個節點來分配slot,這裡只能寫node_id,就是cluster nodes獲得id,from可以是一個節點也可以是多個節點# --cluster-to 到8007節點,同樣是node_id# --cluster-slots 從from節點一共分多少slot,並且from中的node是平均分這個總數的 4096/3# --cluster-yes 不用提示直接執行redis-cli -a cqp1116 --cluster reshard 127.0.0.1:8001 --cluster-from 4248563f9000101bff9ff1beb27a7d595c99fa8e,21ccab2ac6b6724b3469f9c0662119a4ce3a06fc,598304ac00aa2daa61773b1fc32d26f99e6f8463 --cluster-to 75b831369eedd8b5fe0aee4b2819f573ae0592a2 --cluster-slots 4096 --cluster-yes# 給8007增加8008的slave節點redis-cli -a cqp1116 --cluster add-node 127.0.0.1:8008 127.0.0.1:8001 --cluster-slave --cluster-master-id 75b831369eedd8b5fe0aee4b2819f573ae0592a2
節點下線
# 下線節點,現有考慮把slots分給其他節點,這就是在做資料遷移# 我這一次分配,也可以分批移動給多個節點,我要下架8001/8006redis-cli -a cqp1116 --cluster reshard 127.0.0.1:8002 --cluster-from 4248563f9000101bff9ff1beb27a7d595c99fa8e --cluster-to 21ccab2ac6b6724b3469f9c0662119a4ce3a06fc --cluster-slots 4096 --cluster-yes# 檢查一下8001的slot是否全部轉移走127.0.0.1:8002> cluster nodes# 刪除8001節點,這裡的節點建議寫成刪除節點redis-cli -a cqp1116 --cluster del-node 127.0.0.1:8001 4248563f9000101bff9ff1beb27a7d595c99fa8e# 刪除8006節點,這裡的節點建議寫成刪除節點redis-cli -a cqp1116 --cluster del-node 127.0.0.1:8006 58d18e90e4ed86de44a6c14455e2f24825924e93
redis-cluster常用命令
# redis-cli --cluster檢視幫助redis-cli --cluster help# 給新加入的node分配slot,all代表所有master節點redis-cli -a cqp1116 --cluster reshard 127.0.0.1:8001 --cluster-from all --cluster-to 60709ef9ee8238811115c38970468af8b611643a --cluster-slots 4000 --cluster-yes# cluster命令,是執行在redis-cli,一定要先登入到叢集中# 新增master節點cluster meet 127.0.0.1 8007# 使用rebalance命令來自動平均分配slot# --cluster-threshold 1 只要不均衡的slot數量超過1,就觸發rebanlance# --cluster-use-empty-masters 沒有slot槽點的節點也引數均分redis-cli -a cqp1116 --cluster rebalance 127.0.0.1:8001 --cluster-threshold 1 --cluster-use-empty-masters# cluster命令,是執行在redis-cli,一定要先登入到叢集中# 新增slave節點# REPLICATE  -- Configure current node as replica to .# 前提是這個副本節點要先在叢集中cluster meet 127.0.0.1 8008# 加入後切換到新增的slave 8008cluster replicate 60709ef9ee8238811115c38970468af8b611643a
springboot整合叢集
spring:  redis:    password: cqp1116    cluster:      nodes: 127.0.0.1:8001,127.0.0.1:8002,127.0.0.1:8003,127.0.0.1:8004,127.0.0.1:8005,127.0.0.1:8006,127.0.0.1:8007,127.0.0.1:8008
redis效能監控
# redis-benchmark檢查redis的併發效能的# -c 100個連線# -n 500個請求# 主要是測試redis主機的一個本地效能redis-benchmark -h 127.0.0.1 -p 8001 -a cqp1116 -c 100 -n 500
慢查詢
# redis.conf配置# 設定慢查詢的時間下限,超過多少微秒的進行記錄slowlog-log-slower-than 10000# 慢產訊對應的日誌長度,單位:命令數slowlog-max-len 128

檢視慢查詢

# redis-cli客戶端下# 檢視慢查詢127.0.0.1:6379> slowlog get# 獲取慢查詢條目127.0.0.1:6379> slowlog len# 重置慢查詢日誌127.0.0.1:6379> slowlog reset

redis雪崩

什麼是redis雪崩
  • 雪崩是基於資料庫,所有原理應該到Redis的查詢全到DB,並且是同時到達

  • 快取在同一時間大量的key過期(key)

  • 多個使用者同時請求併到達資料,而且這個請求只有一個是有意義的,其他的都是重複無用功

redis雪崩解決方案
  • 快取用不過期:冰封了
  • 過期時間錯開(可以在key建立時加入一個1-10分鐘的隨機數給到key)
  • 多快取資料結合(不要直接打到DB上,可以在DB上再加一個搜尋引擎)
  • 在程式碼裡通過鎖解決(synchronized,分散式鎖zookeeper)

Redisson實現分散式鎖機制

分散式鎖的核心

  • 加鎖
  • 鎖刪除:一定不能因為鎖提前超時導致刪除非自己的鎖
  • 鎖超時:如果業務沒有執行完就應該給鎖延時
  org.redisson  redisson-spring-boot-starter  3.12.1

java程式碼實現

@Configurationpublic class controller {    @Autowired    RedissonClient redissonClient;    @GetMapping("/redisson")    @ResponseBody    public String redissonLock(){        RLock rLock = redissonClient.getLock("orderId");        System.out.println("開啟鎖**********");        try {            //如果有鎖等待5秒,加鎖後持有30秒            rLock.tryLock(5, 30, TimeUnit.SECONDS);            System.out.println("獲取鎖*********");        }catch (Exception ex){            ex.printStackTrace();        } finally {            System.out.println("釋放鎖*********");            rLock.unlock();        }        return "redisson";    }}

redisson預設就是加鎖30秒,建議也是30秒以上,預設的lockWatchdogTimeout會每隔10秒觀察一下,待到20秒的時候如果主程序還沒有釋放鎖,就會主動續期30秒