由上述三個問題,看看redis如何解決這三大難題:node
Redis支持兩種方式的持久化,一種是RDB方式、另外一種是AOF(append-only-file)方式。前者會根據指定的規則「定時」將內存中的數據存儲在硬盤上,然後者每次會將事務操做記錄下來。兩種持久化方式能夠單獨使用其中一種,也能夠將這兩種方式結合使用。mysql
從對比中看看RDB和AOF的持久化的方式:redis
RDB方式 後臺建立(fork)一個子進程去持久化數據,能夠理解成磁盤和內存直接的一個讀寫IO,這個過程咱們會考慮三個問題:算法
AOF方式 默認狀況下Redis沒有開啓AOF(append only file)方式的持久化,能夠經過appendonly參數啓用,在redis.conf中找到 appendonly yes.開啓AOF持久化後每執行一條會更改Redis中的數據的命令後,Redis就會將該命令寫入硬盤中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是經過dir參數設置的,默認的文件名是apendonly.aof. 能夠在redis.conf中的屬性 appendfilename appendonlyh.aof修改.sql
AOF過程當中咱們已經明白的一點是:他的持久化並不是儲存的是數據,而是記錄,有點相似於mysql的binlog.因此AOF就算宕機也是不可能發生數據丟失的。那對於日誌文件愈來愈大,AOF該如何處理?緩存
set foo 1 set foo 2 set foo 3 get 對於AOF的這份日誌,其實最終只須要一個set foo 3.因此對於redis的aof文件能夠配置重寫策略,這個條件的配置爲 auto-aof-rewritepercentage 100 auto-aof-rewrite-min-size 64mb服務器
auto-aof-rewrite-percentage 表示的是當目前的AOF文件大小超過上一次重寫時的AOF文件大小的百分之多少時會再次進行重寫,若是以前沒有重寫過,則以啓動時AOF文件大小爲依據網絡
auto-aof-rewrite-min-size 表示限制了容許重寫的最小AOF文件大小,一般在AOF文件很小的狀況下即便其中有不少冗餘的命令咱們也並不太關心。併發
AOF重寫原理:app
aof的重寫原理能夠解決不阻塞的狀況下保證數據的完整性。 重寫的流程是這樣,主進程會fork一個子進程出來進行AOF重寫,這個重寫過程並非基於原有的aof文件來作的,而是有點相似於快照的方式,全量遍歷內存中的數據,而後逐個序列到aof文件中。在fork子進程這個過程當中,服務端仍然能夠對外提供服務,那這個時候重寫的aof文件的數據和redis內存數據不一致了怎麼辦?不用擔憂,這個過程當中,主進程的數據更新操做,會緩存到aof_rewrite_buf中,也就是單獨開闢一塊緩存來存儲重寫期間收到的命令,當子進程重寫完之後再把緩存中的數據追加到新的aof文件。當全部的數據所有追加到新的aof文件中後,把新的aof文件重命名爲,此後全部的操做都會被寫入新的aof文件。
Redis中提供了多種內存回收策略,當內存容量不足時,爲了保證程序的運行,這時就不得不淘汰內存中的一些對象,釋放這些對象佔用的空間,那麼選擇淘汰哪些對象呢?
過時時間設置
在Redis中提供了Expire命令設置一個鍵的過時時間,到期之後Redis會自動刪除它。這個在咱們實際使用過程當中用得很是多。 EXPIRE命令的使用方法爲 EXPIRE key seconds 其中seconds 參數表示鍵的過時時間,單位爲秒。其中可使用TTL key 查看時間剩餘。
過時key自動刪除的原理:
redis有兩種方式去刪除key:
消極方法(passive way) 在key被訪問時若是發現它已經失效,那麼就刪除它.
積極方法(active way) 週期性地從設置了失效時間的主鍵中選擇一部分失效的key刪除 對於那些從未被查詢的key,即使它們已通過期,被動方式也沒法清除。所以Redis會週期性地隨機測試一些key,已過時的key將會被刪掉。Redis每秒會進行10次操做,具體的流程:
官方的解釋是,CPU並非Redis的瓶頸所在,Redis的瓶頸主要在機器的內存和網絡的帶寬。那麼Redis能不能處理高併發請求呢?固然是能夠的,至於怎麼實現的,目前只說一個名詞:多路複用,至於什麼事多路複用,在後續的netty框架博客中會詳細介紹。
1. 主從複製
配置:
配置步驟很簡單,例如如今有3臺機器(master,node1,node2)
只須要在node1,node2的redis.conf 文件下加上一個slaveof master port。
錯誤排查:如何未成功,先檢驗node1和node2是否能夠鏈接master的服務。
redis-cli -h master的iP -p 端口port
觀察redis服務端狀態的命令:127.0.0.1:6379> INFO replication
能夠用來查看主從是否配置成功。
主從複製的特色:
master機器能夠讀寫,slave機器默認狀況下不能夠寫操做
主從複製,數據同步過程和原理:
slave 剛啓動成爲master的從庫:
觀察輸出日誌:
[2603] 18 Jan 10:32:41.106 * Slave asks for synchronization
[2603] 18 Jan 10:32:41.106 * Full resync requested by slave.
[2603] 18 Jan 10:32:41.106 * Starting BGSAVE for SYNC
[2603] 18 Jan 10:32:41.210 * Background saving started by pid 2618
[2618] 18 Jan 10:32:41.232 * DB saved on disk
[2618] 18 Jan 10:32:41.232 * RDB: 6 MB of memory used by copy-on-write
[2603] 18 Jan 10:32:41.333 * Background saving terminated with success
[2603] 18 Jan 10:32:41.333 * Synchronization with slave succeeded
複製代碼
從日誌能夠看出,redis會觸發bgsave去生成一個快照,而後發送給slave。從庫load快照文件,成功而後通知主庫。接下來會進行,增量複製從redis2.8開始,就支持主從複製的斷點續傳,若是主從複製過程當中,網絡鏈接斷掉了,那麼能夠接着上次複製的地方,繼續複製下去,而不是從頭開始複製一份masternode會在內存中建立一個backlog,master和slave都會保存一個replica offset還有一個masterid,offset就是保存在backlog中的。若是master和slave網絡鏈接斷掉了,slave會讓master從上次的replicat offset開始繼續複製可是若是沒有找到對應的offset,那麼就會執行一次全量同步。
另外一種複製方式就是無磁盤複製: Redis複製的工做原理基於RDB方式的持久化實現的,也就是master在後臺保存RDB快照,slave接收到rdb文件並載入,可是這種方式會存在一些問題
經過如下配置來開啓該功能 repl-diskless-sync yes master在內存中直接建立rdb,而後發送給slave,不會在本身本地落地磁盤了。
哨兵機制
哨兵的做用就是監控和選舉,監控master 和 slave 是否正常,master宕機以後,從新選舉
配置過程:
哨兵模式的配置也很是簡單,只須要啓動一個哨兵的sentinel服務便可。配置信息中有一個須要注意的: sentinel monitor mymaster 192.168.2.7 6379 1 其中192.168.2.7是master的ip 6379是端口,1表明是幾個哨兵經過。通常看哨兵服務有多少個。配置通常是n/2 +1 (半數以上)
接下看看master宕機以後:首先會從slave中選取一個做爲master。選舉完成後會發生以下變化,redis.conf中的,slaveof ip port會變化,sentinel.conf 文件也會發生變化。master的ip 和端口會發生變化。
總而言之,redis的主從複製和哨兵模式服務能夠保證redis服務的高可用。
redis的分片存儲,單臺redis的內存是有限的,若是對於特別大的數據量,就必須使用redis的分片存儲了。目前本人並何嘗試這種開發,在redis3.0版本以後。redis支持集羣的功能,能夠解決路由規則(hash算法的均勻分佈) 和 動態擴容。能簡單的水平擴容,增長節點機器,分片存儲。客戶端操做面向的是集羣。
客戶端選擇:jedis ,Redisson(相似zk的curator,更上層的封裝) Jedis客戶端鏈接有三種方式: 單個redis鏈接池,哨兵模式下鏈接池,集羣鏈接池。在不一樣的框架中如jedis對於三種鏈接定義不一樣的封裝類。 對於後續的redis的分佈式鎖以及布隆過濾器解決緩存擊穿等問題,請持續關注博客更新。
91Code-就要編碼,關注公衆號獲取更多內容!