一篇文章讓你明白Redis是什麼?

引言

在Web應用發展的初期,那時關係型數據庫受到了較爲廣泛的關注和應用,原因是因爲那時候Web站點基本上訪問和併發不高、交互也較少。而在後來,隨着訪問量的提升,使用關係型數據庫的Web站點多多少少都開始在性能上出現了一些瓶頸,而瓶頸的源頭一般是在磁盤的I/O上。

而隨着互聯網技術的進一步發展,各種類型的應用層出不窮,這導致在當今雲計算、大數據盛行的時代,對性能有了更多的需求,主要體現在以下四個方面:

  • 低延遲的讀寫速度:應用快速地反應能極大地提升用戶的滿意度

  • 支撐海量的數據和流量:對於搜索這樣大型應用而言,需要利用PB級別的數據和能應對百萬級的流量

  • 大規模集羣的管理:系統管理員希望分佈式應用能更簡單的部署和管理
    龐大運營成本的考量:IT部門希望在硬件成本、軟件成本和人力成本能夠有大幅度地降低

  • 爲了克服這一問題,NoSQL應運而生,它同時具備了高性能、可擴展性強、高可用等優點,受到廣泛開發人員和倉庫管理人員的青睞。

Redis是什麼

Redis是現在最受歡迎的NoSQL數據庫之一,Redis是一個使用ANSI C編寫的開源、包含多種數據結構、支持網絡、基於內存、可選持久性的鍵值對存儲數據庫,其具備如下特性:

  • 基於內存運行,性能高效

  • 支持分佈式,理論上可以無限擴展

  • key-value存儲系統

  • 開源的使用ANSI C語言編寫、遵守BSD協議、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API
    相比於其他數據庫類型,Redis具備的特點是:

C/S通訊模型
單進程單線程模型
豐富的數據類型
操作具有原子性
持久化
高併發讀寫
支持lua腳本





哪些大廠在使用Redis?

github
twitter
微博
Stack Overflow
阿里巴巴
百度
美團
搜狐






Redis的應用場景有哪些?

Redis 的應用場景包括:緩存系統(“熱點”數據:高頻讀、低頻寫)、計數器、消息隊列系統、排行榜、社交網絡和實時系統。

在這裏插入圖片描述

Redis的數據類型及主要特性

Redis提供的數據類型主要分爲5種自有類型和一種自定義類型,這5種自有類型包括:String類型、哈希類型、列表類型、集合類型和順序集合類型。

在這裏插入圖片描述
String類型:
它是一個二進制安全的字符串,意味着它不僅能夠存儲字符串、還能存儲圖片、視頻等多種類型, 最大長度支持512M。

對每種數據類型,Redis都提供了豐富的操作命令,如:

  • GET/MGET

  • SET/SETEX/MSET/MSETNX

  • INCR/DECR

  • GETSET

  • DEL
    哈希類型:
    該類型是由field和關聯的value組成的map。其中,field和value都是字符串類型的。

Hash的操作命令如下:

  • HGET/HMGET/HGETALL
  • HSET/HMSET/HSETNX
  • HEXISTS/HLEN
  • HKEYS/HDEL
  • HVALS

列表類型:
該類型是一個插入順序排序的字符串元素集合, 基於雙鏈表實現。

List的操作命令如下:

  • LPUSH/LPUSHX/LPOP/RPUSH/RPUSHX/RPOP/LINSERT/LSET
  • LINDEX/LRANGE
  • LLEN/LTRIM -

集合類型:
Set類型是一種無順序集合, 它和List類型最大的區別是:集合中的元素沒有順序, 且元素是唯一的。

Set類型的底層是通過哈希表實現的,其操作命令爲:

  • SADD/SPOP/SMOVE/SCARD

  • SINTER/SDIFF/SDIFFSTORE/SUNION

Set類型主要應用於:在某些場景,如社交場景中,通過交集、並集和差集運算,通過Set類型可以非常方便地查找共同好友、共同關注和共同偏好等社交關係。

順序集合類型:
ZSet是一種有序集合類型,每個元素都會關聯一個double類型的分數權值,通過這個權值來爲集合中的成員進行從小到大的排序。與Set類型一樣,其底層也是通過哈希表實現的。

ZSet命令:

ZADD/ZPOP/ZMOVE/ZCARD/ZCOUNT
ZINTER/ZDIFF/ZDIFFSTORE/ZUNION

Redis的數據結構

Redis的數據結構如下圖所示:

在這裏插入圖片描述
關於上表中的部分釋義:

壓縮列表是列表鍵和哈希鍵的底層實現之一。當一個列表鍵只包含少量列表項,並且每個列表項要麼就是小整數,要麼就是長度比較短的字符串,Redis就會使用壓縮列表來做列表鍵的底層實現
整數集合是集合鍵的底層實現之一,當一個集合只包含整數值元素,並且這個集合的元素數量不多時,Redis就會使用整數集合作爲集合鍵的底層實現
如下是定義一個Struct數據結構的例子:在這裏插入圖片描述
簡單動態字符串SDS (Simple Dynamic String)
基於C語言中傳統字符串的缺陷,Redis自己構建了一種名爲簡單動態字符串的抽象類型,簡稱SDS,其結構如下:



在這裏插入圖片描述
SDS幾乎貫穿了Redis的所有數據結構,應用十分廣泛。

SDS的特點
和C字符串相比,SDS的特點如下:

在這裏插入圖片描述
 1. 常數複雜度獲取字符串長度

Redis中利用SDS字符串的len屬性可以直接獲取到所保存的字符串的長
    度,直接將獲取字符串長度所需的複雜度從C字符串的O(N)降低到了O(1)。

