跟我一起學Redis之五種基本類型及其應用場景舉例(幹了6個小時)

前言

來啦,老弟?來啦,上一篇就當嘮嘮嗑,接下來就開始進行實操擼命令,計劃是先整體單純說說Redis的各種用法和應用,最後再結合代碼歸納總結。

Redis默認有16個數據庫(編號為0~15),默認使用第0個,通過命令select任意切換數據庫,和MySql切換數據庫一個道理;各數據庫之間的數據是隔離的,先啟動服務端,再啟動客戶端,然後開干,如下演示:

Select命令,用於切換數據庫

img

清除數據,主要是測試時使用,在生產環境是杜絕使用這個命令的,如下演示:

Flushdb清除當前庫中的數據

Flushall清除所有庫中的數據

flushdb

Key獲取、移除、判斷是否存在,如下演示

Keys 獲取Key

Move 移動指定Key到指定數據庫

Exists 判斷Key是否存在

key

查看指定Key對應值類型,如下:

type key

img

公共的命令暫時就說這麼多,接下來開始說說五種基本類型的使用及應用場景;之所以用圖片的方式把命令貼出來,主要是在不失真的情況下方便手機閱讀,同時希望小夥伴們可以動手敲敲,不要複製~~~

Redis的命令很多,接下來只是說常用的,其他的小夥伴參照文檔進行實操吧,這裡還是注重實際場景的應用(綜合同事、朋友、還有學習過程中提到的場景,並非我都遇到過~~~);

img

正文

Redis中基本的五種數據結構,分別是字符串string、哈希hash、列表list、集合set、有序集合zset,存儲的數據結構大概如下圖;

img

string

非常常用的類型,搞過Redis的應該都用過。着重分享以下命令:

set key value : 新增或更新字符串鍵值對

mset key value [key1 value1 …]:批量新增或更新鍵值對

setnx key value :如果key不存在就添加,否則就失敗

setex key seconds value:設置簡直對的時同時設置過期時間

get key :獲取指定key的值

mget key [key1 key2 …]:獲取多個key的值

del key [key1 key2 …]:刪除指定key

expire key seconds:設置指定key過期時間,以秒為單位

ttl key:查看指定key還剩餘多長時間

incr key:將指定key存儲的數值加1

decr key:將指定key存儲的數值減1

incrby key step:將指定key存儲的數值加上step

decrby key step :將指定key存儲的數值減去step

結合應用場景演練*↓↓↓*

單值緩存:即簡單鍵值對數據緩存;有一些數據需要共享,比如在沒有統一授權中心的多個系統中,可以通過相同的算法共享token字符串進行各系統統一認證;

img

對象緩存:比如之前都喜歡用Session保存用戶數據,然後在每個網頁中進行使用,但對於分佈式或是集群系統就需要做Session共享了,一般會將用戶信息轉為json字符串進行緩存;

img

對於簡單的對象緩存,也可以用mset和mget實現,但使用相對不如上例方便,如下:

img

以上只是用於共享數據,但其實經常會用於緩存一些高頻率訪問但不頻繁修改的數據上。比如採集設備數據,需要實時核對設備是否正確,當採集比較頻繁,如傳感器數據時,核對的設備信息不可能實時從數據庫中查,需將其進行緩存,減輕數據庫壓力的同時,也能提高效率。

可能看到這,有小夥伴會問key值中的冒號啥意思,其實這裡是用來分層歸類的,就比如userData:userId:userName,理解為:用戶數據中指定用戶的用戶名。

計數器:有沒有遇見一種需要遞增的數據編號,比如說訂單編號:202009290001,後四位不斷的遞增,單體程序還稍微好處理一點,但如果是分佈式系統或集群就有點意思了,所以存在Redis中進行統一遞增是不錯的選擇,針對數據量大的,還可以進行分段計數。

image-20201009094243726

文章閱讀數或網頁瀏覽數統計:常見博客文章或是公眾號都有閱讀數統計,或是自己開發的站點需要統計頁面訪問量,用Redis也可以輕鬆實現,換其他方式估計得費點心思。

img

img

分佈式鎖:單體程序,多線程通過線程鎖來控制資源搶佔,對於分佈式系統用線程鎖就不行了,藉助於setnx(set if not exists的縮寫) 來完成,及如果沒有值就能新增成功,否則就失敗,和資源被占就要等待原理是一樣的,當然還得考慮對應值的過期和刪除,不然一直佔用也不行。

img

字符串的常規操作:比如截取字符串、獲取字符串長度等操作。

img

通過以上可知,字符串的功能還是很強大的,這應該就是很多人喜歡用而且只用它的原因吧。

hash

hash的相關命令一般以h開頭,着重分享以下命令:

hset key field value : 新增或更新key對應字段的值;

hsetnx key field value:新增一個不存在Key的字段值;

hmset key field value [field value …]:在指定Key上存儲多個字段和值

hget key field:獲取指定key中指定字段的值;

hdel key field [field1…]:刪除指定Key值的指定字段

hlen key:獲取指定key中的字段的數量

hgetall key:獲取指定key中所有的字段值

hincrby key field step:指定key中字段值增加step

結合應用場景演練*↓↓↓*

對象緩存:string也能做,為什麼還要用hash?,string一般用於簡單對象的緩存,比如字段不多,記錄也不多的情況,便於序列化解析。

平時項目中有配置信息或下拉數據信息,會用於各個頁面,這種變化頻率不高,但需頻繁的讀取的數據,將其進行緩存減少數據庫訪問是不錯的選擇:

img

