當前位置:首頁 » 密碼管理 » redis集群訪問

redis集群訪問

發布時間: 2022-11-07 04:28:35

① Django連接Redis集群問題排查思路和總結

直接就一個連接失敗

確認賬號密碼和埠沒問題後,問題同事配置有沒驗證過,他說直接從網上 cv 的,完全沒經過驗證。坑啊!!!

把生產的配置和測試配置比較好,修改了幾個地方

信心滿滿,重啟啟動 django shell 測試,結果還是連接不上!這時候心情開始有點糟糕~

冷靜, django shell 不行,那用 python shell 直連試試?

一點毛病都沒有,直接連上了!

一臉懵逼,這到底是啥問題啊!

結果依然是連接不上。

不知不覺已經到了晚上九點,好累,不想卷了。下班回家吧

回家路上整個腦子都被這個問題困擾著。難道密碼中含有 @ 符號的 redis 集群,Django 真的連接不上?反復的問自己。

問了其他同事,生產環境是否有其他的 redis 集群可以用來調試。很遺憾,並沒有。

要不,我自己創建一個 redis 集群,把密碼設置成含有 @ 符號?

可是,自己本地創建 redis 集群好麻煩啊。要本地安裝虛擬機,想到一堆配置就直接勸退。

洗完澡,和老婆聊了 1h 左右的視頻。已經到 11 點多,准備睡覺?

那是不可能的,帶著問題是很難入睡!哎,這個是老毛病了。

突然想到了一個點,最小試錯原則。自己搭建本地集群很麻煩,公司又沒有多餘的集群。

那直接買一個雲版的 redis 集群?說干就干,直接從床上起來,打開電腦。

這時問題又來了,阿里雲還是騰訊雲?

鑒於雙 11 買了騰訊雲 2c 4g 8m 的伺服器,只要 199 就能 3 年。

再對比之前買阿里雲那個 1c 2g 1m 伺服器,3 年也要 100 多。

瞬間對騰訊雲好感倍增,決定先買騰訊雲。

一頓操作,發現騰訊雲是真的難用:

最最最重要,給把實例綁定了安全組後,外網還是無法訪問???(不管了,反正我就是很生氣)

對騰訊雲太失望了,不得不把最後一根稻草壓在阿里雲身上。

所幸,阿里雲沒有讓我失望!

咔咔咔,一頓操作:

密碼中含有 @ 符號,但連接一點毛病都沒有!!!

至此,問題終於解決了!!!

我已經迫不及待明天去公司驗證,但回過頭一看,已經是深夜一點半。

自言自語的說了一句:"睡吧,卷王"

經過對比,發現配置只需要生產的配置僅需要在測試的配置上加多一個 :

修復最磨人的 bug,往往僅需要一點小小的改動~

為什麼測試環境沒報錯了呢???

因為測試環境的 redis 集群不需要密碼

② 編寫一個python程序實現redis集群的訪問

用python-2.7.3\python是對的,但是你的hello.py放在那裡?你需要先用「cd 目錄名」轉換當前目錄到存放hello.py的地方,然後執行python-2.7.3\python hello.py。

③ Redis集群方案應該怎麼做

java語言為例,簡單說一下,除了一些公司自主開發的集群外。常用的解決高並發問題的集群一般有三種:

  1. 使用redis-trib.rb,這個是安裝redis時就自帶的一種集群,採用了服務端分片的方式,支持主備,此集群既解決了高並發的問題,也解決了高可用的問題。Jedis使用JedisCluster類來訪問。

  2. 使用Jedis帶的客戶端分片ShardedJedisPool類。

  3. 使用代理進行分片twemproxy,連接代理可以使用Jedis類(單鏈接)和JedisPool類(多鏈接)。

通過Redis的sentinel機制還可以配置高可用集群,一主多從,主down掉後,sentinel負責選拔一個從機作為新的主機。

如果有什麼疑問,可以留言。

④ Redis怎麼做集群

為什麼集群?

通常,為了提高網站響應速度,總是把熱點數據保存在內存中而不是直接從後端資料庫中讀取。Redis是一個很好的Cache工具。大型網站應用,熱點數據量往往巨大,幾十G上百G是很正常的事兒,在這種情況下,如何正確架構Redis呢?

首先,無論我們是使用自己的物理主機,還是使用雲服務主機,內存資源往往是有限制的,scale up不是一個好辦法,我們需要scale out橫向可伸縮擴展,這需要由多台主機協同提供服務,即分布式多個Redis實例協同運行。

其次,目前硬體資源成本降低,多核CPU,幾十G內存的主機很普遍,對於主進程是單線程工作的Redis,只運行一個實例就顯得有些浪費。同時,管理一個巨大內存不如管理相對較小的內存高效。因此,實際使用中,通常一台機器上同時跑多個Redis實例。

方案

1.Redis官方集群方案 Redis Cluster

Redis Cluster是一種伺服器Sharding技術,3.0版本開始正式提供。

