1. 程式人生 > 資訊 >應急食品備一些:林家鋪子午餐肉 7.5 元 / 罐狂促(豬肉>90%)

應急食品備一些:林家鋪子午餐肉 7.5 元 / 罐狂促(豬肉>90%)

尚矽谷redis筆記

技術的分類:

  1. 解決功能性的問題:Java,Jsp,RDBMS,Tomcat,HTML,Linux,JDBC,SVN
  2. 解決擴充套件性的問題:Struts,Spring,SpringMVC,Hibernate,Mybatis
  3. 解決效能的問題:NoSQL,Java執行緒,Hadoop,Nginx,MQ,ElasticSearch

redis安裝
  1. 下載redis安裝包,解壓後,進入目錄,依次執行makemake install就可以進行安裝。

  2. 預設安裝後文件位置/usr/local/bin/

redis-benchmark:效能測試工具,可以在自己本子執行,看看自己本子效能如何

redis-check-aof:修復有問題的AOF檔案,rdb和aof後面講

redis-check-rdb:修復有問題的dump.rdb檔案

redis-sentinel:Redis叢集使用

redis-server:Redis伺服器啟動命令

redis-cli:客戶端,操作入口


redis啟動
  • 前臺啟動,直接執行redis-server

  • 後臺啟動

    1. 使用redis安裝包中的redis.conf修改引數:

      daemonize yes  #設定後臺啟動
      

​ 2. 使用 redis-server redis.conf的路徑啟動

​ 如 redis-server /root/redis.conf


redis中key的操作

keys *檢視當前庫所有key (匹配:keys *1)

exists key判斷某個key是否存在

type key 檢視你的key是什麼型別

del key 刪除指定的key資料

unlink key 根據value選擇非阻塞刪除(僅將keys從keyspace元資料中刪除,真正的刪除會在後續非同步操作。)

expire key 10 10秒鐘:為給定的key設定過期時間

ttl key 檢視還有多少秒過期,-1表示永不過期,-2表示已過期

select命令切換資料庫

dbsize檢視當前資料庫的key的數量

flushdb清空當前庫

flushall

通殺全部庫


redis資料型別

redis 命令手冊

1. Redis 字串(String)

String型別是二進位制安全的,可以包含任何資料。比如jpg圖片或者序列化的物件。

String型別是Redis最基本的資料型別,一個Redis中字串value最多可以是512M。

String的資料結構為簡單動態字串(Simple Dynamic String,縮寫SDS)。是可以修改的字串。當字串長度小於1M時,擴容都是加倍現有的空間,如果超過1M,擴容時一次只會多擴1M的空間。需要注意的是字串最大長度為512M。

  • set為字串鍵設定值

    NX選項,那麼SET命令只會在鍵沒有值的情況下執行設定操作

    XX選項只會在鍵已經有值的情況下執行設定操作

  • get 獲取字串鍵的值

  • getset 獲取舊值並設定新值

  • del 刪除字串鍵

  • mset 一次為多個字串鍵設定值

  • mget 一次獲取多個字串鍵的值

  • msetnx 只在鍵不存在的情況下,一次為多個字串鍵設定值

  • strlen 獲取字串值的位元組長度

  • getrange 獲取字串值指定索引範圍上的內容

  • setrange 對字串值的指定索引範圍進行設定

  • append 追加新內容到值的末尾

  • incrby,decrby 對整數值執行加法操作和減法操作

  • incr,decr 對整數值執行加1操作和減1操作

  • incrbyfloat 對數字值執行浮點數加法操作

2. Redis列表(List)

單鍵多值、簡單的字串列表,按照插入順序排序。可以新增一個元素到列表的頭部(左邊)或者尾部(右邊)。

它的底層實際是個雙向連結串列,對兩端的操作效能很高,通過索引下標的操作中間的節點效能會較差。

List的資料結構為快速連結串列quickList。

首先在列表元素較少的情況下會使用一塊連續的記憶體儲存,這個結構是ziplist,也即是壓縮列表。

