日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis7之集群(十)

發布時間:2024/5/15 数据库 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis7之集群(十) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

10.1 介紹

  • 由于數據量過大,單個Master復制集難以承擔,因此需要對多個復制集進行集群,形成水平擴展每個復制集只負責存儲整個數據集的一部分,這就是Redis的集群,其作用是提供在多個Redis節點間共享數據的程序集。

  • Redis集群是一個提供在多個Redis節點間共享數據的程序集

    • Redis集群可以支持多個Master

  • Redis集群支持多個Master,每個Master又可以掛載多個Slave
    • 讀寫分離
    • 支持海量數據的高可用
    • 支持海量數據的讀寫存儲操作
  • 由于Cluster自帶Sentinel的故障轉移機制,內置了高可用的支持,無需再去使用哨兵功能
  • 客戶端和Redis的節點連接,不再需要連接集群中所有節點,只需連接集群中的任意一個可用節點即可
  • 槽位slot負責分配到各個物理服務節點,由對應的集群來負責維護節點、插槽和數據之間的關系

10.2 Redis集群分布式存儲

Redis集群分布式存儲有大概有3種解決方法

  • 哈希取余分區
  • 一致性哈希算法分區
  • 哈希槽分區

哈希取余分區

hash(key) % N個機器臺數,計算出哈希值,用來決定數據映射到哪一個節點上。

優點

  • 簡單粗暴,直接有效,只需要預估好數據規劃節點例如3臺、8臺、10臺,就能保證一段時間的數據支撐。使用Hash算法讓固定的一部分請求落到同一臺服務器上,這樣每臺服務器固定處理一部分請求(并維護這些請求的信息),起到負載均衡+分而治之的作用。

缺點

  • 直接規劃好節點,進行擴容或者縮容會很麻煩,不管擴還是縮,每次數據變動會導致節點有變動,映射關系都要重新計算,在服務器個數固定不變時沒有問題。
  • 如果需要彈性擴容或故障停機的情況下,原來的取模公式就會發生變化,Hash(key)/3會變成Hash(key) /?。此時地址經過取余運算的結果將發生很大變化,根據公式獲取的服務器也會變得不可控。
  • 某個redis機器宕機了,由于臺數數量變化,會導致hash取余全部數據重新洗牌。

一致性哈希算法分區

提出一致性Hash解決方案。目的是當服務器個數發生變動時,盡量減少影響客戶端到服務器的映射關系

