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

【workbunny】高速共享緩存

0.6.1 版本
2025-03-04 版本更新時(shí)間
599 安裝
30 star

Build Status Latest Stable Version PHP Version Require License

webman-shared-cache

計(jì)劃 & 說(shuō)明

0.6 版本已發(fā)布

  1. 實(shí)驗(yàn)性功能:Channel的系統(tǒng)信號(hào)監(jiān)聽(tīng),用于緩解定時(shí)輪詢帶來(lái)的空窗問(wèn)題和資源占用問(wèn)題

實(shí)踐分享

http://wtbis.cn/a/1589

最新文檔

https://github.com/workbunny/webman-shared-cache/blob/main/README.md

常見(jiàn)問(wèn)題

1. 它與 Redis/Memcache 的區(qū)別

  • shared-cache是基于APCu的本地緩存,它的底層是帶有鎖的MMAP共享內(nèi)存;
  • Redis和Memcache本質(zhì)上是“分布式”緩存系統(tǒng)/K-V數(shù)據(jù)庫(kù),存在網(wǎng)絡(luò)IO;
  • shared-cache沒(méi)有持久化,同時(shí)也無(wú)法實(shí)現(xiàn)“分布式”,僅可用于本地的多進(jìn)程環(huán)境(進(jìn)程需要有親緣關(guān)系);
  • shared-cache是μs級(jí)別的緩存,redis是ms級(jí)別的緩存;
  • 網(wǎng)絡(luò)IO存在內(nèi)核態(tài)和用戶態(tài)的多次拷貝,存在較大的延遲,共享內(nèi)存不存在這樣的問(wèn)題;

2. 它的使用場(chǎng)景

  • 可以用作一些服務(wù)器的本地緩存,如頁(yè)面緩存、L2-cache;
  • 可以跨進(jìn)程做一些計(jì)算工作,也可以跨進(jìn)程通訊;
  • 用在一些延遲敏感的服務(wù)下,如游戲服務(wù)器;
  • 簡(jiǎn)單的限流插件;

3. 與redis簡(jiǎn)單的比較

  • 運(yùn)行/tests/simple-benchmark.php
    • redis使用host.docker.internal
    • 在循環(huán)中增加不同的間隔,模擬真實(shí)使用場(chǎng)景
    • 結(jié)果如下:
      1^ "count: 100000"
      2^ "interval: 0 μs"
      ^ "redis: 73.606367111206"
      ^ "cache: 0.081215143203735"
      ^ "-----------------------------------"
      1^ "count: 100000"
      2^ "interval: 1 μs"
      ^ "redis: 78.833391904831"
      ^ "cache: 6.4423549175262"
      ^ "-----------------------------------"
      1^ "count: 100000"
      2^ "interval: 10 μs"
      ^ "redis: 79.543494939804"
      ^ "cache: 7.2690420150757"
      ^ "-----------------------------------"
      1^ "count: 100000"
      2^ "interval: 100 μs"
      ^ "redis: 88.58958697319"
      ^ "cache: 17.31387090683"
      ^ "-----------------------------------"
      1^ "count: 100000"
      2^ "interval: 1000 μs"
      ^ "redis: 183.2620780468"
      ^ "cache: 112.18278503418"
      ^ "-----------------------------------"

簡(jiǎn)介

  • 基于APCu拓展的輕量級(jí)高速緩存,讀寫(xiě)微秒級(jí);
  • 支持具備親緣關(guān)系的多進(jìn)程內(nèi)存共享;
  • 支持具備親緣關(guān)系的多進(jìn)程限流;

安裝

  1. 自行安裝APCu拓展
    # 1. pecl安裝
    pecl instanll apcu
    # 2. docker中請(qǐng)使用安裝器安裝
    curl -sSL https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions -o - | sh -s apcu
  2. 安裝composer包
    composer require workbunny/webman-shared-cache
  3. 使用命令進(jìn)行php.ini的配置
    • 進(jìn)入 /config/plugin/workbunny/webman-shared-cache 目錄
    • 運(yùn)行
      # 幫助信息
      sh ./shared-cache-enable.sh --help
      # or
      bash ./shared-cache-enable.sh --help

