當前位置:首頁 » 文件管理 » 社區緩存方案

社區緩存方案

發布時間: 2023-07-13 00:18:55

㈠ Ceph 分層緩存--Tiering Cache

原文來自Ceph官方文檔: CACHE TIERING

部分摘抄自Ceph中國社區翻譯文檔: 分級緩存

    分層緩存為ceph客戶端中的某些存放在存儲層的數據提供更好的IO性能。分級緩存需創建一個由高速而昂貴存儲設備(如 SSD )組成的存儲池、作為緩存層,以及一個相對低速/廉價設備組成的後端存儲池(或糾刪碼編碼的)、作為經濟存儲層。Ceph 的對象處理器決定往哪裡存儲對象,分級代理決定何時把緩存內的對象刷回後端存儲層;所以緩存層和後端存儲層對 Ceph 客戶端來說是完全透明的。

    緩存代理層管理著數據在緩存層和存儲層之間的自動遷移。但是, 管理員也可以通過配置來干預遷移規則, 下面是對兩個主要場景的介紹:

Writeback Mode: 當管理員將緩存層配置成回寫模式, Ceph客戶端將數據寫入緩存層,並接收返回的ACK。同時,寫入緩存層的數據遷移到存儲層,  然後從緩存層刷掉。 直觀的看, 緩存層在存儲層之前。 當Ceph客戶端需要存在於存儲層的數據時, 緩存層代理會把這些數據遷移到緩存層,然後再發往 Ceph 客戶端。因此,Ceph 客戶端將與緩存層進行 I/O 操作,直到數據不再被讀寫。此模式對於易變數據來說較理想(如照片/視頻編輯、事務數據等)。

Read-proxy Mode: 這個模式將使用一些已經存在於緩存層的數據,但是,如果數據不在緩存層,請求將被代理轉發到底層。這個模式對於從回寫模式過渡到禁用緩存非常有用的, 因為它潤需負載一直工作到緩存乾涸,不再向緩存添加任何數據。

  如果負載過多,分層緩存會降低性能。用戶在使用以下特性時需要極其謹慎。

Workload dependent : 緩存是否能提升性能,高度依賴於負載能力。因為將數據移入或移除緩存會導致額外的開銷,它只在對數據集的訪問有大的偏離時有影響。例如, 眾多的請求訪問小數量的objects,這時,你的緩存池需要非常大,才能在處理所有請求時,避免數據過渡。

Difficult to benchmark : 用戶使用評測性能時,大部分的關於分層緩存bechmarks測試結果,將會是一個糟糕的結果。其中部分原因是很少的bechmarks傾斜於一組小的對象集合的請求 , 這會使緩存經過很長時間後才能「活躍起來」,並且這種「活躍起來」會導致高昂的開銷。

Usually slower : 對於並沒有友好使用分級緩存的工作負載,性能普遍低於一個沒使用分級緩存的普通rados池。

librados object enumeration : 對於librados級別的枚舉對象API並不能連貫存在在這種情況中(The librados-level object enumeration API is not meant to be coherent in the presence of the case)。 如果你的應用直接使用rados,並且依賴於枚舉對象,分級緩存不能向期待的那樣工作. (對於RGW, RBD, or CephFS,沒有這個問題)

Complexity : 在使用RADOS集群時,使用分級緩存意味著大量的額外器械和復雜性。這會增加你遇到未知的BUG(可能其他人未遇到過)的可能性, 並且使你的部署擁有更大的風險。

RGW time-skewed : 如果RGW工作中遇到的大部分操作是朝向最近寫入的數據,一個簡單的分級緩存可以工作得很好。

    下面的配置使用分層緩存效果不佳。

RBD with replicated cache and erasure-coded base : 這是一個普遍的需求, 但是通常不能很好工作。即使合理的傾斜工作負載,仍然會遇到一些對於冷門object的寫操作的情況,並且由於糾刪碼類型的池還不支持輕微的讀寫操作,為了適應一些小的寫入操作(通常4kb),整個object塊(通常4MB)必須被全部遷移到緩存 。只有少數用戶成功的應用了這種部署方式,並且這種部署方案只能為他們工作是因為他們的數據是極其「冷門」的(例如備份),並且他們對於性能並不敏感。