Redis Cluster中,Sharding採用slot(槽)的概念,一共分成16384個槽,這有點兒類pre sharding思路。對於每個進入Redis的鍵值對,根據key進行散列,分配到這16384個slot中的某一個中。使用的hash演算法也比較簡單,就是CRC16後16384取模。

Redis集群中的每個node(節點)負責分攤這16384個slot中的一部分,也就是說,每個slot都對應一個node負責處理。當動態添加或減少node節點時,需要將16384個槽做個再分配,槽中的鍵值也要遷移。當然,這一過程,在目前實現中,還處於半自動狀態,需要人工介入。

Redis集群,要保證16384個槽對應的node都正常工作,如果某個node發生故障,那它負責的slots也就失效,整個集群將不能工作。

為了增加集群的可訪問性,官方推薦的方案是將node配置成主從結構,即一個master主節點,掛n個slave從節點。這時,如果主節點失效,Redis Cluster會根據選舉演算法從slave節點中選擇一個上升為主節點,整個集群繼續對外提供服務。這非常類似前篇文章提到的Redis Sharding場景下伺服器節點通過Sentinel監控架構成主從結構,只是Redis Cluster本身提供了故障轉移容錯的能力。

Redis Cluster的新節點識別能力、故障判斷及故障轉移能力是通過集群中的每個node都在和其它nodes進行通信,這被稱為集群匯流排(cluster bus)。它們使用特殊的埠號,即對外服務埠號加10000。例如如果某個node的埠號是6379,那麼它與其它nodes通信的埠號是16379。nodes之間的通信採用特殊的二進制協議。

對客戶端來說,整個cluster被看做是一個整體,客戶端可以連接任意一個node進行操作,就像操作單一Redis實例一樣,當客戶端操作的key沒有分配到該node上時,Redis會返回轉向指令,指向正確的node,這有點兒像瀏覽器頁面的302 redirect跳轉。

Redis Cluster是Redis 3.0以後才正式推出,時間較晚,目前能證明在大規模生產環境下成功的案例還不是很多,需要時間檢驗。

2.Redis Sharding集群

Redis 3正式推出了官方集群技術,解決了多Redis實例協同服務問題。Redis Cluster可以說是服務端Sharding分片技術的體現,即將鍵值按照一定演算法合理分配到各個實例分片上,同時各個實例節點協調溝通,共同對外承擔一致服務。

多Redis實例服務,比單Redis實例要復雜的多,這涉及到定位、協同、容錯、擴容等技術難題。這里,我們介紹一種輕量級的客戶端Redis Sharding技術。

Redis Sharding可以說是Redis Cluster出來之前,業界普遍使用的多Redis實例集群方法。其主要思想是採用哈希演算法將Redis數據的key進行散列,通過hash函數,特定的key會映射到特定的Redis節點上。這樣,客戶端就知道該向哪個Redis節點操作數據。

慶幸的是,java redis客戶端驅動jedis,已支持Redis Sharding功能,即ShardedJedis以及結合緩存池的ShardedJedisPool。

Jedis的Redis Sharding實現具有如下特點:

1. 採用一致性哈希演算法(consistent hashing),將key和節點name同時hashing,然後進行映射匹配,採用的演算法是MURMUR_HASH。採用一致性哈希而不是採用簡單類似哈希求模映射的主要原因是當增加或減少節點時,不會產生由於重新匹配造成的rehashing。一致性哈希隻影響相鄰節點key分配,影響量小。

2.為了避免一致性哈希隻影響相鄰節點造成節點分配壓力,ShardedJedis會對每個Redis節點根據名字(沒有,Jedis會賦予預設名字)會虛擬化出160個虛擬節點進行散列。根據權重weight,也可虛擬化出160倍數的虛擬節點。用虛擬節點做映射匹配,可以在增加或減少Redis節點時,key在各Redis節點移動再分配更均勻,而不是只有相鄰節點受影響。

3.ShardedJedis支持keyTagPattern模式,即抽取key的一部分keyTag做sharding,這樣通過合理命名key,可以將一組相關聯的key放入同一個Redis節點,這在避免跨節點訪問相關數據時很重要。

⑤ 如何安裝Redis集群

