簡介
官網公布資料:讀的速度是110000次/s,寫的速度是81000次/s
redis是一個key-value儲存系統。和Memcached類似,它支援儲存的value類型相對更多,包括string(字串)、list(鏈表)、set(集合)、zset(sorted set –有序集合)和hash(雜湊類型)。這些資料類型都支援push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支援各種不同方式的排序。與memcached一樣,為了保證效率,資料都是緩衝在記憶體中。區別的是redis會周期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步。(來自百度百科) 同類比較 memcache和redis
懶得自己寫了,拷貝自’真實的歸宿’部落格
- 效能方面:沒有必要過多的關心效能,因為二者的效能都已經足夠高了。由於Redis只使用單核,而Memcached可以使用多核,所以在比較上,平均每一個核上Redis在儲存小資料時比Memcached效能更高。而在100k以上的資料中,Memcached效能要高於Redis,雖然Redis最近也在儲存大資料的效能上進行最佳化,但是比起Memcached,還是稍有遜色。說了這麼多,結論是,無論你使用哪一個,每秒處理請求的次數都不會成為瓶頸。(比如瓶頸可能會在網卡)
- 記憶體使用量效率:使用簡單的key-value儲存的話,Memcached的記憶體利用率更高,而如果Redis採用hash結構來做key-value儲存,由於其組合式的壓縮,其記憶體利用率會高於Memcached。當然,這和你的應用情境和資料特性有關。
- 資料持久化:如果你對資料持久化和資料同步有所要求,那麼推薦你選擇Redis,因為這兩個特性Memcached都不具備。即使你只是希望在升級或者重啟系統後快取資料不會丟失,選擇Redis也是明智的。
- 資料結構:當然,最後還得說到你的具體應用需求。Redis相比Memcached來說,擁有更多的資料結構和並支援更豐富的資料操作,通常在Memcached裡,你需要將資料拿到用戶端來進行類似的修改再set回去。這大大增加了網路IO的次數和資料體積。在Redis中,這些複雜的操作通常和一般的GET/SET一樣高效。所以,如果你需要緩衝能夠支援更複雜的結構和操作,那麼Redis會是不錯的選擇。
- 網路IO模型方面:Memcached是多線程,分為監聽線程、worker線程,引入鎖,帶來了效能損耗。Redis使用單線程的IO複用模型,將速度優勢發揮到最大,也提供了較簡單的計算功能
- 記憶體管理方面:Memcached使用預分配的記憶體池的方式,帶來一定程度的空間浪費,並且在記憶體仍然有很大空間時,新的資料也可能會被剔除,而Redis使用現場申請記憶體的方式來儲存資料,不會剔除任何非臨時資料 Redis更適合作為儲存而不是cache
- 資料的一致性方面:Memcached提供了cas命令來保證.而Redis提供了事務的功能,可以保證一串命令的原子性,中間不會被任何操作打斷 redis資料類型
redis有5種資料類型:string(字串)、hash(雜湊表)、list(鏈表)、set(集合)、zset(有序集合)
redis編碼方式:raw(簡單動態字串)、int(long整數)、ht(字典)、linkedlist(雙端鏈表)、ziplist(壓縮鏈表)、skiplist(跳躍表)、intset(整數集合) 類型編碼方式對應關係
簡單動態字串
鏈表
字典
redis字典的使用雜湊表最為底層實現,如圖
redis資料庫鍵空間是的一個字典儲存了資料庫所有索引值對
鍵是資料庫的鍵,為字串對象
值是資料庫的值,可能是5種資料類型的一種
事物 redis事物包含三個階段: 事物開始 命令multi 命令入隊 事物隊列先進先出(FIFO) 事物執行 命令exec
redis的事物不能復原,如三條命令1、2、3,順新執行,當2出現問題是,1不會被復原 持久化 快照rdb
預設使用的持久化方式
命令 SAVE BGSAVE
SAVE會阻塞伺服器處理序,直到rdb檔案建立完成
BGSAVE不會阻塞,會派出一個線程實現
redis預設使用BGSAVE方式,設定檔指定執行間隔
save 900 1 #900秒內有一次變更
save 300 10 #300秒內有10次變更
save 60 10000 #60秒內有10000次變更
啟動伺服器自動匯入rdb檔案,若有aof檔案優先匯入aof檔案 aof(append only file)持久化
通過儲存redis伺服器所執行的寫命令來記錄資料庫狀態
aof持久化分為:命令追加、檔案寫入檔案同步 命令追加:伺服器執行一條寫命令後,會以協議格式(純文字格式)將命令追加到aof_buf緩衝區末尾 檔案寫入檔案同步: 通過ServerCron定時函數,調用flushAppendOnlyFile函數確定是否將緩衝區內容寫入aof檔案
aof檔案載入還原
建立一個不帶網路連結的虛擬用戶端,執行aof檔案中命令
註:redis命令只能在用戶端內容執行 aof重寫 為什麼需要重寫
aof命令追加會導致aof檔案越來越大,影響效能 原理 redis伺服器是單線程,為防止aof重寫時阻塞redis主線程,redis將aof重寫放到子進程執行,這樣不會影響redis伺服器處理命令請求 aof重寫,建立一個新的aof檔案,從redis資料庫讀取當期值,用一條命令去記錄索引值對 在aof重寫進行中,伺服器還在處理請求,為防止資料不一致,增加一個aof重寫緩衝區,等待子進程處理完成是,向伺服器發送訊號,這時會阻塞伺服器,將aof重寫緩衝區內容寫入新的aof檔案,完成後修改檔案名稱替換原來aof檔案,完成aof重寫 觸發時機
觸發AOF後台重寫的條件 1、AOF重寫可以由使用者通過調用BGREWRITEAOF手動觸發。
2、伺服器在AOF功能開啟的情況下,會維持以下三個變數: 記錄當前AOF檔案大小的變數aof_current_size。 記錄最後一次AOF重寫之後,AOF檔案大小的變數aof_rewrite_base_size。 增長百分比變數aof_rewrite_perc。
每次當serverCron(伺服器常規操作)函數執行時,它會檢查以下條件是否全部滿足,如果全部滿足的話,就觸發自動的AOF重寫操作:
1)、沒有BGSAVE命令(RDB持久化)/AOF持久化在執行;
2)、沒有BGREWRITEAOF在進行;
3)、當前AOF檔案大小要大於server.aof_rewrite_min_size(預設為1MB),或者在redis.conf配置了auto-aof-rewrite-min-size大小;
4)、當前AOF檔案大小和最後一次重寫後的大小之間的比率等於或者等於指定的增長百分比(在設定檔設定了auto-aof-rewrite-percentage參數,不設定預設為100%)
如果前面三個條件都滿足,並且當前AOF檔案大小比最後一次AOF重寫時的大小要大於指定的百分比,那麼觸發自動AOF重寫。 複製 slaveof命令讓一個伺服器複製另一個伺服器 被複製的伺服器稱為主伺服器(master) 進行複製的伺服器稱為從伺服器(slave) redis複製功能分為同步、命令傳播 同步實現
命令傳播
主從伺服器達到一致以後,主伺服器執行寫命令後,會將命令發送給從伺服器,確保狀態一致
註:老版的SYNC複製,不能解決斷線重連問題(斷線重連後會整個複製一次,效能很低),新版複製使用PSYNC增加部分複製功能,通過位移量實現(詳情見:redis設計與實現第二版) 哨兵
是redis高可用性的一種解決方案 實現
由一個或多個sentinel執行個體組成sentinel系統,監視任意多個主伺服器及主伺服器的從伺服器,當主伺服器下線時將其從伺服器升級為新的主伺服器,繼續處理命令(詳情見:redis設計與實現第二版) 叢集
redis使用叢集後,就沒有那個資料庫的概念了,叢集將整個資料庫分為16384個槽(slot),每個節點管理0-16384個槽,當所有槽都有節點處理的時候叢集處於上線狀態,否則叢集是下線狀態
計算key屬於那一個槽演算法
CRC16(key) & 16383 CRC16(key)計算CRC-16校正和, & 16383 計算出一個介於0-16383的整數做為key的槽號 發布訂閱
沒有使用過(詳情見:redis設計與實現第二版) 常用命令 redis命令
keys key*
ttl key
type key
del key
exists key
info 列印redis伺服器資訊
flushdb 刪除當前db的所有key
flushall 刪除所有db的所有key 字串、hash、list、set、zset有序集合等
命令可以參考https://www.cnblogs.com/luoxn28/p/5790313.html redis使用情境 一般字元串緩衝(如:token、使用者id、session等) 計數器 排名
假定有一個即時的競技場評分,在玩家結束操作後打分,並動態顯示玩家的熱門排行榜
zadd rank 100 biki 87 zhibin 72 ming 64 fen 98 cat
(integer) 5
顯示得分最高的前三名玩家
ZREVRANGE rank 0 2 WITHSCORES
1) “biki”
2) 100.0
3) “cat”
4) 98.0
5) “zhibin”
6) 87.0 分布式鎖
通過setnx命令實現
成功設定值返回1,否則返回0
127.0.0.1:6379> setnx test value(integer) 1127.0.0.1:6379> setnx test value(integer) 0127.0.0.1:6379>
注意:使用redis實現分布式鎖,需要設定到期時間,防止產生死結
參考資料
官網https://redis.io/
redis設計與實現(第二版)
http://blog.csdn.net/hguisu/article/details/8836819
https://baike.baidu.com/item/Redis/6549233?fr=aladdin