RBD with replicated cache and base : 在使用備份類型為基礎層時比以糾刪碼為基礎層時,RBD的表現更為良好, 但是它在工作負載中仍然依賴於大量的傾斜,並且很難驗證。用戶需要對他們的工作負載有更好的理解, 並且需要仔細調整分層緩存參數。

    為了建立分層緩存,你必須擁有兩個存儲池。一個作為後端存儲,一個作為緩存。

    建立一個後端存儲池包含兩種場景:

標准存儲 : 在這種場景中,這個池在Ceph存儲集群中存儲一個對象的多個副本。

糾刪碼: 在這種場景中,存儲池用糾刪碼高效地存儲數據,性能稍有損失。

    在標准存儲場景中,你可以用 CRUSH 規則集來標識失敗域(如 osd 、主機、機箱、機架、排等)。當規則集所涉及的所有驅動器規格、速度(轉速和吞吐量)和類型相同時, OSD 守護進程運行得最優。創建規則集的詳情見 CRUSH 圖 。創建好規則集後,再創建後端存儲池。

     在糾刪碼編碼情景中,創建存儲池時指定好參數就會自動生成合適的規則集,詳情見 創建存儲池 。

     在後續例子中,我們把cold-storage當作後端存儲池。

㈡ hibernetes mybatis 哪個好

