Redis特性和性能調優

概要

在分佈式裏面知足CP (一致性、分區容錯性)。redis

性能:對於單純只有IO操做來講,單線程能夠將速度優點發揮到最大,可是Redis也提供了一些簡單的計算功能,好比排序、聚合等,對於這些操做,單線程模型實際會嚴重影響總體吞吐量,CPU計算過程當中,整個IO調度都是被阻塞住的。數據庫

一  Redis和Memcached對比

1:數據類型:Memcached單個key-value大小有限,一個value最大隻支持1MB,而Redis最大支持512MB,支持set,list等類型緩存

2:持久性:Memcached只是個內存緩存,對可靠性無要求;而Redis更傾向於內存數據庫,所以對對可靠性方面要求比較高、作了數據持久化服務器

3:數據一致性:redis是單線程模型,保證了數據按順序提交,Redis提供了事務的功能,能夠保證一串 命令的原子性,中間不會被任何操做打斷。  memcached須要cas保證數據一致性,在高併發下。性能會受到影響,甚至不如redis。架構

二  數據回收策略

相關知識:redis 內存數據集大小上升到必定大小的時候,就會施行數據淘汰策略(回收策略)。redis 提供 6種數據淘汰策略:併發

  1. volatile-lru:從已設置過時時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰
  2. volatile-ttl:從已設置過時時間的數據集(server.db[i].expires)中挑選將要過時的數據淘汰
  3. volatile-random:從已設置過時時間的數據集(server.db[i].expires)中任意選擇數據淘汰
  4. allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
  5. allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
  6. no-enviction(驅逐):禁止驅逐數據

三  持久化

fork操做都會形成主線程堵塞。這個時候服務是中止的。app

3.1 RDB(redis database)

         rdb爲二進制文件,redis在指定的時間內(默認配置3個時間段,1分鐘1W次,10分鐘10次,15分鐘1次),把內存的數據集快照寫入到磁盤,恢復的時候是將硬盤中快照文件寫入內存。redis 會單獨建立(fork)一個子進程去進行持久化,先寫入一個臨時文件dump.rdb ,待持久化結束了,再替換上次持久化好的文件,整個過程當中,主線程是不須要任何io操做的。(子進程保持數據一致性)。運維手段(上報dump.rdb)運維

         若是須要大規模恢復,且對數據缺失不是很敏感。那麼採用RDB,RDB的方式比AOF更加高效,可是最後一次持久化的數據可能丟失。通常作冷數據備份dom

         fork的時候,內存中的數據被克隆了一份,大體2倍的膨脹性須要考慮,當數據集比較大額時候,folk的過程是比較耗時的,可能會致使redis在一些毫秒級不能響應客服端請求分佈式

3.2 AOF(append only file)

(若是同時rdb和aof同時存在,先加載aof,error才加載rdb):命令

        redis也會fork一個子進程,以日誌的形式記錄每次寫操做命令。 AOF持久化以日誌的形式記錄服務器所處理的每個寫、刪除操做,查詢操做不會記錄,換句話說,恢復的時候,把文件記錄命令所有再執行一遍

       AOF是存放每條寫命令的,因此會不斷的增大,當大到必定程度時,AOF會作rewrite操做,rewrite操做就是基於當時redis的數據從新構造一個小的AOF文件,而後將大的AOF文件刪除。

  1. 對於同一份文件AOF文件比RDB數據快照要大。
  2. AOF開啓後支持寫的QPS會比RDB支持的寫的QPS低,由於AOF通常會配置成每秒fsync操做,每秒的fsync操做仍是很高的
  3. 數據恢復比較慢,不適合作冷備。

四  事務

不保證原子性,部分支持事務,可是能夠經過watch實現樂觀鎖

開啓事務-》放入隊列-》執行,本質上是一組命令的集合。一個事務中的全部命令都會被序列化,按照順序串行地執行而不會被其餘命令插入。 

原子性:redis事務不能保證原子性,有一個執行失敗,其它依被執行,沒有回滾

隔離級別:沒有數據那些隔離級別概念,隊列裏面沒有提交以前都不會執行,在執行過程當中也不會被其它事務打斷。

  1. 若是中途命令(編譯)出錯。那麼所有不執行
  2. 若是是運行時報錯,其餘依然執行。出錯的不執行:字符串+1

一致性問題:

在事務以前有其餘執行,那麼數據就有誤

WATCH (樂觀鎖)

能夠監視一個或多個key,一旦其中有任意一個key被修改,那麼事務被打斷,都不會被執行,返回失敗,可是並不能保證其餘客戶端不修改監控的值,因此當EXEC命令執行失敗以後須要手動從新執行整個事務

僞代碼:

exec(WATCH stock:1001);

if(exec(HGET stock:1001 state) == "in stock") {

    exec(MULTI);

    exec(HSET stock:1001 state "sold");

    exec(EXEC);

}

五  集羣

軟件架構不是越複雜越好,儘可能減小過分設計,咱們用的主從。

5.1 主從複製

info replication —查看集羣信息

  1. 只有1Master,能夠有Nslaver,並且Slaver也能夠有本身的Slaver,因爲這種主從的關係決定他們是在配置階段就要指定他們的上下級關係,而不是Zookeeper那種平行關係是自主推優出來的。
  2. 讀寫分離,Master只負責寫和同步數據給SlaverSlaver承擔了被讀的任務,因此Slaver的擴容只能提升讀效率不能提升寫效率。
  3. Slaver先將Master那邊獲取到的信息壓入磁盤,再load進內存,client端是從內存中讀取信息的,因此Redis是內存數據庫。
  4. 當一個新的Slaver加入到這個集羣時,會向主服務器發送一個 SYNC 命令,Master發現新的小弟後將全量數據(全量是rdb、增量是aof文件)發送給新的Slaver,數據量越大性能消耗也就越大,因此儘可能避免在運行時作Slaver的擴容

簡單總結下主從模式的設計:

優勢:讀寫分離,經過增長Slaver能夠提升併發讀的能力。

缺點:Master寫能力是瓶頸。

          雖然理論上對Slaver沒有限制可是維護Slaver開銷總將會變成瓶頸。

          Master的Disk大小也將會成爲整個Redis集羣存儲容量的瓶頸。

Sentinel哨兵模式:

可以後臺監控主機是否故障,若是故障了根據投票數自動將從庫轉換爲主庫。

5.2  集羣分片

哈希Slot [slɒt]:就是分庫分表,hash取模

           Redis Cluster中共有16384個hash slot,Redis會計算每一個key的CRC16,將結果與16384取模,來決定該key存儲在哪個hash slot中,同時須要指定Redis Cluster中每一個數據分片負責的Slot數。Slot的分配在任什麼時候間點均可以進行從新分配。

 

5.3  主從分片

           想擴展併發讀就添加Slaver,想擴展併發寫就添加Master,想擴容也就是添加Master,任何一個Slaver或者幾個Master掛了都不會是災難性的故障。

簡單總結下哈希Slot的優缺點:

缺點:每一個Node承擔着互相監聽、高併發數據寫入、高併發數據讀出,工做任務繁重

優勢:將Redis的寫操做分攤到了多個節點上,提升寫的併發能力,擴容簡單。

六  緩存穿透、雪崩