它將所有的元素緊挨著一起儲存,分配的是一塊連續的記憶體。

當資料量比較多的時候才會改成quicklist。

因為普通的連結串列需要的附加指標空間太大,會比較浪費空間。比如這個列表裡存的只是int型別的資料,結構上還需要兩個額外的指標prev和next。

Redis將連結串列和ziplist結合起來組成了quicklist。也就是將多個ziplist使用雙向指標串起來使用。這樣既滿足了快速的插入刪除效能,又不會出現太大的空間冗餘。

  • lpush 將元素推入列表左端

  • rpush 將元素推入列表右端

  • lpushxrpushx 只對已存在的列表執行推入操作.(如果給定列表並不存在,那麼LPUSHX命令和RPUSHX命令將放棄執行推入操作)

  • lpoprpop 彈出列表最左端的元素,彈出列表最右端的元素

  • rpoplpush 將右端彈出的元素推入左端

  • llen 獲取列表的長度

  • lindex 獲取指定索引上的元素

  • lrange 獲取指定索引範圍上的元素

  • lset 為指定索引設定新元素

  • linsert 將元素插入列表

  • ltrim 修剪列表

  • lrem 從列表中移除指定元素

    命令格式:lrem list count element

    • 如果count引數的值等於0,那麼LREM命令將移除列表中包含的所有指定元素。
    • 如果count引數的值大於0,那麼LREM命令將從列表的左端開始向右進行檢查,並移除最先發現的count個指定元素。
    • 如果count引數的值小於0,那麼LREM命令將從列表的右端開始向左進行檢查,並移除最先發現的abs(count)個指定元素(abs(count)即count的絕對值)。
  • blpopbrpop 阻塞式左端彈出操作,阻塞式右端彈出操作

  • brpoplpush 阻塞式彈出並推入操作

3.Redis集合(Set)

Redis set對外提供的功能與list類似是一個列表的功能,特殊之處是set可以自動去重,提供了判斷某個成員是否在一個set集合內的重要介面。

Redis的Set是string型別的無序集合。它底層其實是一個value為null的hash表,所以新增,刪除,查詢的複雜度都是O(1)

Set資料結構是dict字典,字典是用雜湊表實現的。

Redis的set結構類似Java的HashSet,它的內部也使用hash結構,所有的value都指向同一個內部值。

  • sadd 將元素新增到集合

  • srem 從集合中移除元素

  • smove 將元素從一個集合移動到另一個集合

  • smembers 獲取集合包含的所有元素

  • scard 獲取集合包含的元素數量

  • sismember 檢查給定元素是否存在於集合

  • srandmember 隨機獲取集合中的元素

  • spop 隨機地從集合中移除指定數量的元素

  • sintersinterstore 對集合執行交集計算

  • sunionsunionstroe 對集合執行並集計算

  • sdiffsdiffstore 對集合執行差集計算

4.Redis雜湊(Hash)

Redis hash 是一個鍵值對集合,是一個string型別的field和value的對映表

Hash型別對應的資料結構是兩種:ziplist(壓縮列表),hashtable(雜湊表)。當field-value長度較短且個數較少時,使用ziplist,否則使用hashtable。

  • hset 為欄位設定值,也可以為多個欄位設定值

  • hsetnx 只在欄位不存在的情況下為它設定值

  • hget 獲取欄位的值

  • hincrby 對欄位儲存的整數值執行加法或減法操作

  • hincrbyfloat 對欄位儲存的數字值執行浮點數加法或減法操作

  • hstrlen 獲取欄位值的位元組長度

  • hexists 檢查欄位是否存在

  • hdel 刪除欄位

  • hlen 獲取雜湊包含的欄位數量

  • hmset 一次為多個欄位設定值 (Redis 4.0.0 HMSET被視為已棄用,推薦使用HSET)。

  • hmget 一次獲取多個欄位的值

  • hkeyshvalshgetall 獲取所有欄位、所有值、所有欄位和值

