欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis做預(yù)定庫(kù)存緩存功能設(shè)計(jì)使用

 更新時(shí)間:2022年04月01日 16:49:23   作者:HorstXu  
這篇文章主要為大家介紹了Redis做預(yù)定庫(kù)存緩存功能設(shè)計(jì)使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪

最近在自己的工作中,把其中一個(gè)PHP項(xiàng)目的緩存從以前的APC緩存逐漸切換到Redis中,并且根據(jù)Redis所支持的數(shù)據(jù)結(jié)構(gòu)做了庫(kù)存維護(hù)功能。緩存是在業(yè)務(wù)層做的,準(zhǔn)確講應(yīng)該是在MVC模型中Model的ORM里面。主要邏輯就是先查緩存,查不到的話再查數(shù)據(jù)庫(kù)。不過這些不是本文的主要內(nèi)容,下面我把庫(kù)存管理功能的緩存設(shè)計(jì)思路分享一下,希望能帶給大家一些收獲,有不足之處或者有更好方案的,也希望各位多多指教。

一、業(yè)務(wù)背景

為了略去我們公司項(xiàng)目背景,我決定把這次的問題類比成一個(gè)考卷上的問題。至于業(yè)務(wù)細(xì)節(jié),大家也無(wú)需關(guān)注~看題目就可以了:

假設(shè)你是某國(guó)最牛的收藏家,手里有各種價(jià)值連成的寶物。知道有一天,你覺得做收藏太沒意思了,打算把這些寶物賣掉換點(diǎn)現(xiàn)金。

不過把這些值錢的寶貝放在菜市場(chǎng)上賣實(shí)在太low了。在“互聯(lián)網(wǎng)+”時(shí)代,我們當(dāng)然要玩一些不一樣的賣法:在你名下有一棟300個(gè)房間的大樓(編號(hào)為001至300),每個(gè)房間放著一個(gè)密碼鎖保險(xiǎn)箱,在下個(gè)月(12月1日至12月31日)的每一天,你都會(huì)挑選300件最好的“極品寶物”(也稱作A類寶物),分別放入這300個(gè)房間的保險(xiǎn)箱里,每天每個(gè)房間放什么寶物已經(jīng)定好了,所有想買寶物的人必須至少提前一天在網(wǎng)上預(yù)定,到時(shí)候憑借預(yù)定碼自己打開保險(xiǎn)箱取貨。沒有被預(yù)定的寶物將會(huì)被你收回,不再售賣。

要做這樣一個(gè)網(wǎng)絡(luò)預(yù)定系統(tǒng),它的前端界面大概是這樣的:

上圖中三個(gè)要填的控件,單擊后可以出現(xiàn)選擇框?,F(xiàn)在的問題是,一個(gè)房間只有一個(gè)寶物,不能被重復(fù)預(yù)定。所以當(dāng)買家選擇了寶物類型和房間號(hào)之后,在選擇預(yù)定日期時(shí),要在日期選擇框給用戶一個(gè)提示。比如12月3日051號(hào)房間已被預(yù)定,現(xiàn)在又有另一位用戶選擇了051號(hào)房間,那么在彈出日期選擇框時(shí),12月3日要置為不可選。如下圖(12月3日顯示為“缺”):

那么,這樣一個(gè)簡(jiǎn)單的庫(kù)存系統(tǒng),如何在redis中存儲(chǔ)呢?

二、庫(kù)存管理方案(Redis)

最粗暴的想法是,我們的庫(kù)存其實(shí)就是一個(gè)很大的三維數(shù)組,第一維寶物類型,第二維房間號(hào),第三維即預(yù)定日期。Redis支持5種存儲(chǔ)類型:String,Hash,List,Set,Sorted Set。目前的場(chǎng)景中Hash和Set類型都可以滿足要求,在此我們選擇使用Hash類型做存儲(chǔ)。

Redis的key設(shè)置為 寶物類型+房間號(hào)(例如 A:205,A代表極品寶物,205為房間號(hào)),Redis的value為hash類型,hash key為日期(例如 2016-12-05),hash value為true或false,表示已經(jīng)被預(yù)定或沒有被預(yù)定。用圖表示為:

如果A類寶物158房間在12月8日已經(jīng)被預(yù)定,則存儲(chǔ)為

Redis Key —— A:158

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

三、進(jìn)階場(chǎng)景&庫(kù)存管理方案

你所推出的A類極品寶物很受歡迎,剛推出去不久即被預(yù)定出去很多。然而,動(dòng)輒數(shù)十萬(wàn)元的價(jià)格也讓很多有收藏興趣、卻沒那么富裕的中產(chǎn)階級(jí)望而卻步。于是,你又從自己的收藏中挑選出了比A類寶物稍次一些的B類寶物(也稱作“優(yōu)質(zhì)寶物”),價(jià)格更加親民。