2. 減少修改字符串時導致的內存重新分配次數

通過C字符串的特性,我們知道對於一個包含了N個字符的C字符串來說,其底層實現總是N+1個字符長的數組(額外一個空字符結尾)

那麼如果這個時候需要對字符串進行修改,程序就需要提前對這個C字符串數組進行一次內存重分配(可能是擴展或者釋放)

而內存重分配就意味着是一個耗時的操作。

Redis巧妙的使用了SDS避免了C字符串的缺陷。在SDS中,buf數組的長度不一定就是字符串的字符數量加一,buf數組裏面可以包含未使用的字節,而這些未使用的字節由free屬性記錄。

與此同時,SDS採用了空間預分配的策略,避免C字符串每一次修改時都需要進行內存重分配的耗時操作,將內存重分配從原來的每修改N次就分配N次——>降低到了修改N次最多分配N次。

如下是Redis對SDS的簡單定義:

在這裏插入圖片描述
在這裏插入圖片描述

Redis特性1:事務

命令序列化,按順序執行
原子性
三階段: 開始事務 - 命令入隊 - 執行事務
命令:MULTI/EXEC/DISCARD


Redis特性2:發佈訂閱(Pub/Sub)

Pub/sub是一種消息通訊模式
Pub發送消息, Sub接受消息
Redis客戶端可以訂閱任意數量的頻道
“fire and forgot”, 發送即遺忘
命令:Publish/Subscribe/Psubscribe/UnSub



在這裏插入圖片描述

Redis特性3:Stream

Redis 5.0新增
等待消費
消費組(組內競爭)
消費歷史數據
FIFO



以上就是Redis的基本概念,下面我們將介紹在開發過程中可能會踩到的“坑”。

Redis常見問題解析:擊穿

概念:在Redis獲取某一key時, 由於key不存在, 而必須向DB發起一次請求的行爲, 稱爲“Redis擊穿”。

在這裏插入圖片描述
引發擊穿的原因:

第一次訪問
惡意訪問不存在的key
Key過期

合理的規避方案:

服務器啓動時, 提前寫入
規範key的命名, 通過中間件攔截
對某些高頻訪問的Key,設置合理的TTL或永不過期
Redis常見問題解析:雪崩
概念:Redis緩存層由於某種原因宕機後,所有的請求會湧向存儲層,短時間內的高併發請求可能會導致存儲層掛機,稱之爲“Redis雪崩”。



合理的規避方案:

使用Redis集羣
限流
Redis在產品開發中的應用實踐
//加入Java開發交流君樣:756584822一起吹水聊天
後端採用nodeJS
使用Azure的Redis服務
Redis的使用場景
    - token緩存, 用於令牌驗證






- IP白名單

碰到的問題

“網絡抖動”或者Redis服務異常導致Redis訪問超時
Redis客戶端驅動穩定性問題
    - 連接池 “Broken connection” 問題

- JS的Promise引出的Redis重置問題

下面我們來簡單瞭解一下Redis的進階知識。

進階之Redis協議簡介

Redis客戶端通訊協議:RESP(Redis Serialization Protocol),其特點是:

簡單
解析速度快
可讀性好

//加入Java開發交流君樣:756584822一起吹水聊天
Redis集羣內部通訊協議:RECP(Redis Cluster Protocol ) ,其特點是:

每一個node兩個tcp 連接
一個負責client-server通訊(P: 6379)
一個負責node之間通訊(P: 10000 + 6379)

Redis協議支持的數據類型:

簡單字符(首字節: “+”)
  “+OK\r\n”

錯誤(首字節: “-”)
  “-error msg\r\n”

數字(首字節: “:”)
  “:123\r\n”

批量字符(首字節: “$”)
  “&hello\r\nWhoa re you\r\n”

數組(首字節: “*”)
  “*0\r\n”

    “*-1\r\n”

除了Redis,還有什麼NoSQL型數據庫

市面上類似於Redis,同樣是NoSQL型的數據庫有很多,如下圖所示,除了Redis,還有MemCache、Cassadra和Mongo。下面,我們就分別對這幾個數據庫做一下簡要的介紹:在這裏插入圖片描述
Memcache:這是一個和Redis非常相似的數據庫,但是它的數據類型沒有Redis豐富。Memcache由LiveJournal的Brad Fitzpatrick開發,作爲一套分佈式的高速緩存系統,被許多網站使用以提升網站的訪問速度,對於一些大型的、需要頻繁訪問數據庫的網站訪問速度的提升效果十分顯著。

Apache Cassandra:(社區內一般簡稱爲C*)這是一套開源分佈式NoSQL數據庫系統。它最初由Facebook開發,用於儲存收件箱等簡單格式數據,集Google BigTable的數據模型與Amazon Dynamo的完全分佈式架構於一身。Facebook於2008將 Cassandra 開源,由於其良好的可擴展性和性能,被 Apple、Comcast、Instagram、Spotify、eBay、Rackspace、Netflix等知名網站所採用,成爲了一種流行的分佈式結構化數據存儲方案。

MongoDB:是一個基於分佈式文件存儲、面向文檔的NoSQL數據庫,由C++編寫,旨在爲WEB應用提供可擴展的高性能數據存儲解決方案。MongoDB是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係型數據庫的,它支持的數據結構非常鬆散,是一種類似json的BSON格式。

image

最新2020整理收集的一些高頻面試題(都整理成文檔),有很多幹貨,包含mysql,netty,spring,線程,spring cloud、jvm、源碼、算法等詳細講解,也有詳細的學習規劃圖,面試題整理等,需要獲取這些內容的朋友請加Q君樣:756584822

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章