5.Redis有序集合Zset(sorted set)

Redis有序集合zset與普通集合set非常相似,是一個沒有重複元素的字串集合。

不同之處是有序集合的每個成員都關聯了一個評分(score),這個評分(score)被用來按照從最低分到最高分的方式排序集合中的成員。集合的成員是唯一的,但是評分可以是重複了 。

zset底層使用了兩個資料結構

(1)hash,hash的作用就是關聯元素value和權重score,保障元素value的唯一性,可以通過元素value找到相應的score值。

(2)跳躍表,跳躍表的目的在於給元素value排序,根據score的範圍獲取元素列表。

  • zadd 新增或更新成員

  • zrem 移除指定的成員

  • zscore 獲取成員的分值

  • zincrby 對成員的分值執行自增或自減操作

  • zcard 獲取有序集合的大小

  • zrankzrevrank 獲取成員在有序集合中的排名

  • zrangezrevrange 獲取指定索引範圍內的成員

  • zrangebyscorezrevrangebyscore 獲取指定分值範圍內的成員

  • zcount 統計指定分值範圍內的成員數量

  • zremrangebyrank 移除指定排名範圍內的成員

  • zremrangebyscore 移除指定分值範圍內的成員

  • zunionstorezinterstore 有序集合的並集運算和交集運算

  • zrangebylexzrerangebylex 返回指定字典序範圍內的成員

    命令格式:zrangebylex sort_set min max

    命令的min引數和max引數用於指定使用者想要獲取的字典序範圍,它們的值可以是以下4種值之一:

    • 帶有[符號的值表示在結果中包含與給定值具有同等字典序大小的成員。
    • 帶有(符號的值表示在結果中不包含與給定值具有同等字典序大小的成員。
    • 加號+表示無窮大。
    • 減號-表示無窮小。
  • zlexcout 統計位於字典序指定範圍內的成員數量

  • zremrangebylex 移除位於字典序指定範圍內的成員

  • bzpopmaxbzpopmin 彈出分值最高和最低的成員

  • bzpopmaxbzpopmin 阻塞式最大/最小元素彈出操作


6.Bitmaps

Redis提供了Bitmaps這個“資料型別”可以實現對位的操作:

(1)Bitmaps本身不是一種資料型別, 實際上它就是字串(key-value) , 但是它可以對字串的位進行操作。

(2)Bitmaps單獨提供了一套命令, 所以在Redis中使用Bitmaps和使用字串的方法不太相同。 可以把Bitmaps想象成一個以位為單位的陣列, 陣列的每個單元只能儲存0和1, 陣列的下標在Bitmaps中叫做偏移量

  • setbit 設定二進位制位的值

  • getbit 獲取二進位制位的值

  • bitcount 統計被設定的二進位制位數量(可以指定位元組範圍)

  • bitpos 查詢第一個指定的二進位制位值

  • bitop 執行二進位制位運算

    當BITOP命令在對兩個長度不同的點陣圖執行運算時,會將長度較短的那個點陣圖中不存在的二進位制位的值看作0。

  • bitfield

    • 命令格式:bitfield bitmap set type offset value 根據偏移量對區域進行設定

      • offset引數用於指定設定的起始偏移量。這個偏移量從0開始計算,偏移量為0表示設定從點陣圖的第1個二進位制位開始,偏移量為1則表示設定從點陣圖的第2個二進位制位開始,以此類推。如果被設定的值長度不止一位,那麼設定將自動延伸至之後的二進位制位。
      • type引數用於指定被設定值的型別,這個引數的值需要以i或者u為字首,後跟被設定值的位長度,其中i表示被設定的值為有符號整數,而u則表示被設定的值為無符號整數。比如i8表示被設定的值為有符號8位整數,而u16則表示被設定的值為無符號16位整數,諸如此類。BITFIELD的各個子命令目前最大能夠對64位長的有符號整數(i64)和63位長的無符號整數(u63)進行操作。
      • value引數用於指定被設定的整數值,這個值的型別應該和type引數指定的型別一致。如果給定值的長度超過了type引數指定的型別,那麼SET命令將根據type引數指定的型別截斷給定值。比如,如果使用者嘗試將整數123(二進位制表示為01111011)儲存到一個u4型別的區域中,那麼命令會先將該值截斷為4位長的二進位制數字1011(即十進位制數字11),然後再進行設定。
    • 命令格式:bitfield bitmap set type #index value 根據給定型別的位長度,對點陣圖在指定索引上儲存的整數值進行設定

      bitfield bitmap set u8 #132 22 對點陣圖的第133個8位無符號整數進行設定(索引是從0開始計算的)。

    • 命令格式:bitfield bitmap get type offsetbitfield bitmap get type #index 獲取區域儲存的值

    • 命令格式:bitfield bitmap incrby type offset incrementbitfield bitmap incrby type #index increment 執行加法操作或減法操作

    • 命令格式:bitfield bitmap [...] overflow wrap|sat|fail [...] 處理溢位

      • WRAP表示使用迴繞(wrap around)方式處理溢位,這也是C語言預設的溢位處理方式。在這一模式下,向上溢位的整數值將從型別的最小值開始重新計算,而向下溢位的整數值則會從型別的最大值開始重新計算。
      • SAT表示使用飽和運算(saturation arithmetic)方式處理溢位,在這一模式下,向上溢位的整數值將被設定為型別的最大值,而向下溢位的整數值則會被設定為型別的最小值。
      • FAIL表示讓INCRBY子命令在檢測到計算會引發溢位時拒絕執行計算,並返回空值表示計算失敗。
7.HyperLogLog

Redis HyperLogLog 是用來做基數統計的演算法,演算法的標準誤差僅為0.81%。

HyperLogLog 的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定的、並且是很小的。

在 Redis 裡面,每個 HyperLogLog 鍵只需要花費 12 KB 記憶體,就可以計算接近 2^64 個不同元素的基數。這和計算基數時,元素越多耗費記憶體就越多的集合形成鮮明對比。
但是,因為 HyperLogLog 只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個元素。

  • pfadd 對集合元素進行計數
  • pfcount 返回集合的近似基數
  • pfmerge 計算多個HyperLogLog的並集

PFCOUNT命令在計算多個HyperLogLog的近似基數時會執行以下操作:

1)在內部呼叫PFMERGE命令,計算所有給定HyperLogLog的並集,並將這個並集儲存到一個臨時的HyperLogLog中。

2)對臨時HyperLogLog執行PFCOUNT命令,得到它的近似基數(因為這是針對單個HyperLogLog的PFCOUNT,所以這個操作不會引起迴圈呼叫)。3)刪除臨時HyperLogLog。

