日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

redis持久化意義

  1. 是做災難恢復,數據恢復,也可以歸類到高可用的一個環節里面去,比如你的redis整個掛了,然后redis就不可用了,你要做的事情是讓redis變得可用,盡快變得可用
  2. 大量的請求過來,緩存全部無法命中,在redis里根本找不到數據,這個時候就死定了,緩存雪崩問題,所有請求,沒有在redis命中,就會去MySQL數據庫這種數據源頭中去找,一下子MySQL承接高并發,然后就掛了
  3. redis持久化做得好,備份和恢復做到企業級的程度,那么即使你的redis故障了,也可以通過備份數據,快速恢復,一旦恢復立即對外提供服務;

 

Redis持久化RDB

優點:

  1. RDB會生成多個數據文件,每個數據文件都代表了某一個時刻中redis的數據,這種多個數據文件的方式,每個文件都代表了某一個時刻完成的數據快照,非常適合做冷備
  2. RDB對Redis對外提供的讀寫服務,影響非常小,可以讓Redis保持高性能,因為redis主進程只需要fork一個子進程,讓子進程執行磁盤IO操作來進行RDB持久化即可
  3. 相對于AOF持久化機制來說,直接基于RDB數據文件來重啟和恢復Redis數據,更快加速

缺點:

  1. 如果想要在Redis故障時,盡可能少的丟失數據,那么RDB沒有AOF好。一般來說,RDB數據快照文件,都是每隔5分鐘,或者更長時間生成一次,這個時候就得接受一旦Redis進程宕機,那么會丟失最近5分鐘的數據,這個問題,也是RDB最大的缺點,就是不適合做第一有限的恢復方案,如果你依賴RDB做第一優先恢復方案,會導致數據丟失的比較多。
  2. RDB每次在fork子進程來執行RDB快照數據文件生成的時候,如果數據文件特別大,可能會導致客戶端提供的服務暫停數毫秒,甚至數秒,一般不要讓RDB的間隔太長,否則每次生成的RDB文件太大了,對Redis本身的性能可能會有影響的

配置:

  1. save 60 1000:每隔60s,如果有超過1000個key發生了變更,那么就生成一個新的dump.rdb文件,就是當前Redis內存中的完整地數據快照 ,這個操作也被稱之為snapshotting,快照。也可以手動調用save或者bgsave命令,同步或異步執行RDB快照生成,save可以設置多個,就是多個snapshotting檢查點,每到一個檢查點,就會去check一下,是否有指定的key數量發生了變更,如果有,就生成一個新的dump.rdb文件。

工作流程:

  1. Redis根據配置自己嘗試去生成rdb快照文件
  2. fork一個子進程出來
  3. 子進程嘗試將數據dump到臨時的rdb快照文件中
  4. 完成rdb快照文件的生成之后,就替換之前舊的快照文件,dump.rdb文件,每次生成一個新的快照,都會覆蓋之前的老快照,dump.rdb只有一個

模擬實驗:

  1. 通過redis-cli SHUTDOWN這種方式去掉redis,其實是一種安全退出的模式,redis在退出的時候會將內存中的數據立即生成一份完整的rdb快照
  2. 用kill -9粗暴殺死redis進程,模擬redis故障異常退出,導致內存數據丟失的場景,這次就發現,redis進程異常被殺掉,數據沒有dump文件,幾條最新的數據就丟失了

 

Redis持久化AOF

優點:

  1. AOF可以更好地保護數據不丟失,一般AOF會每隔1秒,通過一個后臺線程執行一次fsync操作,最多丟失1秒鐘的數據,每隔1秒,就執行一次fsync操作,保證os cache中的數據寫入磁盤中,redis進程掛了,最多丟掉1秒鐘的數據;
  2. AOF日志文件以Append-only模式寫入,所以沒有任何磁盤尋址的開銷,寫入性能非常高,而且文件不容易損壞,即使文件尾部破損,也很容易修復;
  3. AOF日志文件即使過大的時候,出現后臺重寫操作,也不會影響客戶端的讀寫。因為在rewrite log的時候,會對其中的指導進行壓縮,會創建出一份需要恢復數據的最小日志出來。在創建新日志文件的時候,老的日志文件還是照常寫入。當新的merge后的日志文件ready的時候,再交換新老日志文件即可;
  4. AOF日志文件的命令通過非常刻度的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。比如某人不小心用flushall命令清空了所有數據,只要這個時候后臺rewrite還沒有發生,那么就可以立即拷貝AOF文件,將最后一條flushall命令給刪了,然后再將該AO文件放回去,就可以通過恢復機制,自動恢復所有數據;

