主頁 > 軟體設計 > redis學習總結

redis學習總結

2021-01-09 10:39:59 軟體設計

文章目錄

    • redis資料結構原理
    • redis持久化
      • RDB持久化
      • AOF持久化
    • redis集群三種模式
      • 主從模式(實作主從分離,提高吞吐,多機備份)
      • 哨兵模式(主從高可用,自動化修復)
      • 集群模式(資料分片,解決了寫操作無法負載均衡,單機容量存盤、并發問題)
    • redis應用場景
      • 分布式鎖
    • redis架構思維

redis資料結構原理

待整理~

redis持久化

RDB持久化

  1. 執行流程
  • 父行程執行fork操作創建子行程,這個程序中父行程是阻塞的,Redis不能執行來自客戶端的任何命令,
  • 子行程創建RDB檔案,根據父行程記憶體快照生成臨時快照檔案,完成后對原有檔案進行原子替換,替換后子行程信號通知主行程
  1. rdb自動持久化配置:
    時間策略要按照實際情況配置多條,資料的存盤時不均勻的,高峰期短時間間隔要存一次,低峰期長時間間隔要存一次,
# 檔案名稱
dbfilename dump.rdb

# 時間策略
save 900 1
save 300 10
save 60 10000

# 檔案保存路徑
dir /etc/redis/data/

# 如果持久化出錯,主行程是否停止寫入
stop-writes-on-bgsave-error yes

# 是否壓縮
rdbcompression yes

# 匯入時是否檢查
rdbchecksum yes
  1. rdb策略將記憶體中的資料生成快照保存到磁盤,是全量存盤,記憶體大的話會比較耗時,大量磁盤io,
  2. 持久化的觸發方式:
  • save命令:client向server發送save命令,同步阻塞,
  • bgsave命令:server中執行命令,異步子行程執行,
  • 自動持久化,通過save配置項完成,
  1. rdb檔案恢復:如果開啟了aof,則不生效,如果沒開啟aof,則尋找dir配置下的rdb檔案,

AOF持久化

  1. aof同步步驟:
  • Redis收到寫命令后首先會追加到AOF緩沖區aof_buf(write)
  • 通過一定時機(配置決定),呼叫系統函式 fsync() 把AOF緩沖區的資料刷到磁盤
  1. 落盤時機配置(fsync):
    always: 命令寫入aof緩沖區后立即呼叫系統fsync操作同步到AOF檔案,資料絕對安全,
    no:有作業系統決定何時呼叫fsync()
    everysec:每秒調fsync()一次, 若損失資料只損失1秒,對于大多數系統來說足夠了,
  2. 檔案重寫rewrite
  • 由父行程fork子行程進行重寫
  • 使用寫時重寫技術,在重寫完成期間,Redis的寫命令同時追加到aof_buf和aof_rewirte_buf兩個緩沖區,
  • 重寫檔案完成后,將aof_rewirte_buf資料輸入新檔案
  • 用新aof檔案替換老aof檔案,

redis集群三種模式

主從模式(實作主從分離,提高吞吐,多機備份)