由于B類寶物比A類寶物多一些,你打算換一種玩法,在這300個(gè)房間中,每個(gè)房間又放入了一個(gè)保險(xiǎn)箱,這次,你每隔一個(gè)小時(shí)都會(huì)向300個(gè)房間的箱中各放入一件B類寶物,沒有被預(yù)定的寶物在這一個(gè)小時(shí)過后會(huì)被收回,換成下一個(gè)小時(shí)的寶物。買家預(yù)訂后,按照所預(yù)定的小時(shí)來(lái)取走寶物。對(duì)于B類寶物,你的預(yù)定系統(tǒng)會(huì)多了一個(gè)選項(xiàng),即取貨時(shí)間。如下圖:

現(xiàn)在由于多了一個(gè)預(yù)定條件(取貨時(shí)間),那在做庫(kù)存存儲(chǔ)的時(shí)候,粗暴的方式想一下,庫(kù)存其實(shí)就是一個(gè)大的四維數(shù)組。第一維寶物類型,第二維房間號(hào),第三維預(yù)定日期,第四維取貨時(shí)間。在Redis中怎樣存儲(chǔ)這類寶物呢?

其實(shí)仔細(xì)想一下,在存儲(chǔ)A類極品寶物的時(shí)候,我們?cè)赗edis中的存儲(chǔ)是有浪費(fèi)維度的情況的,

當(dāng)時(shí)hashValue只存了一個(gè)true表示有預(yù)定,這個(gè)維度其實(shí)是被浪費(fèi)掉了??紤]到取貨時(shí)間全是整點(diǎn),一整天也就是0至1點(diǎn),1至2點(diǎn),……,23至24點(diǎn)共計(jì)24種情況,所以我們完全可以使用二進(jìn)制整數(shù)表示被預(yù)定的時(shí)間。例如1表示0至1點(diǎn),2表示1至2點(diǎn),4表示2至3點(diǎn),……,

8388608 (= 2^23)表示23至24點(diǎn)。多個(gè)時(shí)間段被預(yù)定,只需要將數(shù)值取邏輯或操作即可。

這樣,我們的Redis結(jié)構(gòu)變成了這樣子:

例如,B類寶物103房間,12月5日和6日的上午8點(diǎn)至12點(diǎn)被預(yù)定,在redis中存儲(chǔ)為

Redis Key  —— B:103

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

對(duì)于B類寶物,在做新增預(yù)定時(shí),需要注意先將原有的hash value取出,和新的預(yù)定取貨時(shí)間做邏輯或操作,然后再把結(jié)果寫回Redis中,而不能像A類寶物一樣直接調(diào)用hSet去設(shè)置hash value;取消預(yù)定時(shí),要注意先將原有的hash value取出,把要取消的時(shí)間段從hash value中扣除掉(異或+邏輯與操作),然后重新將剩余的已預(yù)訂取貨時(shí)間寫回Redis中,而不能直接調(diào)用hDel去刪除。

四、再次進(jìn)階&庫(kù)存管理方案

自從推出了B類寶物之后,你的生意又比以往火爆了許多。于是新的需求又來(lái)了,現(xiàn)在有大量的游客、學(xué)生黨等沒什么豐厚積蓄的人表示對(duì)你的寶物非常感興趣,來(lái)這個(gè)城市旅游的人都希望帶一些紀(jì)念品回去。然而,B類寶物的價(jià)格雖然比A類便宜一些,對(duì)于這些人來(lái)講還是有點(diǎn)貴。于是,你決定把自己余量最多的實(shí)惠寶物(C類寶物)拿出來(lái)售賣。

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

對(duì)于C類寶物,你的預(yù)定界面成了下面的樣子:

我們又多了一個(gè)預(yù)定條件。此時(shí),又面臨著庫(kù)存存儲(chǔ)的問題。照例,這個(gè)庫(kù)存其實(shí)就是一個(gè)大的五維數(shù)組,寶物類型、房間號(hào)、預(yù)定日期、取貨時(shí)間、寶箱編號(hào)各自占有一個(gè)維度。不過前面我們的Redis各個(gè)維度基本上已經(jīng)占滿了,這次應(yīng)該怎么存儲(chǔ)呢?

這次的Redis庫(kù)存存儲(chǔ)必須要結(jié)合業(yè)務(wù)特點(diǎn)來(lái)了。首先,寶箱編號(hào)和取貨時(shí)間這兩個(gè)維度,能取的值范圍并不太多,寶箱編號(hào)只有100個(gè),只要把hash value變成一個(gè)長(zhǎng)度為100的數(shù)組,數(shù)組的每個(gè)位置都存有INT類型表示的取貨時(shí)間即可。然而hash value只能是string……于是乎,只好做一個(gè)數(shù)組的序列化操作,讀取的時(shí)候再反序列化回來(lái)即可。好在長(zhǎng)度只有100,序列化效率并不會(huì)成為系統(tǒng)的瓶頸。