創建目錄,配置文件
如何安裝Redis集群
修改配置文件
按照此方式修改7001~7005的配置文件,注意修改埠號。
如何安裝Redis集群
啟動各個實例
如何安裝Redis集群
創建集群
現在我們已經有了六個正在運行中的 Redis 實例, 接下來我們需要使用這些實例來創建集群, 並為每個節點編寫配置文件。
通過使用 Redis 集群命令行工具redis-trib,編寫節點配置文件的工作可以非常容易地完成redis-trib位於Redis 源碼的src文件夾中,它是一個 Ruby 程序,這個程序通過向實例發送特殊命令來完成創建新集群,檢查集群,或者對集群進行重新分片(reshared)等工作。
我們需要執行以下命令來創建集群:
[root@localhost src]# ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
/usr/bin/env: ruby: No such file or directory
如何安裝Redis集群
系統中沒有安裝ruby,所以報上面的錯誤。
先安裝ruby
[root@localhost yum.repos.d]# yum install ruby
[root@localhost yum.repos.d]# yum install rubygems
[root@localhost yum.repos.d]# gem install redis
Successfully installed redis-3.2.2
1 gem installed
Installing ri documentation for redis-3.2.2...
Installing RDoc documentation for redis-3.2.2...
如何安裝Redis集群
再次創建集群
[root@localhost src]# ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
Redis自動選擇主從
如何安裝Redis集群
連接集群
redis-cli 也可以作為集群的客戶端工具,要想訪問集群,只需連接任意一個redis實例即可。使用-c參數
[root@localhost bin]# ./redis-cli -c -p 7000
總結
set 命令寫數據,集群將數據寫到7001實例上,當你使用get命令獲取數據時,客戶端即自動切換到7001埠。
redis-cli對集群的支持是非常基本的, 所以它總是依靠 Redis 集群節點來將它轉向(redirect)至正確的節點。一個真正的(serious)集群客戶端應該做得比這更好: 它應該用緩存記錄起哈希槽與節點地址之間的映射(map), 從而直接將命令發送到正確的節點上面。

⑥ redis cluster集群部署

一.伺服器設置准備

1. 將6379埠在防火牆看開啟

[root@redis1 ~]#vi /etc/sysconfig/iptables

-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT

註:必須加在 REJECT 前面。

2.修改Selinux參數

[root@redis1 ~]#vi /etc/selinux/config

SELINUX=disabled

註:分別在其它幾個節點上同樣配置防火牆和 SELINUX。

二.安裝Redis

1.安裝系統組件

安裝gcc、tcl

yum install –y gcc-c++

yum install –y tcl

2.安裝redis

2.1.解壓 Redis 到/usr/local目錄下

[root@redis1 ~]# tar -zxvf /root/software/redis-3.2.6.tar.gz -C /usr/local/

2.2.在解壓後的目錄中進行 make 和 make test

[root@redis1 ~]# cd /usr/local/redis-3.2.6

[root@redis1 redis-3.2.6]# make

[root@redis1 redis-3.2.6]# make test

註:要檢查 make 和 make test 的結果是否都正確,如果報錯,針對性檢查並安裝系統缺少的組件。

2.3. 復制 redis-server 和 redis-cli 到/usr/local/bin 目錄下:

[root@redis1 redis-3.2.6]# cd src

[root@redis1 src]# cp redis-server /usr/local/bin/

[root@redis1 src]# cp redis-cli /usr/local/bin/

2.4驗證 Redis 安裝是否成功:

[root@redis1 ~]# redis-server

[root@redis1 ~]# redis-cli

註:安裝其它 5 台伺服器

三.配置集群模式

1.配置 redis.conf

1.1 配置 redis.conf

[root@redis1 ~]# mkdir /etc/redis

[root@redis1 ~]# cd /etc/redis

[root@redis ~]# vi redis.conf

port 6379

daemonize yes

cluster-enabled yes

cluster-config-file /etc/redis/nodes.conf

cluster-node-timeout 5000

appendonly yes

requirepass Ab123456

注 1:cluster-node-timeout 是集群中各節點相互通訊時,允許「失聯」的最大毫秒數,本演示

中配置的為 5 秒,如果超過 5 秒某個節點沒有向其它節點匯報成功,認為該節點掛了。

注 2:requirepass 是 Redis 訪問密碼,為了安全起見,該參數建議必須配置,從但客戶端

Jedis 版本必須使用 2.8.x 以上的版本,否則需要通過擴展 JedisCluster 來實現對密碼訪問的

支持。此外幾個 Redis 節點的密碼應該設置為相同的。

注 3:分別在其它幾個節點上創建與上面相同的 redis.conf 文件,內容也相同。

注 4:重啟/重建 Redis 集群時,必須刪除去/etc/redis/nodes.conf 文件。

1.2以次啟動所有節點

[root@redis1 ~]# redis-server /etc/redis/redis.conf

[root@redis2 ~]# redis-server /etc/redis/redis.conf

[root@redis3 ~]# redis-server /etc/redis/redis.conf

[root@redis4 ~]# redis-server /etc/redis/redis.conf

[root@redis5 ~]# redis-server /etc/redis/redis.conf

[root@redis6 ~]# redis-server /etc/redis/redis.conf

2.安裝 Redis 集群所需的 Ruby 工具

2.1安裝 Ruby 工具:

Redis 集群需要藉助其它工具將相關節點加入到 Cluster 中,而這個工具是由 Redis 提供

一個名為 redis-trib.rb 的 ruby 腳本,否則接下來創建 cluster 會失敗。

[root@redis1 ~]# cd /usr/local/redis-3.2.6/src

[root@redis1 src]# yum install –y ruby

[root@redis1 src]# yum install -y rubygems

[root@redis1 src]# gem install redis --version 3.0.0

[root@redis1 src]# gem list

