1. 程式人生 > >2018.9.16 Redis 邊學習邊總結

2018.9.16 Redis 邊學習邊總結

block www content 串行 uri 字符 數據備份 相關 文件解析

Redis 是一個使用 C 語言寫成的,開源的 key-value 數據庫。。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。目前,Vmware在資助著redis項目的開發和維護。

書籍推薦

《Redis實戰》

《Redis設計與實現》

教程推薦

redis官方中文版教程:http://www.redis.net.cn/tutorial/3501.html

Redis 教程(菜鳥教程):http://www.runoob.com/redis/redis-tutorial.html

常見問題總結

就我個人而言,我覺得Redis的基本使用是我們每個Java程序員都應該會的。另外,如果需要面試的話,一些關於Redis的理論知識也需要好好的學習一下。學完Redis之後,對照著下面8點看看自己還有那些不足的地方,同時,下面7點也是面試中經常會問到的。另外,《Redis實戰》、《Redis設計與實現》是我比較推薦的兩本學習Redis的書籍。

  1. Redis的兩種持久化操作以及如何保障數據安全(快照和AOF)
  2. 如何防止數據出錯(Redis事務)
  3. 如何使用流水線來提升性能
  4. Redis主從復制
  5. Redis集群的搭建
  6. Redis的幾種淘汰策略
  7. Redis集群宕機,數據遷移問題
  8. Redis緩存使用有很多,怎麽解決緩存雪崩和緩存穿透?

Redis常見問題分析與好文Mark

什麽是Redis?

Redis 是一個使用 C 語言寫成的,開源的 key-value 數據庫。。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。目前,Vmware在資助著redis項目的開發和維護。

Redis與Memcached的區別與比較

1 、Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。memcache支持簡單的數據類型,String。

2 、Redis支持數據的備份,即master-slave模式的數據備份。

3 、Redis支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用,而Memecache把數據全部存在內存之中

4、 redis的速度比memcached快很多

5、Memcached是多線程,非阻塞IO復用的網絡模型;Redis使用單線程的IO復用模型。

技術分享圖片

如果想要更詳細了解的話,可以查看慕課網上的這篇手記(非常推薦) :《腳踏兩只船的困惑 - Memcached與Redis》:https://www.imooc.com/article/23549

Redis與Memcached的選擇

終極策略: 使用Redis的String類型做的事,都可以用Memcached替換,以此換取更好的性能提升; 除此以外,優先考慮Redis;

使用redis有哪些好處?

(1) 速度快,因為數據存在內存中,類似於HashMap,HashMap的優勢就是查找和操作的時間復雜度都是O(1)

(2)支持豐富數據類型,支持string,list,set,sorted set,hash

(3) 支持事務 :redis對事務是部分支持的,如果是在入隊時報錯,那麽都不會執行;在非入隊時報錯,那麽成功的就會成功執行。詳細了解請參考:《Redis事務介紹(四)》:https://blog.csdn.net/cuipeng0916/article/details/53698774

redis監控:鎖的介紹

(4) 豐富的特性:可用於緩存,消息,按key設置過期時間,過期後將會自動刪除

Redis常見數據結構使用場景

1. String

常用命令: set,get,decr,incr,mget 等。

String數據結構是簡單的key-value類型,value其實不僅可以是String,也可以是數字。
常規key-value緩存應用;
常規計數:微博數,粉絲數等。

2.Hash

常用命令: hget,hset,hgetall 等。

Hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象。 比如我們可以Hash數據結構來存儲用戶信息,商品信息等等。

舉個例子: 最近做的一個電商網站項目的首頁就使用了redis的hash數據結構進行緩存,因為一個網站的首頁訪問量是最大的,所以通常網站的首頁可以通過redis緩存來提高性能和並發量。我用jedis客戶端來連接和操作我搭建的redis集群或者單機redis,利用jedis可以很容易的對redis進行相關操作,總的來說從搭一個簡單的集群到實現redis作為緩存的整個步驟不難。感興趣的可以看我昨天寫的這篇文章:

《一文輕松搞懂redis集群原理及搭建與使用》: https://juejin.im/post/5ad54d76f265da23970759d3

3.List

常用命令: lpush,rpush,lpop,rpop,lrange等

list就是鏈表,Redis list的應用場景非常多,也是Redis最重要的數據結構之一,比如微博的關註列表,粉絲列表,最新消息排行等功能都可以用Redis的list結構來實現。

Redis list的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷。

4.Set

常用命令:
sadd,spop,smembers,sunion 等

set對外提供的功能與list類似是一個列表的功能,特殊之處在於set是可以自動排重的。
當你需要存儲一個列表數據,又不希望出現重復數據時,set是一個很好的選擇,並且set提供了判斷某個成員是否在一個set集合內的重要接口,這個也是list所不能提供的。