例如,C類寶物,12月23日、24日,258房間,97和99號(hào)寶箱在11點(diǎn)至13點(diǎn)被預(yù)定,則存儲(chǔ)為:

Redis Key  —— B:103

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

其中6144用二進(jìn)制表示為‘110000000000’,hash value為數(shù)組序列化以后的字符串,實(shí)際項(xiàng)目中可以使用json格式。好了,現(xiàn)在Redis對(duì)于三種寶物的存儲(chǔ)都有了。

對(duì)于C類寶物,在用戶取消預(yù)定、新增預(yù)定時(shí),同樣不能簡(jiǎn)單地調(diào)用hSet和hDel進(jìn)行覆蓋設(shè)置和刪除,要取出已經(jīng)預(yù)定的情況,與已經(jīng)預(yù)定的取貨時(shí)間做位運(yùn)算。

五、存儲(chǔ)優(yōu)化

庫(kù)存理論上就是一個(gè)多維數(shù)組,我們所做的主要工作就是怎樣把各個(gè)維度合理的存儲(chǔ)起來(lái),并能夠方便地進(jìn)行增加、刪除、查詢操作。從節(jié)約使用內(nèi)存的角度講,在最開始還沒有任何人預(yù)定的時(shí)候,Redis整個(gè)可以是空的,對(duì)于A類寶物來(lái)說(shuō),hash value等于false和根本不存在對(duì)應(yīng)的redis key或hash key是等效的。

另外,寶物類型和房間號(hào)合起來(lái)做redis key,會(huì)導(dǎo)致我們?cè)趓edis中和寶物庫(kù)存相關(guān)的key的數(shù)量比較多,為了方便統(tǒng)一管理這些key,可以再增加一條redis緩存,專門用來(lái)存儲(chǔ)和寶物庫(kù)存相關(guān)的所有redis key值,如下圖所示。需要注意的是,這次我們并不需要hash數(shù)據(jù)類型了,set類型就已經(jīng)足夠,增刪改查復(fù)雜度都是O(1)。里面存儲(chǔ)了所有redis中已經(jīng)存在的庫(kù)存key值。

這么做的一個(gè)好處是,萬(wàn)一哪天碰到一些特殊情況,需要把所有庫(kù)存相關(guān)緩存全部清空的話,我們可以很容易地取出所有的庫(kù)存key并做刪除操作。另外一個(gè)好處是,給我們提供了繼續(xù)擴(kuò)展的思路……設(shè)想一下,現(xiàn)在最復(fù)雜的情況是C類寶物,一共5個(gè)維度。假設(shè)未來(lái),你不再使用一幢樓的300個(gè)房間去售賣寶物,而是多幢樓,那么用戶在下訂單的時(shí)候又要多出一個(gè)維度——樓棟編號(hào)。碰到這種情況,我們完全可以將這個(gè)多出來(lái)的庫(kù)存Key集合退化為樓棟編號(hào)來(lái)使用,保證了可能出現(xiàn)的更復(fù)雜情況下的擴(kuò)展性。

在做了這次擴(kuò)展之后,每次新增預(yù)定記錄時(shí),需要注意檢測(cè)庫(kù)存key集合中是否已經(jīng)存在對(duì)應(yīng)的redis key值,如果不存在需要將redis key值加入庫(kù)存key集合中。刪除操作也類似。

六、總結(jié)

上面使用了循序漸進(jìn)的方法講述了一下問題,不過現(xiàn)實(shí)的場(chǎng)景中,這三種寶物類型在我們的業(yè)務(wù)中是同時(shí)存在的。上面的設(shè)計(jì)保持了三種寶物類型存儲(chǔ)上的統(tǒng)一性。如果只考慮A類寶物的話,庫(kù)存只有三個(gè)維度,其實(shí)完全不必使用hash數(shù)據(jù)類型來(lái)存儲(chǔ),set類型就足夠了。

我們存儲(chǔ)這些預(yù)定情況的主要目的,就是為了方便快速地查到庫(kù)存沖突情況。比如有人已經(jīng)定了12月3日,59號(hào)房間的A類寶物,那又有另外一個(gè)人想預(yù)定一樣的日期、房間的A類寶物時(shí),通過內(nèi)存中的庫(kù)存查詢,我們可以很方便地告訴客戶,該庫(kù)存已經(jīng)被其他人搶先預(yù)定了。

以上就是我在業(yè)務(wù)中碰到的一個(gè)緩存設(shè)計(jì)的小問題,不吝賜教!