使用

注:\Workbunny\WebmanSharedCache\Cache::$fuse為全局阻塞保險(xiǎn)

1. Cache基礎(chǔ)使用

  • 類(lèi)似Redis的String【使用方法與Redis基本一致】

    • 支持 Set/Get/Del/Keys/Exists
    • 支持 Incr/Decr,支持浮點(diǎn)運(yùn)算
    • 支持 儲(chǔ)存對(duì)象數(shù)據(jù)
    • 支持 XX/NX模式,支持秒級(jí)過(guò)期時(shí)間
  • 類(lèi)似Redis的Hash【使用方法與Redis基本一致】

    • 支持 HSet/HGet/HDel/HKeys/HExists
    • 支持 HIncr/HDecr,支持浮點(diǎn)運(yùn)算
    • 支持 儲(chǔ)存對(duì)象數(shù)據(jù)
    • 支持 HashKey的秒級(jí)過(guò)期時(shí)間【版本 ≥ 0.5】
  • 通配符/正則匹配Search

    $result = [];
    # 默認(rèn)正則匹配 - 以50條為一次分片查詢
    \Workbunny\WebmanSharedCache\Cache::Search('/^abc.+$/', function ($key, $value) use (&$result) { 
      $result[$key] = $value;
    }, 50);
    
    # 通配符轉(zhuǎn)正則
    \Workbunny\WebmanSharedCache\Cache::Search(
      \Workbunny\WebmanSharedCache\Cache::WildcardToRegex('abc*'),
      function ($key, $value) use (&$result) {
          $result[$key] = $value;
      }
    );

    Tips:Cache::Search()本質(zhì)上是個(gè)掃表匹配的過(guò)程,是O(N)的操作,如果需要對(duì)特定族群的數(shù)據(jù)進(jìn)行監(jiān)聽(tīng),推薦使用Channel相關(guān)函數(shù)實(shí)現(xiàn)監(jiān)聽(tīng)。

  • 原子性執(zhí)行

    # key-1、key-2、key-3會(huì)被當(dāng)作一次原子性操作
    
    # 非阻塞執(zhí)行 - 成功執(zhí)行則返回true,失敗返回false,鎖沖突會(huì)導(dǎo)致執(zhí)行失敗
    $result = \Workbunny\WebmanSharedCache\Cache::Atomic('lock-test', function () { 
      \Workbunny\WebmanSharedCache\Cache::Set('key-1', 1);
      \Workbunny\WebmanSharedCache\Cache::Set('key-2', 2);
      \Workbunny\WebmanSharedCache\Cache::Set('key-3', 3);
    });
    # 阻塞等待執(zhí)行 - 默認(rèn)阻塞受Cache::$fuse阻塞保險(xiǎn)影響
    $result = \Workbunny\WebmanSharedCache\Cache::Atomic('lock-test', function () { 
      \Workbunny\WebmanSharedCache\Cache::Set('key-1', 1);
      \Workbunny\WebmanSharedCache\Cache::Set('key-2', 2);
      \Workbunny\WebmanSharedCache\Cache::Set('key-3', 3);
    }, true);
    # 自行實(shí)現(xiàn)阻塞
    $result = false
    while (!$result) {
      # TODO 可以適當(dāng)增加保險(xiǎn),以免超長(zhǎng)阻塞
      $result = \Workbunny\WebmanSharedCache\Cache::Atomic('lock-test', function () { 
          \Workbunny\WebmanSharedCache\Cache::Set('key-1', 1);
          \Workbunny\WebmanSharedCache\Cache::Set('key-2', 2);
          \Workbunny\WebmanSharedCache\Cache::Set('key-3', 3);
      });
    }
  • 查看cache信息

    # 全量數(shù)據(jù)
    var_dump(\Workbunny\WebmanSharedCache\Cache::Info());
    
    # 不查詢數(shù)據(jù)
    var_dump(\Workbunny\WebmanSharedCache\Cache::Info(true));
  • 查看鎖信息

    # Hash數(shù)據(jù)的處理建立在寫(xiě)鎖之上,如需調(diào)試,則使用該方法查詢鎖信息
    var_dump(\Workbunny\WebmanSharedCache\Cache::LockInfo());
  • 查看鍵信息

    # 包括鍵的一些基礎(chǔ)信息
    var_dump(\Workbunny\WebmanSharedCache\Cache::KeyInfo('test-key'));
  • 清空cache

    • 使用Del多參數(shù)進(jìn)行清理
      # 接受多個(gè)參數(shù)
      \Workbunny\WebmanSharedCache\Cache::Del($a, $b, $c, $d);
      # 接受一個(gè)key的數(shù)組
      \Workbunny\WebmanSharedCache\Cache::Del(...$keysArray);
    • 使用Clear進(jìn)行清理
      \Workbunny\WebmanSharedCache\Cache::Clear();