當做數據庫:有一個同學,做硬件相關係統,通常關於硬件的相關的參數配置都放在內存中,但由於參數過多時,維護是非常不爽的事,而且稍微一個參數的改動,就會重新發佈程序。有些也採用SQLite來存儲,對於高效訪問和修改,Redis卻是相對比較優的選擇:

如:多個主機,每個主機中有不同的屬性,每個屬性有對應的值。

img

做購物車(之前學習記錄的):因為大型的網站,用戶很多,將每個人的購物車信息都進行關係存儲,做以下頁面是有點難處的。所以用Redis做比較高效,至於一些明細信息,可以通過商品ID從關係數據庫中查找。

img

相對於string來說,對於對象存儲,不用來回進行序列化,減少內存和CPU的消耗,但設置過期不能到具體字段,只能針對Key設置。

list

着重分享以下命令:

lpush key value [value1 …] :在指定key的列表左邊插入一個或多個值;

rpush key value [value1 …] :在指定key的列表右邊插入一個或多個值;

lpop key :從指定key的列表左邊取出第一個值;

rpop key:從指定key的列表右邊取出第一個值;

lrange key start end:從指定key列表中獲取指定區間內的數據;

blpop key [key1 …] timeout:從指定key列表中左邊取出第一個值,若列表中沒有元素就等待timeout時間,如果timeout為0就一直等待。

brpop key [key1 …] timeout:從指定key列表中右邊取出第一個值,若列表中沒有元素就等待timeout時間,如果timeout為0就一直等待。

lset key index value:將指定下標的值更新為value,

img

結合應用場景演****練↓↓↓

用於模擬數據結構:

  • 棧:先進後出,lpush+lpop 或 rpush+rpop;

    img

  • 隊列:先進先出,lpush+rpop 或 rpush+lpop;

    img

  • 阻塞隊列:先進先出,如果列表沒有元素就等待,lpush+brpop或rpush+blpop;

    img

用於數據傳輸橋樑:經常會遇見採集一些儀器相關數據的需求,但通常方式都會讓儀器生成數據文件,供其它程序進行解析,也有用Redis中List作為橋樑傳輸數據的,減少自己生成文件的過程,通過用List的方式,一邊塞進去,一邊定時取出,然後發送到遠程。同樣的道理,也可以用於一些消息的推送,比如關注了一個公眾號,要發送給訂閱者,首先公眾號發表文章到List,有一個後台任務程序定時進行取出發給訂閱者,這裡就是拿公眾號舉一個例,並非公眾號是這麼實現。

img

模擬消息推送

img

專門有一個後台任務程序從關注者消息列表中取出消息,依次發給每個關注者。

list常規操作(獲取,更新,插入):

img

set

set命令一般以s開頭,裏面元素無序且不重複,着重分享以下命令:

sadd key member [member …]:在集合中增加一個或多個元素;

srem key member [member …]:從集合中刪除一個或多個元素;

smembers key:獲取集合中的所欲元素;

scard key:獲取集合中的元素個數;

sismember key member:判斷指定member是否在集合中;

srandmember key [count]:從集合中獲取count個元素,不從集合中刪除;

spop key [count]:從集合中獲取count個元素,從集合中刪除

sinter key [key1 …]:指定多個集合進行交集運算;

sinterstore dest key [key1 …]:指定多個集合進行交集運算,存入dest集合;

sunion key [key1 …]:指定多個集合進行並集運算;

sunionstore dest key [key1 …]:指定多個集合進行並集運算,存入dest集合;

sdiff key [key1 …]:指定多個集合進行差集運算;

sdiffstore dest key [key1 …]:指定多個集合進行差集運算,並存入dest集合;

結合應用場景演練*↓↓↓*

抽獎邏輯:抽獎小夥伴們不陌生了吧,不管是公司年會抽獎,還是公眾號參與抽獎,應該幾乎不用親手抓鬮了吧。都是通過程序,把人員都放在一起,然後隨機抽取,set很符合這種應用場景,如下:

img

以上是隨便找一個抽獎小程序創建的抽獎,開始命令演練:

img

文章點贊:發表文章之後,可以進行點贊、取消點贊等相關操作;

img

共同好友統計

img

zset

zset的命令一般以z開頭,裏面元素是有序不可重複的。和Set用法基本一樣,只是每個元素中多了一個分值,用於元素排序。

zadd key score member [(score member)…]:往有序集合中添加帶分值的元素;

zrem key member [member…]:從有序集合中刪除成員;

zscore key member:返回集合中指定成員的分值;

zcard key:統計集合中元素個數;

zrange key start stop [withscores]:返回指定範圍的元素,withscores代表返回的元素包含對應的分值。

zreverange key start stop [withscores]:返回指定範圍的倒序元素,withscores代表返回的元素包含對應的分值。

同set一樣也可以進行交集、並集、差集的集合運算。

綜合應用場景*↓↓↓*

用於排名:比如考試成績的排名,新聞熱度排行榜,直播打賞排名等。

img

新聞熱榜:

img

img

總結

以上簡單結合實例應用場景將五種基礎類型的常用命令進行分享,還有大量的命令需要小夥伴們結合實際需求進行應用。文中實例大部分是周圍項目中的使用場景,少部分是參考學習資料,總體來說,文中實例應用只作為思路參考,小夥伴可根據業務需求進行應用,對於命令的使用還需要小夥伴們多多練習實踐。下一篇聊聊三種特殊類型。

一個被程序搞丑的帥小伙,關注”Code綜藝圈”,識別關注跟我一起學~~~

擼文不易,莫要白瞟,三連走起~~~~