2.2 設置 Ruby 連接 Redis 的密碼:

[root@redis1 ~]# vi /usr/lib/ruby/gems/1.8/gems/redis-3.0.0/lib/redis/client.rb

:password => "Ab123456"

註:分別在其它幾個節點上用同樣的方式安裝好 Ruby 工具

3 利用redis-trib.rb 創建 Redis集群

3. 1. 在 src 目錄下運行以下腳本:

[root@redis1 ~]# cd /usr/local/redis-3.2.6/src

[root@redis1 src]# ./redis-trib.rb create --replicas 1 10.50.130.101:6379 10.50.130.102:6379

10.50.130.103:6379 10.50.130.104:6379 10.50.130.105:6379 10.50.130.106:6379

注 1:只需在其中某個個節點執行以上腳本(本例在第一個節點執行)。

注 2:利用 redis-trib 創建 Cluster,只需要操作一次即可,假設系統關機、重啟,把所有的

節點全部關閉之後,下次重啟後,即自動進入 Cluster 模式,不用現次執行 redis-trib.rb cteate

命令。

3.2查看 Cluster 進程:

[root@redis1 ~]# ps -ef|grep redis

[root@redis2 ~]# ps -ef|grep redis

[root@redis3 ~]# ps -ef|grep redis

[root@redis4 ~]# ps -ef|grep redis

[root@redis5 ~]# ps -ef|grep redis

[root@redis6 ~]# ps -ef|grep redis

3.3 查看節點屬性(Master/Slave)

[root@redis1 ~]# cd /usr/local/redis-3.2.6/src

[root@redis1 src]# ./redis-trib.rb check 10.50.130.101:6379

[root@redis1 src]# ./redis-trib.rb check 10.50.130.102:6379

[root@redis1 src]# ./redis-trib.rb check 10.50.130.103:6379

[root@redis1 src]# ./redis-trib.rb check 10.50.130.104:6379

[root@redis1 src]# ./redis-trib.rb check 10.50.130.105:6379

[root@redis1 src]# ./redis-trib.rb check 10.50.130.106:6379

3.4查看節點/集群信息

redis-cli 客戶端登錄到任一個節點,查看:

4.Jedis 測試 Redis 集群

⑦ 使用 redis-cli 搭建 Redis 集群

參考: Redis 集群教程

redis.conf 文件中包含很多信息,如:埠號、持久化方式、持久化的文件等等。

使用寫入了不同埠號的配置文件就可以啟動多個 Redis 實例。
下面是一個最少選項的集群的配置文件:

文件中的 cluster-enabled 選項用於開實例的集群模式, 而 cluster-conf-file 選項則設定了保存節點配置文件的路徑, 默認值為 nodes.conf 。節點配置文件無須人為修改, 它由 Redis 集群在啟動時創建, 並在有需要時自動進行更新。

要讓集群正常運作至少需要三個主節點,不過在剛開始試用集群功能時, 強烈建議使用六個節點: 其中三個為主節點, 而其餘三個則是各個主節點的從節點。

首先, 讓我們進入一個新目錄, 並創建六個以埠號為名字的子目錄, 稍後我們在將每個目錄中運行一個 Redis 實例: 命令如下:

在文件夾 7000 至 7005 中, 各創建一個 redis.conf 文件, 文件的內容可以使用上面的示例配置文件, 但記得將配置中的 port 和 cluster-conf-file 中的埠號數字 從 7000 改為與文件夾名字相同的號碼。不同的集群節點要使用不同的 cluster-conf-file 。
配置文件的路徑是可以自定義的。創建完畢後分別啟動一個實例。

網上看到的教程,包括參考的官方文檔里的文章,大多是使用以下方式創建集群。

這個命令在這里用於創建一個新的集群, 選項–replicas 1 表示我們希望為集群中的每個主節點創建一個從節點。
之後跟著的其他參數則是這個集群實例的地址列表,3 個 master 3 個 slave redis-trib 會列印出一份預想中的配置給你看,如果你覺得沒問題的話,就可以輸入 yes,redis-trib 就會將這份配置應用到集群當中,讓各個節點開始互相通訊,最後可以得到如下信息:

這表示集群中的 16384 個槽都有至少一個主節點在處理,集群運作正常。

但是在 Redis 的 github 倉庫 中看到,該文件已經不建議使用。

我在 手把手教你實現 Docker 部署 Redis 集群 的評論中看到, 現在 redis-cli --cluster 命令已經可以創建集群,分配槽,分配主從伺服器了 ,於是使用以下命令了解到相關的命令。

可以看到,命令的組成形式和舊方式是一致的。

可以看到執行命令後,redis 客戶端做了以下工作:

輸入 yes 後,redis 客戶端做了以下工作:

集群搭建完畢。

因為 Redis Cluster 默認要求所有的槽位被覆蓋,可以通過修改 cluster-require-full-coverage yes 配置來改變該行為。
CLUSTERDOWN The cluster is down in redis 這里的回答中提到:我們可以使用 N 個Master 和 N+1 個 Slave,正常情況下多餘的一個實例作為隨機一個 Master 的 Slave,一旦有實例宕機,可以迅速頂替,以保證每個主節點總是有至少一個從節點保持數據同步。

