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

分享一下我們的workerman項(xiàng)目+apcu案例,性能秒殺Redis

army

前言: 我們的項(xiàng)目要頻繁讀寫遍歷緩存,起初用的Redis,CPU占用20%左右,顯然不理想。
當(dāng)接觸到php自帶的apcu后,簡直就是神一樣,單機(jī)效率超Redis幾十甚至上百倍,
利用workerman的text協(xié)議來搭配apcu 也能秒Redis 2倍以上,
關(guān)鍵是...關(guān)鍵是...關(guān)鍵是CPU消耗不足redis十分之一,
上測試截圖:

//走tcp

15516 13 16
13個(gè)評(píng)論

luohonen

真的假的,比redis都高?

army

如果只作為單純的進(jìn)程間共享變量函數(shù)以及類,可說是非常完美,高Redis百倍性能。
如果作為kv緩存的話有一些特殊情況,大致根據(jù)自己項(xiàng)目情況來選擇,
第一種:對(duì)單key的過期時(shí)間有要求的,在遍歷全部key會(huì)包含已過期的key且無法分辨過期和未過期。
第二種:對(duì)遍歷全部key只要有效key的話,單key無法自動(dòng)過期。
對(duì)于key未設(shè)置過期的不影響,這些是運(yùn)行在cli下才有的問題,fpm下不存在能完美Redis特性并秒殺百倍性能。

  • army 2023-04-01

    對(duì)于以上的問題已解決,用git倉庫源碼編譯(pecl.php.net下載的不行),需配置use_request_time=0,灰常的奈斯

  • 賈亭西 2023-06-25

    您好,上面說的問題,在fpm模式下都不存在是嗎,我們現(xiàn)在還是在fpm模式,最近我想著用apcu,至于無法共享cache的問題,我想著定時(shí)十分鐘淘汰就好了,每隔十分鐘去mysql或者redis拿一次數(shù)據(jù)

  • army 2023-06-26

    @賈亭西 從git拉取編譯不管是fpm還是cli都沒問題了

  • 賈亭西 2023-06-26

    好的,謝了

chaz6chez

apcu實(shí)際上已經(jīng)邊緣化了,只能單進(jìn)程,整體的設(shè)計(jì)更適合fpm,在cli下面有挺多問題的,包括過期時(shí)間等,甚至不如shmop,早期shmop是為cli下設(shè)計(jì)的;
不考慮分布式、持久化容錯(cuò)的話,用shmop會(huì)更好,memcache也可以,性能都比redis更好;畢竟webman/workerman都常駐內(nèi)存了,連接可以持久化。
早期實(shí)現(xiàn)過shmop/apcu + 邊車定時(shí)器進(jìn)程進(jìn)行過期時(shí)間處理,實(shí)話實(shí)說,那個(gè)性能沒法看,尤其是堆積數(shù)據(jù)過大的時(shí)候,時(shí)間復(fù)雜度畢竟是O(n),而且單進(jìn)程的定時(shí)器在堆積數(shù)據(jù)過大的情況下也存在延時(shí)。

當(dāng)然,這樣玩一玩,了解實(shí)踐一些服務(wù)層的知識(shí)肯定是好處,有益的

  • chaz6chez 2023-04-03

    而且其實(shí)這里面我們還得出一個(gè)實(shí)踐,用持久化連接的SQLite3的memory也非??欤途彺媸穷愃频?,用file也可以達(dá)到redis的持久化效果,而且還帶事務(wù),當(dāng)然肯定和純內(nèi)存是沒辦法比的;我們后續(xù)的很多小組件都是通過RPC + SQLite3進(jìn)行的數(shù)據(jù)存儲(chǔ)和緩存處理,相當(dāng)穩(wěn)定。

  • chaz6chez 2023-04-03

    最主要的是SQLite3非常穩(wěn)定,切具備工業(yè)化標(biāo)準(zhǔn),PHP自帶該拓展庫無需額外安裝及配置

  • army 2023-04-03

    cli下和fpm使用一致,并沒有過期時(shí)間的問題,pecl.php.net下載的存在時(shí)間過期問題,從倉庫拉源碼編譯是正常的,當(dāng)然我們修改了源碼增加了一個(gè)時(shí)間字段來遍歷時(shí)更好的過濾失效key,我們已應(yīng)用在生產(chǎn)環(huán)境。不考慮分布式以及持久化,只用簡單的kv緩存的話,apcu就是神一樣的存在。

  • army 2023-04-03

    在單機(jī)下,apcu可以完美替代workerman提供的globalData 實(shí)現(xiàn)多進(jìn)程變量共享,且是globalData的幾十倍效率。

  • chaz6chez 2023-04-03

    不考慮持久化和分布式的話,其實(shí)常駐內(nèi)存框架可以直接用php的靜態(tài)變量,其中還可以使用Spl的一些數(shù)據(jù)結(jié)構(gòu),比如堆、優(yōu)先隊(duì)列,在處理包含資源類型的緩存的時(shí)候比apcu更有競爭力,而且性能更好,你們可以在8.0及以上的php版本測試一下,效果是比apcu更好的

  • kane 2023-10-03

    都用php了還考慮啥性能,要性能用golang吧!