在微博應用中,可以將一個用戶所有的關註人存在一個集合中,將其所有粉絲存在一個集合。Redis可以非常方便的實現如共同關註、共同喜好、二度好友等功能。

5.Sorted Set

常用命令: zadd,zrange,zrem,zcard等

和set相比,sorted set增加了一個權重參數score,使得集合中的元素能夠按score進行有序排列。

舉例: 在直播系統中,實時排行信息包含直播間在線用戶列表,各種禮物排行榜,彈幕消息(可以理解為按消息維度的消息排行榜)等信息,適合使用Redis中的SortedSet結構進行存儲。

MySQL裏有2000w數據,Redis中只存20w的數據,如何保證Redis中的數據都是熱點數據(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(驅逐):禁止驅逐數據

Redis的並發競爭問題如何解決?

Redis為單進程單線程模式,采用隊列模式將並發訪問變為串行訪問。Redis本身沒有鎖的概念,Redis對於多個客戶端連接並不存在競爭,但是在Jedis客戶端對Redis進行並發訪問時會發生連接超時、數據轉換錯誤、阻塞、客戶端關閉連接等問題,這些問題均是由於客戶端連接混亂造成。對此有2種解決方法:

 1.客戶端角度,為保證每個客戶端間正常有序與Redis進行通信,對連接進行池化,同時對客戶端讀寫Redis操作采用內部鎖synchronized。
 
2.服務器角度,利用setnx實現鎖。

 註:對於第一種,需要應用程序自己處理資源的同步,可以使用的方法比較通俗,可以使用synchronized也可以使用lock;第二種需要用到Redis的setnx命令,但是需要註意一些問題。

Redis回收進程如何工作的? Redis回收使用的是什麽算法?

Redis內存回收:LRU算法(寫的很不錯,推薦):https://www.cnblogs.com/WJ5888/p/4371647.html

Redis 大量數據插入

官方文檔給的解釋:http://www.redis.cn/topics/mass-insert.html

Redis 分區的優勢、不足以及分區類型

官方文檔提供的講解:http://www.redis.net.cn/tutorial/3524.html

Redis持久化數據和緩存怎麽做擴容?

《redis的持久化和緩存機制》 :https://github.com/Snailclimb/Java-Guide/blob/master/數據存儲/春夏秋冬又一春之Redis持久化.md

擴容的話可以通過redis集群實現,之前做項目的時候用過自己搭的redis集群
然後寫了一篇關於redis集群的文章:《一文輕松搞懂redis集群原理及搭建與使用》:https://juejin.im/post/5ad54d76f265da23970759d3

Redis常見性能問題和解決方案:

  1. Master最好不要做任何持久化工作,如RDB內存快照和AOF日誌文件
  2. 如果數據比較重要,某個Slave開啟AOF備份數據,策略設置為每秒同步一次
  3. 為了主從復制的速度和連接的穩定性,Master和Slave最好在同一個局域網內
  4. 盡量避免在壓力很大的主庫上增加從庫

Redis與消息隊列

作者:翁偉
鏈接:https://www.zhihu.com/question/20795043/answer/345073457

不要使用redis去做消息隊列,這不是redis的設計目標。但實在太多人使用redis去做去消息隊列,redis的作者看不下去,另外基於redis的核心代碼,另外實現了一個消息隊列disque: antirez/disque:https://github.com/antirez/disque部署、協議等方面都跟redis非常類似,並且支持集群,延遲消息等等。

我在做網站過程接觸比較多的還是使用redis做緩存,比如秒殺系統,首頁緩存等等。

好文Mark

非常非常推薦下面幾篇文章。。。

《Redis深入之道:原理解析、場景使用以及視頻解讀》:https://zhuanlan.zhihu.com/p/28073983:
主要介紹了:Redis集群開源的方案、Redis協議簡介及持久化Aof文件解析、Redis短連接性能優化等等內容,文章幹貨太大,容量很大,建議時間充裕可以看看。另外文章裏面還提供了視頻講解,可以說是非常非常用心了。

《阿裏雲Redis混合存儲典型場景:如何輕松搭建視頻直播間系統》:https://yq.aliyun.com/articles/582487?utm_content=m_46529:
主要介紹視頻直播間系統,以及如何使用阿裏雲Redis混合存儲實例方便快捷的構建大數據量,低延遲的視頻直播間服務。還介紹到了我們之前提高過的redis的數據結構的使用場景

參考:

https://www.cnblogs.com/Survivalist/p/8119891.html

http://www.redis.net.cn/tutorial/3524.html

https://redis.io/

2018.9.16 Redis 邊學習邊總結