1. 程式人生 > >【redis篇】redis的單節點/叢集方式搭建及說明

【redis篇】redis的單節點/叢集方式搭建及說明

第一部分:安裝
1.單節點搭建

  • 2.解壓 tar xf xxx
  • 3.下載gcc,tcl 命令編譯器 yum -y install gcc tcl (命令名字別寫錯)
  • 4.編譯、建立目錄、拷貝make && make PREFIX=/opt/jw/redis install
  • 5.配置環變: EXPORT REDIS_PREFIX=/opt/jw/redis
  • 6.重新載入配置檔案: . /etc/profile
  • 7.測試 re+tab
  • 8.utils 目錄,服務指令碼安裝:./install_server.sh
  • 9.埠、例項、配置檔案、日誌、持久化資料目錄、執行路徑配置(安裝過程的選擇項,直接enter到底就行)
  • 10.enter執行 、ctrl+c退出(9中已說明,勿退出!)
  • 11.啟動客戶端:redis -cli (6379) // 預設6379 不用輸入
    幫助: 直接輸入 help
  • 12.使用幫助:
    utils目錄下: redis-cli -h
    redis-server -h

2.偽分散式搭建

  • 1.建立redis目錄: mkdir redis
  • 2.在redis目錄下分別建立3個埠目錄: 6380,6381,6382
    (不在配置檔案中寫他的目錄指定關係,直接在當前目錄下執行,持久化目錄)
  • 3.當前目錄下分別啟動3個例項:
    redis-server --port 6380
    redis-server --port 6381 --slaveof 127.0.0.1 6380
    redis-server --port 6382 --slaveof 127.0.0.1 6380
  • 4.主從演示 crud許可權,高可用
    演示如下:
    啟動6380埠主服務:redis-server --port 6380
    啟動6381埠從節點服務:redis-server --port 6381 --slaveof 127.0.0.1 6380
    啟動6382從節點服務:redis-server --port 6382 --slaveof 127.0.0.1 6380
    在6380、6381和6382節點分別啟動客戶端。redis-cli -p 638?
    6380主節點才有CRUD的操作。其他從節點的客戶端只有查詢的許可權。
    如果把6380主節點的服務掛點,則6381和6382的從節點就會六神無主,一直在嘗試連線。此時只需要在6381或者6382的客戶端上執行:slaveof no one
    讓6381/6382由從變成主。如果讓6381變成主,再通知6382。slaveof 127.0.0.1 6381 通知6382,作為6381的從。

偽分佈哨兵叢集搭建:

  • 1 拷貝src下的redis-sentinel至bin目錄下:
  • 2 啟動三個主從redis例項
  • 3 建立哨兵配置檔案目錄: mkdir sent
  • 4 目錄下建立啟動配置檔案病拷貝: vi s1.conf cp s2.conf s3.conf
    配置檔案內容:
    port 26380,1,2
    sentinel monitor jw 127.0.0.1 6380 2
  • 5 啟動sentinel讀取配置檔案:
    redis-sentinel s1.conf s2.conf s3.conf
  • 6 測試:演示自動提備
    說明:通過啟動6380/6381/6382分別為主、從、從。以及啟動s1.cong s2.conf s3.conf 哨兵監控主。
    通過主動殺死6380主節點,檢視6381 6382從節點的情況。發現,先連線異常,後來選出新的主節點。通過哨兵就可以看到選出的主是誰。以及在客戶端測試是否可以set操作。