army

下圖是我們生產(chǎn)環(huán)境中的各種方案,起初我們把后端用go+redis和go+自寫cache,并發(fā)上來后都不如fpm+apcu,后來又使用了workerman+redis,起初也一樣,無法完美使用apcu,導(dǎo)致Redis有些扛不住,又切換到了fpm+apcu,然后我們前端APP要websocket,沒辦法又用回了workerman+redis,不死心去研究了下apcu源碼,最后就是workerman+apcu,終于比fpm+apcu強(qiáng)了。

  • jesse 2023-10-20

    go有兩個(gè)節(jié)點(diǎn)飚的好高

fenger

Redis 為 127.0.0.1 本機(jī),該服務(wù)端的Redis還存在IO瓶頸嗎? 手動(dòng)狗頭

  • 菏澤曹縣 2023-08-02

    有道理啊,換成本機(jī)redis呢,,或者直接存workman 進(jìn)程內(nèi)存。。豈不是更快

  • chaz6chez 2023-08-02

    redis只要走網(wǎng)絡(luò)就會(huì)存在內(nèi)核態(tài)和用戶態(tài)的拷貝,就會(huì)被redis的epoll影響,apcu是走的共享內(nèi)存,并不會(huì)存在內(nèi)核態(tài)和用戶態(tài)的拷貝問題,是比redis更快的

artisan

NB關(guān)注一下

  • 暫無評(píng)論
fengchujun

關(guān)注一下

  • 暫無評(píng)論
hongs

謝謝作者和
chaz6chez的分享.

  • 暫無評(píng)論

是這個(gè)源碼地址嗎?有誰教教我怎么編譯。https://github.com/krakjoe/apcu

  • army 2023-08-04

    拉取到服務(wù)器,cd到源碼目錄,依次執(zhí)行以下幾個(gè)步驟
    /server/php/bin/phpize (你的phpize路徑)
    ./configure --with-php-config=/server/php/bin/php-config (你的php-config路徑)
    make && make install

  • army 2023-08-04

    最后在php.ini里添加apcu的配置
    [apcu]
    apc.enabled=1
    apc.shm_segments=1
    apc.shm_size=512M
    apc.entries_hint=0
    apc.ttl=0
    apc.gc_ttl=5
    apc.mmap_file_mask=
    apc.slam_defense=0
    apc.enable_cli=1
    apc.use_request_time=0
    apc.serializer="php"
    apc.coredump_unmap=0
    apc.preload_path=

    ;
    extension=apcu.so

  • 2023-08-10

    贊!

  • aspire 2023-08-17

    這是安裝方法嗎?

大地瓜