缺點:

  1. 對于同一份數據來說,AOF日志文件通常比RDB數據快照文件更大;
  2. AOF開啟后,支持的寫QPS會比RDB支持的寫QPS低,因為AOF一般會配置成每秒fsync一次日志文件,當然,每秒一次fsync,性能也還是很高的,如果你要保證一條數據都不丟失,也是可以的,AOF的fsync設置成每寫入一條數據,fsync一次,那就完蛋了,redis的QPS效率大降;
  3. 做數據恢復的時候,會比較慢,還有做冷備,定期的備份,不太方便,可能要自己手寫復雜的腳本去做,做冷備不太合適;

配置:

  1. AOF持久化,默認是關閉的,默認是打開的RDB持久化,appendonly yes,可以打開AOF持久化機制,在生產環境里面,一般來說AOF都是要打開的,除非你說隨便丟個幾分鐘的數據也無所謂,打開AOF持久化機制之后,redis每次即受到一條寫命令,就會寫入日志文件中,當然是先寫入os cache的,然后每隔一定時間再fsync一下
  2. 而且即使APF和RDB都開啟了,redis重啟的時候,也是優先通過AOF進行數據恢復的,因為AOF數據比較完整。
  3. 可以配置AOF的fsync策略,有三種策略可以選擇:
  • 一種是每次寫入一條數據就執行一次fsync;
  • 一種是每隔一秒執行一次fsync;
  • 一種是不主動執行fsync;

① always:每次寫入一條數據,立即將這個數據對應的寫日志fsync到磁盤上去,性能非常差,吞吐量很低,確保說redis里的數據一條都不丟,那就只能這樣了;

② mysql => 內存策略,大量磁盤,QPS到多少,一兩k。(QPS,每秒鐘的請求數量 )

redis => 內存,磁盤持久化,QPS到多少,單機,一般來說,上萬QPS沒問題

③ everysec:每秒將os cache中的數據fsync到磁盤,這個最常用的,生產環境一般都這么配置,性能很高,QPS還是可以上萬的;

④ no:僅僅redis負責將數據寫入os cache就撒手不管了,然后后面os自己會時不時有自己的策略將數據刷入磁盤,不可控了;

模擬實驗:

  1. kill -9殺掉Redis進程,重新啟動redis進程,發現數據被恢復回來了,從AOF文件中恢復回來的。在appendonly.aof文件中,可以看到剛寫的日志,他們其實就是先寫入os cache的,然后1秒后才fsync到磁盤中,只有fsync到磁盤中了,才是安全的,要不然光是在os cache中,機器只要重啟,就什么都沒有了;
  2. redis進程啟動的時候,直接就會從appendonly.aof中加載所有的日志,把內存中的數據恢復回來;

 

AOF rewrite:

  1. redis中的數據其實有限的,很多數據可能會自動過期,可能會被用戶刪除,可能會被reids用緩存清除的算法清理掉;
    redis中的數據會不斷淘汰掉舊的,就一部分常用的數據會被自動保留在redis內存中;
    所以可能很多之前的已經被清理掉的數據,對應的寫日志還停留在AOF中,AOF日志文件就一個,會不斷地膨脹,到很大很大;
    所有AOF會自動在后臺每隔一定時間做rewrite操作,比如日志里面已經存放了針對100W數據的寫日志了;redis內存只剩下10w;基于內存中當前的10w數據構建一套最新的日志,到AOF中,覆蓋之前的老日志,確保AOF日志文件不會過大,保持跟redis內存數據量一致;
  2. 在redis.conf中,可以配置rewrite策略:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
比如說上一次AOF rewrite之后,是128mb;然后就會接著128mb繼續寫AOF的日志,如果發現增長的比例,超過了之前的100%,256mb,就可能會去觸發一次rewrite;但是此時還要去跟min-size,64mb去比較,256mb>64mb,才會去觸發rewrite

比如說上一次AOF rewrite之后,是128mb;
然后就會接著128mb繼續寫AOF的日志,如果發現增長的比例,超過了之前的100%,256mb,就可能會去觸發一次rewrite;
但是此時還要去跟min-size,64mb去比較,256mb>64mb,才會去觸發rewrite

工作流程:

  1. redis fork一個子進程;
  2. 子進程基于當前內存中的數據,構建日志,開始往一個新的臨時的AOF文件中寫入日志;
  3. redis主進程,接收到client新的寫操作之后,在內存中寫入日志,同時新的日志也繼續寫入舊的AOF文件;
  4. 子進程寫完新的日志文件之后,reids主進程將內存中的新日志再次追加到新的AOF文件中;
  5. 用新的日志文件替換掉舊的日志文件;

 