3.全分散式搭建
備:全分散式只在node02上搭建。所有的操作都在一個節點的不同的客戶端視窗中進行。

  • 1.刪redis2.8下的bin目錄和檔案
    rm -fr /opt/jw/reids
  • 2.ftp上傳reids-cluster
    解壓裡面的redis 3.0
  • 3.make命令編譯拷貝到/opt/jw/redis下
    make && make PREFIX=/opt/jw/redis install
    成功後會有哨兵的提示。
  • 4.測試是否成功
    re+tab
  • 5.安裝ruby編譯環境
    yum -y install ruby rubygems
  • 6.redis-cluster目錄下安裝 redis gem 模組
    gem install --local redis-3.3.0.gem
  • 8.建立檔案目錄、主從節點並匹配埠
    指定3個主節點埠為7000 7001 7002 對應3個從節點埠為7003 7004 7005
    mkdir 7000 7001 7002 7003 7004 7005
  • 9.建立配置檔案redis.conf
    上述的目錄下新建redis.conf 裡面寫入:
    1 cluster-enabled yes
    2 port 7000
  • 10.分別啟動6個節點:
    redis-server redis.conf redis.conf
    ss -tanl | grep 700
  • 11.建立叢集,槽位認領
    在安裝目錄下的src中, 找到redis-trib.rb 這是rubby指令碼執行程式,完成redis3.0叢集建立
    ./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
  • 12.客戶端測試
    redis-cli -p 7000 -c
    127.0.0.1:7000> set k1 a
    -> Redirected to slot [12706] located at 127.0.0.1:7002 // a模值在槽位在7002上會跳轉到7002上。
    OK
    127.0.0.1:7002>

[[email protected] ~]# redis-cli -p 7001 -c
127.0.0.1:7001> get k1
-> Redirected to slot [12706] located at 127.0.0.1:7002
"a"
127.0.0.1:7002>

如果檢視需要在7002的客戶端上去拿。

測試,如果把7000掛掉,則7003會由備變成主。測試從7003的客戶端可以檢視7000上的資料。

第二部分:帶哨兵的叢集架構細節分析
叢集的分析:
由於單點故障/瓶頸,因此需多個節點負載
一變多(一致性<弱一致,最終一致性>)->可用性
最終一致性:一部分角色確認 -> 網路分割槽(腦裂)->過半機制
映象:資料容量不變
切片:橫向擴充套件
Cap原則

叢集分類
主從複製 Replication:映象:增刪改(主<退化到單節點>)查詢負載到從節點
高可用 Sentinel
分散式 twemproxy:切片
叢集 Cluster

主從複製 Replication

  • 1.一個Redis服務可以有多個該服務的複製品,這個Redis服務稱為Master,其他複製品稱為Slaves
  • 2.只要網路連線正常,Master會一直將自己的資料更新同步給Slaves,保持主從同步
  • 3.只有Master可以執行寫命令,Slaves只能執行讀命令

  • 4.從伺服器執行客戶端傳送的讀命令,比如GET、LRANGE、SMEMMBERS、HGET、ZRANGE等等

  • 5.客戶端可以連線Slaves執行讀請求,來降低Master的讀壓力。
  • 6.相對於無主模型,更加簡單. 主單點返回確認即可。Redis採用非同步主從同步資料,有瑕疵。另外主單點,使用哨兵解決單點故障。

主從複製建立

  • 每個redis例項預設自己是主,需要手動變更
    redis-server --slaveof <master-ip> <master-port>,配置當前服務稱為某Redis服務的Slave
    redis-server --port 6380 --slaveof 127.0.0.1 6379
    SLAVEOF host port命令,將當前伺服器狀態從Master修改為別的伺服器的Slave
    redis > SLAVEOF 192.168.1.1 6379,將伺服器轉換為Slave
    redis > SLAVEOF NO ONE ,將伺服器重新恢復到Master,不會丟棄已同步資料

    配置方式:啟動時,伺服器讀取配置檔案,並自動成為指定伺服器的從伺服器

主從複製問題

  • 一個Master可以有多個Slaves
  • Slave下線,只是讀請求的處理效能下降
  • Master下線,寫請求無法執行
  • 其中一臺Slave使用SLAVEOF no one命令成為Master,其它Slaves執行SLAVEOF命令指向這個新的Master,從它這裡同步資料
  • 以上過程是手動的,能夠實現自動,這就需要Sentinel哨兵,實現故障轉移Failover操作

監控 Monitoring
Sentinel會不斷檢查Master和Slaves是否正常
每一個Sentinel可以監控任意多個Master和該Master下的Slaves

