摘要:進(jìn)程切換太多,影響了了效率應(yīng)該是原因之一。當(dāng)時(shí),十萬(wàn)條記錄,個(gè)進(jìn)程插入總時(shí)間為單進(jìn)程插入萬(wàn)條數(shù)據(jù),耗時(shí)秒,相對(duì)個(gè)進(jìn)程插入萬(wàn)記錄來(lái)說(shuō),耗時(shí)少些。而單進(jìn)程插入萬(wàn)條記錄,耗時(shí),相對(duì)來(lái)說(shuō),是挺慢的了。
個(gè)人在虛擬機(jī)centos7,單核,1G內(nèi)存
/** * 模擬并發(fā)請(qǐng)求,10萬(wàn)次寫入數(shù)據(jù)庫(kù) * 拆分為10個(gè)進(jìn)程,每個(gè)進(jìn)程處理一萬(wàn)條插入 */ $total = 10000; $num = 10; $per = $total/$num; $sql = ""; $child = ""; echo "start ".microtime(true).PHP_EOL; for($i = 1; $i<= $num; $i++) { $pid = pcntl_fork(); if($pid == -1) { die("fork error"); } if($pid > 0) { //$id = pcntl_wait($status,WNOHANG); $child[] = $pid; } else if ($pid == 0) { $link = mysqli_connect("localhost","root","root","yii2advanced"); $start = ($i-1)*$per + 1; $end = $start + $per; for($j = $start; $j< $end; $j++){ $time = microtime(true); $sql = "insert pcntl_test (rank,time) values (".$j.",".$time.")"; mysqli_query($link,$sql); } mysqli_close($link); $id = getmypid(); echo "child ".$id." finished ".microtime(true).PHP_EOL; exit(0); } } while(count($child)){ foreach($child as $k => $pid) { $res = pcntl_waitpid($pid, $status, WNOHANG); if ( -1 == $res || $res > 0) { unset($child[$k]); } } } echo "end ".microtime(true).PHP_EOL;
當(dāng)$total=10000,$num = 10;執(zhí)行結(jié)果如下:
start 1491903371.5548 child 19860 finished 1491903417.2113 child 19857 finished 1491903417.6909 child 19864 finished 1491903417.7793 child 19855 finished 1491903417.8695 child 19859 finished 1491903417.9162 child 19861 finished 1491903418.0089 child 19856 finished 1491903418.0532 child 19863 finished 1491903418.0842 child 19862 finished 1491903418.1474 child 19858 finished 1491903418.4341 end 1491903418.4424 總時(shí)間為46.88759994506836秒
當(dāng)$total=10000,$num = 100時(shí),執(zhí)行結(jié)果如下:
start 1491904334.1735 child 20085 finished 1491904337.0712 child 20086 finished 1491904337.144 …… child 20262 finished 1491904341.5602 child 20264 finished 1491904341.5803 end 1491904341.5869 總時(shí)間為7.413399934768677
當(dāng)$total=10000,$num = 1000時(shí),執(zhí)行結(jié)果如下:
start 1491904562.0166 child 20282 finished 1491904562.1191 child 20277 finished 1491904562.1268 child 20279 finished 1491904562.1352 ... child 21586 finished 1491904576.6954 child 21582 finished 1491904576.7024 child 21584 finished 1491904576.7226 end 1491904576.7297 總時(shí)間為14.71310019493103,相比100個(gè)子進(jìn)程,耗時(shí)更長(zhǎng)了。進(jìn)程切換太多,影響了了效率應(yīng)該是原因之一。
當(dāng)$total=100000 ,$num=100時(shí),十萬(wàn)條記錄,100個(gè)進(jìn)程插入
start 1491905670.2652 child 21647 finished 1491905725.4382 child 21651 finished 1491905725.4595 child 21642 finished 1491905725.5402 .... child 21810 finished 1491905729.7709 child 21812 finished 1491905729.8498 child 21811 finished 1491905729.9612 end 1491905729.9679 總時(shí)間為59.70270013809204
單進(jìn)程插入1萬(wàn)條數(shù)據(jù),耗時(shí)18秒,相對(duì)10個(gè)進(jìn)程插入1萬(wàn)記錄來(lái)說(shuō),耗時(shí)少些。
而單進(jìn)程插入10萬(wàn)條記錄,耗時(shí)187.40066790581,相對(duì)來(lái)說(shuō),是挺慢的了。三分鐘。。。
不過(guò),本人再fork 1000個(gè)進(jìn)程,來(lái)插入10萬(wàn)記錄時(shí),成功的情況下36秒左右,也可能會(huì)出現(xiàn)錯(cuò)誤,mysqli_connection返回false,是不是連接數(shù)受限制了?
fork 一萬(wàn)個(gè)子進(jìn)程,插入一百萬(wàn)數(shù)據(jù),這時(shí),出現(xiàn)連接錯(cuò)的情況就很多了。最后耗時(shí)360秒,數(shù)據(jù)表中插入了945300條記錄,成功率94.53%。于是查看數(shù)據(jù)庫(kù)的相關(guān)配置信息
mysql> show global status like "%connect%"; +-----------------------------------------------+---------------------+ | Variable_name | Value | +-----------------------------------------------+---------------------+ | Aborted_connects | 0 | | Connection_errors_accept | 0 | | Connection_errors_internal | 0 | | Connection_errors_max_connections | 628 | | Connection_errors_peer_address | 0 | | Connection_errors_select | 0 | | Connection_errors_tcpwrap | 0 | | Connections | 16519 | | Locked_connects | 0 | | Max_used_connections | 501 | | Max_used_connections_time | 2017-04-12 15:19:54 | | Performance_schema_session_connect_attrs_lost | 0 | | Ssl_client_connects | 0 | | Ssl_connect_renegotiates | 0 | | Ssl_finished_connects | 0 | | Threads_connected | 4 | +-----------------------------------------------+---------------------+ mysql> show global variables like "%connect%"; +-----------------------------------------------+--------------------+ | Variable_name | Value | +-----------------------------------------------+--------------------+ | character_set_connection | utf8mb4 | | collation_connection | utf8mb4_general_ci | | connect_timeout | 10 | | disconnect_on_expired_password | ON | | init_connect | | | max_connect_errors | 100 | | max_connections | 500 | | max_user_connections | 0 | | performance_schema_session_connect_attrs_size | 512 | +-----------------------------------------------+--------------------+ 修改 myqsql 配置文件,/etc/my.cnf 把max_connections 改為10000,然后重啟mysql 實(shí)際MySQL服務(wù)器允許的最大連接數(shù)16384; 結(jié)果然并卵,虛擬機(jī)好像掛了了。
并發(fā)量大的時(shí)候,問(wèn)題就出在了連接mysql這里。
可以通過(guò)一個(gè)連接池來(lái)嘗試解決該問(wèn)題。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/22694.html
摘要:最近在學(xué)習(xí)進(jìn)程相關(guān)的知識(shí),配合實(shí)際編碼,覺(jué)得有點(diǎn)意思。閑話不說(shuō)了,進(jìn)入正題,受網(wǎng)友啟發(fā),如何創(chuàng)建恒定數(shù)量的進(jìn)程呢有進(jìn)程掛了,就創(chuàng)建新的,進(jìn)程,進(jìn)程多了就殺掉幾個(gè)。 最近在學(xué)習(xí)進(jìn)程相關(guān)的知識(shí),配合實(shí)際編碼,覺(jué)得有點(diǎn)意思。這段時(shí)間工作不忙,有時(shí)間自己研究進(jìn)步,感覺(jué)這才是真正的工作啊。相比上一家公司(壓抑的工作飽和度……)感覺(jué)開(kāi)心很多。下一步再研究一下多線程??纯茨懿荒懿迦胍磺f(wàn)條數(shù)據(jù)。閑話...
摘要:任何進(jìn)程在退出前使用退出都會(huì)變成僵尸進(jìn)程用于保存進(jìn)程的狀態(tài)等信息,然后由進(jìn)程接管。這時(shí)候就算手動(dòng)結(jié)束腳本程序也無(wú)法關(guān)閉這個(gè)僵尸子進(jìn)程了。那么子進(jìn)程結(jié)束后,沒(méi)有回收,就產(chǎn)生僵尸進(jìn)程了。本小節(jié)我們通過(guò)安裝信號(hào)處理函數(shù)來(lái)解決僵尸進(jìn)程問(wèn)題。 上一篇文章講解了pcntl_fork和pcntl_wait兩個(gè)函數(shù)的使用,本篇繼續(xù)講解PHP多進(jìn)程相關(guān)新知識(shí)。 僵尸(zombie)進(jìn)程 這里說(shuō)下僵尸進(jìn)程...
摘要:對(duì)編程的理解,應(yīng)該到深入到操作系統(tǒng)級(jí)別。進(jìn)程控制,我一直都沒(méi)有接觸,感覺(jué)好高端,今天啃了一下擴(kuò)展的最簡(jiǎn)單的兩個(gè)函數(shù),有點(diǎn)心得,記錄一下吧,歡迎拋磚。 對(duì)編程的理解,應(yīng)該到深入到操作系統(tǒng)級(jí)別。進(jìn)程控制,我一直都沒(méi)有接觸,感覺(jué)好高端,今天啃了一下pcntl擴(kuò)展的最簡(jiǎn)單的兩個(gè)函數(shù),有點(diǎn)心得,記錄一下吧,歡迎拋磚。新建代碼文件 pcntl_wait.php,如下: $i = 0; ...
摘要:用于創(chuàng)建子進(jìn)程。該函數(shù)阻塞當(dāng)前進(jìn)程,只到當(dāng)前進(jìn)程的一個(gè)子進(jìn)程退出或者收到一個(gè)結(jié)束當(dāng)前進(jìn)程的信號(hào)。注意處需要注意子進(jìn)程需要防止子進(jìn)程也進(jìn)入循環(huán)。如果沒(méi)有,最終創(chuàng)建的子進(jìn)程不只個(gè)。 本系列文章將向大家講解pcntl_*系列函數(shù),從而更深入的理解進(jìn)程相關(guān)知識(shí)。 PCNTL在PHP中進(jìn)程控制支持默認(rèn)是關(guān)閉的。您需要使用 --enable-pcntl 配置選項(xiàng)重新編譯PHP的 CGI或CLI版本...
摘要:消息隊(duì)列更常見(jiàn)的用途是主進(jìn)程分配任務(wù),子進(jìn)程消費(fèi)執(zhí)行。子進(jìn)程前面加了個(gè),這是為了防止父進(jìn)程還未往消息隊(duì)列中加入內(nèi)容直接退出。 前面幾節(jié)都是講解pcntl擴(kuò)展實(shí)現(xiàn)的多進(jìn)程程序。本節(jié)給大家介紹swoole擴(kuò)展的swoole_process模塊。 swoole多進(jìn)程 swoole_process 是swoole提供的進(jìn)程管理模塊,用來(lái)替代PHP的pcntl擴(kuò)展。 首先,確保安裝的swoole...
閱讀 3837·2021-11-17 09:33
閱讀 2049·2021-10-26 09:51
閱讀 1573·2021-09-29 09:44
閱讀 1715·2019-08-30 15:55
閱讀 1473·2019-08-30 15:52
閱讀 2355·2019-08-30 15:43
閱讀 3459·2019-08-29 17:00
閱讀 2328·2019-08-29 16:23