首頁 資料庫 Redis 怎麼用Redis做預定庫存快取功能

怎麼用Redis做預定庫存快取功能

May 28, 2023 am 10:12 AM
redis

一、業務背景

我決定將本次問題比喻為考卷上的問題,以避免介紹我們公司專案的背景。至於業務細節,大家也不需要關注~看題目就可以了:

假設你是某國最牛的收藏家,手裡有各種價值連成的寶物。有一天你可能會感到收藏變得無聊了,於是決定出售這些珍貴物品以獲取現金。

不過把這些值錢的寶貝放在菜市場上賣實在太low了。在「網路」時代,我們當然要玩一些不一樣的賣法:在你名下有一棟300個房間的大樓(編號為001至300),每個房間放著一個密碼鎖保險箱,在下個月( 12月1日至12月31日)的每一天,你都會挑選300件最好的「極品寶物」(也稱為A類寶物),分別放入這300個房間的保險箱裡,每天每個房間放什麼寶物已經定好了,所有想買寶物的人必須至少提前一天在網上預定,到時候憑藉預定碼自己打開保險箱取貨。沒有被預定的寶物將會被你收回,不再販賣。

要做這樣一個網路預定係統,它的前端介面大概是這樣的:

怎麼用Redis做預定庫存快取功能

#上圖中三個要填的控件,點擊後可以出現選擇框。現在的問題是,一個房間只有一個寶物,不能被重複預定。當買家選定寶物類型和房間號碼後,當他們選擇預定日期時,建議在日期選擇框中提供一些提示資訊。例如12月3日051號房間已被預定,現在又有另一位用戶選擇了051號房間,那麼在彈出日期選擇框時,12月3日要置為不可選。如下圖(12月3日顯示為「缺」):

怎麼用Redis做預定庫存快取功能

那麼,這樣一個簡單的庫存系統,如何在redis中儲存呢?

二、庫存管理方案(Redis)

我們最初的構想是,我們的存貨可以被視為一個巨大的三維數組,其中第一個維度表示寶物類型,第二維表示房間號,第三維表示預定日期。 Redis提供了五種儲存類型,分別為:String、Hash、List、Set、Sorted Set。我們可以在目前場景下使用Hash類型來儲存數據,因為它能夠滿足我們的需求,同時Set類型也是一個可行的選項。

Redis的key設定為 寶物類型房間號碼(例如 A:205,A代表極品寶物,205為房間號碼),Redis的value為hash類型,hash key為日期(例如 2016-12-05 ),hash value為true或false,表示已經被預定或沒有被預定。用圖表示為:

怎麼用Redis做預定庫存快取功能

如果A類寶物158房間在12月8日已經被預定,則儲存為

1

2

3

#Redis Key —— A:158