各有各的好處,
1.1 Hibernate 簡介
Hibernate對資料庫結構提供了較為完整的封裝,Hibernate的O/R Mapping實現了POJO 和資料庫表之間的映射,以及SQL 的自動生成和執行。程序員往往只需定義好了POJO 到資料庫表的映射關系,即可通過Hibernate 提供的方法完成持久層操作。程序員甚至不需要對SQL 的熟練掌握, Hibernate/OJB 會根據制定的存儲邏輯,自動生成對應的SQL 並調用JDBC 介面加以執行。
1.2 MyBatis簡介
iBATIS 的著力點,則在於POJO 與SQL之間的映射關系。然後通過映射配置文件,將SQL所需的參數,以及返回的結果欄位映射到指定POJO。 相對Hibernate「O/R」而言,iBATIS 是一種「Sql Mapping」的ORM實現。
第二章 開發對比
開發速度
Hibernate的真正掌握要比Mybatis來得難些。Mybatis框架相對簡單很容易上手,但也相對簡陋些。個人覺得要用好Mybatis還是首先要先理解好Hibernate。
開發社區
Hibernate 與Mybatis都是流行的持久層開發框架,但Hibernate開發社區相對多熱鬧些,支持的工具也多,更新也快,當前最高版本4.1.8。而Mybatis相對平靜,工具較少,當前最高版本3.2。
開發工作量
Hibernate和MyBatis都有相應的代碼生成工具。可以生成簡單基本的DAO層方法。
針對高級查詢,Mybatis需要手動編寫SQL語句,以及ResultMap。而Hibernate有良好的映射機制,開發者無需關心SQL的生成與結果映射,可以更專注於業務流程。
第三章 系統調優對比
Hibernate的調優方案
制定合理的緩存策略;
盡量使用延遲載入特性;
採用合理的Session管理機制;
使用批量抓取,設定合理的批處理參數(batch_size);
進行合理的O/R映射設計
Mybatis調優方案
MyBatis在Session方面和Hibernate的Session生命周期是一致的,同樣需要合理的Session管理機制。MyBatis同樣具有二級緩存機制。 MyBatis可以進行詳細的SQL優化設計。
SQL優化方面
Hibernate的查詢會將表中的所有欄位查詢出來,這一點會有性能消耗。Hibernate也可以自己寫SQL來指定需要查詢的欄位,但這樣就破壞了Hibernate開發的簡潔性。而Mybatis的SQL是手動編寫的,所以可以按需求指定查詢的欄位。
Hibernate HQL語句的調優需要將SQL列印出來,而Hibernate的SQL被很多人嫌棄因為太丑了。MyBatis的SQL是自己手動寫的所以調整方便。但Hibernate具有自己的日誌統計。Mybatis本身不帶日誌統計,使用Log4j進行日誌記錄。
擴展性方面
Hibernate與具體資料庫的關聯只需在XML文件中配置即可,所有的HQL語句與具體使用的資料庫無關,移植性很好。MyBatis項目中所有的SQL語句都是依賴所用的資料庫的,所以不同資料庫類型的支持不好。
第四章 對象管理與抓取策略
對象管理
Hibernate 是完整的對象/關系映射解決方案,它提供了對象狀態管理(state management)的功能,使開發者不再需要理會底層資料庫系統的細節。也就是說,相對於常見的 JDBC/SQL 持久層方案中需要管理 SQL 語句,Hibernate採用了更自然的面向對象的視角來持久化 Java 應用中的數據。
換句話說,使用 Hibernate 的開發者應該總是關注對象的狀態(state),不必考慮 SQL 語句的執行。這部分細節已經由 Hibernate 掌管妥當,只有開發者在進行系統性能調優的時候才需要進行了解。
而MyBatis在這一塊沒有文檔說明,用戶需要對對象自己進行詳細的管理。
抓取策略
Hibernate對實體關聯對象的抓取有著良好的機制。對於每一個關聯關系都可以詳細地設置是否延遲載入,並且提供關聯抓取、查詢抓取、子查詢抓取、批量抓取四種模式。 它是詳細配置和處理的。
而Mybatis的延遲載入是全局配置的。
第五章 緩存機制對比
Hibernate緩存
Hibernate一級緩存是Session緩存,利用好一級緩存就需要對Session的生命周期進行管理好。建議在一個Action操作中使用一個Session。一級緩存需要對Session進行嚴格管理。
Hibernate二級緩存是SessionFactory級的緩存。 SessionFactory的緩存分為內置緩存和外置緩存。內置緩存中存放的是SessionFactory對象的一些集合屬性包含的數據(映射元素據及預定SQL語句等),對於應用程序來說,它是只讀的。外置緩存中存放的是資料庫數據的副本,其作用和一級緩存類似.二級緩存除了以內存作為存儲介質外,還可以選用硬碟等外部存儲設備。二級緩存稱為進程級緩存或SessionFactory級緩存,它可以被所有session共享,它的生命周期伴隨著SessionFactory的生命周期存在和消亡。
MyBatis緩存
MyBatis 包含一個非常強大的查詢緩存特性,它可以非常方便地配置和定製。MyBatis 3 中的緩存實現的很多改進都已經實現了,使得它更加強大而且易於配置。
默認情況下是沒有開啟緩存的,除了局部的 session 緩存,可以增強變現而且處理循環 依賴也是必須的。要開啟二級緩存,你需要在你的 SQL 映射文件中添加一行: <cache/>
字面上看就是這樣。這個簡單語句的效果如下:
映射語句文件中的所有 select 語句將會被緩存。
映射語句文件中的所有 insert,update 和 delete 語句會刷新緩存。
緩存會使用 Least Recently Used(LRU,最近最少使用的)演算法來收回。
根據時間表(比如 no Flush Interval,沒有刷新間隔), 緩存不會以任何時間順序 來刷新。
緩存會存儲列表集合或對象(無論查詢方法返回什麼)的 1024 個引用。
緩存會被視為是 read/write(可讀/可寫)的緩存,意味著對象檢索不是共享的,而 且可以安全地被調用者修改,而不幹擾其他調用者或線程所做的潛在修改。
所有的這些屬性都可以通過緩存元素的屬性來修改。
比如: <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
這個更高級的配置創建了一個 FIFO 緩存,並每隔 60 秒刷新,存數結果對象或列表的 512 個引用,而且返回的對象被認為是只讀的,因此在不同線程中的調用者之間修改它們會 導致沖突。可用的收回策略有, 默認的是 LRU:
LRU – 最近最少使用的:移除最長時間不被使用的對象。
FIFO – 先進先出:按對象進入緩存的順序來移除它們。
SOFT – 軟引用:移除基於垃圾回收器狀態和軟引用規則的對象。
WEAK – 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的對象。
flushInterval(刷新間隔)可以被設置為任意的正整數,而且它們代表一個合理的毫秒 形式的時間段。默認情況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新。
size(引用數目)可以被設置為任意正整數,要記住你緩存的對象數目和你運行環境的 可用內存資源數目。默認值是1024。
readOnly(只讀)屬性可以被設置為 true 或 false。只讀的緩存會給所有調用者返回緩 存對象的相同實例。因此這些對象不能被修改。這提供了很重要的性能優勢。可讀寫的緩存 會返回緩存對象的拷貝(通過序列化) 。這會慢一些,但是安全,因此默認是 false。
相同點
Hibernate和Mybatis的二級緩存除了採用系統默認的緩存機制外,都可以通過實現你自己的緩存或為其他第三方緩存方案,創建適配器來完全覆蓋緩存行為。
不同點
Hibernate的二級緩存配置在SessionFactory生成的配置文件中進行詳細配置,然後再在具體的表-對象映射中配置是那種緩存。
MyBatis的二級緩存配置都是在每個具體的表-對象映射中進行詳細配置,這樣針對不同的表可以自定義不同的緩存機制。並且Mybatis可以在命名空間中共享相同的緩存配置和實例,通過Cache-ref來實現。
兩者比較
因為Hibernate對查詢對象有著良好的管理機制,用戶無需關心SQL。所以在使用二級緩存時如果出現臟數據,系統會報出錯誤並提示。
而MyBatis在這一方面,使用二級緩存時需要特別小心。如果不能完全確定數據更新操作的波及范圍,避免Cache的盲目使用。否則,臟數據的出現會給系統的正常運行帶來很大的隱患。
第六章 Hibernate與Mybatis對比總結
兩者相同點
Hibernate與MyBatis都可以是通過SessionFactoryBuider由XML配置文件生成SessionFactory,然後由SessionFactory 生成Session,最後由Session來開啟執行事務和SQL語句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。
Hibernate和MyBatis都支持JDBC和JTA事務處理。
Mybatis優勢
MyBatis可以進行更為細致的SQL優化,可以減少查詢欄位。
MyBatis容易掌握,而Hibernate門檻較高。
Hibernate優勢
Hibernate的DAO層開發比MyBatis簡單,Mybatis需要維護SQL和結果映射。
Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。
Hibernate資料庫移植性很好,MyBatis的資料庫移植性不好,不同的資料庫需要寫不同SQL。
Hibernate有更好的二級緩存機制,可以使用第三方緩存。MyBatis本身提供的緩存機制不佳。
他人總結
Hibernate功能強大,資料庫無關性好,O/R映射能力強,如果你對Hibernate相當精通,而且對Hibernate進行了適當的封裝,那麼你的項目整個持久層代碼會相當簡單,需要寫的代碼很少,開發速度很快,非常爽。
Hibernate的缺點就是學習門檻不低,要精通門檻更高,而且怎麼設計O/R映射,在性能和對象模型之間如何權衡取得平衡,以及怎樣用好Hibernate方面需要你的經驗和能力都很強才行。
iBATIS入門簡單,即學即用,提供了資料庫查詢的自動對象綁定功能,而且延續了很好的SQL使用經驗,對於沒有那麼高的對象模型要求的項目來說,相當完美。
iBATIS的缺點就是框架還是比較簡陋,功能尚有缺失,雖然簡化了數據綁定代碼,但是整個底層資料庫查詢實際還是要自己寫的,工作量也比較大,而且不太容易適應快速資料庫修改。