4)向用戶返回之前得到的近似基數

8.Geospatial

Redis 3.2 中增加了對GEO型別的支援。GEO,Geographic,地理資訊的縮寫。該型別,就是元素的2維座標,在地圖上就是經緯度。redis基於該型別,提供了經緯度設定,查詢,範圍查詢,距離查詢,經緯度Hash等常見操作。

  • geoadd 儲存座標
  • geopos 獲取指定位置的座標
  • geodist 計算兩個位置之間的直線距離
  • georadius 查詢指定座標半徑範圍內的其他位置
  • georadiusbymember 查詢指定位置半徑範圍內的其他位置
  • geohash 獲取指定位置的Geohash值
9.流

流(stream)是Redis 5.0版本中新增加的資料結構。

流是一個包含零個或任意多個流元素的有序佇列,佇列中的每個元素都包含一個ID和任意多個鍵值對,這些元素會根據ID的大小在流中有序地進行排列。

  • xadd 追加新元素到流的末尾

    流元素的ID由ID和順序編號(sequcen number)兩部分組成。如果輸入只包含ID,不包含序號,redis會自動將序號部分設定成0.

    同一個流中的不同元素是不允許使用相同ID的,且要求新元素的ID必須比流中所有已有元素的ID都要大。

    流元素ID可以輸入特殊值*,Redis將自動為新新增的元素生成一個可用的新ID(毫秒時間(millisecond)和順序編號(sequcen number)兩部分組成)。

  • xtrim 對流進行修剪

  • xdel 移除指定元素

  • xlen 獲取流包含的元素數量

  • xrangexrevrange 訪問流中元素

  • xread 以阻塞或非阻塞方式獲取流元素

  • xgroup 管理消費者組

  • xreadgroup 讀取消費者組中的訊息

  • xpending 顯示待處理訊息的相關資訊

  • xack 將訊息標記為“已處理”

  • xclaim 轉移訊息的歸屬權

  • xinfo 檢視流和消費者組的相關資訊


