本文由葡萄城技術團隊編撰并首發
轉載請注明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者,
引言
在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
- 微博
- 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在產品開發中的應用實踐
為此,我很高興的為大家介紹,葡萄城架構師Jim將在2019-11-27 14:00 為大家帶來一場公開課,其中 Jim除了為大家講解Redis的基礎,同時也會實際演示他所在的專案組使用Redis時碰到的問題以及解決方案,對于剛接觸Redis的同學來說,更具參考意義和學習價值,歡迎大家屆時參加,公開課地址:https://live.vhall.com/661463644,
- 后端采用nodeJS
- 使用Azure的Redis服務
- Redis的使用場景
- token快取, 用于令牌驗證
- IP白名單
碰到的問題
- “網路抖動”或者Redis服務例外導致Redis訪問超時
- Redis客戶端驅動穩定性問題
- 連接池 “Broken connection” 問題
- JS的Promise引出的Redis重置問題
下面我們來簡單了解一下Redis的進階知識,
進階之Redis協議簡介
Redis客戶端通訊協議:RESP(Redis Serialization Protocol),其特點是:
- 簡單
- 決議速度快
- 可讀性好
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格式,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/103907.html
標籤:其他