㈢ Redis 6 將採用全新協議 RESP3,以提供客戶端緩存功能

Redis 創始人兼核心開發者 antirez 在博客介紹了將在 Redis 6 提供的新功能 —— Client side caching(客戶端緩存)

antirez 表示 全新的 Redis 協議 RESP3 將是 Redis 6 中最重要的特性,並解釋了他為何如此急切地改進 Redis 協議,原因主要有兩個,一是因為希望能為客戶端提供更多的語義化響應(semantical replies),以開發使用舊協議難以實現的功能;另一個原因也是 antirez 認為最重要的一個,實現 Client side caching(客戶端緩存)功能 這個功能十分常見,但 Redis 尚未提供。

當使用者需要進行快速存儲或快速取操作時,就需要在客戶端內存中存儲一小部分信息,這是為了降低程序獲取數據時的延遲。此功能在大規模的應用程序上十分重要,因為數據離應用程序越近,程序就能更快獲取到數據。

antirez 受 Ben Malec 演講的啟發,他想到可以將大部分需要頻繁存和取的數據直接放在伺服器的內存中,以便讓 Redis 為客戶端完成部分工作,並使客戶端緩存更簡單、更有效。這個就是 Client side caching(客戶端緩存)的概念。

不過這個思路有一個需要解決的問題是,如何控制數據彎雀皮的有效時間?在程序允許的情況下,雖然可以直接設置數據的有效時間,讓數據在一段時間後失效。但 antirez 表示,大多數的應用程序無法接受提供過時的數據的風險,因此必須找到更理想的方案來控制數據的失效時間。