ps:搜索命令行的輸出時,才看到 深入理解Redis系列之集群環境搭建 這篇文章,有時候搜索的關鍵詞不合適容易走彎路啊……

⑧ 玩轉Redis的高可用(主從、哨兵、集群)

所謂的高可用,也叫 HA(High Availability),是分布式系統架構設計中必須考慮的因素之一,它是保證系統SLA的重要指標。Redis 高可用的主要有三種模式: 主從模式 哨兵模式和集群模式

Redis 提供了 Redis 提供了復制(replication)功能,當一台 redis 資料庫中的數據發生了變化,這個變化會被自動地同步到其他的 redis 機器上去。

Redis 多機器部署時,這些機器節點會被分成兩類,一類是主節點(master 節點),一類是從節點(slave 節點)。一般 主節點可以進行讀、寫操作 ,而 從節點只能進行讀操作 。一個主節點可以有多個從節點,但是一個從節點只會有一個主節點,也就是所謂的 一主多從結構

· 支持主從復制,主機會自動將數據同步到從機,可以進行讀寫分離;

· Master 是以非阻塞的方式為主 Slaves 提供服務。所以在 Master-Slave 同步期間,客戶端仍然可以提交查詢或修改請求;

· Slave 同樣是以非阻塞的方式完成數據同步。在同步期間,如果有客戶端提交查詢請求,Redis 則返回同步之前的數據。

· Redis 不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的 IP 才能恢復;

· 主機宕機,宕機前有部分數據未能及時同步到從機,切換 IP 後面還會引入數據不一致的問題,降低了系統的可用性;

· Redis 較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜;

· Redis 的主節點和從節點中的數據是一樣的,降低的內存的可用性


實際生產中,我們優先考慮哨兵模式。這種模式下,master 宕機,哨兵會自動選舉 master 並將其他的 slave 指向新的 master。

在主從模式下,redis 同時提供了哨兵命令 redis-sentinel ,哨兵是一個獨立的進程,作為進程,它會獨立運行。其原理是哨兵進程向所有的 redis 機器人發送命令,等待 Redis 伺服器響應,從而監控運行的多個 Redis 實例。一般為了便於決策選舉,使用 奇數個哨兵 。多個哨兵構成一個哨兵集群,哨兵直接也會相互通信,檢查哨兵是否正常運行,同時發現 master 戰機哨兵之間會進行決策選舉新的 master


哨兵模式的作用:

· 通過發送命令,讓 Redis 伺服器返回監控其運行狀態,包括主伺服器和從伺服器;

· 然而一個哨兵進程對 Redis 伺服器進行監控,也可能會出現問題,為此,我們可以使用多個哨兵進行監控。各個哨兵之間還會進行監控,這樣就形成了多種哨兵模式。

哨兵很像 kafka 集群中的 zookeeper 的功能。

· 哨兵模式是基於主從模式的,所有主從的優點,哨兵模式都具有。

· 主從可以自動切換,系統更健壯,可用性更高。

· 具有主從模式的缺點,每台機器上的數據是一樣的,內存的可用性較低。

· Redis 較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜。


Redis 集群模式本身沒有使用一致性 hash 演算法,而是使用 slots 插槽

Redis 哨兵模式基本已經可以實現高可用,讀寫分離 ,但是在這種模式下每台 Redis 伺服器都存儲相同的數據,很浪費內存,所以在 redis3.0 上加入了 Cluster 集群模式,實現了 Redis 的分布式存儲,對數據進行分片,也就是說每台 Redis 節點上存儲不同的內容;每個節點都會通過集群匯流排(cluster bus),與其他的節點進行通信。 通訊時使用特殊的埠號,即對外服務埠號加 10000。例如如果某個 node 的埠號是 6379,那麼它與其它 nodes 通信的埠號是 16379。nodes 之間的通信採用特殊的二進制協議。


對客戶端來說,整個 cluster 被看做是一個整體,客戶端可以連接任意一個 node 進行操作,就像操作單一 Redis 實例一樣, 當客戶端操作的時候 key 沒有分配到該 node 上時,Redis 會返回轉向指令,指向正確的 node,這有點兒像瀏覽器頁面的 302 redirect 跳轉。

根據官方推薦,集群部署至少要 3 台以上的 master 節點,最好使用 3 主 3 從六個節點的模式。

在 Redis 的每一個節點上,都有這么兩個東西, 一個是插槽(slot),它的的取值范圍是:0-16383, 可以從上面 redis-trib.rb 執行的結果看到這 16383 個 slot 在三個 master 上的分布。還有一個就是 cluster,可以理解為是一個集群管理的插件,類似的哨兵。