Redis的釋出和訂閱

1、客戶端可以訂閱頻道如下圖

2、當給這個頻道釋出訊息後,訊息就會發送給訂閱的客戶端


登入redis客戶端,使用subscribe 頻道來訂閱頻道;使用 publish 頻道 "字串"將字串釋出到指定頻道。


Redis的事務定義

Redis事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷。

Redis事務的主要作用就是串聯多個命令防止別的命令插隊。

1.Multi、Exec、discard

從輸入Multi命令開始,輸入的命令都會依次進入命令佇列中,但不會執行,直到輸入Exec後,Redis會將之前的命令佇列中的命令依次執行。

組隊的過程中可以通過discard來放棄組隊。

2.事務的錯誤處理

組隊中某個命令出現了報告錯誤,執行時整個的所有佇列都會被取消。

如果執行階段某個命令報出了錯誤,則只有報錯的命令不會被執行,而其他的命令都會執行,不會回滾。


樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量。Redis就是利用這種check-and-set機制實現事務的。

3.watch key [key ...]

在執行multi之前,先執行watch key1 [key2],可以監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。

執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。

4.unwatch

取消 WATCH 命令對所有 key 的監視。

如果在執行 WATCH 命令之後,EXEC 命令或DISCARD 命令先被執行了的話,那麼就不需要再執行UNWATCH 了。


Redis持久化之RDB.

Redis 提供了2個不同形式的持久化方式。

  • RDB(Redis DataBase)
  • AOF(Append Of File)

官方文件關於持久化章節


Redis會單獨建立(fork)一個子程序來進行持久化,會先將資料寫入到 一個臨時檔案中,待持久化過程都結束了,再用這個臨時檔案替換上次持久化好的檔案。 整個過程中,主程序是不進行任何IO操作的,這就確保了極高的效能 如果需要進行大規模資料的恢復,且對於資料恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺點是最後一次持久化後的資料可能丟失


1. RDB持久化流程
2.命令save VS bgsave
  • save :save時只管儲存,其它不管,全部阻塞。手動儲存。不建議。
  • bgsave:Redis會在後臺非同步進行快照操作, 快照同時還可以響應客戶端請求。
  • 可以通過lastsave 命令獲取最後一次成功執行快照的時間
3.優勢
  • 適合大規模的資料恢復

  • 對資料完整性和一致性要求不高更適合使用

  • 節省磁碟空間

  • 恢復速度快

4.劣勢
  • Fork的時候,記憶體中的資料被克隆了一份,大致2倍的膨脹性需要考慮

  • 雖然Redis在fork時使用了寫時拷貝技術,但是如果資料龐大時還是比較消耗效能。

  • 在備份週期在一定間隔時間做一次備份,所以如果Redis意外down掉的話,就會丟失最後一次快照後的所有修改。

5.總結

Redis持久化之AOF

AOF(Append Only File)以日誌的形式來記錄每個寫操作(增量儲存),將Redis執行過的所有寫指令記錄下來(讀操作不記錄), 只許追加檔案但不可以改寫檔案,redis啟動之初會讀取該檔案重新構建資料,換言之,redis 重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作

1.AOF持久化流程