RDB VS AOF

區別:

  1. RDB:可以做冷備,生成多個文件,每個文件都代表了某一個時刻的完整的數據快照;
    AOF:也可以做冷備,只有一個文件,但是你可以,每隔一定時間,去copy一份這個文件出來;
  2. RDB:每次寫,都是直接寫redis內存,只是在一定的時候,才會將數據寫入磁盤中;
    AOF:每次都是要寫文件的,雖然可以快速寫入os cache中,但是還是有一定的時間開銷的,速度肯定比RDB策略慢一些;
  3. AOF:存放的指令日志,做數據恢復的時候,其實是要回放和執行所有的指令日志,來恢復出來內存中的所有數據的;
    RDB:就是一份數據文件,恢復的時候,直接加載到內存中即可;

同時工作:

  1. 如果RDB在執行snapshotting操作,那么redis不會執行AOF rewrite;如果redis再執行AOF rewrite,那么就不會執行RDB snapshotting;
  2. 如果RDB在執行snapshotting操作,此時用戶執行BGREWRITEAOF命令,那么等RDB快照生成之后,才回去執行AOF rewrite;
  3. 同時有RDB snapshot文件和AOF日志文件,那么redis重啟的時候,會優先使用AOF進行數據恢復,因為其中的日志更完整;

 

Redis主從架構

主從核心機制

  1. redis采用異步方式復制數據到slave節點,不過Redis2.8開始,slave node會周期性地確認自己每次復制的數據量;
  2. 一個master node是可以配置多個slave node的;
  3. slave node也可以連接其他的slave node;
  4. slave node做復制的時候,是不會block master node的正常工作的;
  5. slave node在做復制的時候,也不會block對自己的查詢操作,他會用舊的數據集來提供服務;但是復制完成的時候,需要刪除舊的數據集,加載新的數據集,這個時候就會暫停對外服務了;
  6. slave node主要用來進行橫向擴容,做讀寫分離,擴容的slave node可以提高讀的吞吐量;

 

Redis哨兵模式

主要功能

  1. 集群監控,負責監控redis master和slave進程是否正常工作;
  2. 消息通知,如果某個redis實例有故障,那么哨兵負責發送消息作為報警通知給管理員;
  3. 故障轉移,如果master node掛掉了,會自動轉移到slave node上;
  4. 配置中心,如果故障轉移發生了,通知client客戶端新的master地址

分布式

  1. 故障轉移時,判斷一個master node是宕機了,需要大部分的哨兵同意才行,涉及到了分布式的選舉的問題;
  2. 即使部分哨兵節點掛掉了,哨兵集群還是能正常工作的,因為如果一個作為高可用機制重要組成部分的故障轉移系統本身是單點的,那就很坑爹了;

核心知識

  1. 哨兵至少需要3個實例,來保證自己的健壯性;
  2. 哨兵+redis主從的部署架構,是不會保證數據零丟失的,只能保證redis集群的高可用性;
  3. 對于哨兵+redis主從這種復雜的部署架構,盡量在測試環境和生產環境,都進行充足的測試和演練;

數據丟失

(一)異步復制

  1. 因為 master => slave 的復制是異步的,所以可能有部分數據還沒有復制到slave,master就宕機了,此時這些部分數據就丟失了;

(二)腦裂

① 某個master所在機器突然脫離了正常的網絡,跟其他slave機器不能連接,但是實際上master還運行著;

② 此時哨兵可能就會認為master宕機了,然后開啟選舉,將其他slave切換成了master;

③ 這個時候,集群里就會有兩個master,也就是所謂的腦裂;

④ 此時雖然某個slave被切換成了master,但是可能client還沒來得及切換到新的master,還繼續寫向舊的master的數據可能也丟失了;

⑤ 因此舊master再次恢復的時候,會被作為一個slave掛到新的master上去,自己的數據會清空,重新從新的master復制數據

(三)解決

min-salves-to-write 1
min-slaves-max-lag 10

要求至少有一個slave,數據復制和同步的延遲不能超過10秒

如果說一旦所有的slave,數據復制和同步的延遲都超過了10秒鐘,那么這個時候,master你就不會再接收任何請求了;

上面兩個配置可以減少異步復制腦裂導致的數據丟失;

  1. 減少異步復制的數據丟失

有了min-slaves-max-lag這個配置,就可以確保說,一旦slave復制數據和ack延時太長,就認為可能master宕機后損失的數據太多了,那么就拒絕寫請求,這樣可以把master宕機時由于部分數據未同步到slave導致的數據丟失降低的可控范圍內

  1. 減少腦裂的數據丟失