當我們的存取的 Key 到達的時候,Redis 會根據 crc16 的演算法對計算後得出一個結果,然後把結果和 16384 求余數,這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽,通過這個值,去找到對應的插槽所對應的節點,然後直接自動跳轉到這個對應的節點上進行存取操作。

為了保證高可用, redis-cluster 集群引入了主從模式 ,一個主節點對應一個或者多個從節點。當其它主節點 ping 主節點 master 1 時,如果半數以上的主節點與 master 1 通信超時,那麼認為 master 1 宕機了,就會啟用 master 1 的從節點 slave 1,將 slave 1 變成主節點繼續提供服務。

如果 master 1 和它的從節點 slave 1 都宕機了,整個集群就會進入 fail 狀態,因為集群的 slot 映射不完整。 如果集群超過半數以上的 master 掛掉,無論是否有 slave,集群都會進入 fail 狀態。

redis-cluster 採用去中心化的思想 ,沒有中心節點的說法,客戶端與 Redis 節點直連,不需要中間代理層,客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可。

對 redis 集群的擴容就是向集群中添加機器,縮容就是從集群中刪除機器,並重新將 16383 個 slots 分配到集群中的節點上(數據遷移)。

擴縮容也是使用集群管理工具 redis-tri.rb。

擴容時,先使用 redis-tri.rb add-node 將新的機器加到集群中,這是新機器雖然已經在集群中了,但是沒有分配 slots,依然是不起做用的。在使用 redis-tri.rb reshard 進行分片重哈希(數據遷移),將舊節點上的 slots 分配到新節點上後,新節點才能起作用。

縮容時,先要使用 redis-tri.rb reshard 移除的機器上的 slots,然後使用 redis-tri.rb add-del 移除機器。

採用去中心化思想,數據按照 slot 存儲分布在多個節點,節點間數據共享,可動態調整數據分布;

可擴展性:可線性擴展到 1000 多個節點,節點可動態添加或刪除;

高可用性:部分節點不可用時,集群仍可用。通過增加 Slave 做 standby 數據副本,能夠實現故障自動 failover,節點之間通過 gossip 協議交換狀態信息,用投票機制完成 Slave 到 Master 的角色提升;

降低運維成本,提高系統的擴展性和可用性。

1.Redis Cluster 是無中心節點的集群架構,依靠 Goss 協議(謠言傳播)協同自動化修復集群的狀態。但 GosSIp 有消息延時和消息冗餘的問題,在集群節點數量過多的時候,節點之間需要不斷進行 PING/PANG 通訊,不必須要的流量佔用了大量的網路資源。雖然 Reds4.0 對此進行了優化,但這個問題仍然存在。

2.數據遷移問題

Redis Cluster 可以進行節點的動態擴容縮容,這一過程,在目前實現中,還處於半自動狀態,需要人工介入。在擴縮容的時候,需要進行數據遷移。

而 Redis 為了保證遷移的一致性,遷移所有操作都是同步操作 ,執行遷移時,兩端的 Redis 均會進入時長不等的阻塞狀態,對於小 Key,該時間可以忽略不計,但如果一旦 Key 的內存使用過大,嚴重的時候會接觸發集群內的故障轉移,造成不必要的切換。

主從模式:master 節點掛掉後,需要手動指定新的 master,可用性不高,基本不用。

哨兵模式:master 節點掛掉後,哨兵進程會主動選舉新的 master,可用性高,但是每個節點存儲的數據是一樣的,浪費內存空間。數據量不是很多,集群規模不是很大,需要自動容錯容災的時候使用。

集群模式:數據量比較大,QPS 要求較高的時候使用。 Redis Cluster 是 Redis 3.0 以後才正式推出,時間較晚,目前能證明在大規模生產環境下成功的案例還不是很多,需要時間檢驗。

⑨ Redis的哨兵模式和集群模式

原文地址: https://www.cnblogs.com/itplay/p/11098990.html

哨兵模式 #

哨兵模式是redis高可用的實現方式之一

使用一個或者多個哨兵(Sentinel)實例組成的系統,對redis節點進行監控,在主節點出現故障的情況下,能將從節點中的一個升級為主節點,進行故障轉義,保證系統的可用性。

哨兵們是怎麼感知整個系統中的所有節點(主節點/從節點/哨兵節點)的 #

首先主節點的信息是配置在哨兵(Sentinel)的配置文件中

哨兵節點會和配置的主節點建立起兩條連接命令連接和訂閱連接

哨兵會通過命令連接每10s發送一次INFO命令,通過INFO命令,主節點會返回自己的run_id和自己的從節點信息

哨兵會對這些從節點也建立兩條連接命令連接和訂閱連接

哨兵通過命令連接向從節點發送INFO命令,獲取到他的一些信息

a. run_id

b. role

c. 從伺服器的復制偏移量 offset

d. 等

因為哨兵對與集群中的其他節點(主從節點)當前都有兩條連接,命令連接和訂閱連接

a. 通過命令連接向伺服器的_sentinel:hello頻道發送一條消息,內容包括自己的ip埠、run_id、配置紀元(後續投票的時候會用到)等