(1)客戶端的請求寫命令會被append追加到AOF緩衝區內;

(2)AOF緩衝區根據AOF持久化策略[always,everysec,no]將操作sync同步到磁碟的AOF檔案中;

(3)AOF檔案大小超過重寫策略或手動重寫時,會對AOF檔案rewrite重寫,壓縮AOF檔案容量;

(4)Redis服務重啟時,會重新load載入AOF檔案中的寫操作達到資料恢復的目的;

2.配置

AOF預設不開啟,可以在redis.conf中配置檔名稱,預設為 appendonly.aof。AOF檔案的儲存路徑,同RDB的路徑一致

AOF和RDB同時開啟,系統預設取AOF的資料(資料不會存在丟失)

3.AOF啟動/修復/恢復

AOF的備份機制和效能雖然和RDB不同, 但是備份和恢復的操作同RDB一樣,都是拷貝備份檔案,需要恢復時再拷貝到Redis工作目錄下,啟動系統即載入。

  • 正常恢復
    修改預設的appendonly no,改為yes
    將有資料的aof檔案複製一份儲存到對應目錄(檢視目錄:config get dir)
    恢復:重啟redis然後重新載入

  • 異常恢復
    修改預設的appendonly no,改為yes
    如遇到AOF檔案損壞,通過/usr/local/bin/redis-check-aof--fix appendonly.aof進行恢復
    備份被寫壞的AOF檔案
    恢復:重啟redis,然後重新載入

  1. AOF同步頻率設定

    appendfsync always
    始終同步,每次Redis的寫入都會立刻記入日誌;效能較差但資料完整性比較好
    appendfsync everysec
    每秒同步,每秒記入日誌一次,如果宕機,本秒的資料可能丟失。
    appendfsync no
    redis不主動進行同步,把同步時機交給作業系統。

4.Rewrite壓縮
(1)是什麼:

AOF採用檔案追加方式,檔案會越來越大為避免出現此種情況,新增了重寫機制, 當AOF檔案的大小超過所設定的閾值時,Redis就會啟動AOF檔案的內容壓縮, 只保留可以恢復資料的最小指令集.可以使用命令bgrewriteaof。

(2)重寫原理,如何實現重寫

AOF檔案持續增長而過大時,會fork出一條新程序來將檔案重寫(也是先寫臨時檔案最後再rename),redis4.0版本後的重寫,是指上就是把rdb 的快照,以二級制

的形式附在新的aof頭部,作為已有的歷史資料,替換掉原來的流水賬操作。

no-appendfsync-on-rewrite:

​ 如果 no-appendfsync-on-rewrite=yes ,不寫入aof檔案只寫入快取,使用者請求不會阻塞,但是在這段時間如果宕機會丟失這段時間的快取資料。(降低資料安全性,提高效能)
​ 如果 no-appendfsync-on-rewrite=no, 還是會把資料往磁盤裡刷,但是遇到重寫操作,可能會發生阻塞。(資料安全,但是效能降低)

觸發機制,何時重寫:

Redis會記錄上次重寫時的AOF大小,預設配置是當AOF檔案大小是上次rewrite後大小的一倍且檔案大於64M時觸發。

重寫雖然可以節約大量磁碟空間,減少恢復時間。但是每次重寫還是有一定的負擔的,因此設定Redis要滿足一定條件才會進行重寫。

auto-aof-rewrite-percentage:設定重寫的基準值,檔案達到100%時開始重寫(檔案是原來重寫後文件的2倍時觸發)

auto-aof-rewrite-min-size:設定重寫的基準值,最小檔案64MB。達到這個值開始重寫。

例如:檔案達到70MB開始重寫,降到50MB,下次什麼時候開始重寫?100MB

系統載入時或者上次重寫完畢時,Redis會記錄此時AOF大小,設為base_size,

如果Redis的AOF當前大小>= base_size +base_size*100% (預設)且當前大小>=64mb(預設)的情況下,Redis會對AOF進行重寫。