Redis Value —— hash table ['2016-12-08' #=> 1]

三、進階場景&庫存管理方案

A類頂級寶物的推出受到了熱烈歡迎,僅推出不久便已被訂購數不少。許多中產階級對收藏感興趣,但高昂的價格常常令他們望而卻步。於是,你從自己的珍藏中選擇了B類寶物,它比A類寶物稍遜一些,但價格更為合理,也被稱為「優良寶物」。

由於B類寶物比A類寶物多一些,你打算換一種玩法,在這300個房間中,每個房間又放入了一個保險箱,這次,你每隔一個小時都會將300個房間的箱子各放入一件B類寶物,沒有被預定的寶物在這一小時過後會被收回,換成下一個小時的寶物。買家預訂後,請按照預定的小時取走寶物。對於B類寶物,你的預定係統會多了一個選項,也就是取貨時間。如下圖:

怎麼用Redis做預定庫存快取功能

現在由於多了一個預定條件(取貨時間),那在做庫存存放的時候,粗暴的方式想一下,庫存其實就是一個大的四維數組。這句話可以改寫為:四維資訊包括寶物類型、房間號碼、預定日期和取貨時間。在Redis中怎麼儲存這類寶物呢?

其實仔細想一下,在儲存A類極品寶物的時候,我們在Redis中的存儲是有浪費維度的​​情況的,

實際上,當時只使用了一個hashValue存儲了預定的狀態,導致該維度的資訊被浪費了。考慮到取貨時間全是整點,一整天也就是0至1點,1至2點,……,23至24點共計24種情況,所以我們完全可以使用二進制整數表示被預定的時間。例如1表示0至1點,2表示1至2點,4表示2至3點,……,

23至24點可以用2的23次方(8388608)來表示。多個時間段被預定,只需要將數值取邏輯或操作即可。

這樣,我們的Redis結構變成了這樣子:

怎麼用Redis做預定庫存快取功能

#例如,B類寶物103房間,12月5日和6日的上午8點至12點被預定,在redis中儲存為

##

對於B類寶物,在做新增預定時,需要注意先將原有的hash value取出,和新的預定取貨時間做邏輯或操作,然後再把結果寫回Redis中,而不能像A類寶物一樣直接調用hSet去設定hash value;取消預定時,要注意先將原有的hash value取出,將要取消的時間段從hash value中扣除(異或邏輯與操作),然後重新將剩餘的已預訂取貨時間寫回Redis中,而不能直接呼叫hDel去刪除。

四、再進階&庫存管理方案

自從推出了B類寶物之後,你的生意又比以往火爆了許多。於是新的需求又來了,現在有大量的遊客、學生黨等沒什麼豐厚積蓄的人表示對你的寶物非常感興趣,來這個城市旅遊的人都希望帶一些紀念品回去。儘管B類寶物價格略低於A類,但對這些人來說仍有些昂貴。於是,你決定把自己餘量最多的實惠寶物(C類寶物)拿出來販售。

在這300個房間中,C類寶物儲存數量最多,因此你在每個房間增加了100個專門用於儲存C類寶物的寶箱。這100個寶箱分別被編號為1號,2號,……,100號。同樣的,每天的每個小時,你都會向這300個房間中,每個房間的100個寶箱中分別放入一件C類寶物(也就意味著,整個大樓每小時C類寶物會更新30000件)。如果沒有人預定,則下一個小時寶物更換。終於,這下可以滿足所有人的需求了。

對於C類寶物,你的預定介面成了下面的樣子:

怎麼用Redis做預定庫存快取功能

#我們又多了一個預定條件。此時,又面臨庫存儲存的問題。照例,這個庫存其實就是一個大的五維數組,寶物類型、房間號碼、預定日期、取貨時間、寶箱編號各自佔有一個維度。前面我們已經用掉了Redis的各個容量,現在要儲存資料該怎麼辦?

這次的Redis庫存儲存必須要結合業務特點來了。首先,寶箱編號和取貨時間這兩個維度,能取的值範圍並不太多,寶箱編號只有100個,只要把hash value變成一個長度為100的數組,數組的每個位置都存有INT類型表示的取貨時間即可。然而hash value只能是string……於是乎,只好做一個陣列的序列化操作,讀取的時候再反序列化回來即可。還好長度只有100,序列化效率不會成為系統的瓶頸。

儲存方式為:12月23日、24日在258房間的C類寶物中,編號為97和99的寶箱在上午11點至下午1點期間已被預定

#1

2

3

Redis Key  —— B:103

 

##Redis Value —— hash table [ '2016-12-05' => 3840, '2016-12-06' => 3840]

#1

2

3

#Redis Key —— C :258

 

Redis Value —— hash table [#'2016-12-23' =&gt ; '[97 => 6144, 99 => 6144]''2016-12-24' =&gt ; '[97 => 6144, 99 => 6144]' ]

其中6144用二進位表示為‘110000000000’,hash value為數組序列化以後的字串,實際項目中可以使用json格式。好了,現在Redis對於三種寶物的儲存都有了。

怎麼用Redis做預定庫存快取功能

對於C類寶物,當使用者取消預定、新增預定時,同樣不能簡單地呼叫hSet和hDel進行覆蓋設定和刪除,要取出已經預定的情況,與已經預定的取貨時間做位運算。

五、儲存最佳化

庫存理論上就是一個多維數組,我們所做的主要工作就是怎樣把各個維度合理的儲存起來,並且能夠方便地進行增加、刪除、查詢操作。從節省使用記憶體的角度來講,在最開始還沒有任何人預定的時候,Redis整個可以是空的,對於A類寶物來說,hash value等於false和根本不存在對應的redis key或hash key是等效的。

另外,寶物類型和房號合起來做redis key,會導致我們在redis中和寶物庫存相關的key的數量比較多​​,為了方便統一管理這些key,可以再增加一條redis緩存,專門用來儲存和寶物庫存相關的所有redis key值,如下圖所示。需要注意的是,在這種情況下,使用set資料類型就可以滿足要求了,而不必使用hash資料類型,因為set資料類型的增刪改查複雜度都為O(1)。裡面儲存了所有redis中已經存在的庫存key值。

怎麼用Redis做預定庫存快取功能

這麼做的一個好處是,萬一哪天碰到一些特殊情況,需要把所有庫存相關緩存全部清空的話,我們可以很容易地取出所有的庫存key並做刪除操作。另外一個好處是,給我們提供了繼續擴展的思路……設想一下,現在最複雜的情況是C類寶物,一共5個維度。假設未來,你不再使用一棟樓的300個房間去販賣寶物,而是多幢樓,那麼用戶在下訂單的時候又要多出一個維度——樓樓編號。碰到這種情況,我們完全可以將這個多出來的庫存Key集合退化為樓棟編號來使用,保證了可能出現的更複雜情況下的擴展性。

在做了這次擴充之後,每次新增預定記錄時,需要注意偵測庫存key集合中是否已經存在對應的redis key值,如果不存在需要將redis key值加入庫存key集合中。刪除操作也類似。

以上是怎麼用Redis做預定庫存快取功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

redis集群模式怎麼搭建 redis集群模式怎麼搭建 Apr 10, 2025 pm 10:15 PM

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

redis數據怎麼清空 redis數據怎麼清空 Apr 10, 2025 pm 10:06 PM

如何清空 Redis 數據:使用 FLUSHALL 命令清除所有鍵值。使用 FLUSHDB 命令清除當前選定數據庫的鍵值。使用 SELECT 切換數據庫,再使用 FLUSHDB 清除多個數據庫。使用 DEL 命令刪除特定鍵。使用 redis-cli 工具清空數據。

redis怎麼讀取隊列 redis怎麼讀取隊列 Apr 10, 2025 pm 10:12 PM

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

redis指令怎麼用 redis指令怎麼用 Apr 10, 2025 pm 08:45 PM

使用 Redis 指令需要以下步驟:打開 Redis 客戶端。輸入指令(動詞 鍵 值)。提供所需參數(因指令而異)。按 Enter 執行指令。 Redis 返迴響應,指示操作結果(通常為 OK 或 -ERR)。

centos redis如何配置Lua腳本執行時間 centos redis如何配置Lua腳本執行時間 Apr 14, 2025 pm 02:12 PM

在CentOS系統上,您可以通過修改Redis配置文件或使用Redis命令來限制Lua腳本的執行時間,從而防止惡意腳本佔用過多資源。方法一:修改Redis配置文件定位Redis配置文件:Redis配置文件通常位於/etc/redis/redis.conf。編輯配置文件:使用文本編輯器(例如vi或nano)打開配置文件:sudovi/etc/redis/redis.conf設置Lua腳本執行時間限制:在配置文件中添加或修改以下行,設置Lua腳本的最大執行時間(單位:毫秒)

redis怎麼使用鎖 redis怎麼使用鎖 Apr 10, 2025 pm 08:39 PM

使用Redis進行鎖操作需要通過SETNX命令獲取鎖,然後使用EXPIRE命令設置過期時間。具體步驟為:(1) 使用SETNX命令嘗試設置一個鍵值對;(2) 使用EXPIRE命令為鎖設置過期時間;(3) 當不再需要鎖時,使用DEL命令刪除該鎖。

redis命令行怎麼用 redis命令行怎麼用 Apr 10, 2025 pm 10:18 PM

使用 Redis 命令行工具 (redis-cli) 可通過以下步驟管理和操作 Redis:連接到服務器,指定地址和端口。使用命令名稱和參數向服務器發送命令。使用 HELP 命令查看特定命令的幫助信息。使用 QUIT 命令退出命令行工具。

redis過期策略怎麼設置 redis過期策略怎麼設置 Apr 10, 2025 pm 10:03 PM

Redis數據過期策略有兩種:定期刪除:定期掃描刪除過期鍵,可通過 expired-time-cap-remove-count、expired-time-cap-remove-delay 參數設置。惰性刪除:僅在讀取或寫入鍵時檢查刪除過期鍵,可通過 lazyfree-lazy-eviction、lazyfree-lazy-expire、lazyfree-lazy-user-del 參數設置。

See all articles