您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Redis怎么批量設(shè)置過(guò)期時(shí)間,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
不要說(shuō)在foreach中通過(guò)set()函數(shù)批量設(shè)置過(guò)期時(shí)間
我們引入redis的PIPLINE,來(lái)解決批量設(shè)置過(guò)期時(shí)間的問(wèn)題。
未使用pipline執(zhí)行N條命令
使用pipline執(zhí)行N條命令
通過(guò)圖例可以很明顯的看出來(lái)PIPLINE的原理:
客戶(hù)端通過(guò)PIPLINE拼接子命令,只需要發(fā)送一次請(qǐng)求,在redis收到PIPLINE命令后,處理PIPLINE組成的命令塊,減少了網(wǎng)絡(luò)請(qǐng)求響應(yīng)次數(shù)。
網(wǎng)絡(luò)延遲越大PIPLINE的優(yōu)勢(shì)越能體現(xiàn)出來(lái)
拼接的子命令條數(shù)越多使用PIPLINE的優(yōu)勢(shì)越能體現(xiàn)出來(lái)
注意:并不是拼接的子命令越多越好,N值也有是上限的,當(dāng)拼接命令過(guò)長(zhǎng)時(shí)會(huì)導(dǎo)致客戶(hù)端等待很長(zhǎng)時(shí)間,造成網(wǎng)絡(luò)堵塞;我們可以根據(jù)實(shí)際情況,把大批量命令拆分成幾個(gè)PIPLINE執(zhí)行。
//批量設(shè)置過(guò)期時(shí)間 public static function myPut(array $data, $ttl = 0) { if (empty($data)) { return false; } $pipeline = Redis::connection('cache') ->multi(\Redis::PIPELINE); foreach ($data as $key => $value) { if (empty($value)) { continue; } if ($ttl == 0) { $pipeline->set(trim($key), $value); } else { $pipeline->set(trim($key), $value, $ttl); } } $pipeline->exec(); }
打開(kāi)APP,給喜歡我的人發(fā)送我的上線通知(為了避免打擾,8小時(shí)內(nèi)重復(fù)登錄不觸發(fā)通知)
每個(gè)人每半小時(shí)只會(huì)收到一次這類(lèi)上線通知(即半小時(shí)內(nèi)就算我喜歡的1萬(wàn)人都上線了,我也只收到一次喜歡的人上線通知)
合理使用緩存,減少DB讀寫(xiě)次數(shù)
不僅要減少DB讀寫(xiě)次數(shù),也要減少Redis的讀寫(xiě)次數(shù),使用PIPLINE
canRecall() 寫(xiě)的比較優(yōu)雅,先判斷是否已發(fā)送的標(biāo)記,再判斷HouseOpen::getCurrentOpen(),因?yàn)镠ouseOpen::getCurrentOpen()是要查詢(xún)DB計(jì)算的,這種代碼要盡可能少的被執(zhí)行到,減少DB查詢(xún)。
array_diff() 取差集的思路,獲得需要推送的人
封裝工具類(lèi)
<?php namespace App\Model\House; . . . class HouseLikeRecallUser { protected $_userid = ''; protected $_availableUser = []; protected $_recallFlagKey = ''; const TYPE_TTL_HOUSE_LIKE_RECALL = 60 * 30; //半小時(shí)后可以再次接收到喜歡的xxx進(jìn)入通知 const TYPE_TTL_HOUSE_LIKE_RECALL_FLAG = 60 * 60 * 8; //8小時(shí)重復(fù)登錄不觸發(fā) //初始化 傳入setRecalled 的過(guò)期時(shí)間 public function __construct($userid) { $this->_userid = $userid; //登錄后給喜歡我的人推送校驗(yàn):同一場(chǎng)次重復(fù)登錄不重復(fù)發(fā)送 $this->_recallFlagKey = CacheKey::getCacheKey(CacheKey::TYPE_HOUSE_LIKE_RECALL_FLAG, $this->_userid); } //設(shè)置當(dāng)前用戶(hù)推送標(biāo)示 public function setRecalled() { Cache::put($this->_recallFlagKey, 1, self::TYPE_TTL_HOUSE_LIKE_RECALL_FLAG); } //獲取當(dāng)前用戶(hù)是否觸發(fā)推送 public function canRecall() { $res = false; if (empty(Cache::get($this->_recallFlagKey))) { $houseOpen = HouseOpen::getCurrentOpen(); if ($houseOpen['status'] == HouseOpen::HOUSE_STATUS_OPEN) { $res = true; } } return $res; } //獲取需要推送用戶(hù) public function getAvailableUser() { //獲得最近喜歡我的用戶(hù) $recentLikeMeUser = UserRelationSingle::getLikeMeUserIds($this->_userid, 100, Utility::getBeforeNDayTimestamp(7)); //獲得最近喜歡我的用戶(hù)的 RECALL緩存標(biāo)記 foreach ($recentLikeMeUser as $userid) { $batchKey[] = CacheKey::getCacheKey(CacheKey::TYPE_HOUSE_LIKE_RECALL, $userid); } //獲得最近喜歡我的且已經(jīng)推送過(guò)的用戶(hù) $cacheData = []; if (!empty($batchKey)) { $cacheData = Redis::connection('cache')->mget($batchKey); } //計(jì)算最近喜歡我的用戶(hù) 和 已經(jīng)推送過(guò)的用戶(hù) 的差集:就是需要推送的用戶(hù) $this->_availableUser = array_diff($recentLikeMeUser, $cacheData); return $this->_availableUser; } //更新已經(jīng)推送的用戶(hù) public function updateRecalledUser() { //批量更新差集用戶(hù) $recalledUser = []; foreach ($this->_availableUser as $userid) { $cacheKey = CacheKey::getCacheKey(CacheKey::TYPE_HOUSE_LIKE_RECALL, $userid); $recalledUser[$cacheKey] = $userid; } //批量更新 設(shè)置過(guò)期時(shí)間 self::myPut($recalledUser, self::TYPE_TTL_HOUSE_LIKE_RECALL); } //批量設(shè)置過(guò)期時(shí)間 public static function myPut(array $data, $ttl = 0) { if (empty($data)) { return false; } $pipeline = Redis::connection('cache') ->multi(\Redis::PIPELINE); foreach ($data as $key => $value) { if (empty($value)) { continue; } if ($ttl == 0) { $pipeline->set(trim($key), $value); } else { $pipeline->set(trim($key), $value, $ttl); } } $pipeline->exec(); } }
調(diào)用工具類(lèi)
public function handle() { $userid = $this->_userid; $houseLikeRecallUser = new HouseLikeRecallUser($userid); if ($houseLikeRecallUser->canRecall()) { $recallUserIds = $houseLikeRecallUser->getAvailableUser(); $houseLikeRecallUser->setRecalled(); $houseLikeRecallUser->updateRecalledUser(); //群發(fā)推送消息 . . . } }
關(guān)于“Redis怎么批量設(shè)置過(guò)期時(shí)間”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。