(3)重寫流程

(1)bgrewriteaof觸發重寫,判斷是否當前有bgsave或bgrewriteaof在執行,如果有,則等待該命令結束後再繼續執行。

(2)主程序fork出子程序執行重寫操作,保證主程序不會阻塞。

(3)子程序遍歷redis記憶體中資料到臨時檔案,客戶端的寫請求同時寫入aof_buf緩衝區和aof_rewrite_buf重寫緩衝區保證原AOF檔案完整以及新AOF檔案生成期間的新的資料修改動作不會丟失。

(4)

​ 1).子程序寫完新的AOF檔案後,向主程序發訊號,父程序更新統計資訊。

​ 2).主程序把aof_rewrite_buf中的資料寫入到新的AOF檔案。

(5)使用新的AOF檔案覆蓋舊的AOF檔案,完成AOF重寫。

5.優勢
  • 備份機制更穩健,丟失資料概率更低。

  • 可讀的日誌文字,通過操作AOF穩健,可以處理誤操作。

6.劣勢

比起RDB佔用更多的磁碟空間。

恢復備份速度要慢。

每次讀寫都同步的話,有一定的效能壓力。

存在個別Bug,造成恢復不能。

7.總結

RDB和AOF用哪個好

官方推薦兩個都啟用。

如果對資料不敏感,可以選單獨用RDB。

不建議單獨用 AOF,因為可能會出現Bug。

如果只是做純記憶體快取,可以都不用。

官網建議:

RDB持久化方式能夠在指定的時間間隔能對你的資料進行快照儲存

AOF持久化方式記錄每次對伺服器寫的操作,當伺服器重啟的時候會重新執行這些命令來恢復原始的資料,AOF命令以redis協議追加儲存每次寫的操作到檔案末尾.

Redis還能對AOF檔案進行後臺重寫,使得AOF檔案的體積不至於過大

只做快取:如果你只希望你的資料在伺服器執行的時候存在,你也可以不使用任何持久化方式.

同時開啟兩種持久化方式

在這種情況下,當redis重啟的時候會優先載入AOF檔案來恢復原始的資料, 因為在通常情況下AOF檔案儲存的資料集要比RDB檔案儲存的資料集要完整.

RDB的資料不實時,同時使用兩者時伺服器重啟也只會找AOF檔案。那要不要只使用AOF呢?

建議不要,因為RDB更適合用於備份資料庫(AOF在不斷變化不好備份), 快速重啟,而且不會有AOF可能潛在的bug,留著作為一個萬一的手段。

效能建議

因為RDB檔案只用作後備用途,建議只在Slave上持久化RDB檔案,而且只要15分鐘備份一次就夠了,只保留save 900 1這條規則。

如果使用AOF,好處是在最惡劣情況下也只會丟失不超過兩秒資料,啟動指令碼較簡單隻load自己的AOF檔案就可以了。

代價,一是帶來了持續的IO,二是AOF rewrite的最後將rewrite過程中產生的新資料寫到新檔案造成的阻塞幾乎是不可避免的。

只要硬碟許可,應該儘量減少AOF rewrite的頻率,AOF重寫的基礎大小預設值64M太小了,可以設到5G以上。

預設超過原大小100%大小時重寫可以改到適當的數值。


Redis_主從複製

主機資料更新後根據配置和策略, 自動同步到備機的master/slaver機制,Master以寫為主,Slave以讀為主

1.作用
  • 讀寫分離,效能擴充套件

  • 容災快速恢復

2.搭建
  • 複製多個redis.conf配置檔案,分別修改其中如下引數:

    # xxx 表示每一個redis例項的配置都不相同
    port xxx   
    protected-mode no
    daemonize yes
    pidfile /var/run/redis_xxx.pid
    dbfilename dumpxxx.rdb
    
  • 分別啟動每個redis例項

