分布式快取 redis實現

2022-06-09 22:51:28 字數 3975 閱讀 9481

為什麼要做分布式快取?即應用場景

1、需要用到快取,但是應用又分布在不同的機器上,也就是會有資料一致性的問題,分布式快取可以解決這個問題。

2、快取量很大,本地快取或者單個redis之類的快取應用無法支撐

3、提供分布式鎖

什麼是分布式快取?

分布式和集群:分布式經常與集群進行區分,兩者的特點都是整個系統涉及到多台伺服器,但是區別在於,集群是多台伺服器完成同一件事,而分布式系統是各個伺服器(服務,不一定是多台機器)各司其職,共同協作完成一件事。集群在完成業務的時候不需要在各個節點間進行通訊,獨立完成業務分布式系統需要通訊,協作完成業務

分布式快取:將快取任務分到多個節點協作完成。一般會使用memcache或者redis來做。redis-cluster 是一種分布式集群系統,也就是說他兼有集群和分布式系統的特性,每個節點負責的資料是不一樣的,但是每個節點提供的功能都是一樣的,都可以作為查詢的入口。

ps:redis如何在多節點分布儲存資料?通過slot(槽,hash槽)這個概念,集群內部通過槽來確定資料位置,如果新增節點,槽位會重新分配(可以選擇全部重新分配,也可以指定)。當放入乙個鍵值對的時候,對key使用crc16演算法得到乙個值,再用這個值對16384取模得到乙個雜湊值(槽位),將他放到槽位對應的節點上。ps:redis集群最少有3個節點,最多有16384個槽位

分布式快取的優缺點?  參考

1. 支援大資料量儲存,不受應用程序重啟影響

分布式快取由於是獨立部署的程序,擁有自身獨立的記憶體空間,不會受到應用程序重啟的影響,在應用程序重啟時,分布式快取的資料依然存在。同時對於資料量而言,由於不需要占用應用程序的記憶體空間,並且一般支援以集群的方式拓展,故可以進行大資料量的資料快取。

2. 資料集中儲存,保證資料一致性

當應用程序採用集群方式部署時,集群的每個部署節點都通過乙個統一的分布式快取進行資料訪問操作,故不存在本地快取中的資料更新問題,保證了不同節點的應用程序的資料一致性問題

3. 資料讀寫分離,高效能,高可用

分布式快取一般支援資料副本機制,可以實現讀寫分離,故可以解決高併發場景中的資料讀寫效能問題。並且由於在多個快取節點冗餘儲存資料,提高了快取資料的可用性,避免某個快取節點宕機導致資料不可用問題。

4. 資料跨網路傳輸,效能低於本地快取

由於分布式快取是獨立部署的程序,並且一般都是與應用程序位於不同的機器,故需要通過網路來進行資料傳輸,這樣相對於本地快取的程序內部的資料讀取操作,效能會較低。

分布式快取可能會出現的問題與解決方案。

快取一致性問題:在分布式的情況下如何保證快取和資料庫裡資料一致性

快取穿透:快取穿透指查詢乙個根本不存在的資料,快取層和儲存層都不命中

快取雪崩

1、快取集體過期,導致集中查詢資料庫

2、快取伺服器掛掉了

快取擊穿:快取過期了,此處正好有大量併發訪問此資料,此時都發現快取中不存在資料,都去訪問資料庫,導致資料庫崩潰

上述問題參考:

資料傾斜問題

hot key

乙個key在一段時間內被頻繁訪問,造成對應伺服器訪問壓力很大造成的。

比如hot key 解決方案

1. 使用本地快取即二級快取

在 client 端使用本地快取,從而降低了redis集群對hot key的訪問量,但是同時帶來兩個問題:

1、如果對可能成為 hot key 的 key 都進行本地快取,那麼本地快取是否會過大,從而影響應用程式本身所需的快取開銷。

2、如何保證本地快取和redis集群資料有效期的一致性。

所以在使用本地快取的時候需要考慮場景,適用場景是快取的資料內容在有效期內不會變更,如果有變更的話就會產生資料不一致的問題。

2、將key進行打散處理即備份key(推薦)

