大廠技術,基於的Redis 購物車設計

1。1。

購物車常見實現方式

購物車是任何一個電商專案都會使用到的功能,面試的時候也經常問到,傳統的做法是使用關係型資料庫,比如mysql,建立一個cat購物車表,把相關的購物車產品資訊都放到資料庫裡面。

CREATE TABLE goods_shopcar (id int(4) NOT NULL ,uid int(10) NULL ,goods_id int(10) NULL ,number int(10) NULL ,status tinyint(4) NULL ,create_time int(10) NULL ,update_time int(10) NULL ,PRIMARY KEY (id));

這樣的設計在功能完全沒問題,但在實際使用中,由於購物車的資料量太大,而且修改頻繁,會導致資料庫的壓力增加,所以在正式專案開發中,一般不會直接使用關係型資料庫來儲存購物車資訊。

既然不用關係型資料庫,但就從非關係型資料庫裡面做選擇了,很多的架構師會選擇使用mongodb 存購物車的資料,這也完全可以,mongodb有非常豐富的查詢API,效能也比傳統關係型資料庫要好,使用mongodb確實是個不錯的選擇。

但比起使用mongodb,有部分公司也會使用redis來存放購物車的資訊,比起mongdb的效能,redis的效能要來得更好。

在這就來談論下使用redis來完成購物車的思路。

1。2。

開啟持久化

購物車的資料,既然不存在關係型資料庫中,使用redis儲存也不能讓資料丟失,那redis必須開啟持久化,這樣哪怕redis重啟資料也不至於丟失。

Redis有兩種持久化機制,一種叫rdb,一種叫aof。

rdb也叫映象檔案,存放的是某個時刻redis記憶體資料的一個映象

aof就是append only file的簡寫,裡面存放的是日誌檔案,準確的來說是存放RESP的指令日誌,這裡RESP指令並不是這次的重點,這裡不做討論。

首先,RDB預設是開啟的,在Redis配置檔案裡面,關於RDB的配置如下

save 900 1:表示900 秒內如果至少有 1 個 key 的值變化,則儲存save 300 10:表示300 秒內如果至少有 10 個 key 的值變化,則儲存save 60 10000:表示60 秒內如果至少有 10000 個 key 的值變化,則儲存

預設的配置最少是60秒並且有10000個key發生變化才會重新整理一次映象,這樣如果在時間沒到60秒,這個時候redis意外宕機,在這個時間段的資料都會丟失

你可能會想,是否可以增加一條配置

save 1 1:表示1 秒內如果至少有 1 個 key 的值變化,則儲存

這樣資料視乎就不會丟失,但這肯定是不行的,每一秒都對redis記憶體的所有資料都寫入一次磁碟變成映象檔案,這樣對效能影響非常大。

為了防止資料丟失,光從rdb上下手還是不行,預設aof並沒開啟,應該開啟aof日誌檔案,這時候得修改配置檔案,增加aof的相關配置

appendonly yes

開啟了aof日誌,丟失資料的可能性就減少很多了。

1。3。

業務分析

大廠技術,基於的Redis 購物車設計

以京東的購物車為例,按業務分析,需要完成如下功能:

全選功能-獲取所有該使用者的所有購物車商品

商品數量-購物車圖示上要顯示購物車裡商品的總數

刪除-要能移除購物車裡某個商品

增加或減少某個商品的數量

1。4。

資料結構選擇

Redis常用有5種資料型別分別為string,hash,list,set,zset,在這個案例裡面我們選擇使用hash來完成這個購物車功能

先對hash這種資料型別的常用命令進行介紹

redis中hash的新增命令hset,如果key不存在,建立key,存在,則覆蓋原有值

redis 127。0。0。1:6379>hset myhash name enjoy ——給key為myset的鍵值設定鍵為name值為enjoy

redis中hash的檢視命令hget

redis 127。0。0。1:6379>hget myhash name ——輸出: “enjoy”,獲取key為myset,鍵為name的valueredis 127。0。0。1:6379>hset myhash name xiangxue ——覆蓋原有值,值改為xiangxue替換 redis 127。0。0。1:6379>hget myhash name ——-輸出:“xiangxue”

redis中hash的獲取key包含的field數量的命令hlen

redis 127。0。0。1:6379>hset myhash age 20 ——- 設定key為 myhash 鍵為age的value=20redis 127。0。0。1:6379>hlen myhash ——-輸出為2,key為myhash的field數量為2