為了操作簡單,我本地使用單臺伺服器,通過不同埠號啟動3個redis程序

  • 使用info replication檢視redis狀態

    這時每個redis程序都是主節點,3個redis沒有任何關係

  • 使用slaveof redis主節點IP redis主節點埠號將當前redis作為對應redis的從節點

  • 使用info replication再檢視redis狀態,確認叢集建立成功

3.特點

這種主從複製叢集不能自動進行主從切換(主節點掛掉後,從節點不能變成主節點)。

從節點只能讀,不能寫。

  • 上一個Slave可以是下一個slave的Master,Slave同樣可以接收其他 slaves的連線和同步請求,那麼該slave作為了鏈條中下一個的master, 可以有效減輕master的寫壓力,去中心化降低風險。

    中途變更轉向:會清除之前的資料,重新建立拷貝最新的

    風險是一旦某個slave宕機,後面的slave都沒法備份

    主機掛了,從機還是從機,無法寫資料了

    當一個master宕機後,後面的slave可以立刻升為master,其後面的slave不用做任何修改。

    slaveof no one 將從機變為主機

4.複製原理
  1. Slave啟動成功連線到master後會傳送一個sync命令
  1. Master接到命令啟動後臺的存檔程序,同時收集所有接收到的用於修改資料集命令, 在後臺程序執行完畢之後,master將傳送整個資料檔案到slave,以完成一次完全同步

  2. 全量複製:而slave服務在接收到資料庫檔案資料後,將其存檔並載入到記憶體中。

  3. 增量複製:Master繼續將新的所有收集到的修改命令依次傳給slave,完成同步

  4. 但是隻要是重新連線master,一次完全同步(全量複製)將被自動執行


哨兵模式(sentinel)

還有哨兵叢集模式,解決單個哨兵掛掉的問題。

能夠後臺監控主機是否故障,如果故障了根據投票數自動將從庫轉換為主庫。

1.搭建

1). 參考主從複製章節搭建redis主從複製叢集。

2). 新建sentinel.conf檔案,名字絕不能錯。

​ 檔案內容如下(其中mymaster為監控物件起的伺服器名稱, 1 為至少有多少個哨兵同意遷移的數量。 )

sentinel monitor mymaster 127.0.0.1 6379 1

3). 執行redis-sentinel sentinel.conf路徑

2.複製延時

由於所有的寫操作都是先在Master上操作,然後同步更新到Slave上,所以從Master同步到Slave機器有一定的延遲,當系統很繁忙的時候,延遲問題會更加嚴重,Slave機器數量的增加也會使這個問題更加嚴重。


Redis叢集

1.搭建

如果redis之前已經有資料,需要刪除原來的rdb檔案

  • 修改每個redis.conf關於叢集配置的引數
# xxx 表示每一個redis例項的配置都不相同
port xxx   
protected-mode no
daemonize yes
pidfile /var/run/redis_xxx.pid
dbfilename dumpxxx.rdb
cluster-enabled yes    #開啟叢集模式
cluster-config-file nodes-xxx.conf  #設定節點配置檔名
cluster-node-timeout 15000   #設定節點失聯時間,超過該時間(毫秒),叢集自動進行主從切換。

  • 啟動各個redis

  • 組合成叢集

    redis-cli --cluster create --cluster-replicas 1  127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385
    # --cluster-replicas 1  表示1個主對應1個從
    
2.操作

在redis-cli每次錄入、查詢鍵值,redis都會計算出該key應該送往的插槽,如果不是該客戶端對應伺服器的插槽,redis會報錯,並告知應前往的redis例項地址和埠。

redis-cli客戶端提供了 –c 引數實現自動重定向。

如 redis-cli -c –p 6379 登入後,再錄入、查詢鍵值對可以自動重定向。

不在一個slot下的鍵值,是不能使用mget,mset等多鍵操作。

可以通過{}來定義組的概念,從而使key中{}內相同內容的鍵值對放到一個slot中去。

查詢叢集中的值:

CLUSTER GETKEYSINSLOT 返回 count 個 slot 槽中的鍵。