所以 antirez 決定開發新的協議 RESP3,在協議中加入新特性來支持客戶端緩存功能,保證存儲在客戶端內存的數據,在收到來自伺服器的失效通知時才失效。

另外,當客戶端和伺服器的連接中斷時,客戶端無法接收到數據失效通知,這可能會導致服務出現問題。針對這種情況,一般的做法是重新建立客戶端和伺服器之間的連接,並更新客戶端當前的緩存。antirez 表示可以一直保持連接是最好的情況,但為了降低風險,Redis 伺服器在與客戶端斷開連接時,會將失效通知發送給其他客戶端埋差。

這項名為"Client side caching"的功能尚未正式確定名字,最後可能會被成為"Tracking"。Redis 作者還表示在 Redis 6 候選版發布之前,這些功能都會進行調整,希望社區能積極反饋意見。

由於 Client side caching 功能需要使用 RESP3 協議來支持實現,antirez 表示會想辦法通過 RESP2 協議也能啟用此功能。

閱歲配讀原文:「鏈接」

㈣ Redis分布式緩存搭建

花了兩天時間整理了之前記錄的Redis單體與哨兵模式的搭建與使用,又補齊了集群模式的使用和搭建經驗,並對集群的一些個原理做了理解。

筆者安裝中遇到的一些問題:

如果make報錯,可能是沒裝gcc或者gcc++編輯器,安裝之 yum -y install gcc gcc-c++ kernel-devel ,有可能還是提示一些個c文件編譯不過,gcc -v查看下版本,如果不到5.3那麼升級一下gcc:

在 /etc/profile 追加一行 source /opt/rh/devtoolset-9/enable

scl enable devtoolset-9 bash

重新make clean, make

這回編譯通過了,提示讓你最好make test一下/

執行make test ,如果提示 You need tcl 8.5 or newer in order to run the Redis test

那就升級tcl, yum install tcl

重新make test,如果還有error就刪了目錄,重新tar包解壓重新make , make test

o/ All tests passed without errors! ,表示編譯成功。

然後make install即可。

直接運行命令: ./redis-server /usr/redis-6.0.3/redis.conf &

redis.conf 配置文件里 bind 0.0.0.0 設置外部訪問, requirepass xxxx 設置密碼

redis高可用方案有兩種:

常用搭建方案為1主1從或1主2從+3哨兵監控主節點, 以及3主3從6節點集群。

(1)sentinel哨兵

/usr/redis-6.0.3/src/redis-sentinel /usr/redis-6.0.3/sentinel2.conf &

sentinel2.conf配置:

坑1:master節點也會在故障轉移後成為從節點,也需要配置masterauth

當kill master進程之後,經過sentinel選舉,slave成為了新的master,再次啟動原master,提示如下錯誤:

原因是此時的master再次啟動已經是slave了,需要向現在的新master輸入密碼,所以需要在master.conf
中配置:

坑2:哨兵配置文件要暴露客戶端可以訪問到的master地址

在 sentinel.conf 配置文件的 sentinel monitor mymaster 122.xx.xxx.xxx 6379 2 中,配置該哨兵對應的master名字、master地址和埠,以及達到多少個哨兵選舉通過認為master掛掉。其中master地址要站在redis訪問者(也就是客戶端)的角度、配置訪問者能訪問的地址,例如sentinel與master在一台伺服器(122.xx.xxx.xxx)上,那麼相對sentinel其master在本機也就是127.0.0.1上,這樣 sentinel monitor mymaster 127.0.0.1 6379 2 邏輯上沒有問題,但是如果另外伺服器上的springboot通過lettuce訪問這個redis哨兵,則得到的master地址為127.0.0.1,也就是springboot所在伺服器本機,這顯然就有問題了。