Sentinel網路
監控同一個Master的Sentinel會自動連線,組成一個分散式的Sentinel網路,互相通訊並交換彼此關於被監視伺服器的資訊
右圖中3個Sentinel監控著S1和它的2個Slave
這裡寫圖片描述

伺服器下線

  • 當一個sentinel認為被監視的伺服器已經下線時,它會向網路中的其他Sentinel進行確認,判斷該伺服器是否真的已經下線
  • 如果下線的伺服器為主伺服器,那麼sentinel網路將對下線主伺服器進行自動故障轉移,通過將下線主伺服器的某個從伺服器提升為新的主伺服器,並讓其從伺服器轉為複製新的主伺服器,以此來讓系統重新回到上線的狀態

Sentinel 配置檔案
至少包含一個監控配置選項,用於指定被監控Master的相關資訊
指定sentinel埠號:
port 26380(Sentinel預設埠號為26379)
Sentinel monitor<name><ip><port><quorum>
例如:sentinel monitor mymaster 127.0.0.1 63802
監視mymaster的主伺服器,伺服器ip和埠,將這個主伺服器判斷為下線失效至少需要2個Sentinel同意,如果多數Sentinel同意才會執行故障轉移
Sentinel會根據Master的配置自動發現Master的Slaves

Sentinel 配置舉例
執行以下兩條命令,將建立兩個監視主伺服器s1的sentinel例項:
$redis-sentinel sentinel1.conf
$redis-sentinel sentinel2.conf

其中sentinel1.conf的內容為:
port 26379
Sentinel monitor s1 127.0.0.1 6380 1
sentinel2.conf的內容為:
Port 26380
Sentinel monitor s1 127.0.0.1 6379 2

Sentinel 總結

  • 主從複製,解決了讀請求的分擔,從節點下線,會使得讀請求能力有所下降
    Master只有一個,寫請求單點問題
  • Sentinel會在Master下線後自動執行Failover操作,提升一臺Slave為Master,並讓其他Slaves重新成為新Master的Slaves
  • 主從複製+哨兵Sentinel只解決了讀效能和高可用問題,但是沒有解決寫效能問題

第三部分:全分散式叢集架構細節分析
在redis3.0版本之前推特公司自己研發了叢集版redis。主要的是利用代理服務。
這裡寫圖片描述
分析:

  • Twitter開發的代理伺服器,他相容Redis和Memcached,允許使用者將多個redis伺服器新增到一個伺服器池(pool)裡面,並通過使用者選擇的雜湊函式和分佈函式,將來自客戶端的命令請求分發給伺服器池中的各個伺服器
  • 通過使用twemproxy我們可以將資料庫分片到多臺redis伺服器上面,並使用這些伺服器來分擔系統壓力以及資料庫容量:在伺服器硬體條件相同的情況下,對於一個包含N臺redis伺服器的池來說,池中每臺平均1/N的客戶端命令請求
  • 向池裡新增更多伺服器可以線性的擴充套件系統處理命令請求的能力,以及系統能夠儲存的資料量
    代理存在單點故障問題,將key採用hash取模方式分發到不同節點。但是如果加節點還需要重新對取模演算法調整。而且如果資料特殊,同一個key過多,會造成資料傾斜。造成負載不均衡。但是資料遷移不好做。

redis3.0版本正式版
簡介:採用取模方式但是優化的地方在於,採用槽位的思想
一共有16384個槽位(slot),然後這些槽位被幾個幾點分割。比如節點1從0-1000。節點2從1001-1600,節點3從16001-16383.這樣,如果增加了節點,只需要把操作再分配以下就可以了。不想推特的做法,還需要重新計算取模的方式。在資料遷移、傾斜的時候都會因為之前知道key和槽位的關係。就會好辦些。

