Redis概述 Redis是一種key-value型資料庫,運行於記憶體中,與它相似的資料庫有memcached,現在基本被Redis替代。 Redis適用場景 我們要與傳統的關係型資料庫進行對比才能更好的瞭解與使用Redis 1.高併發場景, redis是個單線程的程式對於純記憶體操作如hash查找可 ...
Redis概述
Redis是一種key-value型資料庫,運行於記憶體中,與它相似的資料庫有memcached,現在基本被Redis替代。
Redis適用場景
我們要與傳統的關係型資料庫進行對比才能更好的瞭解與使用Redis
1.高併發場景, redis是個單線程的程式對於純記憶體操作如hash查找可達到每秒百萬次的數量級。
比如說點贊這個業務,我們在redis中可以這樣用set(關於redis的數據結構下文會詳述)來存,key就是被點贊實體(如問題或評論)的id或唯一標誌,主動點贊的用戶ID都存在這個set裡面, 執行點贊時把用戶ID存在這個set裡面就行了。 我們再看看MySQL里怎麼做,被點贊實體的ID和點贊實體的ID就是一條記錄,第一點由於鎖的存在讀取點贊人數時會對錶加讀鎖,這時候就不能添加記錄,第二點是基於磁碟的,讀寫速率都很慢。
2.列舉最新列表
redis中可使用list這個數據結構,用來存儲最新的n條記錄(lpush,和trim配合使用),每回取就使用lrange命令就行 。我們再看看MySQL在裡面怎麼做,如下是一個典型的查詢語句:select * from table where.... order by time desc limit n ,隨著數據增多只會越來越慢。
3.排行榜
redis提供一種數據結構sortset,優先隊列即裡面的元素可以按分值來排序。常用操作zadd等,由於這些信息也是常常跟新的基於磁碟的MySQL顯然性能不夠好。
4.消息隊列,阻塞隊列
redis提供阻塞隊列這種數據數據結構常用,命令如brpop。
5.設置過期數據
redis,的K-V數據結構提供數據過期值,比如對於驗證碼,緩存(基於緩存計劃會再寫一篇詳細的文章)
綜上,在實際開發中我們常常是將MySQL和Redis一起結合來使用的,不同場景使用不同的工具。
Redis 常用數據結構及命令
- 雙向列表List: lpush,lpop,brpop,lrange,linsert等等
- 無序集合Set: scard,sdiff(A中有B中沒的),smembers,sinter(交集)
- 有序集合SortedSet: zadd,zscore
- 單一數值KV: set,setex
- 存儲對象Hash: hset,hget
更多詳細信息請見https://redis.io/commands
Redis部分數據結構的底層設計
1.動態字元串SDS
我們執行一個命令,set msg "hello" ,那麼底層就是產生兩個SDS對象。 接下來我們看看SDS與C語言的傳統字元串有什麼區別(Redis使用C語言來編寫)。SDS實則是一個結構體:如下圖
這個結構體有一個位元組數組,當前字元長度,可以數組長度(free)組成,SDS主要在以下兩方面做了優化
- C語言若字元串溢出,那麼系統將重新分配記憶體(這個可能執行系統調用)並將內容都複製到另一個數組當中,對於高性能的redis來說這是很耗時間的。SDS則在每一次拼接字元串時判斷空間是否夠大,不夠分配1MB記憶體,夠則分配free大小記憶體。
- 字元串縮短時記憶體先不回收,而是暫時存起來,減少記憶體重分配次數
- 二進位安全,使用len判斷字元串是否結束,可保存二進位數據
2.鏈表
- 雙向無環鏈表
3.字典
- 廣泛用於redis各種功能,一個字典有兩個哈希表,一個平時使用一個rehash時使用
- hash衝突時一個索引上的多個鍵連接成一個單項列表(加在表頭)
- 根據負載因數(記憶體與時間的平衡,已保存節點數/哈希表大小,臨界值分別是0.1,5)決定是否rehash。採用漸進式rehash(保證性能,和寫時複製技術思路相似),主要為以下幾個步驟
-
-
- 為上面說的另一個hash h1表分配空間
- 字典內維持一個索引計數器,每次執行添加,刪除,查找或更新時除指定操作後還將相應鍵值對rehash到h1上,直至操作完成(每個哈希表會標有已存在的實體數)
-
-
Redis持久性
Redis提供兩種持久化方式:快照(RDB),和AOF(記錄每一個操作)
- RDB每隔一個特定的時間保存那個時間點的一個數據快照
- AOF保存每一個操作,Redis重啟時逐條執行每個操作重建原來的數據
- 兩種持久化方式可以同時存在,Redis重啟時優先使用AOF
RDB
原理
- Redis調用Fork()創建子進程
- 子進程將數據寫入到一個RDB文件里
- 替換舊的RDB文件
- 文件存放在當前目錄的dump.rdb文件內,可以通過redis.conf修改文件名及目錄
缺點
- 由於每隔一段時間執行,,可能會造成數據丟失。
- 使用Fork()創建子進程時,如果數據量很大Fork()造作會造成Redis暫停服務幾秒鐘。
優點
- RDB文件易於做備份,數據量大時啟動速度快
常見配件信息(redis.conf中)
AOF
優點
- 丟失數據的可能性減少
缺點
- AOF文件比RDB大
未完待續。。。
參考資料
https://www.zhihu.com/question/19764056
https://segmentfault.com/a/1190000002906345
http://blog.csdn.net/hguisu/article/details/8836819