b. 通過訂閱連接對伺服器的_sentinel:hello頻道做了監聽,所以所有的向該頻道發送的哨兵的消息都能被接受到

c. 解析監聽到的消息,進行分析提取,就可以知道還有那些別的哨兵服務節點也在監聽這些主從節點了,更新結構體將這些哨兵節點記錄下來

d. 向觀察到的其他的哨兵節點建立命令連接----沒有訂閱連接

哨兵模式下的故障遷移 #

主觀下線

哨兵(Sentinel)節點會每秒一次的頻率向建立了命令連接的實例發送PING命令,如果在down-after-milliseconds毫秒內沒有做出有效響應包括(PONG/LOADING/MASTERDOWN)以外的響應,哨兵就會將該實例在本結構體中的狀態標記為SRI_S_DOWN主觀下線

客觀下線

當一個哨兵節點發現主節點處於主觀下線狀態是,會向其他的哨兵節點發出詢問,該節點是不是已經主觀下線了。如果超過配置參數quorum個節點認為是主觀下線時,該哨兵節點就會將自己維護的結構體中該主節點標記為SRI_O_DOWN客觀下線

詢問命令SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <run_id>

參數意義

ip/port當前認為下線的主節點的ip和埠

current_epoch配置紀元

run_id*標識僅用於詢問是否下線

有值標識該哨兵節點希望對方將自己設置為leader

詢問時用*,選舉時用run_id

leader選舉

在認為主節點客觀下線的情況下,哨兵節點節點間會發起一次選舉,命令還是上面的命令SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <run_id>,只是run_id這次會將自己的run_id帶進去,希望接受者將自己設置為主節點。如果超過半數以上的節點返回將該節點標記為leader的情況下,會有該leader對故障進行遷移

故障遷移

在從節點中挑選出新的主節點

a. 通訊正常

b. 優先順序排序

c. 優先順序相同是選擇offset最大的

將該節點設置成新的主節點 SLAVEOF no one,並確保在後續的INGO命令時,該節點返回狀態為master

將其他的從節點設置成從新的主節點復制, SLAVEOF命令

將舊的主節點變成新的主節點的從節點

優缺點 #

優點

高可用,在主節點故障時能實現故障的轉移

缺點:好像沒辦法做到水平拓展,如果內容很大的情況下

集群模式 #

官方提供的分布式方案(槽指派/重新分片/故障轉移)

集群內的節點,都會有個數據結構存儲整個集群內的節點信息

//整體structclusterState{clusterNode *mySelf;  ....  dict *nodes;//集群內的所有節點}// 單個節點structclusterNode{charname[];charip[];intport;  clusterLink *link;//保存節點間,連接的信息intflags;//狀態標記}//節點間連接的信息structclusterLink{mstime_tctime;//創建時間intfd;//tcp套接字描述符sds sndbuf;// 輸出緩存區sds rcvbuf;//輸入緩存區structclusterNode*node;}

槽指派 #

redis集群可以被分為16384個槽,只有這些槽全被指派了處理的節點的情況下,集群的狀態才能是上線狀態(ok)

操作redis集群的時候,將key作為參數,就可以計算出對應的處理槽上,所以存儲等操作都應該在該槽對應的節點上。通過這種方式,可以完美的實現集群存儲的水平拓展。

defslot_number(key):returnCRC16(key) &16383//得到的結果就是槽的序號

槽指派的信息是怎麼存儲的

structclusterState{clusterNode *slots[16384] }structclusterNode{unsignedcharslots[16384/8]}

通過上面兩個結構體中的定義可以看出,槽指派的信息是分了兩種方式,保存在結構體裡面。

分兩種存儲的好處

1. 如果需要判斷某一個節點負責的槽,只需要獲取方式二中的數組做判斷就可以

2.如果找某個槽是哪個節點負責,只需要獲取方式一的列表,一查就知道

重新分片 #

將已經指派給節點的槽,重新執行新的節點。

故障轉移 #

發現故障節點

集群內的節點會向其他節點發送PING命令,檢查是否在線

如果未能在規定時間內做出PONG響應,則會把對應的節點標記為疑似下線

集群中一半以上負責處理槽的主節點都將主節點X標記為疑似下線的話,那麼這個主節點X就會被認為是已下線

向集群廣播主節點X已下線,大家收到消息後都會把自己維護的結構體里的主節點X標記為已下線

從節點選舉

當從節點發現自己復制的主節點已下線了,會向集群裡面廣播一條消息,要求所有有投票權的節點給自己投票(所有負責處理槽的主節點都有投票權)

主節點會向第一個給他發選舉消息的從節點回復支持

當支持數量超過N/2+1的情況下,該從節點當選新的主節點

故障的遷移

新當選的從節點執行 SLAVEOF no one,修改成主節點

新的主節點會撤銷所有已下線的老的主節點的槽指派,指派給自己

新的主節點向集群發送命令,通知其他節點自己已經變成主節點了,負責哪些槽指派

