国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

使用webman-shared-cache共享緩存,定時上報大并發(fā)時,上報進程busy

xiaopi

問題描述

需求:
使用webman提供一個http服務(wù),接收大量的請求(1000w+/天),并將請求根據(jù)請求中的參數(shù)task_id存儲到apcu共享內(nèi)存中,由新開的進程定時獲取共享內(nèi)存種的數(shù)據(jù),每次獲取100條,批量存儲到redis中,供其他程序使用。

問題:

開了10個上報進程,每個上報進程每10秒會調(diào)用Cache::search()獲取需要上報的任務(wù),然后加鎖此任務(wù),對該任務(wù)下的數(shù)據(jù)進行上報,上報完成后釋放任務(wù)鎖。
隨著程序啟動時間越長,上報進程會出現(xiàn)busy的情況。此時重啟上報進程會恢復(fù)[idle]狀態(tài),持續(xù)一天時間,相同的業(yè)務(wù)量繼續(xù)出現(xiàn)busy的情況。

分析
我懷疑是隨著apcu的持續(xù)使用,導(dǎo)致Cache::search()模糊獲取key的方法會越來越慢,所以導(dǎo)致這個問題,但是不知道如何下手解決這個問題。

apcuinfo的信息為:
{"num_slots":4099,"ttl":0,"num_hits":11045579162,"num_misses":692074161,"num_inserts":1451177345,"num_entries":15239,"expunges":0,"start_time":1715919517,"mem_size":3907568,"memory_type":"mmap","mem_size_mb":3.7265}

核心代碼為:

public static function push(): void
    {
        Cache::Search(Cache::WildcardToRegex(Util::TENANT_TASK_PREFIX . '*'), function ($taskKey, $value) {
            // 獲取待上報任務(wù)
            list(, $tenantId, $taskId) = explode(':', $taskKey, 3);

            // 增加原子鎖,保證【是否存在上報的任務(wù)】和【任務(wù)加鎖】的原子性
            $isExists = true;
            Cache::Atomic('report-lock', function () use ($taskId, &$isExists) {
                // 判斷是否已經(jīng)在上報
                if (!static::exists($taskId)) {

                    // 記錄不存在標識
                    $isExists = false;

                    // 上報任務(wù)加鎖
                    static::lock($taskId);
                }
            });

            if ($isExists) {
                return;
            }

            $result = [];
            // 每次獲取100條通話記錄
            Cache::Search(Cache::WildcardToRegex(static::getCacheKey() . $taskId . '_*'),
                function ($key, $value) use ($tenantId, $taskId, &$result) {

                    $result[$key] = $value;

                });

            // 刪除已上報的緩存
            Cache::Del(...array_keys($result));

            // 上報任務(wù)釋放鎖
            static::unlock($taskId);

            // 上報消息
            if (!empty($result)) {

                // 分塊 每次上報100條
                foreach (array_chunk($result, 100) as $messages) {
                    static::reportMessage($tenantId, $taskId, $messages);
                }
            }

        });
    }

負載均衡node-1
兩周未重啟進程情況為:
截圖

負載均衡node-2
一天未重啟進程情況為:
截圖

1056 2 0
2個回答

walkor 打賞

http://wtbis.cn/doc/workerman/debug/status.html
這里有定位busy的文檔。
另外也可以自己記錄下懷疑慢操作代碼的耗時情況。

  • xiaopi 2024-05-31

    感謝,我再研究研究文檔

chaz6chez

Cache::search()這個函數(shù)本質(zhì)上是O(N)的復(fù)雜度,會掃表遍歷匹配,不建議在數(shù)據(jù)量非常大的情況下來做頻繁的處理;
在這種業(yè)務(wù)場景下,我更建議開啟進程然后使用Cache的channel進行監(jiān)聽,然后生產(chǎn)端將需要數(shù)據(jù)推送到channel中,由進程監(jiān)聽消費并更新到對應(yīng)的數(shù)據(jù)儲存器中

  • xiaopi 2024-08-29

    感謝,找到問題了,業(yè)務(wù)代碼的問題,問題是key太多了,沒有及時的清理,后面我推送完del掉key就沒事了,然后用nignx做了負載到了三個節(jié)點分流,目前推送沒啥問題了,不過后面如果數(shù)據(jù)量進一步擴大,就換成channel監(jiān)聽

年代過于久遠,無法發(fā)表回答
??