內存數據庫,讀寫速度快,被應用於緩存。redis
數據類型豐富,支持事務、持久化、LUA腳本、LRU驅動事件、多種集羣方案。算法
豐富的特性:緩存,消息,過時,自動刪除數據庫
hash:k-v集合,適用於存儲對象。因爲組合式的壓縮,內存利用率更高。後端
字符串:一個鍵最大能存512MB緩存
列表:按照插入順序排序。安全
異步隊列:rpush爲生產消息,lpop爲消費消息。可是消費者下線時,生產消息會丟失。服務器
set集合:string類型的無序集合,經過哈希表實現,增刪查的複雜度是O(1)。網絡
zset:有序集合,且不重複。數據結構
redis通信協議RESP格式的命令文本存儲。是redis客戶端和服務端以前使用的一種通信協議。特色:實現簡單、快速解析、可讀性好。多線程
a 假如用戶第一次訪問數據庫中的某些數據。這個過程會比較慢,由於是從硬盤上讀取的。b 將該用戶訪問的數據存在緩存中,這樣下一次再訪問這些數據的時候就能夠直接從緩存中獲取了。操做緩存就是直接操做內存,因此速度至關快。c 若是數據庫中的對應數據改變的以後,同步改變緩存中相應的數據便可!
直接操做緩存可以承受的請求是遠遠大於直接訪問數據庫的,因此咱們能夠考慮把數據庫中的部分數據轉移到緩存中去,這樣用戶的一部分請求會直接到緩存這裏而不用通過數據庫。
分佈式緩存:
使用 redis 或 memcached 之類的稱爲分佈式緩存,在多實例的狀況下,各實例共用一份緩存數據,緩存具備一致性。缺點是須要保持 redis 或 memcached服務的高可用,整個程序架構上較爲複雜。
1.徹底基於內存操做,絕大部分請求是純粹的內存操做,很是快速。數據存在內存中,查找和操做的時間複雜度都是O(1)
忽略磁盤操做。
2.數據結構簡單,對數據操做也簡單
3.採用單線程,避免頻繁的上下文切換和競爭條件,也不存在多進程或者多線程致使的切換而消耗CPU,不用去考慮各類鎖的問題,不存在加鎖釋放鎖操做,沒有由於可能出現死鎖而致使的性能消耗
4.採用I/O多路複用機制,非阻塞。
5.使用底層模型不一樣,它們之間底層實現方式以及客戶端之間的通訊的應用協議不同,redis直接本身構建了VM機制,由於通常的系統調用系統函數的話,會浪費必定的時間去移動和請求。
持久化就是將內存的數據寫到磁盤中,防止宕機時內存數據丟失。
持久化策略包括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放入哪一個桶(節點)。
Memcached相似於一致性哈希的分佈式算法實現分佈式存儲。
一致性哈希:DHT能夠經過減小影響範圍的方式,解決增減服務器致使的數據散列問題,解決分佈式環境下負載均衡問題。若是存在熱點數據,能夠經過增添節點的方
Redis中有個設置時間過時的功能,即對存儲在 redis 數據庫中的值能夠設置一個過時時間。做爲一個緩存數據庫,這是很是實用的。如咱們通常項目中的 token 或者一些登陸信息,尤爲是短信驗證碼都是有時間限制的,按照傳統的數據庫處理方式,通常都是本身判斷過時,這樣無疑會嚴重影響項目性能。
咱們 set key 的時候,均可以給一個 expire time,就是過時時間,經過過時時間咱們能夠指定這個 key 能夠存活的時間。若是假設你設置了一批 key 只能存活1個小時,那麼接下來1小時後,redis是怎麼對這批key進行刪除的?
按期刪除+惰性刪除。
可是僅僅經過設置過時時間仍是有問題的。咱們想一下:若是按期刪除漏掉了不少過時 key,而後你也沒及時去查,也就沒走惰性刪除,此時會怎麼樣?若是大量過時key堆積在內存裏,致使redis內存塊耗盡了。怎麼解決這個問題呢? redis 內存淘汰機制。
redis 提供 6種數據淘汰策略:
4.0版本後增長如下兩種:
Redis 經過 MULTI、EXEC、WATCH 等命令來實現事務(transaction)功能。事務提供了一種將多個命令請求打包,而後一次性、按順序地執行多個命令的機制,而且在事務執行期間,服務器不會中斷事務而改去執行其餘客戶端的命令請求,它會將事務中的全部命令都執行完畢,而後纔去處理其餘客戶端的命令請求。
注意:redis同一個事務中若是有一條命令執行失敗,其後的命令仍然會被執行,沒有回滾。
當緩存服務器重啓或者大量緩存集中在一個時間段失效,失效時會對後端系統帶來很大壓力,嚴重時數據庫會宕機。
避免:
1.緩存失效後,經過加鎖或者隊列控制讀數據庫、寫緩存的線程數量。好比某個key只容許一個線程查詢數據和寫緩存,其餘線程等待
2.作二級緩存,A1爲原始緩存,A2爲拷貝緩存,A1失效時,訪問A2,A1緩存失效時間短時間,A2爲長期
3.不一樣的key設置不一樣的過時時間,讓緩存失效的時間點儘可能均勻。
通常的緩存系統是按照key去緩存查詢,不存在對應的value時,會去後端系統查詢。而惡意的請求會故意查詢不存在的key,請求量直接到數據庫上,請求量很大時,會對後端系統形成很大壓力,就叫緩存穿透。
正常處理流程:
解決:
1.查詢結果爲空的狀況進行緩存過時時間,緩存時間短,最長不超過5分鐘,或者key對應的數據插入後清理緩存。
2.使用布隆過濾器。對必定不存在的key進行過濾。把全部可能存在的key放在一個大的bitmap(哈希表)中,查詢時經過bitmap過濾,這樣避免了對底層存儲系統的查詢壓力。
緣由:
redis併發競爭key時,多個系統同時對一個 key 進行操做,可是最後執行的順序和咱們指望的順序不一樣,這樣也就致使告終果的不一樣!
先使用setnx搶鎖,設置超時時間以釋放鎖、超過一半的redis實例設置成功,就表示加鎖完成。
注意:若是不存在 Redis 的併發競爭 Key 問題,不要使用分佈式鎖,這樣會影響性能