新的主節點開始處理自己負責的槽的命令

集群模式和哨兵模式的區別 #

哨兵模式監控權交給了哨兵系統,集群模式中是工作節點自己做監控

哨兵模式發起選舉是選舉一個leader哨兵節點來處理故障轉移,集群模式是在從節點中選舉一個新的主節點,來處理故障的轉移

轉自:https://www.jianshu.com/p/d6d2325a5ec7

⑩ 怎麼連接redis集群 使用jedis連接單機和集群redis的兩種方式

第一:非集群狀態下

非集群狀態下用Jedis獲取Redis連接,得到Jedis對象即可,一共有兩種:

1.利用Jedis構造器,僅限用於測試,在實際項目中肯定是用JedisPool。
Jedis(String host);

Jedis(String host , int port);

2.利用JedisPool

主要是利用Jedis jedis=jedisPool.getResource();

JedisPool有N多個構造器,常用的構造器參數有GenericObjectPoolConfig poolConfig,String host,int port,int timeout,String password,創建GenericObjectPoolConfig對象時我們一般用其子類JedisPoolConfig (redis.clients.jedis.JedisPoolConfig),timeout是連接redis伺服器的超時時間,以毫秒為單位,一般設置為0,如果不設為0,則不可設置太小,如果設成1、2,那麼可能因為網路原因在1毫秒、2毫秒之內沒有連上伺服器而報錯。見下例:
[java] view plain
public static void main(String[] args) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
// 最大連接數
poolConfig.setMaxTotal(2);
// 最大空閑數
poolConfig.setMaxIdle(2);
// 最大允許等待時間,如果超過這個時間還未獲取到連接,則會報JedisException異常:
// Could not get a resource from the pool
poolConfig.setMaxWaitMillis(1000);
JedisPool pool = new JedisPool(poolConfig, "192.168.83.128", 6379, 0, "123");
Jedis jedis = null;
try {
for (int i = 0; i < 5; i++) {
jedis = pool.getResource();
jedis.set("foo" + i, "bar" + i);
System.out.println("第" + (i + 1) + "個連接, 得到的值為" + jedis.get("foo" + i));
// 用完一定要釋放連接
jedis.close();
}
} finally {
pool.close();
}
}
如上,創建出一個JedisPool對象,然後調用其getResource()方法獲取redis連接即可,之後就可以調用Jedis API操作redis了。jedis連接用完要釋放即close,如果不close,則產生的連接會越來越多,當達到了最大連接數,再想獲得連接,就會等待,當超過了最大等待時間後就會報異常。
第二:集群狀態下

集群狀態下用Jedis獲取redis連接,是得到JedisCluster對象,之後對redis進行操作都是用此對象的方法進行的:

[java] view plain
public static void main(String[] args) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
// 最大連接數
poolConfig.setMaxTotal(1);
// 最大空閑數
poolConfig.setMaxIdle(1);
// 最大允許等待時間,如果超過這個時間還未獲取到連接,則會報JedisException異常:
// Could not get a resource from the pool
poolConfig.setMaxWaitMillis(1000);
Set<HostAndPort> nodes = new LinkedHashSet<HostAndPort>();
nodes.add(new HostAndPort("192.168.83.128", 6379));
nodes.add(new HostAndPort("192.168.83.128", 6380));
nodes.add(new HostAndPort("192.168.83.128", 6381));
nodes.add(new HostAndPort("192.168.83.128", 6382));
nodes.add(new HostAndPort("192.168.83.128", 6383));
nodes.add(new HostAndPort("192.168.83.128", 6384));
JedisCluster cluster = new JedisCluster(nodes, poolConfig);
String name = cluster.get("name");
System.out.println(name);
cluster.set("age", "18");
System.out.println(cluster.get("age"));
try {
cluster.close();
} catch (IOException e) {
e.printStackTrace();
}
}
用集群時,好像沒有辦法設置集群的參數,比如最大連接數,雖然在創建JedisCluster 對象時傳了JedisPoolConfig對象進去,但是JedisPoolConfig對象中的設置是不生效的。

熱點內容
內置存儲卡可以拆嗎 發布:2025-05-18 04:16:35 瀏覽:333
編譯原理課時設置 發布:2025-05-18 04:13:28 瀏覽:377
linux中進入ip地址伺服器 發布:2025-05-18 04:11:21 瀏覽:611
java用什麼軟體寫 發布:2025-05-18 03:56:19 瀏覽:31
linux配置vim編譯c 發布:2025-05-18 03:55:07 瀏覽:107
砸百鬼腳本 發布:2025-05-18 03:53:34 瀏覽:942
安卓手機如何拍視頻和蘋果一樣 發布:2025-05-18 03:40:47 瀏覽:739
為什麼安卓手機連不上蘋果7熱點 發布:2025-05-18 03:40:13 瀏覽:802
網卡訪問 發布:2025-05-18 03:35:04 瀏覽:510
接收和發送伺服器地址 發布:2025-05-18 03:33:48 瀏覽:371