![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SOyEDNjNDN1ATZ3UjMkFzMwgzNmJDMiFzN1MTO3kDZz8CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
原文出處:https://juejin.im/post/5dc4c5ef5188252af967afd7
Redis 是什麼
Redis
是開源的記憶體中的資料結構存儲系統,它可以用作資料庫、緩存和消息中間件。它支援多種類型的資料結構,如 字元串
strings
, 散列
hashes
, 清單
lists
, 集合
sets
, 有序集合
sorted sets
與範圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。
Redis
還内置了 複制(
replication
),LUA腳本(
Lua scripting
), LRU驅動事件(
LRU eviction
),事務(
transactions
) 和不同級别的 磁盤持久化(
persistence
), 并通過 Redis哨兵(
Sentinel
)和自動 分區(
Cluster
)提供高可用性(
high availability
)。
嗯,沒錯!這就是
redis
中文官方網站上面的介紹,簡潔明了。
NoSQL 是什麼
我們知道
redis
是一種非關系型資料庫
NoSQL
。而為什麼出現
NoSQL
?
NoSQL
又是什麼呢?
單機資料庫的年代
在一個網站通路量不大的時候,我們使用一個資料庫就足以應對流量請求。
緩存 + 拆分
随着通路量的上升,一個資料庫已經不能滿足我們的需求了。為了更高的性能,我們在中間加上了一個緩存層并且将資料庫做了叢集、結構優化和讀寫分離。
而這裡的緩存就是
NoSQL
,當然做緩存也隻是
NoSQL
的一種功能,就像
Redis
并不僅僅有緩存這一種功能。比如它還能實作 簡單的消息隊列,解決Session共享,計數器,排行榜,好友關系處理 等等功能,可見
Redis
是一個非常強大工具,讓我們來學習它吧!
Redis 通用指令
首先我們抛開資料類型來講關于
Redis
的通用指令。
操作 key 和 value
Redis
是一種
key
value
存儲的緩存資料庫,所有的資料都有一個自己唯一的key。
這裡為了友善示範,我使用了字元串相關的設定指令
-
擷取符合要求的所有key。時間複雜度為keys [pattern]
,一般在生産環境中不使用,因為O(n)
是單線程的,執行耗時的任務會阻塞其他任務。一般會使用Redis
指令替代(非阻塞)。scan
-
擷取目前存儲資料個數。dbsize
-
判斷是否存在該keyexists key
-
删除指定資料del key
-
擷取指定key的資料類型type key
-
重命名rename key newkey
過期時間
Redis
中很多資料都是用來作為緩存資料的,而作為緩存就需要有過期時間,在
Redis
中提供了很強大的過期時間設定功能。
-
為某個 key 設定過期時間。expire key seconds
-
檢視某個 key 的剩餘時間,傳回正數代表剩餘的時間,-1代表永久,-2代表已過期或不存在。ttl key
Redis 的五種基本資料類型
在上面我說到了很多
Redis
作為緩存能實作的其他功能,比如計數器,排行榜,好友關系等,這些實作的依據就是靠着
Redis
的資料結構。在整個
Redis
中一共有五種基本的資料結構(還有些進階資料結構以後會講),他們分别是 字元串
strings
, 散列
hashes
, 清單
lists
, 集合
sets
, 有序集合
sorted sets
。
字元串 string
在絕大部分程式設計語言中都有
String
字元串類型,對于作為資料庫的
Redis
也是必不可少的。
-
設定值set key value
-
擷取某個key的值get key
-
批量設定并且是原子的,可以用來減少網絡時間消耗mset key1 value1 key2 value2
-
批量擷取并且是原子的,可以用來減少網絡時間消耗mget key1 key2
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
自增指定key的值incr key
-
自減指定key的值decr key
-
自增指定數值incrby key value
-
自減指定數值decrby key value
-
增加指定浮點數 前面幾個操作就可以用來實作計數器的功能。incrbyfloat key floatvalue
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
如果不存在該key則可以設定成功,否則會失敗,加上過期時間限制,則是redis實作分布式鎖的一種方式(後面會提到)。setnx key value
-
與前面相反,如果存在則設定成功,否則失敗(相當于更新操作)set key value xx
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
設定新值并傳回舊值getset key newvalue
-
為原本内容追加内容append key value
-
擷取字元串長度strlen key
-
擷取指定範圍的内容getrange key start end
-
設定指定範圍的内容setrange key index value
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
設定值且設定過期時間setex key seconds value
-
為不存在的key設定值且設定過期時間,分布式鎖的實作方式。set key value ex seconds nx
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺?
hash
其實我們可以了解
hash
為 小型Redis ,
Redis
在底層實作上和
Java
中的
HashMap
差不多,都是使用 數組 + 連結清單 的二維結構實作的。
不同的是,在
Redis
中字典的值隻能是字元串,而且他們
rehash
的方式不一樣,在
Redis
中使用的是 漸進式rehash 。
在 rehash 的時候會保留新舊兩個 hash 字典,在資料遷移的時候會将舊字典中的内容一點一點遷移到新字典中,查詢的同時會查詢兩個 hash 字典,等資料全部遷移完成才會将新字典代替就字典。
下面我們來看一下關于
hash
的基本操作。
-
設定字典中某個key的值hset key field value
-
設定字典中某個key的值(不存在的)hsetnx key field value
-
批量設定hmset key field1 value1 field2 value2 ...
-
擷取字典中某個key的值hget key field
-
批量擷取hmget key field1 field2
-
擷取全部hgetall key
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
删除某個keyhdel key field
-
判斷是否存在hexists key field
-
擷取指定key對應的字典中的存儲個數hlen key
-
傳回所有的valuehvals key
-
傳回所有的keyhkeys key
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
增加某個value的值(也可以增加負數)hincrby key field increValue
-
增加某個value的值(浮點數)hincrbyfloat key field floatValue
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺?
list
Redis
中的清單相當于
Java
中的
LinkedList
(雙向連結清單) ,也就是底層是通過 連結清單 來實作的,是以對于
list
來說 插入删除操作很快,但 索引定位非常慢。
Redis
提供了許多對于
list
的操作,如出,入等操作,你可以充分利用它們來實作一個 棧 或者 隊列。
下面我們來看一下關于
list
的基本操作。
-
從左入棧lpush key item1 item2 item3...
-
從右入棧rpush key item1 item2 item3...
-
從左出棧lpop key
-
從右出棧rpop key
-
擷取指定索引的元素 O(n)謹慎使用lindex key index
-
擷取指定範圍的元素 O(n)謹慎使用lrange key start end
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
在指定元素的前面或者後面添加新元素linsert key before|after item newitem
-
删除指定個數值為value的元素lrem key count value
- count = 0 :删除所有值為value的元素
- count > 0 :從左到右删除 count 個值為 value 的元素
- count < 0 :從右到做删除 |count| 個值為 value 的元素
-
保留指定範圍的元素ltrim key start end
-
更新某個索引的值lset key index newValue
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
沒有則阻塞(timeout指定阻塞時間 為0代表永久)blpop key timeout
-
沒有則阻塞(timeout指定阻塞時間 為0代表永久) 這兩個可以用來實作消費者生産者brpop key timeout
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺?
總結來說我們可以使用 左入又出或者右入左出 來實作隊列,左入左出或者右入右出 來實作棧。
- lpush + lpop = Stack
- rpush + rpop = Stack**
- lpush + rpop = Queue
- rpush + lpop = Queue
- lpush/rpush + ltrim = Capped List (定長清單)
- lpush + brpop = Message Queue (消息隊列)
- rpush + blpop = Message Queue (消息隊列)
set
Redis
中的
set
相當于
Java
中的
HashSet
(無序集合),其中裡面的元素不可以重複,我們可以利用它實作一些去重的功能。我們還有對幾個集合進行取交集,取并集等操作,這些操作就可以擷取不同使用者之間的共同好友,共同愛好等等。
下面我們就來看一下關于
set
的一些基本操作。
-
添加元素sadd key value
-
删除某個元素sdel key value
-
判斷是否是集合中的元素sismember key value
-
随機擷取指定個數的元素(不會影響集合結構)srandmember key count
-
從集合中随機彈出元素(會破壞結合結構)spop key count
-
擷取集合所有元素 O(n)複雜度smembers key
-
擷取集合個數scard key
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
擷取所有集合中的交集sinter set1 set2 ...
-
擷取所有集合中的差集sdiff set1 set2 ...
-
擷取所有集合中的并集sunion set1 set2 ...
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺?
zset
Redis
中的
zset
是一個 有序集合,通過它可以實作很多有意思的功能,比如學生成績排行榜,視訊播放量排行榜等等。
zset
中是使用 跳表 來實作的,我們知道隻有數組這種連續的空間才能使用二分查找進行快速的定位,而連結清單是不可以的。跳表幫助連結清單查找的時候節省了很多時間(使用跳的方式來周遊索引來進行有序插入),如果不了解跳表的同學可以補習一下。
下面我們來看一下關于
zset
的一些基本操作。
-
添加,score用于排序,value需要唯一,由于使用的跳表,時間複雜度為 O(logn)。zadd key score element
-
删除某元素 O(1)時間複雜度zrem key element
-
擷取某個元素的分數zscore key element
-
增加某個元素的分數zincrby key incrScore element
-
擷取指定索引範圍的元素 加上zrange key start end [withscores]
則傳回分數 O(logn + m)時間複雜度withscores
-
擷取指定分數範圍的元素 加上zrangebyscore key minScore maxScore [withscores]
則傳回分數,O(logn + m)時間複雜度withscores
-
擷取有序集合長度zcard key
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺?
Redis 中的事務和管道
管道 Pipeline
在某些場景下我們在一次操作中可能需要執行多個指令,而如果我們隻是一個指令一個指令去執行則會浪費很多網絡消耗時間,如果将指令一次性傳輸到
Redis
中去再執行,則會減少很多開銷時間。但是需要注意的是
pipeline
中的指令并不是原子性執行的,也就是說管道中的指令到達
Redis
伺服器的時候可能會被其他的指令穿插。
事務
關系型資料庫具有
ACID
特性,
Redis
能保證A(原子性)和I(隔離性),D(持久性)看是否有配置
RDB
或者
AOF
持久化操作,但無法保證一緻性,因為
Redis
事務不支援復原。
我們可以簡單了解為
Redis
中的事務隻是比
Pipeline
多了個原子性操作,也就是不會被其他指令給分割,如上圖。
-
事務開始的标志multi
-
事務執行exec
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺? -
清除在這個事務中放入隊列的所有指令,即解除整個事務。discard
-
在事務開始前監控某個元素,如果在送出事務的時候發現這個元素的值被其他用戶端更改了則事務會運作失敗。watch key
-
解除監控unwatch key
redis 批量删除_Redis基礎你掌握多少了?來查漏補缺?
Redis常用指令總結
(試了好幾次,圖檔傳上來還是不清晰,需要的朋友就加個人微信:fangzhen0219,我私發吧)
好了,這就是這篇文章全部的内容了,對于
Redis
你還有多少遺忘的或者沒學習到的呢?歡迎留言區評論
猜你喜歡
1、Apache iceberg:Netflix 資料倉庫的基石
2、基于 MySQL Binlog 的 Elasticsearch 資料同步實踐
3、bilibili 實時計算平台架構與實踐
4、常見的大資料平台架構設計思路
過往記憶大資料微信群,請添加微信:fangzhen0219,備注【進群】