Redis叢集分片

  • 叢集將整個資料庫分為16384個槽位slot,所有key都屬於這些slot(槽位)中的一個,key的槽位計算公式為slot_number=crc16(key)%16384,其中crc16為16位的迴圈冗餘校驗和函式
  • 叢集中的每個主節點都可以處理0個至16383個槽,當16384個槽都有某個節點在負責處理時,叢集進入上線狀態,並開始處理客戶端傳送的資料命令請求
  • 舉例
    三個主節點7000、7001、7002平均分片16384個slot槽位
    節點7000指派的槽位為0到5060
    節點7001指派的槽位為5461到10022
    節點7002指派的槽位為10923到16383
    節點7003指派的槽位為5061到5460,10023-10922

Redis叢集節點複製

  • Redis叢集的每個節點都有兩種角色可選:主節點master node、從節點slave node。其中主節點用於儲存資料,而從節點則是某個主節點的複製品
  • 當用戶需要處理更多讀請求的時候,新增從節點可以擴充套件系統的讀效能,因為Redis叢集重用了單機Redis複製特性的程式碼,所以叢集的複製行為和我們之前介紹的單機複製特性的行為是完全一樣的

Redis叢集故障轉移

  • Redis叢集的主節點內建了類似Redis Sentinel的節點故障檢測和自動故障轉移功能,當叢集中的某個主節點下線時,叢集中的其他線上主節點會注意到這一點,並對已下線的主節點進行故障轉移
  • 叢集進行故障轉移的方法和Redis Sentinel進行故障轉移的方法基本一樣,不同的是,在叢集裡面,故障轉移是由叢集中其他線上的主節點負責進行的,所以叢集不必另外使用Redis Sentinel

Redis叢集Redirect轉向

  • 由於Redis叢集無中心節點(無主模型),請求會發給任意主節點
    • 主節點只會處理自己負責槽位的命令請求,其它槽位的命令請求,該主節點會返回客戶端一個轉向錯誤
    • 客戶端根據錯誤中包含的地址和埠重新向正確的負責的主節點發起命令請求

redis叢集的缺點:
不支援類似MR的suffle的過程。比如不同節點都有相同set集合。redis讓2者不可以匯聚,既不可以交併差操作。群杜絕了它們之間對的溝通。防止影響其負載均衡的能力。

第四部分:原理及簡介
1.redis的引入
介紹在資料沒出來前都是通過檔案系統的儲存資料的。但是存在如果檔案中的資料過多,讀取過慢情況,因此產生了資料庫的概念。有2大知識點支援資料的發展。第一是:DP(datapage),有很多的DP,通過切片的方式儲存大檔案的資料。每個DP是4k。(4K,是因為磁碟的最小單位是扇區,每個扇區最大是512個位元組)。比如匯入資料庫的檔案,都是被切割成很多4k的小塊儲存的。
2.redis簡單介紹

  • 2.1.開源的(BSD協議),(genu)使用ANSI C 編寫,基於記憶體的且支援持久化,高效能的Key-Value的NoSQL資料庫

  • 2.2.redis把資料分為冷資料和熱資料。 熱資料放在記憶體裡,冷資料放在磁碟中。客戶端訪問伺服器,如果第一次第一,記憶體中沒有此資料。伺服器讀取磁碟上表結構的資料。把資料放入記憶體中,下次訪問直接走記憶體。redis機制中,會對資料設定過期時間。然後定期查詢,時間輪循的方式。(類似的記憶體資料庫, NameNode,DataNode,memcache)。其中redis比memcache火的原因,mencache只支援String型別,而redis支援海量型別。

  • 2.3.支援資料結構型別豐富,有如 字串(strings), 雜湊(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與範圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。
    豐富的支援主流語言的客戶端,C、C++、Python、Erlang、R、C#、Java、PHP、Objective-C、Perl、Ruby、Scala、Go、JavaScript

  • 2.4.用途:快取(StackOverFlow)、資料庫(微博)、訊息中介軟體(微博)

  • 2.5. 世界上任何資料型別都可以由以下幾種(組合)方式表達
    a=1 a=k
    a=(1,3,98)
    a={x=11,w=88}

  • 2.6.視覺化客戶端
    RedisDesktopManager

3.Nosql分類:
這裡寫圖片描述