將key加上隨機字首(這裡不要加字尾,下有說明),讓key有多個副本,因為他們的key不同所以會盡量分散到不同的redis例項或者說slot上,當然slot如果也集中在乙個例項的話要手動分配一下。但是這種方案只適用於唯讀的key,如果要讀寫的話就不行了,會產生資料不一致

ps:如果使用twemproxy**redis,那麼根據他的分片演算法,越靠前的資料權重越大,所以把隨機數生成字首比較容易區分key以便分到不同的redis例項或者slot

big key

即資料量大的 key ,由於其資料大小遠大於其他key,導致某個具體儲存這個 big key 的例項記憶體使用量遠大於其他例項,造成記憶體不足,拖累整個集群的使用。big key 在不同業務上,通常體現為不同的資料,比如:

論壇中的大型持久蓋樓活動;

聊天室系統中熱門聊天室的訊息列表;

big key解決方案

1、刪除key如果業務不需要了,將bigkey刪除,但是注意如果直接del,由於redis是單執行緒,很有可能會發生阻塞。

如果是string,則直接刪除

如果 key 型別為 hash、list、set、sorted set,使用 hscan 命令,每次獲取部分(例如100個)field-value,再利用 hdel 刪除每個 field;漸進式刪除

redis 在4.0 版本支援 lazy delete free 的模式,刪除 bigkey 不會阻塞 redis

2、拆分key考慮兩種情況拆分

可以嘗試將物件分拆成幾個key-value, 使用mget獲取值,這樣分拆的意義在於分拆單次操作的壓力,將操作壓力平攤到多個redis例項中,降低對單個redis的io影響;mget可以從不同例項獲取key  參考 :

可以像第一種做法一樣,分拆成幾個key-value,  也可以將這個儲存在乙個hash中,每個field代表乙個具體的屬性,使用hget,hmget來獲取部分的value,使用hset,hmset來更新部分屬性  

3、更換資料庫  如果很多資料都是bigkey,那說明不適合使用redis儲存,可以考慮mongodb,儲存長文字

如何提前發現bigkey 和 hotkey?

1. 根據業務預判

在業務開發階段,就要對可能變成 hot key ,big key 的資料進行判斷,提前處理,如秒殺商品的資訊,這需要的是對產品業務的理解,對資料設計的經驗。

2.事中-監控和自動處理

監控在應用程式端,對每次請求 redis 的操作進行收集上報;不推薦,但是在運維資源缺少的場景下可以考慮。開發可以繞過運維搞定;

在proxy層,對每乙個 redis 請求進行收集上報;(推薦,改動涉及少且好維護);

對 redis 例項使用monitor命令統計熱點key(不推薦,高併發條件下會有造成redis 記憶體爆掉的隱患);

自己抓包處理,難度大,還把架構搞複雜了,不推薦

自動處理

通過監控之後,程式可以獲取 big key 和 hot key,再報警的同時,程式對 big key 和 hot key 進行自動處理。或者通知程式猿利用一定的工具進行定製化處理(在程式中對特定的key 執行前面提到的解決方案)

3、事後就盡量別事後了,黃花菜都涼了

Redis分布式快取實現

定義 特點快取解決的問題 快取能提高效率,那專案中所有書庫加入快取是否更好?本地快取與分布式快取的區別?mybatis中應用級快取 二級快取 sqlsessionfactory級別快取 所有會話共享 如何開啟二級快取 本地快取 檢視cache標籤快取實現 自定義rediscache實現 如何解決關聯...

Redis實現分布式快取

1.什麼是快取 cache 定義 就是計算機記憶體中的一段資料 2.記憶體中資料特點 a.讀寫快 b.斷電立即丟失 3.快取解決了什麼問題?a.提高 吞吐量,提高 執行效率 b.核心解決問題 快取的存在是用來減輕資料庫訪問壓力 4.既然快取能提高效率,那專案中所有資料加入快取豈不是更好?注意 使用快...

Redis 分布式快取

1 官網 3 菜鳥教程 4 redis的集群教程 5 史上最全redis高可用技術解決方案大全 一 redis的特點?redis 本質上是乙個 key value 型別的記憶體資料庫,很像 memcached,整個 資料庫統統載入在記憶體當中進行操作,定期通過非同步操作把資料庫資料 flush 到硬...