redis知識點

1 redis特色

  內存數據庫,讀寫速度快,被應用於緩存。redis

  數據類型豐富,支持事務、持久化、LUA腳本、LRU驅動事件、多種集羣方案。算法

  豐富的特性:緩存,消息,過時,自動刪除數據庫

2 數據類型:

  hash:k-v集合,適用於存儲對象。因爲組合式的壓縮,內存利用率更高。後端

  字符串:一個鍵最大能存512MB緩存

  列表:按照插入順序排序。安全

    異步隊列:rpush爲生產消息,lpop爲消費消息。可是消費者下線時,生產消息會丟失。服務器

  set集合:string類型的無序集合,經過哈希表實現,增刪查的複雜度是O(1)。網絡

  zset:有序集合,且不重複。數據結構

存儲結構:

  redis通信協議RESP格式的命令文本存儲。是redis客戶端和服務端以前使用的一種通信協議。特色:實現簡單、快速解析、可讀性好。多線程

4 redis作緩存的緣由

  高性能:

  a 假如用戶第一次訪問數據庫中的某些數據。這個過程會比較慢,由於是從硬盤上讀取的。b 將該用戶訪問的數據存在緩存中,這樣下一次再訪問這些數據的時候就能夠直接從緩存中獲取了。操做緩存就是直接操做內存,因此速度至關快。c 若是數據庫中的對應數據改變的以後,同步改變緩存中相應的數據便可

  高併發:

  直接操做緩存可以承受的請求是遠遠大於直接訪問數據庫的,因此咱們能夠考慮把數據庫中的部分數據轉移到緩存中去,這樣用戶的一部分請求會直接到緩存這裏而不用通過數據庫。

  分佈式緩存:

  使用 redis 或 memcached 之類的稱爲分佈式緩存,在多實例的狀況下,各實例共用一份緩存數據,緩存具備一致性。缺點是須要保持 redis 或 memcached服務的高可用,整個程序架構上較爲複雜。

單線程redis快速的緣由:

  1.徹底基於內存操做,絕大部分請求是純粹的內存操做,很是快速。數據存在內存中,查找和操做的時間複雜度都是O(1)

  忽略磁盤操做。

  2.數據結構簡單,對數據操做也簡單

  3.採用單線程,避免頻繁的上下文切換和競爭條件,也不存在多進程或者多線程致使的切換而消耗CPU,不用去考慮各類鎖的問題,不存在加鎖釋放鎖操做,沒有由於可能出現死鎖而致使的性能消耗

  4.採用I/O多路複用機制,非阻塞。

  5.使用底層模型不一樣,它們之間底層實現方式以及客戶端之間的通訊的應用協議不同,redis直接本身構建了VM機制,由於通常的系統調用系統函數的話,會浪費必定的時間去移動和請求。

6 持久化技術

  持久化就是將內存的數據寫到磁盤中,防止宕機時內存數據丟失。

  持久化策略包括RDB(redis database)快照和AOF(append-only file)日誌

  RDB是每隔一段時間對redis進行一次持久化,速度快,性能好,可是數據不完整。核心函數有rdbSave爲rdb文件和rdbLoad。

  AOF是從新執行命令,數據完整,安全可是速度慢,文件大。主要是調用flushappendonlyfile函數。將aof_buf中的緩存寫入到AOF文件,或者是調用fsync、fdatasync函數,將AOF文件保存到磁盤中。

架構模式:單機版和分佈式

  單機版:內存容量有限,處理能力有限,沒法高可用。

  分佈式:主從複製。保證數據相同。沒法保證高可用。沒有解決master寫的壓力。

  哨兵:分佈式系統中監控redis主從服務器,並在主服務器下線時自動進行故障轉移。

    特性:監控:不斷地檢查主從服務器是否運做正常。

    提醒:當被監控的某個redis服務器出現問題時,哨兵能夠經過API向管理員或者其餘應用程序發送通知。

    自動故障遷移:當一個主服務器不能正常工做時,哨兵會開始一次自動故障遷移操做。

    特色:保證高可用、監控各個節點、自動故障遷移;主從模式,切換須要時間,可能丟數據,沒有解決master寫的壓力

  集羣proxy

    特色:twemproxy,代理服務器,快速的,單線程。

    優勢:能夠支持多種hash算法,失敗節點會自動刪除,後端sharding分片邏輯對業務透明,業務方的讀寫方式和操做單個redis一致。

    缺點:增長新proxy時,須要維護高可用。不支持故障的自動轉移。

    須要本身實現failover,擴展性差。手動干預擴容和縮容。

  集羣codis:

    和twemproxy效果一致,可是支持在節點數量改變的狀況下,舊節點恢復到新hash節點。

  集羣直連型:無中心結構,每一個節點保存數據和整個集羣狀態,每一個節點都和其餘節點鏈接。

    特色:沒有中心節點,沒有proxy層。

      節點間數據共享,能夠動態調整數據分佈。

      可擴展,到1000個節點,節點可動態增長或者刪除。

      高可用,部分節點不可用時,集羣仍然可使用。slave作備份數據。

      實現故障自動failover,節點間經過gossip協議交換狀態信息,投票機制完成slave到master的角色提高。

    缺點:資源隔離性差,容易互相影響。

      數據異步複製,不保證數據的一致性。

    hash槽:根據CRC16(key) mod 16384,以爲key-value放入哪一個桶(節點)。

