使用緩存以及用redis拓展解決實際問題

2018-11-21 21:30 更新

PHALAPI-進(jìn)階篇7(使用緩存以及用REDIS拓展解決實際問題)

前言

先在這里感謝phalapi框架創(chuàng)始人@dogstar,為我們提供了這樣一個優(yōu)秀的開源框架.

當(dāng)我們在開發(fā)一個項目時,我們可能會遇到很多問題,比如消息推送,發(fā)送郵件,發(fā)送短信,以及并發(fā)跟不上,這個時候就該輪到常用的緩存出手解救我們了,我們接下來來講講緩存Redis在實際中的使用,解決實際問題.在這里是基于redis的基本知識,和簡單看一下PhalApi的redis拓展文檔在前來閱讀此小節(jié).

附上:

喵了個咪的博客:w-blog.cn

官網(wǎng)地址:http://www.phalapi.net/

開源中國Git地址:http://git.oschina.net/dogstar/PhalApi/tree/release

開源中國擴展Git地址:http://git.oschina.net/dogstar/PhalApi-Library

1. 能解決什么問題

當(dāng)我們使用一門技術(shù)的時候,我們當(dāng)然是為了解決問題才去使用它的,那么我們使用緩存技術(shù)Redis能解決什么具體的問題呢?

1.1 緩存結(jié)果集

這里給一個例子大家看一下就會明白緩存結(jié)果集是什么意思

//從緩存redis的clubcache庫中查詢club表where條件是city,city值是$city
$cache = DI()->redis->get_Time('club'.'city'.$city,'clubcache');
//如果查詢到了就直接返回緩存的結(jié)果
if($cache){
    return $cache;
}
//如果不存在從數(shù)據(jù)庫里面獲取結(jié)果然后存入redis緩存key的條件和取值時一樣,最后一個參數(shù)為過期時間
$rs = $this->getORM()->select('*')->where('city',$city)->fetchAll();
DI()->redis->set_Time('club'.'city'.$city,$rs,'clubcache',600);

上面做的事情就是把結(jié)果保存600秒,600秒內(nèi)的再次查詢會獲取一樣的結(jié)果

1.2 隊列處理

Redis運用到時間中有一個比較關(guān)鍵的作用就是他的隊列

我們先過一下幾個特殊的redis函數(shù)

//寫入隊列左邊
set_lPush
//寫入隊列左邊 如果value已經(jīng)存在,則不添加 
set_lPushx
//寫入隊列右邊
set_rPush
//寫入隊列右邊 如果value已經(jīng)存在,則不添加
set_rPushx

//讀取隊列左邊
get_lPop
//讀取隊列右邊
get_rPop
//讀取隊列左邊 如果沒有讀取到阻塞一定時間
get_blPop
//讀取隊列右邊 如果沒有讀取到阻塞一定時間
get_brPop

比如我們在做消息推送,發(fā)送郵件,發(fā)送短信這類業(yè)務(wù)的時候,我們需要請求第三方接口,請求的速度是第三方來決定的,比如微信一個推送接口就是200ms,如果放到我們的API業(yè)務(wù)里面就會出現(xiàn)一個巨大的問題,用戶訪問速度極度下降,解決這類問題的方案就是隊列流程如下

當(dāng)我們接收到用戶的推送請求時
            ↓
把推送請求加入到隊列API里面不做任何操作(比如加入到左邊)
            ↓
在后臺有一個PHP腳本運行一直在讀取隊列(讀取右邊就是后進(jìn)后出,如果讀取左邊就是先進(jìn)先出)
            ↓
然后執(zhí)行響應(yīng)的推送邏輯

一般我們的腳本是一個死循環(huán),或者shell定時請求,我們會采用讀取不到數(shù)據(jù)是阻塞來解決去不到值循環(huán)過快的問題

1.3 臨時數(shù)據(jù)存儲

臨時數(shù)據(jù)就不需要太多的說明了,舉個例子就夠了

比如我們獲取驗證碼,我們需要把驗證碼存到庫中嗎,我覺得是沒有必要的,而且數(shù)據(jù)庫并不好做過期的操作只能我們自己判斷

那么我們使用redis把驗證碼存入redis 然后給一個過期時間就很好的解決這個問題了

1.4 數(shù)據(jù)庫

把redis作為數(shù)據(jù)庫用算是比較深入的使用了,這里聊下思想

大家之后service可以分布式,但是對于大部分?jǐn)?shù)據(jù)庫的分布式并不容易,所以導(dǎo)致了很多系統(tǒng)到后面拼接堆積在數(shù)據(jù)庫,當(dāng)然可以使用緩存存儲結(jié)果集,但是這種解決方便治標(biāo)不治本,在和童鞋們探討的時候得出了一個解決方便,就是把redis作為第一數(shù)據(jù)庫mysql作為元數(shù)據(jù)庫

做了這種操作之后服務(wù)器會自動把熱數(shù)據(jù)同步到redis,把冷數(shù)據(jù)存放到mysql,當(dāng)使用到冷數(shù)據(jù)了在存放到redis,用戶大部分的操作基本是基于redis進(jìn)行的操作

當(dāng)作這樣實現(xiàn)的成本比較高要實現(xiàn)redis 數(shù)據(jù)同步 封裝使用 where查詢 等等需要很大的精力去做,在后期筆者有打算做一個通用的拓展

2. 規(guī)范化使用

其實以上的類容已經(jīng)講的差不多了,為什么還有單獨拿出一段來講一講規(guī)范呢,因為緩存不像是數(shù)據(jù)庫當(dāng)你需要去查看緩存的時候,如果所有的數(shù)據(jù)都堆積在redis的一個庫,你會非常痛苦

但是redis支持多庫所以需要一套規(guī)范來劃分,這里分享一下我這邊是如何使用的

0~10庫 作為正常業(yè)務(wù)庫,也就是推送隊列,臨時數(shù)據(jù),每一個庫都只存儲一種業(yè)務(wù)的數(shù)據(jù),比如微信推送就存在5庫,而郵件推送的數(shù)據(jù)就存在6庫,發(fā)送驗證碼的臨時數(shù)據(jù)存儲在3庫,一次類推,如果覺得10個庫還不夠用可以根據(jù)業(yè)務(wù)增加

10庫以上作為cache庫用來存儲每張表的結(jié)果集數(shù)據(jù),或者是其余的數(shù)據(jù)

所有的key的命名規(guī)范必須帶有類型+表名+條件

3. 總結(jié)

看了本小節(jié)之后相信大家都對緩存在時間開發(fā)中起到了什么樣的作用有了個了解,這一小節(jié)的完成,我們的進(jìn)階篇也步入尾聲了,下一篇是對于進(jìn)階篇的總結(jié)了,也多謝大家一路的陪伴!

注:筆者能力有限有說的不對的地方希望大家能夠指出,也希望多多交流!

官網(wǎng)QQ交流群:421032344 歡迎大家的加入!

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號