如果一個master出現腦裂,跟其他slave丟了連接,那么上面兩個配置就可以確保說,如果不能繼續給指定數量的slave發送數據,而且slave超過10秒沒有給自己ack消息,那么就直接拒絕客戶端的寫請求;

這樣腦裂后的舊master就不會接受client的新數據,也就避免了數據丟失;

上面的配置就確保了,如果跟任何一個slave丟了連接,在10秒后發現沒有slave給自己ack,那么就拒絕新的寫請求;

因此在腦裂場景下,最多就丟失10秒的數據

底層原理

(一)sdown和odown兩種失敗狀態轉換機制

    1. sdown是主觀宕機,就一個哨兵如果自己覺得一個master宕機了,那么就是主觀宕機;
      sdown達成的條件很簡單,如果一個哨兵ping一個master,超過了is-master-down-milliseconds指定的毫秒數之后,就主觀認為master宕機;
  1. odown是客觀宕機,如果quorum數量的哨兵都覺得一個master宕機了,那么就是客觀宕機;
    sdown和odown轉換的條件很簡單,如果一個哨兵在指定時間內,收到了quorum指定數量的其他哨兵也認為那個master是sdown了,那么就認為是odown了,客觀認為master宕機;

 

(二)哨兵集群的自動發現機制

哨兵互相之間的發現,是通過redis的pub/sub系統實現的,每個哨兵都會往 _sentinel_:hello 這個channel里發送一個消息,這時候所有其他哨兵都可以消費到這個消息,并感知到其他的哨兵的存在;

每隔兩秒鐘,每隔哨兵都會往自己監控的某個master+slaves對應的_sentinel_:hello channel 里發送一個消息,內容是自己的host、ip和runid還有對這個master的監控配置;

每個哨兵也會去監聽自己監控的每個master+slaves對應的_sentinel_:hello channel,然后去感知到同樣在監聽這個master+slaves的其他哨兵的存在;

每個哨兵還會跟其他哨兵交換對master的監控配置,互相進行監控配置的同步;

(三)slave => master選舉算法

    1. 如果一個master被認為odown了,而且majority燒餅都允許了主備切換,那么某個哨兵就會執行主備切換操作,此時首先要選舉一個slave來,會考慮slave的一些信息:
      ① 跟master斷開連接的時長;
      ② slave優先級;
      ③ 復制offset;
      ④ run id;
  1. 如果一個slave跟master斷開連接已經超過了down-after-milliseconds的10倍,外加master宕機的時長,那么slave就會被認為不適合選舉為master
    (down-after-milliseconds * 10)+milliseconds_since_master_is_in_SDOWN_state
  2. 接下來會對slave進行排序
    ① 按照slave優先級進行排序,slave priority 越低,優先級就越高;
    ② 如果slave priority相同,那么看replica offset,哪個slave復制了越多的數據,offset越靠后,優先級就越高;
    ③ 如果上面兩個條件都相同,那么選擇一個run id比較小的那個slave;

瓶頸

  1. 如果你的數據量很少,主要是承載高并發高性能的場景,比如你的緩存一般就幾個G,單機足夠了;
  2. replication,一個master,多個slave,要幾個slave跟你的要求的讀吞吐量有關系,然后自己搭建一個sentinal集群,去保證redis主從架構的高可用性,就可以了;

 

Reids cluster

介紹

cluster

  1. 自動將數據進行分片,每個master上放一部分數據;
  2. 提供內置的高可用支持,部分master不可用時,還是可以繼續工作的;

cluster端口

  1. 每個redis要開放兩個端口號,比如一個是6379,另外一個就是加10000的端口號,比如16379;
  2. 16379端口號是用來進行節點間通信的,也就是cluster bus的東西,集群總線。cluster bus的通信,用來進行故障檢測,配置更新,故障轉移授權;
    cluster bus用了另一種二進制的協議,主要用于節點間進行高效的數據交換,占用更少的網絡帶寬和處理時間;

hash slot算法

  1. redis cluster有固定的16384個hash slot,對每個key計算CRC16值,然后對16384取模,可以獲取key對應的hash slot;
    redis cluster中每個master都會持有部分slot,比如有3個master,那么可能每個master持有5000多個hash slot
  2. hash slot讓node的增加和一處很簡單,增加一個master,就將其他的master的hash slot移動部分過去,減少一個master,就將它的hash slot移動到其他master上去;
    移動hash slot的成本是非常低的;
    客戶端的api,可以對指定的數據,讓他們走同一個hash slot,通過hash tag來實現;