8 redis和memcached區別 

  1. redis支持更豐富的數據類型(支持更復雜的應用場景):Redis不只僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。memcache支持簡單的數據類型,String。
  2. Redis支持數據的持久化,能夠將內存中的數據保持在磁盤中,重啓的時候能夠再次加載進行使用,而Memecache把數據所有存在內存之中。
  3. 集羣模式:memcached沒有原生的集羣模式,須要依靠客戶端來實現往集羣中分片寫入數據;可是 redis 目前是原生支持 cluster 模式的.
  4. Memcached是多線程,非阻塞IO複用的網絡模型;Redis使用單線程的多路 IO 複用模型。
  5. Memcached相似於一致性哈希的分佈式算法實現分佈式存儲。

    一致性哈希:DHT能夠經過減小影響範圍的方式,解決增減服務器致使的數據散列問題,解決分佈式環境下負載均衡問題。若是存在熱點數據,能夠經過增添節點的方

 

9 redis設置過時時間

  Redis中有個設置時間過時的功能,即對存儲在 redis 數據庫中的值能夠設置一個過時時間。做爲一個緩存數據庫,這是很是實用的。如咱們通常項目中的 token 或者一些登陸信息,尤爲是短信驗證碼都是有時間限制的,按照傳統的數據庫處理方式,通常都是本身判斷過時,這樣無疑會嚴重影響項目性能。

  咱們 set key 的時候,均可以給一個 expire time,就是過時時間,經過過時時間咱們能夠指定這個 key 能夠存活的時間。若是假設你設置了一批 key 只能存活1個小時,那麼接下來1小時後,redis是怎麼對這批key進行刪除的?

  按期刪除+惰性刪除。

  • 按期刪除:redis默認是每隔 100ms 就隨機抽取一些設置了過時時間的key,檢查其是否過時,若是過時就刪除。注意這裏是隨機抽取的。爲何要隨機呢?你想想假如 redis 存了幾十萬個 key ,每隔100ms就遍歷全部的設置過時時間的 key 的話,就會給 CPU 帶來很大的負載!
  • 惰性刪除 :按期刪除可能會致使不少過時 key 到了時間並無被刪除掉。因此就有了惰性刪除。假如你的過時 key,靠按期刪除沒有被刪除掉,還停留在內存裏,除非你的系統去查一下那個 key,纔會被redis給刪除掉。這就是所謂的惰性刪除,也是夠懶的哈!

  可是僅僅經過設置過時時間仍是有問題的。咱們想一下:若是按期刪除漏掉了不少過時 key,而後你也沒及時去查,也就沒走惰性刪除,此時會怎麼樣?若是大量過時key堆積在內存裏,致使redis內存塊耗盡了。怎麼解決這個問題呢? redis 內存淘汰機制。

10 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:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key(這個是最經常使用的)
  5. allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
  6. no-eviction:禁止驅逐數據,也就是說當內存不足以容納新寫入數據時,新寫入操做會報錯。

  4.0版本後增長如下兩種:

  1. volatile-lfu:從已設置過時時間的數據集(server.db[i].expires)中挑選最不常用的數據淘汰
  2. allkeys-lfu:當內存不足以容納新寫入數據時,在鍵空間中,移除最不常常使用的key

11 redis事務(不是原子性)

  Redis 經過 MULTI、EXEC、WATCH 等命令來實現事務(transaction)功能。事務提供了一種將多個命令請求打包,而後一次性、按順序地執行多個命令的機制,而且在事務執行期間,服務器不會中斷事務而改去執行其餘客戶端的命令請求,它會將事務中的全部命令都執行完畢,而後纔去處理其餘客戶端的命令請求。

  注意:redis同一個事務中若是有一條命令執行失敗,其後的命令仍然會被執行,沒有回滾。 

12 緩存雪崩和緩存穿透

  緩存雪崩:

    當緩存服務器重啓或者大量緩存集中在一個時間段失效,失效時會對後端系統帶來很大壓力,嚴重時數據庫會宕機。

    避免:

    1.緩存失效後,經過加鎖或者隊列控制讀數據庫、寫緩存的線程數量。好比某個key只容許一個線程查詢數據和寫緩存,其餘線程等待

    2.作二級緩存,A1爲原始緩存,A2爲拷貝緩存,A1失效時,訪問A2,A1緩存失效時間短時間,A2爲長期

    3.不一樣的key設置不一樣的過時時間,讓緩存失效的時間點儘可能均勻。

  緩存穿透:

    通常的緩存系統是按照key去緩存查詢,不存在對應的value時,會去後端系統查詢。而惡意的請求會故意查詢不存在的key,請求量直接到數據庫上,請求量很大時,會對後端系統形成很大壓力,就叫緩存穿透。

    正常處理流程:

    解決:

      1.查詢結果爲空的狀況進行緩存過時時間,緩存時間短,最長不超過5分鐘,或者key對應的數據插入後清理緩存。

      2.使用布隆過濾器。對必定不存在的key進行過濾。把全部可能存在的key放在一個大的bitmap(哈希表)中,查詢時經過bitmap過濾,這樣避免了對底層存儲系統的查詢壓力。

13 分佈式鎖

  緣由

    redis併發競爭key時,多個系統同時對一個 key 進行操做,可是最後執行的順序和咱們指望的順序不一樣,這樣也就致使告終果的不一樣!

  先使用setnx搶鎖,設置超時時間以釋放鎖、超過一半的redis實例設置成功,就表示加鎖完成。

  注意:若是不存在 Redis 的併發競爭 Key 問題,不要使用分佈式鎖,這樣會影響性能

相關文章
相關標籤/搜索