workerman本身已經(jīng)常駐內(nèi)存了,一步到位,直接使用全局變量豈不是更快!
程序啟動(dòng)時(shí)初始化全局變量:$a=[];
寫入/修改:
$a["key"]="value";
$a["key2"]="value2";...
讀?。?br /> $b=$a["key"];...
刪除:
unset($a["key"]);

  • army 2023-11-14

    全局變量的話進(jìn)程與進(jìn)程之間無法共享,主進(jìn)程的變量子進(jìn)程可讀不可寫

  • 大地瓜 2023-11-15

    apcu本身也是單進(jìn)程單線程設(shè)計(jì)的,多個(gè)主進(jìn)程間或者多個(gè)子進(jìn)程間apcu緩存不支持共享,每個(gè)進(jìn)程都有獨(dú)立的apcu緩存

    如果僅提供單進(jìn)程單線程服務(wù),高并發(fā)且頻繁讀寫增刪緩存,例如實(shí)時(shí)游戲等追求極致性能的實(shí)例,不用想,使用全局變量肯定比其他外部擴(kuò)展快

    例如:
    <?php
    //error_reporting(0);
    use Workerman\Worker;
    use Workerman\Connection\TcpConnection;
    use Workerman\Timer;

    require_once __DIR__ . '/vendor/autoload.php';
    $worker = new Worker("websocket://0.0.0.0:10001"); // 創(chuàng)建websocket
    $worker->name = "桀桀桀桀";
    $worker->count = 1; // 啟動(dòng)1個(gè)進(jìn)程 如果開啟多個(gè)進(jìn)程,則每個(gè)進(jìn)程都會(huì)產(chǎn)生獨(dú)立的緩存,業(yè)務(wù)中如果提供向指定用戶推送消息且開啟多進(jìn)程,同進(jìn)程推送成功否則失敗,進(jìn)程間緩存不共享(在A魚塘釣不了B魚塘的羅飛魚)

    //$worker啟動(dòng)時(shí)
    $worker->onWorkerStart = function () {
    //初始化MySQL redis等
    global $test; //桀桀桀桀桀 全局變量
    $test=[]; //初始化全局變量

       //定時(shí)任務(wù) 每隔1800秒同步一次
        $time_interval = 1800;
    Timer::add($time_interval, function () {
        global $test;
                //各種邏輯 然后操作$test
    }

    }
    //用戶握手連接時(shí)初始化用戶數(shù)據(jù)
    $worker->onConnect = function (TcpConnection $connection) {
    $connection->onWebSocketConnect = function (TcpConnection $connection, $request) {
    global $test;
    //從連接參數(shù)中獲取用戶數(shù)據(jù) 各種邏輯 然后操作$test
    };
    };
    //收發(fā)數(shù)據(jù)
    $worker->onMessage = function (TcpConnection $connection, $data) {
    global $test;
    //業(yè)務(wù)邏輯 操作$test
    }
    // 用戶連接斷開時(shí)
    $worker->onClose = function (TcpConnection $connection) {
    global $test;
    //各種邏輯 然后操作$test
    }
    Worker::runAll();
    ?>

    看業(yè)務(wù)情況只需修改下cli的php.ini腳本內(nèi)存限制,如:memory_limit=256M

  • army 2023-11-15

    workerman主進(jìn)程下不管多少個(gè)子進(jìn)程,都是共享的,均可讀寫,并發(fā)能力也超棒

  • chaz6chez 2023-11-15

    apcu可以開啟mmap內(nèi)存映射,非親緣進(jìn)程也可以共享,底層使用的是mmap()函數(shù)實(shí)現(xiàn)的

  • 大地瓜 2023-11-15

    向大佬們學(xué)習(xí)!

chaz6chez

最近在研究這個(gè),http://www.wtbis.cn/plugin/133 ,可以看看,應(yīng)該能用得上

  • army 2023-11-15

    他這個(gè)加鎖我沒搞明白,apcu內(nèi)部已經(jīng)有讀鎖機(jī)制,他再套一層是為啥?

  • chaz6chez 2023-11-15

    對(duì)于map的操作,需要原子性加鎖,因?yàn)槭嵌?jí)內(nèi)容的修改,比如update

  • army 2023-11-15

    我覺得沒這個(gè)必要,直接apcu_store就可以了,加鎖apcu已經(jīng)在內(nèi)部有操作,我們只管用,隨意并發(fā)寫。

  • chaz6chez 2023-11-15

    很多時(shí)候上層需要一個(gè)原子性操作來保證業(yè)務(wù)原子性,apcu底層提供了鎖來保證apcu自己的函數(shù)具備原子性,但是上層的封裝需要多次調(diào)用一個(gè)或N個(gè)apcu函數(shù),需要保證上層業(yè)務(wù)的原子性,所以需要用到apcu提供的原子性鎖,有些地方需要阻塞等待式調(diào)用,所以需要自行在此基礎(chǔ)上實(shí)現(xiàn)搶占式鎖來保證原子性和業(yè)務(wù)完整性

  • chaz6chez 2023-11-15

    多進(jìn)程下,AB兩個(gè)進(jìn)程在每一個(gè)apcu的函數(shù)上肯定是原子性的,但是有些時(shí)候A上面有多個(gè)apcu操作,B也有多個(gè)apcu函數(shù)操作,相互之間需要各自的原子性,如果不加鎖,這些apcu函數(shù)會(huì)在apcu實(shí)際執(zhí)行中穿插執(zhí)行,并不能保證原子性,這個(gè)是測試后得到的結(jié)果,畢竟apcu只保證自己函數(shù)的原子性

  • army 2023-11-15

    apc在寫入的時(shí)候,內(nèi)部總是以 鎖->寫->釋放的過程,不管你的有多少個(gè)進(jìn)程同時(shí)操作,這不會(huì)變,也可以理解為阻塞寫入,在業(yè)務(wù)代碼上再套一層鎖,真有必要嗎? 麻煩分享下測試過程,這對(duì)我們很重要,目前沒遇到過并發(fā)安全性問題,我們項(xiàng)目深度依賴apcu 希望能漲些知識(shí) ??

  • chaz6chez 2023-11-15

    你沒懂我的意思

    假設(shè)兩個(gè)進(jìn)程同時(shí)執(zhí)行以下操作:
    {
    1.apuc_get('a',一些數(shù)據(jù));
    其他的一些業(yè)務(wù)結(jié)果a
    2.apuc_store('a', a);
    另一些業(yè)務(wù)
    }
    業(yè)務(wù)是一次原子性操作,業(yè)務(wù)邏輯是依賴apcu的數(shù)據(jù)

    在apuc層面每一次調(diào)用都是原子性帶鎖的沒錯(cuò),會(huì)互斥沒錯(cuò),但是兩個(gè)進(jìn)程同時(shí)進(jìn)行的時(shí)候,1/2的數(shù)據(jù)可能被另一個(gè)進(jìn)程的操作污染,因?yàn)闃I(yè)務(wù)不具備原子性,那么我在上層增加atomic原子性操作,依賴自己實(shí)現(xiàn)的鎖就可以避免這個(gè)問題,但代價(jià)就是當(dāng)多個(gè)相同的進(jìn)程同時(shí)執(zhí)行對(duì)相同數(shù)據(jù)進(jìn)行操作的時(shí)候,會(huì)互斥并排隊(duì);原理和redis的nx 或者 xx是類似的

  • chaz6chez 2023-11-15

    由于apcu是非常高效的微妙級(jí)別的操作,通常來說上下文執(zhí)行的過程是比apcu處理會(huì)慢的,所以很多時(shí)候感受不到這個(gè)問題,當(dāng)并發(fā)量達(dá)到一定程度,或者其中業(yè)務(wù)存在一定執(zhí)行時(shí)間的時(shí)候,這樣的問題就會(huì)暴露出來;這樣的問題就跟使用數(shù)據(jù)庫對(duì)數(shù)據(jù)進(jìn)行處理的時(shí)候不加事務(wù)一樣,原則上是為了保證整個(gè)業(yè)務(wù)的完整性和原子性

  • chaz6chez 2023-11-15

    具體場景就是當(dāng)apcu儲(chǔ)存了一個(gè)map,我需要對(duì)map里面的一個(gè)鍵值進(jìn)行自增,那么我需要先讀取出來,比如a=>1,當(dāng)我利用apcu讀取的時(shí)候可能是1,在我自增寫入的時(shí)候我期望是2,但在這時(shí)候其他親緣進(jìn)程可能已經(jīng)先于我操作了,就在我讀取并自增的間隙內(nèi),已經(jīng)自增到了2,那么最后我的結(jié)果還是2,不能保證是3;因?yàn)閍pcu的每次函數(shù)調(diào)用是一個(gè)原子性操作,但是很多業(yè)務(wù)是需要多次apcu的函數(shù)調(diào)用來完成一次原子性操作的

  • chaz6chez 2023-11-15

    a進(jìn)程map自增,b進(jìn)程map也自增,存在ab進(jìn)程都讀取的是1,ab進(jìn)程最后的結(jié)果都是2,而不是一個(gè)是2一個(gè)是3

  • army 2023-11-15

    原來存入的map,這下就明白了,我們用不到這種場景,我們都是直接存單key,比如5萬臺(tái)車需要實(shí)時(shí)上傳位置,每臺(tái)車一個(gè)key,這種場景下用map效率比單key低。

  • chaz6chez 2023-11-15

    還有這個(gè)插件支持redis的nx和xx這兩個(gè)場景,都需要鎖+搶占式循環(huán)來進(jìn)行實(shí)現(xiàn),其他的業(yè)務(wù)實(shí)際上沒有用到鎖;包括后續(xù)的業(yè)務(wù)需要對(duì)mmap進(jìn)行支持,我也在想辦法如何對(duì)內(nèi)存的變動(dòng)進(jìn)行有效的監(jiān)聽

  • xiaopi 2024-04-17

    老哥說的很詳細(xì),給我就解惑了。我現(xiàn)在有的項(xiàng)目是接收大量的http報(bào)文請(qǐng)求,然后分析以后存儲(chǔ)到當(dāng)前進(jìn)程的內(nèi)存變量二維數(shù)組中,通過條數(shù)積累到一定數(shù)量后統(tǒng)一上報(bào)給后端某個(gè)服務(wù)中。但是過程中出現(xiàn)了一些問題,比如由于要保證接收http報(bào)文的性能,所以開了多個(gè)進(jìn)程,而進(jìn)程隔離導(dǎo)致無法判斷兩個(gè)進(jìn)程中的兩份報(bào)文是否有重復(fù)的。所以打算優(yōu)化這個(gè)操作,使用apcu共享內(nèi)存,但是新的問題又出現(xiàn)了,每個(gè)進(jìn)程中都要判斷當(dāng)前報(bào)文的條數(shù)是否符合上報(bào)的要求,然后符合要求的進(jìn)行上報(bào),上報(bào)完成后清空當(dāng)前key,重復(fù)下一次報(bào)文積累,這樣一定會(huì)出現(xiàn)并發(fā)的問題,比如上報(bào)了兩次,或者上報(bào)的條數(shù)超過了等等并發(fā)問題。 我現(xiàn)在使用上述包試試,使用對(duì)上報(bào)、apcu的查詢、存儲(chǔ)進(jìn)行加鎖試試。

  • army 2024-04-17

    @xiaopi 不要存數(shù)組,存單key,給個(gè)識(shí)別的前綴標(biāo)識(shí),單開一個(gè)進(jìn)程定時(shí)去遍歷key進(jìn)行上報(bào)即可,存數(shù)組這種形式明顯不合理且性能低。

  • xiaopi 2024-04-17

    @army 感謝提醒,不過我這個(gè)項(xiàng)目對(duì)上報(bào)的時(shí)效性要求比較高,原先的邏輯是存在靜態(tài)數(shù)組中,然后如果數(shù)組長度達(dá)到100或者10s中后,自動(dòng)上報(bào),所以是放在Timer定時(shí)器中的。改成apcu全局緩存后,請(qǐng)教一下老哥,如果單進(jìn)程上報(bào)會(huì)不會(huì)效率比較低啊,如果多進(jìn)程還是要加鎖的吧? 還有一個(gè)是存單key的話,不太好獲取上報(bào)的條數(shù)吧? 用的是這個(gè)擴(kuò)展 http://www.wtbis.cn/plugin/133
    不過里面提供了search方法,還不知道效率如何

    默認(rèn)正則匹配 - 以50條為一次分片查詢

    \Workbunny\WebmanSharedCache\Cache::Search('/^abc.+$/', function ($key, $value) use (&$result) { 
      $result[$key] = $value;
    }, 50);
  • army 2024-04-17

    @xiaopi 我認(rèn)為跟我的場景差不多,我說下我的場景是怎么實(shí)現(xiàn)的,應(yīng)該對(duì)你有幫助。
    我這有5萬臺(tái)車實(shí)時(shí)上報(bào)位置,我將每臺(tái)車的位置信息用apcu去緩存,set key為:“AAA:LINE:DRIVER:車牌號(hào):經(jīng)緯度“,也就是不斷的向緩存中去set,單開了一個(gè)進(jìn)程專門跑timer定時(shí)器,每2秒遍歷一次apcu的key,組合成inert語句入庫,整體下來5萬臺(tái)車的實(shí)時(shí)位置只需要每2秒執(zhí)行一次sql,效率高得離譜,存單key不用考慮搶占鎖什么的問題,希望能給到你思路。

  • xiaopi 2024-04-17

    @army 感謝,單進(jìn)程遍歷5萬個(gè)key,這個(gè)過程是阻塞的吧,包括插入數(shù)據(jù)庫的IO都是阻塞的,那么2秒鐘之內(nèi)可以完成這些操作嗎,會(huì)不會(huì)導(dǎo)致Timer不準(zhǔn)了啊,實(shí)際上不是間隔2s了。 還有單開進(jìn)程指的是在worker進(jìn)程中指定某個(gè)進(jìn)程專門用來上報(bào)的,還是process中自定義的task進(jìn)程??? 如果自定義的task進(jìn)程可以訪問到worker進(jìn)程set的全局緩存嗎,我記得有親緣性的進(jìn)程才可以訪問吧,我沒測試過

  • xiaopi 2024-04-17

    感謝

  • army 2024-04-17

    @xiaopi 是阻塞的,所以要單開進(jìn)程去跑,但是遍歷+入庫幾百毫秒就完成了。單開進(jìn)程是指 new 一個(gè)或多個(gè)Worker專門用來跑task

zhezhebie

應(yīng)該對(duì)比一下memcache,看看是不是還是這個(gè)情況。

  • chaz6chez 2024-01-08

    memcache也涉及到網(wǎng)絡(luò)和事件驅(qū)動(dòng)庫,效率還是沒有apcu高

lwb.6@qq.com

單走一個(gè)6

  • 暫無評(píng)論
年代過于久遠(yuǎn),無法發(fā)表評(píng)論

army

1100
積分
0
獲贊數(shù)
0
粉絲數(shù)
2023-03-01 加入
×
??