redis中判斷指定key中指定field是否存在的命令hexists,存在返回1,不存在返回0

redis 127。0。0。1:6379>hexists myhash name ——-返回1,說明存在redis 127。0。0。1:6379>hexists myhash name1 ——-返回0,說明不存在

redis中hash刪除命令hdel,刪除一個或多個指定的欄位

redis 127。0。0。1:6379>hset myhash sex boy ——新增資料redis 127。0。0。1:6379>hset myhash likes sports ——新增資料redis 127。0。0。1:6379>hdel myhash likes ——刪除單個數據,filed為likes 的資料

redis中hash如果key或field不存在插入有效,否則不採取操作的命令hsetnx

redis 127。0。0。1:6379>hsetnx myhash sex boy ——-設定myhash,field為sex的value為boy,不成功返回0,因為原來存在sex這個欄位並且有值redis 127。0。0。1:6379>hget myhash sex ——輸出“boy”

redis中hash中的value為數值時操作增減的命令hincrby

redis 127。0。0。1:6379>del myhash ——-刪除該鍵redis 127。0。0。1:6379>hset myhash age 20 ——-設定key為myhash的鍵為age值為20redis 127。0。0。1:6379>hincrby myhash age 10 ——-給key為myhash,鍵為age的值加10,輸出結果為30redis 127。0。0。1:6379>hincrby myhash age -10 ——-給key為myhash,鍵為age的值減去10,輸出結果為20

批次新增key/value的命令hmset

redis 127。0。0。1:6379>del myhash ——刪除該鍵redis 127。0。0。1:6379>hmset myhash name enjoy age 20 issingle yes ——給key為myhash的hash新增name=enjoy,age=20,issingle=yes 的多個鍵值

批次獲取key/value的命令hmget

redis 127。0。0。1:6379>hmget myhash name age issingle ——輸出結果為:enjoy 20 yes

根據myhash鍵獲取所有的欄位及value的命令hgetall

redis 127。0。0。1:6379>hgetall myhash ——輸出結果為:name age issingle enjoy 20 yes

獲取所有的field的命令hkeys

redis 127。0。0。1:6379>hkeys myhash ——-輸出結果為:name age issingle

獲取所有欄位的值的命令hvals

redis 127。0。0。1:6379>hvals myhash ——輸出結果為:enjoy 20 yes

1。5。

業務設計

在購物車的場景下,既然選擇使用hash來完成,可以總體規劃如下

以使用者ID作為key

以商品id作為field

以商品的數量作為value

1。5。1。

增加購物車商品

假設現在使用者ID為1001,這使用者往購物車放3個商品,產品的ID為10021,10025,10079,對應的指令應該為

hset cart:1001 10021 1hset cart:1001 10025 1hset cart:1001 10079 1

大廠技術,基於的Redis 購物車設計

1。5。2。

全選功能

全選功能-獲取所有該使用者的所有購物車商品,這個就非常好完成了,使用hgetall 指令就好。

hgetall cart:1001 這樣就能把使用者1001的購物車裡面所有商品列出來。

大廠技術,基於的Redis 購物車設計

1。5。3。

商品數量

商品數量-購物車圖示上要顯示購物車裡商品的總數,這樣也不難,使用hlen指令就好。

hlen cart:1001 顯示3,顯示的是購物車的商品數量。

大廠技術,基於的Redis 購物車設計

1。5。4。

刪除商品

刪除-要能移除購物車裡某個商品。

hdel cart:1001 10079 刪除了購物車裡商品ID為10079的商品。

大廠技術,基於的Redis 購物車設計

1。5。5。

增加商品

增加或減少某個商品的數量。

hincrby cart:1001 10021 1 透過這樣指令,使購物車產品id為10021的商品數量增加了1。

大廠技術,基於的Redis 購物車設計

這樣設計,的購物車,效能是很好的,而且也減少了資料庫的壓力,在真實的專案中可以考慮這樣使用。

問題:

redis的持久化機制有哪些?

解答:

Redis支援aof,rdb兩種持久化機制,預設使用的是rdb,aof需要修改配置檔案開啟。rdb也叫映象檔案,存放的是某個時刻redis記憶體資料的一個映象。aof就是append only file的簡寫,裡面存放的是日誌檔案,準確的來說是存放RESP的指令日誌,每一條對 redis的操作命令都儲存在裡面。