2. RateLimiter插件

高效輕量的親緣進(jìn)程限流器

  1. 在/config/plugin/workbbunny/webman-shared-cache/rate-limit.php中配置
  2. 在使用的位置調(diào)用
    • 當(dāng)沒(méi)有執(zhí)行限流時(shí),返回空數(shù)組
    • 當(dāng)執(zhí)行但沒(méi)有到達(dá)限流時(shí),返回?cái)?shù)組is_limit為false
    • 當(dāng)執(zhí)行且到達(dá)限流時(shí),返回?cái)?shù)組is_limit為true
      $rate = \Workbunny\WebmanSharedCache\RateLimiter::traffic('test');
      if ($rate['is_limit'] ?? false) {
      // 限流邏輯 如可以拋出異常、返回錯(cuò)誤信息等
      return new \support\Response(429, [
        'X-Rate-Reset' => $rate['reset'],
        'X-Rate-Limit' => $rate['limit'],
        'X-Rate-Remaining' => $rate['reset']
      ])
      }

3. Cache的Channel功能

  • Channel是一個(gè)類(lèi)似Redis-stream、Redis-list、Redis-Pub/Sub的功能模塊

  • 一個(gè)通道可以被多個(gè)進(jìn)程監(jiān)聽(tīng),每個(gè)進(jìn)程只能監(jiān)聽(tīng)一個(gè)相同通道(也就是對(duì)相同通道只能創(chuàng)建一個(gè)監(jiān)聽(tīng)器)

  • 向通道發(fā)布消息

    • 臨時(shí)消息
      # 向一個(gè)名為test的通道發(fā)送臨時(shí)消息;
      # 通道沒(méi)有監(jiān)聽(tīng)器時(shí),臨時(shí)消息會(huì)被忽略,只有通道存在監(jiān)聽(tīng)器時(shí),該消息才會(huì)被存入通道
      Cache::ChPublish('test', '這是一個(gè)測(cè)試消息', false);
    • 暫存消息
      # 向一個(gè)名為test的通道發(fā)送暫存消息;
      # 通道存在監(jiān)聽(tīng)器時(shí),該消息會(huì)被存入通道內(nèi)的所有子通道
      Cache::ChPublish('test', '這是一個(gè)測(cè)試消息', true);
    • 指定workerId
      # 指定發(fā)送消息至當(dāng)前通道內(nèi)workerId為1的子通道
      Cache::ChPublish('test', '這是一個(gè)測(cè)試消息', true, 1);
  • 創(chuàng)建通道監(jiān)聽(tīng)器

    • 一個(gè)進(jìn)程對(duì)相同通道僅能創(chuàng)建一個(gè)監(jiān)聽(tīng)器
    • 一個(gè)進(jìn)程可以同時(shí)監(jiān)聽(tīng)多個(gè)不同的通道
    • 建議workerId使用workerman的workerId進(jìn)行區(qū)分
      # 向一個(gè)名為test的通道創(chuàng)建一個(gè)workerId為1的監(jiān)聽(tīng)器;
      # 通道消息先進(jìn)先出,當(dāng)有消息時(shí)會(huì)觸發(fā)回調(diào)
      Cache::ChCreateListener('test', '1', function(string $channelKey, string|int $workerId, mixed $message) {
      // TODO 你的業(yè)務(wù)邏輯
      dump($channelKey, $workerId, $message);
      });
  • 移除通道監(jiān)聽(tīng)器

    • 移除監(jiān)聽(tīng)器子通道及子通道內(nèi)消息
      # 向一個(gè)名為test的通道創(chuàng)建一個(gè)workerId為1的監(jiān)聽(tīng)器;
      # 通道移除時(shí)不會(huì)移除其他子通道消息
      Cache::ChRemoveListener('test', '1', true);
    • 移除監(jiān)聽(tīng)器子通道,但保留子通道內(nèi)消息
      # 向一個(gè)名為test的通道創(chuàng)建一個(gè)workerId為1的監(jiān)聽(tīng)器;
      # 通道移除時(shí)不會(huì)移除所有子通道消息
      Cache::ChRemoveListener('test', '1', false);
  • 實(shí)驗(yàn)性功能:信號(hào)通知

    • 由于共享內(nèi)存無(wú)法使用事件監(jiān)聽(tīng),所以底層使用Timer定時(shí)器進(jìn)行輪詢,實(shí)驗(yàn)性功能可以開(kāi)啟使用系統(tǒng)信號(hào)來(lái)監(jiān)聽(tīng)數(shù)據(jù)的變化
      // 設(shè)置信號(hào)
      // 因?yàn)閑vent等事件循環(huán)庫(kù)是對(duì)標(biāo)準(zhǔn)信號(hào)的監(jiān)聽(tīng),所以不能使用自定實(shí)時(shí)信號(hào)SIGRTMIN ~ SIGRTMAX
      // 默認(rèn)暫時(shí)使用SIGPOLL,異步IO監(jiān)聽(tīng)信號(hào),可能影響異步文件IO相關(guān)的觸發(fā)
      Future::$signal = \SIGPOLL;
      // 開(kāi)啟信號(hào)監(jiān)聽(tīng),這時(shí)候開(kāi)啟的監(jiān)聽(tīng)會(huì)觸發(fā)之前的回調(diào)和通道回調(diào),不會(huì)影響之前的回調(diào)
      Cache::channelUseSignalEnable(true)
    • 當(dāng)使用的監(jiān)聽(tīng)信號(hào)存在已注冊(cè)的回調(diào)產(chǎn)生回調(diào)沖突時(shí),可以手動(dòng)設(shè)置回調(diào)事件共享
      // 設(shè)置信號(hào)
      // 因?yàn)閑vent等事件循環(huán)庫(kù)是對(duì)標(biāo)準(zhǔn)信號(hào)的監(jiān)聽(tīng),所以不能使用自定實(shí)時(shí)信號(hào)SIGRTMIN ~ SIGRTMAX
      // 默認(rèn)暫時(shí)使用SIGPOLL
      Future::$signal = \SIGPOLL;
      // 假設(shè)\SIGPOLL存在一個(gè)已注冊(cè)的回調(diào),YourEventLoop::getCallback(\SIGPOLL)可以獲取該事件在當(dāng)前進(jìn)程注冊(cè)的回調(diào)響應(yīng)
      // 設(shè)置回調(diào)
      Future::setSignalCallback(YourEventLoop::getCallback(\SIGPOLL));
      // 開(kāi)啟信號(hào)監(jiān)聽(tīng),這時(shí)候開(kāi)啟的監(jiān)聽(tīng)會(huì)觸發(fā)之前的回調(diào)和通道回調(diào),不會(huì)影響之前的回調(diào)
      Cache::channelUseSignalEnable(true)

      通道信號(hào)監(jiān)聽(tīng)維系了一個(gè)事件隊(duì)列,多次觸發(fā)信號(hào)時(shí),回調(diào)只會(huì)根據(jù)事件隊(duì)列是否存在事件消費(fèi)標(biāo)記而執(zhí)行事件回調(diào)

      其他功能具體可以參看代碼注釋和測(cè)試用例

贊助商