91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis怎么批量設置過期時間

發布時間:2021-11-24 11:08:21 來源:億速云 閱讀:877 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關Redis怎么批量設置過期時間,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

Redis如何批量設置過期時間呢?

不要說在foreach中通過set()函數批量設置過期時間

我們引入redis的PIPLINE,來解決批量設置過期時間的問題。

PIPLINE的原理是什么?

未使用pipline執行N條命令

Redis怎么批量設置過期時間

使用pipline執行N條命令

Redis怎么批量設置過期時間

通過圖例可以很明顯的看出來PIPLINE的原理:

客戶端通過PIPLINE拼接子命令,只需要發送一次請求,在redis收到PIPLINE命令后,處理PIPLINE組成的命令塊,減少了網絡請求響應次數。

網絡延遲越大PIPLINE的優勢越能體現出來

拼接的子命令條數越多使用PIPLINE的優勢越能體現出來

注意:并不是拼接的子命令越多越好,N值也有是上限的,當拼接命令過長時會導致客戶端等待很長時間,造成網絡堵塞;我們可以根據實際情況,把大批量命令拆分成幾個PIPLINE執行。

代碼封裝

//批量設置過期時間
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();
}

項目實戰

需求描述

  • 打開APP,給喜歡我的人發送我的上線通知(為了避免打擾,8小時內重復登錄不觸發通知)

  • 每個人每半小時只會收到一次這類上線通知(即半小時內就算我喜歡的1萬人都上線了,我也只收到一次喜歡的人上線通知)

要點分析

  • 合理使用緩存,減少DB讀寫次數

  • 不僅要減少DB讀寫次數,也要減少Redis的讀寫次數,使用PIPLINE

代碼實現解析

  • canRecall() 寫的比較優雅,先判斷是否已發送的標記,再判斷HouseOpen::getCurrentOpen(),因為HouseOpen::getCurrentOpen()是要查詢DB計算的,這種代碼要盡可能少的被執行到,減少DB查詢。

  • array_diff() 取差集的思路,獲得需要推送的人

封裝工具類

<?php
namespace App\Model\House;
.
.
.
class HouseLikeRecallUser
{
    protected $_userid = '';
    protected $_availableUser = [];
    protected $_recallFlagKey = '';

    const TYPE_TTL_HOUSE_LIKE_RECALL = 60 * 30; //半小時后可以再次接收到喜歡的xxx進入通知
    const TYPE_TTL_HOUSE_LIKE_RECALL_FLAG = 60 * 60 * 8; //8小時重復登錄不觸發

    //初始化 傳入setRecalled 的過期時間
    public function __construct($userid)
    {
        $this->_userid = $userid;
        //登錄后給喜歡我的人推送校驗:同一場次重復登錄不重復發送
        $this->_recallFlagKey = CacheKey::getCacheKey(CacheKey::TYPE_HOUSE_LIKE_RECALL_FLAG, $this->_userid);
    }

    //設置當前用戶推送標示
    public function setRecalled()
    {
        Cache::put($this->_recallFlagKey, 1, self::TYPE_TTL_HOUSE_LIKE_RECALL_FLAG);
    }

    //獲取當前用戶是否觸發推送
    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;
    }

    //獲取需要推送用戶
    public function getAvailableUser()
    {
        //獲得最近喜歡我的用戶
        $recentLikeMeUser = UserRelationSingle::getLikeMeUserIds($this->_userid, 100, Utility::getBeforeNDayTimestamp(7));

        //獲得最近喜歡我的用戶的 RECALL緩存標記
        foreach ($recentLikeMeUser as $userid) {
            $batchKey[] = CacheKey::getCacheKey(CacheKey::TYPE_HOUSE_LIKE_RECALL, $userid);
        }

        //獲得最近喜歡我的且已經推送過的用戶
        $cacheData = [];
        if (!empty($batchKey)) {
            $cacheData = Redis::connection('cache')->mget($batchKey);
        }

        //計算最近喜歡我的用戶 和 已經推送過的用戶 的差集:就是需要推送的用戶
        $this->_availableUser = array_diff($recentLikeMeUser, $cacheData);
        return $this->_availableUser;
    }

    //更新已經推送的用戶
    public function updateRecalledUser()
    {
        //批量更新差集用戶
        $recalledUser = [];
        foreach ($this->_availableUser as $userid) {
            $cacheKey = CacheKey::getCacheKey(CacheKey::TYPE_HOUSE_LIKE_RECALL, $userid);
            $recalledUser[$cacheKey] = $userid;
        }
        //批量更新 設置過期時間
        self::myPut($recalledUser, self::TYPE_TTL_HOUSE_LIKE_RECALL);
    }

    //批量設置過期時間
    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();
    }
}

調用工具類

public function handle()
{
    $userid = $this->_userid;
    $houseLikeRecallUser = new HouseLikeRecallUser($userid);
    if ($houseLikeRecallUser->canRecall()) {
        $recallUserIds = $houseLikeRecallUser->getAvailableUser();
        $houseLikeRecallUser->setRecalled();
        $houseLikeRecallUser->updateRecalledUser();
        //群發推送消息
        .
        .
        .
    }
}

關于“Redis怎么批量設置過期時間”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

资中县| 宁津县| 广安市| 铜山县| 广水市| 应城市| 上蔡县| 安丘市| 蚌埠市| 宁夏| 元阳县| 天全县| 葫芦岛市| 康乐县| 法库县| 营山县| 米脂县| 新巴尔虎右旗| 武义县| 永兴县| 贵港市| 体育| 桦甸市| 西丰县| 阿尔山市| 太仆寺旗| 哈尔滨市| 黑河市| 望都县| 乌拉特后旗| 安阳市| 扬州市| 九龙城区| 长白| 宁津县| 姜堰市| 甘肃省| 舟曲县| 临朐县| 清水县| 明光市|