從資料庫一般都是只讀的,并且接收主資料庫同步過來的資料
要點:

  1. 主從復制還是哨兵和集群能夠實施的基礎,主從復制是Redis高可用的基礎,
  2. 再看CAP,由于redis復制是異步復制,會導致短時的資料不一致,所以無法滿足一致性C,但可以保證當網路磁區發生時,各個節點依舊可用,redis主從模式是CP,而不是AP,redis會使用最終一致性策略,保證主從同步資料一致,
  3. 主從復制實作原理:
  • 6大步驟: 1. 設定主節點ip及埠、2. 建立套接字socket、 3. 發送ping命令、 4. 權限驗證 、 5. 同步 6. 命令傳播
  • 設定主節點ip及埠: 使用slaveof命令,可組態檔使用、可命令列使用
  • 復制階段:從節點向主節點發送psync或sync命令(2.8版本之前),可以實作全量復制與增量復制
  • 命令傳播:當通過復制階段后,主從節點進入命令傳播階段,主節點將自己執行的寫命令發送給從節點,從節點接收命令并執行,從而保證主從節點資料的一致性,命令傳播是異步的,主節點并不會等從節點同步執行完命令,這樣會導致“延遲不一致”現象,
  1. 延遲不一致現象:網路波動、寫命令頻率過高,會導致資料延遲不一致,同時,repl-disable-tcp-nodelay配置也會影響,設定為yes,會將代發資料合并發送,延遲大概40ms(取決于系統),如果設定為no,寫命令實時發送同步,
  2. 全量復制和部分復制
  • 全量復制:用于初次復制或其他無法進行部分復制的情況,將主節點中的所有資料都發送給從節點,是一個非常重型的操作
  • 部分復制:用于網路中斷等情況后的復制,只同步網路斷開期間的快取寫資料,如果網路中斷時間過長,導致主節點沒有能夠完整地保存中斷期間執行的寫命令,則無法進行部分復制,仍使用全量復制,
  1. 全量復制原理剖析:
    fork子行程,開始執行bgsave,生成RDB檔案,同時開辟緩沖區記錄從現在開始的寫命令,2. 將rdb檔案傳輸給從服務器,從服務器執行完畢后,主節點將緩沖區寫資料同步到從節點,保證最終一致性,3. 如果從節點開啟了AOF,會觸發bgrewriteof,從而保證從節點的aof檔案最新,
  2. 部分復制原理剖析:
  • 復制偏移量:與mysql類似,主從節點各自維護offset欄位,不一致則復制
  • 復制積壓緩沖區:底層結構是定長、先進先出FIFO的佇列,可以repl-backlog-size引數設定大小, 當主從節點offset的差距過大超過緩沖區長度時,將無法執行部分復制,只能執行全量復制,
  • 服務器運行id(runid):每個從節點都存盤著主節點同步下來的runid,當網路磁區發生時,重連后slave節點會判斷同步的runid是否存在,如果存在優先考慮增量復制,如果不存在,則全量復制,
  1. psync命令復制原理:主節點收到psync命令后,進行判斷,如果命令為psync命令,則執行全量復制,如果收到的為psync {runid} {offset}命令,則執行增量復制,執行增量復制程序中如果offset差超過了buffer,則執行全量復制,
  2. 心跳檢測機制及其作用:1. 檢測主從鏈接 2. 輔助實作min-slaves選項 3. 檢測命令丟失,保證資料一致
  • 通過判斷在線的從節點數量,實作min-slaves,
    min-slaves概念,保證高可用:
    未達到下面兩個條件時,寫操作就不會被執行
    min-slaves-to-write 3 #最少包含的從服務器
    min-slaves-max-lag 10 #延遲值
  • 心跳會回傳offset資訊,通過offset判斷從節點的資料同步是否及時,不及時則通過offset補發資料
  1. 主從復制超時原理:斷開連接后會嘗試重連,
  • 主節點判斷超時:每秒1次呼叫復制定時函式replicationCron(),如果時間大于到上次REPLCONF ACK的時長,則斷開連接,釋放資源(緩沖器、連接、帶寬),超時時間由引數repl-timeout值控制,
  • 從節點判斷超時:主要也是由repl-timeout引數控制,1. 連接建立階段,若大于時間則斷開連接, 2. 全量復制階段:如果收到rdb的時間超時,則斷開連接, 3. 命令傳播階段:如果收到主節點ping的時間過長,超過timeout,則斷開連接,
  • 如果rdb檔案過大,會導致一直同步失敗,會無線重連,應適當調大timeout值
  1. 主庫掛了發生什么?
    不影響slave的讀,但redis不再提供寫服務,master重啟后redis將重新對外提供寫服務,
    如果slave-serve-stale-data引數設定為yes,主節點掛掉后從節點可以繼續提供服務,如果設定為no,主節點掛掉后從節點不再提供讀資料服務,僅提供info、slaveof等少量命令,在強一致場景需要考慮設定為no,如分布式鎖,如果主節點掛掉,資料沒來得及同步從節點,會導致從節點讀不到,鎖失效,
    重啟master節點需要保證rdb檔案或者aof檔案是最新,
  2. redis如何保證主從服務器連接正常且資料最終一致?
    命令傳播階段,從服務器會利用心跳檢測機制定時的向主服務發送訊息,
  3. 如果提高資料實時一致性?
    優化主從節點之間的網路環境(如在同機房部署);監控主從節點延遲(通過offset)判斷,如果從節點延遲過大,通知應用不再通過該從節點讀取資料;
  4. java客戶端連接redis如何實作讀寫分離,讀負載均衡?
    常見的客戶端有jredis,lettuce,redission,以lettuce為例,可以使用
StatefulRedisMasterSlaveConnection connection = MasterSlave.connect(redisClient, new Utf8StringCodec(), redisURI);
connection.setReadFrom(ReadFrom.NEAREST);
// MASTER 主讀
// SLAVE 從讀
// MASTER_PREFERRED 優先master -> slave
// SLAVE_PREFERRED 優先slave -> master
// NEAREST 最近節點讀
// 實作很簡單,重寫ReadFrom的select方法,自帶的方法均無法實作負載均衡
static final class ReadFromSlavePreferred extends ReadFrom {
 
        @Override
        public List<RedisNodeDescription> select(Nodes nodes) {
 
            List<RedisNodeDescription> result = new ArrayList<>(nodes.getNodes().size());
            //優先添加slave節點
            for (RedisNodeDescription node : nodes) {
                if (node.getRole() == RedisInstance.Role.SLAVE) {
                    result.add(node);
                }
            }
            //最后添加master節點
            for (RedisNodeDescription node : nodes) {
                if (node.getRole() == RedisInstance.Role.MASTER) {
                    result.add(node);
                }
            }
            return result;
        }
// 自定義負載均衡
@Bean(destroyMethod = "close")
   StatefulRedisMasterSlaveConnection<String, String> statefulRedisMasterSlaveConnection(RedisClient redisClient, RedisURI redisURI) {
       StatefulRedisMasterSlaveConnection connection = MasterSlave.connect(redisClient, new Utf8StringCodec(), redisURI);
       connection.setReadFrom(new ReadFrom() {
           @Override
           public List<RedisNodeDescription> select(Nodes nodes) {
               List<RedisNodeDescription> list = nodes.getNodes();
               Collections.shuffle(list);
               return list;
           }
       });
       return connection;
   }

哨兵模式(主從高可用,自動化修復)