核心原理(節點間的內部通信機制)

基礎通信原理

(一)節點間采取gossip協議進行通信

    1. 跟集中式不同,不是將集群元數據(節點信息,故障,等等)集中存儲在某個節點上,而是互相之間不斷通信,保持整個集群所有節點的數據是完整的;
    2. 集中式:
      好處在于,元數據的更新和讀取,時效性非常好,一旦元數據出現了變更,立即就更新到集中式的存儲中,其他節點讀取的時候立即就可以感知到;
      不好在于,所有的元數據的更新壓力全部集中在一個地方,可能會導致元數據的存儲有壓力;
  1. gossip:
    好處在于:元數據的更新比較分散,不是集中在一個地方,更新請求會陸陸續續,打到所有節點上去更新,有一定的延時,降低了壓力;
    缺點:元數據更新有延時,可能導致集群的一些操作會有一些滯后;

(二)10000端口

    1. 每個節點都有一個專門用于節點間通信的端口,就是自己提供服務的端口號+10000,比如7001,那么用于節點間通信的就是17001端口;
    2. 每個節點每隔一段時間都會往另外幾個節點發送ping信息,同時其他幾個節點接收到ping之后返回pong

(三)交換的信息

    1. 故障信息,節點的增加和移除,hash clot信息,等等;

gossip協議

  1. gossip協議包含多種消息,包括ping、pong、meet、fail等;
  2. meet:某個節點發送meet給新加入的節點,讓新節點加入集群中,然后新節點就會開始與其他節點進行通信;
    redis-trib.rb add-node命令:其實內部就是發送了一個gossip meet消息,給新加入的節點,通知那個節點去加入我們的集群;
  3. ping:每個節點都會頻繁給其他節點發送ping,其中包含自己的狀態還有自己維護的集群元數據,互相通過ping交換元數據;
    每個節點每秒都會頻繁發送ping給其他的集群,ping,頻繁的互相之間交換數據,互相進行元數據的更新;
  4. pong:返回ping和meet,包含自己的狀態和其他信息,也可以用于信息廣播和更新;
  5. fail:某個節點判斷另一個節點fail之后,就發送fail給其他節點,通知其他節點,指定的節點宕機了;

ping消息深入

  1. ping很頻繁,而且要攜帶一些元數據,所以可能會加重網絡負擔;
    每個節點每秒會執行10次ping,每次會選擇5個最久沒有通信的其他節點
  2. 當然如果發現某個節點通信延時達到了cluster_node_timeout/2,那么立即發送ping,避免數據交換延時過長,落后的時間太長了;
  3. 所以cluster_node_timeout可以調節,如果調節比較大,那么會降低發送頻率;
    所以每次ping,一個是帶上自己節點的信息,還有就是帶上1/10其他節點的信息,發送出去,進行數據交換;
    至少包含3個其他節點的信息,最多包含【總節點-2】個其他節點信息;

 

Redis回收算法

介紹

  1. redis是會在數據達到一定程度之后,超過了一個最大的限度之后,就會將數據進行一定的清理,從內存中清理掉一些數據;
  2. redis默認情況下就是使用LRU策略的,因為內存是有限的;
  3. LRU:Least Recently Used,最近最少使用算法;
    將最近一段時間內,最少使用的一些數據,給干掉。比如說有一個key,在最近一個小時內,只被訪問了一次,還有一個key在最近一個小時內,被訪問了一萬次

緩存清理設置

  1. maxmemory,設置redis用來存放數據的最大的內存大小,一旦超出這個內存大小之后,就會立即使用LRU算法清理掉部分數據;
  2. 對于64bit的機器,如果maxmemory設置為0,那么就默認不限制內存的使用,直到耗盡機器中所有的內存為止;
  3. maxmemory-policy,可以設置內存達到最大限制后,采取什么策略來處理;

清理策略

  1. noeviction:如果內存使用達到了maxmemory,client還要繼續寫入數據,那么就直接報錯給客戶端;
  2. allkeys-lru:就是我們常說的LRU算法,移除掉最少使用的那些keys對應的數據;
  3. volatile-lru:也是采取LRU算法,但是僅僅針對那些設置了指定存活時間(TTL)的key才會清理掉;
  4. allkeys-random:隨機選擇一些key來刪除掉;
  5. volatile-random:隨機選擇一些設置了TTL的key來刪除掉;
  6. volatile-ttl:移除掉部分keys,選擇那些TTL時間比較短的keys;

分享到:
標簽:Redis
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定