三個步驟
  • 算法構建一致性哈希環

    • 一致性哈希算法必然有個hash函數并按照算法產生hash值,這個算法的所有可能哈希值會構成一個全量集,這個集合可以成為一個hash空間[0,2^32-1],這個是一個線性空間,但是在算法中,我們通過適當的邏輯控制將它首尾相連(0 = 2^32),這樣讓它邏輯上形成了一個環形空間。
    • 它也是按照使用取模的方法,前面筆記介紹的節點取模法是對節點(服務器)的數量進行取模。而一致性Hash算法是對232取模,簡單來說,一致性Hash算法將整個哈希值空間組織成一個虛擬的圓環,如假設某哈希函數H的值空間為0-232-1(即哈希值是一個32位無符號整形),整個哈希環如下圖:整個空間按順時針方向組織,圓環的正上方的點代表0,0點右側的第一個點代表1,以此類推,2、3、4、……直到232-1,也就是說0點左側的第一個點代表232-1, 0和232-1在零點中方向重合,我們把這個由232個點組成的圓環稱為Hash環。
  • 服務器IP節點映射

    • 將集群中各個IP節點映射到環上的某一個位置。

    • 將各個服務器使用Hash進行一個哈希,具體可以選擇服務器的IP或主機名作為關鍵字進行哈希,這樣每臺機器就能確定其在哈希環上的位置。假如4個節點NodeA、B、C、D,經過IP地址的哈希函數計算(hash(ip)),使用IP地址哈希后在環空間的位置如下:

  • key 落到服務器的落鍵規則

    • 當我們需要存儲一個kv鍵值對時,首先計算key的hash值,hash(key),將這個key使用相同的函數Hash計算出哈希值并確定此數據在環上的位置,從此位置沿環順時針“行走”,第一臺遇到的服務器就是其應該定位到的服務器,并將該鍵值對存儲在該節點上。

    • 如我們有Object A、Object B、Object C、Object D四個數據對象,經過哈希計算后,在環空間上的位置如下:根據一致性Hash算法,數據A會被定為到Node A上,B被定為到Node B上,C被定為到Node C上,D被定為到Node D上。

  • 優點
    • 一致性哈希算法的容錯性

      • 假設Node C宕機,可以看到此時對象A、B、D不會受到影響,只有C對象被重定位到Node D。一般的,在一致性Hash算法中,如果一臺服務器不可用,則受影響的數據僅僅是此服務器到其環空間中前一臺服務器(即沿著逆時針方向行走遇到的第一臺服務器)之間數據,其它不會受到影響。簡單說,就是C掛了,受到影響的只是B、C之間的數據,并且這些數據會轉移到D進行存儲。

    • 一致性哈希算法的擴展性

      • 數據量增加了,需要增加一臺節點NodeX,X的位置在A和B之間,那收到影響的也就是A到X之間的數據,重新把A到X的數據錄入到X上即可,
        不會導致hash取余全部數據重新洗牌。

    缺點
    • 一致性哈希算法的數據傾斜問題

      • Hash環的數據傾斜問題
        一致性Hash算法在服務節點太少時,容易因為節點分布不均勻而造成數據傾斜(被緩存的對象大部分集中緩存在某一臺服務器上)問題,
        例如系統中只有兩臺服務器:

    哈希槽分區

    • 哈希槽實質就是一個數組,數組[0,2^14 -1]形成hash slot空間。

    • 解決均勻分配的問題,在數據和節點之間又加入了一層,把這層稱為哈希槽(slot),用于管理數據和節點之間的關系,現在就相當于節點上放的是槽,槽里放的是數據。

    • 槽解決的是粒度問題,相當于把粒度變大了,這樣便于數據移動。哈希解決的是映射問題,使用key的哈希值來計算所在的槽,便于數據分配

    • 一個集群只能有16384個槽,編號0-16383(0-2^14-1)。這些槽會分配給集群中的所有主節點,分配策略沒有要求。

    • 集群會記錄節點和槽的對應關系,解決了節點和槽的關系后,接下來就需要對key求哈希值,然后對16384取模,余數是幾key就落入對應的槽里。HASH_SLOT = CRC16(key) mod 16384。以槽為單位移動數據,因為槽的數目是固定的,處理起來比較容易,這樣數據移動問題就解決了。

    • 當需要在 Redis 集群中放置一個 key-value時,redis先對key使用crc16算法算出一個結果然后用結果對16384求余數[ CRC16(key) % 16384],這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽,也就是映射到某個節點上。如下代碼,key之A 、B在Node2, key之C落在Node3上

    分片是什么使用Redis集群時我們會將存儲的數據分散到多臺redis機器上,這稱為分片。簡言之,集群中的每個Redis實例都被認為是整個數據的一個分片。
    如何找到給定key的分片為了找到給定key的分片,我們對key進行CRC16(key)算法處理并通過對總分片數量取模。然后,使用確定性哈希函數,這意味著給定的key將多次始終映射到同一個分片,我們可以推斷將來讀取特定key的位置。

    優勢:

    缺點

    Redis集群不保證 強一致性,這意味著在特定的條件下,Redis集群可能會丟掉一些被系統收到的寫入請求命令

    10.3 為什么redis集群的最大槽數是16384

    • Redis集群并沒有使用一致性hash而是引入了哈希槽的概念。Redis 集群有16384個哈希槽,每個key通過CRC16校驗后對16384取模來決定放置哪個槽,集群的每個節點負責一部分hash槽。

      • 正常的心跳數據包帶有節點的完整配置,可以用冪等方式用舊的節點替換舊節點,以便更新舊的配置。這意味著它們包含原始節點的插槽配置,該節點使用2k的空間和16k的插槽,但是會使用8k的空間(使用65k的插槽)。同時,由于其他設計折衷,Redis集群不太可能擴展到1000個以上的主節點。因此16k處于正確的范圍內,以確保每個主機具有足夠的插槽,最多可容納1000個矩陣,但數量足夠少,可以輕松地將插槽配置作為原始位圖傳播。請注意,在小型群集中,位圖將難以壓縮,因為當N較小時,位圖將設置的slot / N位占設置位的很大百分比。

    **(1)如果槽位為65536,發送心跳信息的消息頭達8k,發送的心跳包過于龐大。**在消息頭中最占空間的是myslots[CLUSTER_SLOTS/8]。 當槽位為65536時,這塊的大小是: 65536÷8÷1024=8kb

    在消息頭中最占空間的是myslots[CLUSTER_SLOTS/8]。 當槽位為16384時,這塊的大小是: 16384÷8÷1024=2kb

    因為每秒鐘,redis節點需要發送一定數量的ping消息作為心跳包,如果槽位為65536,這個ping消息的消息頭太大了,浪費帶寬。

    (2)redis的集群主節點數量基本不可能超過1000個。

    集群節點越多,心跳包的消息體內攜帶的數據越多。如果節點過1000個,也會導致網絡擁堵。因此redis作者不建議redis cluster節點數量超過1000個。 那么,對于節點數在1000以內的redis cluster集群,16384個槽位夠用了。沒有必要拓展到65536個。

    (3)槽位越小,節點少的情況下,壓縮比高,容易傳輸

    Redis主節點的配置信息中它所負責的哈希槽是通過一張bitmap的形式來保存的,在傳輸過程中會對bitmap進行壓縮,但是如果bitmap的填充率slots / N很高的話(N表示節點數),bitmap的壓縮率就很低。 如果節點數很少,而哈希槽數量很多的話,bitmap的壓縮率就很低。

    10.4 集群配置(三主三從)

    1.準備三臺虛擬機,各自新建文件目放配置文件

    mkdir -p /myredis/cluster

    2.新建6個獨立的redis實例服務 (一臺虛擬機兩個)因為多個太過于占內存了,也可以用6個服務器

    • 第一臺虛擬機IP: 192.168.238.111 + 端口 6381 / 6382

      • 端口6381 (記著將密碼改成自己平常用的)

        vim /myredis/cluster/redisCluster6381.conf bind 0.0.0.0 daemonize yes protected-mode no port 6381 logfile "/myredis/cluster/cluster6381.log" pidfile /myredis/cluster6381.pid dir /myredis/cluster dbfilename dump6381.rdb appendonly yes appendfilename "appendonly6381.aof" requirepass 123456 masterauth 123456cluster-enabled yes cluster-config-file nodes-6381.conf cluster-node-timeout 5000
      • 端口 6382

        vim /myredis/cluster/redisCluster6382.conf bind 0.0.0.0 daemonize yes protected-mode no port 6382 logfile "/myredis/cluster/cluster6382.log" pidfile /myredis/cluster6382.pid dir /myredis/cluster dbfilename dump6382.rdb appendonly yes appendfilename "appendonly6382.aof" requirepass 123456 masterauth 123456cluster-enabled yes cluster-config-file nodes-6382.conf cluster-node-timeout 5000
    • 第二臺虛擬機IP: 192.168.238.112 + 端口 6383 / 6384

      • 端口 6383

        vim /myredis/cluster/redisCluster6383.conf bind 0.0.0.0 daemonize yes protected-mode no port 6383 logfile "/myredis/cluster/cluster6383.log" pidfile /myredis/cluster6383.pid dir /myredis/cluster dbfilename dump6383.rdb appendonly yes appendfilename "appendonly6383.aof" requirepass 123456 masterauth 123456cluster-enabled yes cluster-config-file nodes-6383.conf cluster-node-timeout 5000
      • 端口 6384

        vim /myredis/cluster/redisCluster6384.conf bind 0.0.0.0 daemonize yes protected-mode no port 6384 logfile "/myredis/cluster/cluster6384.log" pidfile /myredis/cluster6384.pid dir /myredis/cluster dbfilename dump6384.rdb appendonly yes appendfilename "appendonly6384.aof" requirepass 123456 masterauth 123456cluster-enabled yes cluster-config-file nodes-6384.conf cluster-node-timeout 5000
    • 第三臺虛擬機IP: 192.168.238.113 + 端口 6385 / 6386

      • 端口 6385

        vim /myredis/cluster/redisCluster6385.conf bind 0.0.0.0 daemonize yes protected-mode no port 6385 logfile "/myredis/cluster/cluster6385.log" pidfile /myredis/cluster6385.pid dir /myredis/cluster dbfilename dump6385.rdb appendonly yes appendfilename "appendonly6385.aof" requirepass 111111 masterauth 111111cluster-enabled yes cluster-config-file nodes-6385.conf cluster-node-timeout 5000
      • 端口 6386

        vim /myredis/cluster/redisCluster6386.conf bind 0.0.0.0 daemonize yes protected-mode no port 6386 logfile "/myredis/cluster/cluster6386.log" pidfile /myredis/cluster6386.pid dir /myredis/cluster dbfilename dump6386.rdb appendonly yes appendfilename "appendonly6386.aof" requirepass 111111 masterauth 111111cluster-enabled yes cluster-config-file nodes-6386.conf cluster-node-timeout 5000

    3.啟動6臺redis實例

    redis-server /myredis/cluster/redisCluter6381.conf .......... redis-server /myredis/cluster/redisCluter6386.conf

    4.通過redis-cli命令為6臺機器構建集群關系

    • 構建主從關系 注意用自己的IP

      redis-cli -a 123456 --cluster create --cluster-replicas 1 192.168.238.111:6381 192.168.238.111:6382 192.168.238.112:6383 192.168.238.112:6384 192.168.238.113:6385 192.168.238.113:6386
      • -cluster-replicas 1 表示為每個master創建一個slave節點

    5.任意連接一個作為切入點(集群只需要連一個),并檢驗集群狀態

    • 這里連6381端口

      redis-cli -a 123456 -p 6381 -c // -c表示集群 不加的話不是按照集群啟動的,對于在別的機器上的key,會報錯
      • 加 -c 啟動

      • 不加 -c 啟動 ,在存值時,會報錯

    • 查看節點狀態

      • cluster nodes // 查看集群的主從關系

      • cluster info // 查看集群信息

        • info replication // 查看主從

    6.測試一下集群

    • 新增兩個key,看看集群是否成功

    • 查看這個key的槽位值

      cluster keyslot k2

    7.主從容錯切換遷移

    在我這里我的6381是slave,他的master是6384(在 cluster nodes 中 看他們的id)

    • 把6384停了,6381會成為master

    • 啟動6384,6381還是master,并不會讓位


    • Redis集群不保證強一致性,意味著在特定的條件下,Redis集群可能會丟掉一些被系統收到的寫入請求命令

      • 因為本質還是發送心跳包,需要一些時間判斷是否down機,如果down機,對應的slave直接成為master
    • 如果想要原先的master繼續做master的話

      • CLUSTER FAILOVER // 讓誰上位 就在誰的端口號下執行這個命令

    8.主從擴容

    • 新建6387、6388 兩個服務實例配置文件+啟動 (又加了個虛擬機 或者 直接在三個虛擬機里選一個)

      • 6387端口

      • bind 0.0.0.0 daemonize yes protected-mode no port 6387 logfile "/myredis/cluster/cluster6387.log" pidfile /myredis/cluster6387.pid dir /myredis/cluster dbfilename dump6387.rdb appendonly yes appendfilename "appendonly6387.aof" requirepass 123456 masterauth 123456cluster-enabled yes cluster-config-file nodes-6387.conf cluster-node-timeout 5000
      • 6388 端口

      • bind 0.0.0.0 daemonize yes protected-mode no port 6388 logfile "/myredis/cluster/cluster6388.log" pidfile /myredis/cluster6388.pid dir /myredis/cluster dbfilename dump6388.rdb appendonly yes appendfilename "appendonly6388.aof" requirepass 123456 masterauth 123456cluster-enabled yes cluster-config-file nodes-6388.conf cluster-node-timeout 5000
    • 啟動,此時這兩個實例都是master

      • redis-server /myredis/cluster/redisCluster6388.conf redis-server /myredis/cluster/redisCluster6387.conf
    • 將新增的6387節點作為master加入原集群

      • redis-cli -a 123456 --cluster add-node 192.168.230.114:6387 192.168.238.111:6381

    • 檢查集群情況,6381

      • redis-cli -a 123456 --cluster check 192.168.238.111:6381

    • 分配槽號,上圖沒有分配槽

      • redis-cli -a 123456 --cluster reshard 192.168.238.111:6381

        重新分配成本太高,所以前3家各自勻出來一部分,從6381/6383/6385三個舊節點分別勻出1364個坑位,注意本機這里經過調整所以我是需要從6381中分出4096即可

      • 做的時候如果slots都一樣的話,直接用all,所有節點均勻分配給新節點

    • 再次檢查集群情況

      • redis-cli -a 123456 --cluster check 192.168.238.111:6381

    • 為主節點6387分配從節點6388 –cluster-master-id 后跟的是6387的id

      • redis-cli -a 123456 --cluster add-node 192.168.238.114:6388 192.168.238.114:6387 --cluster-slave --cluster-master-id b861764cbba16a1b21536a3182349748e56f24cc

    • 查看集群信息

    9.主從縮容

    讓6388和6387下線

    • 先獲得6388的節點id(上圖可獲取),在集群中將6388刪除

      • redis-cli -a 123456 --cluster del-node 192.168.238.114:6388 411144d66f28e876de5a6433689c8cbfab10686f

    • 檢查節點,只剩7臺

    • 將6387的槽號情況,重新分配,先全部都給6381

      • redis-cli -a 123456 --cluster reshard 192.168.238.111:6381

    • 查看集群情況

    成功!

    10.5 補充

    總結

    以上是生活随笔為你收集整理的Redis7之集群(十)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。