  1. 高可用架構一般將sentinel與redis實體部署在不同的服務器上,
  2. 作業機制:每個sentinel以每秒鐘一次的頻率向它所知的master,slave以及其他sentinel實體發送一個 PING 命令 ,如果回應超過 down-after-milliseconds,則標記為主觀下線,其它sentinel以每秒鐘一次的頻率ping主觀下線的實體,如果足夠多的(通過配置指定)sentinel確認該實體的主觀下線狀態,則置為客觀下線,Sentinel 和其他 Sentinel 協商 主節點 的狀態,如果 主節點 處于 SDOWN 狀態,則投票自動選出新的 主節點,將剩余的 從節點 指向 新的主節點 進行 資料復制
  3. 當使用sentinel模式的時候,客戶端就不要直接連接Redis,而是連接sentinel的ip和port,由luttuce自動獲取redis集群拓撲,從而獲取master節點與slave節點的資訊,并通過監聽redis事件更新拓撲資訊,
  4. 哨兵模式切換主節點導致資料不一致,“腦裂問題”的解決方案:
  • 當網路磁區發生時,會導致master下線,實際master沒有掛,選舉出新的master后會出現兩個master,當網路磁區修好后,舊master會變為slave同步新master的資料,導致資料丟失,
    配置:
    min-slaves-to-write 1 # 必須至少要有1個slave
    min-slaves-max-lag 10 # 資料復制和同步延遲不能超過10秒
    不符合以上情況,master將拒絕接受請求,將資料丟失控制在10秒,
    從業務上看,及其重要的資料,可以進行處理:
    進redis前可以在其它地方臨時存盤,
    可以加網關,降低流入速度,防止瞬間進入過多資料,

集群模式(資料分片,解決了寫操作無法負載均衡,單機容量存盤、并發問題)

  1. 一致性hash與hash槽
  • 簡單hash演算法,通過計算hash值 % 機器數量,得到資料的實際對應節點,當增加或洗掉節點時,會導致大量的快取失效,甚至導致雪崩,
  • 一致性哈希演算法中,整個哈希空間是一個虛擬圓環,共計2^32 - 1 個節點,將每個redis節點的ip地址進行hash計算后落位虛擬節點,每條資料通過計算hash值后順時針落位對應節點,當某個節點增、刪、不可用時,只會影響下一個節點,而不會影響所有節點,
    一致性hash演算法的問題是會導致資料傾斜,如果節點數過少,在盤中的分布又不均勻,可能會導致所有資料都落在極少的節點上,
  • 哈希槽,redis包含了16384個哈希槽,每個 key 通過計算后都會落在具體一個槽位上,而這個槽位是屬于哪個存盤節點的,則由用戶自己定義分配,
    對于槽位的轉移和分派,redis 集群是不會自動進行的,而是需要人工配置的,所以 redis 集群的高可用是依賴于節點的主從復制與主從間的自動故障轉移,
  1. redis-cluster是redis集群的官方實作版,具有投票、容錯性等特點,
  • 集群中可以有多個master節點,需要保證所有master節點恰好覆寫所有hash槽,否則集群不能啟動,添加、洗掉節點,只需要更改對應的哈希槽范圍,
    node1 : [1,15000]
    node2 : [15001,20000]
  • 何時master節點算掛掉?
    半數以上master節點與master節點通信超時(cluster-node-timeout),認為當前master節點掛掉,如果此時該master節點由slave節點,則集群依舊正常運行,對應掛掉的節點不再提供寫入服務,
  • 何時集群掛掉?
    1.只要某個槽段失效,集群就會進入不可用狀態,主、從都掛,
    2.超過半數的master節點掛掉,不管slave是否正常,集群不可用,
  • 一般情況,各個槽段的主、從redis節點可以交叉部署,部署在不同的服務器上,

redis應用場景

分布式鎖

  1. 單機版分布式鎖:
  • 加鎖終極版:set nx px + 事務id
  • 解鎖終極版:使用lua腳本實作,
    if redis.call(“get”,KEYS[1]) == ARGV[1] then
    return redis.call(“del”,KEYS[1])
    else
    return 0
    end
  • 為何解鎖需要用lua,而加鎖不需要?
    加鎖程序,set命令的 nx 引數 = set if not exist,get value->判斷不存在->set value,set 命令的 px引數,設定過期時間,相當于三條命令保持原子性,
    解鎖程序,get獲取鍵值,判斷value是否相等,如果此時JVM

redis架構思維

待整理~

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/246531.html

標籤:其他

上一篇:資料結構——堆疊(C語言)

下一篇:React fiber 架構淺析

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more