以上就是Redis做預(yù)定庫(kù)存緩存功能設(shè)計(jì)使用的詳細(xì)內(nèi)容,更多關(guān)于Redis預(yù)定庫(kù)存緩存設(shè)計(jì)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Redis安全策略詳解

    Redis安全策略詳解

    緩存穿透是指當(dāng)用戶在查詢一條數(shù)據(jù)的時(shí)候,而此時(shí)數(shù)據(jù)庫(kù)和緩存卻沒有關(guān)于這條數(shù)據(jù)的任何記錄,而這條數(shù)據(jù)在緩存中沒找到就會(huì)向數(shù)據(jù)庫(kù)請(qǐng)求獲取數(shù)據(jù)。用戶拿不到數(shù)據(jù)時(shí),就會(huì)一直發(fā)請(qǐng)求,查詢數(shù)據(jù)庫(kù),這樣會(huì)對(duì)數(shù)據(jù)庫(kù)的訪問造成很大的壓力
    2022-07-07
  • Redis中的bitmap詳解

    Redis中的bitmap詳解

    BitMap是通過一個(gè)bit位來(lái)表示某個(gè)元素對(duì)應(yīng)的值或者狀態(tài),其中的key就是對(duì)應(yīng)元素本身。我們知道8個(gè)bit可以組成一個(gè)Byte,所以bitmap本身會(huì)極大的節(jié)省儲(chǔ)存空間,下面通過本文給大家介紹Redis中的bitmap知識(shí),感興趣的朋友一起看看吧
    2021-10-10
  • redis常用命令小結(jié)

    redis常用命令小結(jié)

    這篇文章主要介紹了redis的一些常用命令,需要的朋友可以參考下
    2014-06-06
  • Redis優(yōu)惠券秒殺解決方案

    Redis優(yōu)惠券秒殺解決方案

    這篇文章主要介紹了Redis解決優(yōu)惠券秒殺應(yīng)用案例,本文先講了搶購(gòu)問題,指出其中會(huì)出現(xiàn)的多線程問題,提出解決方案采用悲觀鎖和樂觀鎖兩種方式進(jìn)行實(shí)現(xiàn),然后發(fā)現(xiàn)在搶購(gòu)過程中容易出現(xiàn)一人多單現(xiàn)象,需要的朋友可以參考下
    2022-12-12
  • Redis設(shè)置Hash數(shù)據(jù)類型的過期時(shí)間

    Redis設(shè)置Hash數(shù)據(jù)類型的過期時(shí)間

    在Redis中,我們可以使用Hash數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)一組鍵值對(duì),而有時(shí)候,我們可能需要設(shè)置這些鍵值對(duì)的過期時(shí)間,本文主要介紹了Redis設(shè)置Hash數(shù)據(jù)類型的過期時(shí)間,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Redis實(shí)現(xiàn)分布式鎖的五種方法詳解

    Redis實(shí)現(xiàn)分布式鎖的五種方法詳解

    在分布式架構(gòu)中,我們同樣會(huì)遇到數(shù)據(jù)共享操作問題,本文章使用Redis來(lái)解決分布式架構(gòu)中的數(shù)據(jù)一致性問題,需要的小伙伴可以參考一下
    2022-06-06
  • Redis+Caffeine實(shí)現(xiàn)分布式二級(jí)緩存組件實(shí)戰(zhàn)教程

    Redis+Caffeine實(shí)現(xiàn)分布式二級(jí)緩存組件實(shí)戰(zhàn)教程

    這篇文章主要介紹了Redis+Caffeine實(shí)現(xiàn)分布式二級(jí)緩存組件實(shí)戰(zhàn)教程,介紹了分布式二級(jí)緩存的優(yōu)勢(shì),使用組件的方法,通過示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • 一篇文章揭秘Redis的磁盤持久化機(jī)制

    一篇文章揭秘Redis的磁盤持久化機(jī)制

    這篇文章主要給大家介紹了如何通過一篇文章揭秘Redis的磁盤持久化機(jī)制的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 基于Redis分布式鎖的實(shí)現(xiàn)代碼

    基于Redis分布式鎖的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Redis分布式鎖的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-05-05
  • Redis的常見四種部署方案

    Redis的常見四種部署方案

    這篇文章介紹Reids最為常見的四種部署模式,其實(shí)Reids和數(shù)據(jù)庫(kù)的集群模式差不多,可以分為 Redis單機(jī)模式部署、Redis主從模式部署、Redis哨兵模式部署、Cluster集群模式部署,其他的部署方式基本都是圍繞以下幾種方式在進(jìn)行調(diào)整到適應(yīng)的生產(chǎn)環(huán)境,感興趣的朋友一起看看吧
    2023-11-11

最新評(píng)論