附springboot2.1 redis哨兵配置:

坑3:要注意配置文件.conf會被哨兵修改

redis-cli -h localhost -p 26379 ,可以登到sentinel上用info命令查看一下哨兵的信息。

曾經遇到過這樣一個問題,大致的信息如下

slaves莫名其妙多了一個,master的地址也明明改了真實對外的地址,這里又變成127.0.0.1 !
最後,把5個redis進程都停掉,逐個檢查配置文件,發現redis的配置文件在主從哨兵模式會被修改,master的配置文件最後邊莫名其妙多了一行replicaof 127.0.0.1 7001, 懷疑應該是之前配置錯誤的時候(見坑2)被哨兵動態加上去的! 總之,實踐中一定要多注意配置文件的變化。

(2)集群

當數據量大到一定程度,比如幾十上百G,哨兵模式不夠用了需要做水平拆分,早些年是使用codis,twemproxy這些第三方中間件來做分片的,即 客戶端 -> 中間件 -> Redis server 這樣的模式,中間件使用一致性Hash演算法來確定key在哪個分片上。後來Redis官方提供了方案,大家就都採用官方的Redis Cluster方案了。

Redis Cluster從邏輯上分16384個hash slot,分片演算法是 CRC16(key) mod 16384 得到key應該對應哪個slot,據此判斷這個slot屬於哪個節點。

每個節點可以設置1或多個從節點,常用的是3主節點3從節點的方案。

reshard,重新分片,可以指定從哪幾個節點移動一些hash槽到另一個節點去。重新分片的過程對客戶端透明,不影響線上業務。

搭建Redis cluster

redis.conf文件關鍵的幾個配置:

啟動6個集群節點

[root@VM_0_11_centos redis-6.0.3]# ps -ef|grep redis
root 5508 1 0 21:25 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7001 [cluster]
root 6903 1 0 21:32 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7002 [cluster]
root 6939 1 0 21:33 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7003 [cluster]
root 6966 1 0 21:33 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7004 [cluster]
root 6993 1 0 21:33 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7005 [cluster]
root 7015 1 0 21:33 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7006 [cluster]

這時候這6個節點還是獨立的,要把他們配置成集群:

說明: -a xxxx 是因為筆者在redis.conf中配置了requirepass xxxx密碼,然後 --cluster-replicas 1 中的1表示每個master節點有1個從節點。

上述命令執行完以後會有一個詢問: Can I set the above configuration? yes同意自動做好的分片即可。

最後 All 16384 slots covered. 表示集群中16384個slot中的每一個都有至少有1個master節點在處理,集群啟動成功。

查看集群狀態:

坑1:暴露給客戶端的節點地址不對

使用lettuce連接發現連不上,查看日誌 Connection refused: no further information: /127.0.0.1:7002 ,跟之前哨兵配置文件sentinel.conf里邊配置master地址犯的錯誤一樣,集群啟動的時候帶的地址應該是提供給客戶端訪問的地址。

我們要重建集群:先把6個redis進程停掉,然後刪除 nodes-7001.conf 這些節點配置文件,刪除持久化文件 mp.rdb 、 appendonly.aof ,重新啟動6個進程,在重新建立集群:

然後,還是連不上,這次報錯 connection timed out: /172.xx.0.xx:7004 ,發現連到企鵝雲伺服器的內網地址上了!

解決辦法,修改每個節點的redis.conf配置文件,找到如下說明:

所以增加配置:

然後再重新構建集群,停進程、改配置、刪除節點文件和持久化文件、啟動進程、配置集群。。。再來一套(累死了)

重新使用Lettuce測試,這次終於連上了!

坑2:Lettuce客戶端在master節點故障時沒有自動切換到從節點

name這個key在7002上,kill這個進程模擬master下線,然後Lettuce一直重連。我們期望的是應該能自動切換到其slave 7006上去,如下圖:

重新啟動7002進程,

7006已成為新master,7002成為它的slave,然後Lettuce也能連接上了。
解決辦法,修改Lettuce的配置:

筆者用的是springboot 2.1 spring-boot-starter-data-redis 默認的Lettuce客戶端,當使用Redis cluster集群模式時,需要配置一下 RedisConnectionFactory 開啟自適應刷新來做故障轉移時的自動切換從節點進行連接。

重新測試:停掉master 7006,這次Lettuce可以正常切換連到7002slave上去了。(仍然會不斷的在日誌里報連接錯誤,因為需要一直嘗試重連7006,但因為有7002從節點頂上了、所以應用是可以正常使用的)

Redis不保證數據的強一致性

Redis並不保證數據的強一致性,也就是取CAP定理中的AP

關於一致性Hash演算法,可以參考 一致性Hash演算法 - (jianshu.com)

Redis cluster使用的是hash slot演算法,跟一致性Hash演算法不太一樣,固定16384個hash槽,然後計算key落在哪個slot里邊(計算key的CRC16值再對16384取模),key找的是slot而不是節點,而slot與節點的對應關系可以通過reshard改變並通過gossip協議擴散到集群中的每一個節點、進而可以為客戶端獲知,這樣key的節點定址就跟具體的節點個數沒關系了。也同樣解決了普通hash取模演算法當節點個數發生變化時,大量key對應的定址都發生改動導致緩存失效的問題。

比如集群增加了1個節點,這時候如果不做任何操作,那麼新增加的這個節點上是沒有slot的,所有slot都在原來的節點上且對應關系不變、所以沒有因為節點個數變動而緩存失效,當reshard一部分slot到新節點後,客戶端獲取到新遷移的這部分slot與新節點的對應關系、定址到新節點,而沒遷移的slot仍然定址到原來的節點。

關於熱遷移,猜想,內部應該是先做復制遷移,等遷移完了,再切換slot與節點的對應關系,復制沒有完成之前仍按照原來的slot與節點對應關系去原節點訪問。復制結束之後,再刪除原節點上已經遷移的slot所對應的key。

與哨兵模式比較類似,當1個節點發現某個master節點故障了、會對這個故障節點進行pfail主觀宕機,然後會通過gossip協議通知到集群中的其他節點、其他節點也執行判斷pfail並gossip擴散廣播這一過程,當超過半數節點pfail時那麼故障節點就是fail客觀宕機。接下來所有的master節點會在故障節點的從節點中選出一個新的主節點,此時所有的master節點中超過半數的都投票選舉了故障節點的某個從節點,那麼這個從節點當選新的master節點。

所有節點都持有元數據,節點之間通過gossip這種二進制協議進行通信、發送自己的元數據信息給其他節點、故障檢測、集群配置更新、故障轉移授權等等。

這種去中心化的分布式節點之間內部協調,包括故障識別、故障轉移、選主等等,核心在於gossip擴散協議,能夠支撐這樣的廣播協議在於所有的節點都持有一份完整的集群元數據,即所有的節點都知悉當前集群全局的情況。

Redis高可用方案 - (jianshu.com)

面試題:Redis 集群模式的工作原理能說一下么 - 雲+社區 - 騰訊雲 (tencent.com)

深度圖解Redis Cluster原理 - detectiveHLH - 博客園 (cnblogs.com)

Redis學習筆記之集群重啟和遇到的坑-阿里雲開發者社區 (aliyun.com)

雲伺服器Redis集群部署及客戶端通過公網IP連接問題

熱點內容
構成c語言程序的基本單位 發布:2025-02-04 13:49:53 瀏覽:988
如何修改已經更改的密碼 發布:2025-02-04 13:38:38 瀏覽:772
唐dm2021買哪個配置劃算 發布:2025-02-04 13:38:38 瀏覽:627
真空壓縮重 發布:2025-02-04 13:38:37 瀏覽:639
alias腳本 發布:2025-02-04 13:38:03 瀏覽:739
linux終端字元 發布:2025-02-04 12:52:40 瀏覽:736
c語言程序設計mobi 發布:2025-02-04 12:51:55 瀏覽:259
rsa演算法c語言 發布:2025-02-04 12:50:36 瀏覽:785
阿里雲伺服器託管破解 發布:2025-02-04 12:47:43 瀏覽:257
汽車都有什麼配置 發布:2025-02-04 12:42:51 瀏覽:458