亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用MySQL + PHP + nginx并行化請求?

如何使用MySQL + PHP + nginx并行化請求?

PHP
森林海 2022-08-05 16:33:59
最近發現在我嘗試過的其他所有操作中,我用自定義JavaScript替換了我的JMeter配置文件,該JavaScript在無限循環中依次命中我的每個API端點,然后在不同的瀏覽器(一個Firefox,一個Chrome,一個Safari)中并行運行此腳本 - 以嘗試排除與我來自同一來源的所有連接相關的問題(相同的用戶代理, 相同的 Cookie、相同的會話 ID 等)當我這樣做時,我注意到我的所有問題都消失了。查詢并行運行,該應用程序的響應速度比JMeter讓您相信的要快得多。在我看來,JMeter不可能序列化請求,因為它是負載測試的事實標準。所以我開始嘗試重現這種行為。為了重新創建JMeter,我創建了以下兩個PHP腳本,它們(希望)模擬了我的Yii應用程序:慢.php<?phpsession_start();$_SESSION['some'] = 'value';// Yii is calling session_write_close() almost immediately after// the session is initialized, but to try and exacerbate issues,// I've commented it out:// session_write_close();$dsn = "mysql:host=localhost;dbname=platypus;unix_socket=/tmp/mysql.sock";$pdo = new PDO($dsn, "user", "password");// Yii was using whatever the default persistence behavior was,// but to try and exacerbate issues I set this flag:$pdo->setAttribute(PDO::ATTR_PERSISTENT, true);// Simulate a query running for 1 second by issuing a 1-second sleep$pdo->query("DO SLEEP(1)");echo "Done";快速.php<?phpsession_start();$_SESSION['some'] = 'value';$dsn = "mysql:host=localhost;dbname=platypus;unix_socket=/tmp/mysql.sock";$pdo = new PDO($dsn, "user", "password");$pdo->setAttribute(PDO::ATTR_PERSISTENT, true);// Simulate a query running for 0.1 seconds$pdo->query("DO SLEEP(0.1)");echo "Done";針對這兩個新端點運行 JMeter 時,沒有序列化請求。一切都是并行運行的。fast.php總是在100-150ms內返回并且速度很慢.php總是在1000-1050ms內返回,即使我擴展到3,4和5個線程也是如此。我能夠看到東西在11個線程處崩潰,但那是因為我超過了PHP中的工作線程數。所以總結一下:僅當使用 JMeter 分析我的 API 時,才會出現此問題,而這并不是應用本身所固有的這個問題不僅僅是一個JMeter錯誤,而是以某種方式與我的應用程序或Yii 1.1有關。我嘗試過,但無法提出最小的重現案例盡管在使用其他工具進行分析時不存在該問題,但很多人都做出了回應并提供了許多有用的信息:避免PHP中的持久連接(可能導致多個請求共享一個連接,可能不是)通過盡早呼叫來避免會話鎖定session_write_close()確保有足夠的 PHP 工作線程來處理同時連接數MySQL完全支持并行請求(如果硬件可以處理它)警惕表鎖定(任何具有語句的事務都可能鎖定表)UPDATEMyISAM 執行表級鎖定而不是行級鎖定
查看完整描述

4 回答

?
ibeautiful

TA貢獻1993條經驗 獲得超6個贊

MySQL + PHP + Apache一直非常擅長在“并行”中運行單獨的SQL語句。如果單獨的用戶發出HTTP請求,他們自然會快速通過Apache(可能是按順序,但很快)并到達單獨的PHP實例(假設Apache已經配置了足夠的“子級”)。每個PHP腳本都會建立自己的連接MySQL。MySQL將非??焖俚亟邮芏鄠€連接(假設足夠高,這是默認的)。每個MySQL連接都將獨立工作(禁止低級數據庫鎖,互斥鎖等)。每個都將在完成后完成,PHP也是如此,Apache將結果返回給用戶。max_connections

我假設(不確定)nginx的工作原理類似。

注意:我建議Apache(和nginx)按順序做事。但我懷疑將HTTP請求傳遞給PHP需要一毫秒的數量級,所以這個“串行”步驟不會解釋你找到的時間。

我的結論是,其中一個并沒有真正發生:

  • 每個步驟的配置不允許3個子/連接/等,或者

  • 有 3 個單獨的 HTTP 請求。

  • 有 3 個單獨的 PHP 腳本。

  • 這 3 個 SQL 語句不會相互阻止。(請提供 SQL。注意:使用表鎖定;僅此一點,就可以解釋問題所在。(請提供 。ENGINE=MyISAMSHOW CREATE TABLE

也許有可能(在看到SQL之后)加速SQL,從而減少整體的遲鈍問題。

查詢

假設 是每個表的,那么這些其他索引可能有利于加速查詢 2:idPRIMARY KEY

backup_broadcast:  (deletion, id)

shares:  (media_type, media_id, site_id)

broadcast:  (site_id, id)

video:  (deletion, id)

playlists_playlists:  (playlist_id, broadcast_id)

playlist_broadcast聞起來像一個“多對多映射”表。如果是這樣,我建議按照 http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table 中的提示進行操作。(同上,對于任何類似的表。

OR并且往往是低效的結構。但聽起來您無法控制查詢?IN ( SELECT ... )

這是沒有?的嗎?你關心你得到哪10行嗎?這將是不可預測的。LIMITORDER BY

如此大量的列會發生什么?似乎每次運行查詢時它們中的大多數都是相同的,因此主要是浪費時間??

對于查詢 3,需要(按任一順序)。但是,將其重新配制為使用或可能會運行得更快。siteINDEX(deletion, customer_id)JOINEXISTS


查看完整回答
反對 回復 2022-08-05
?
牧羊人nacy

TA貢獻1862條經驗 獲得超7個贊

我認為你有一個php會話鎖定的問題:你的第二個和第三個查詢正在嘗試訪問相同的php會話,并且正在等待。

嘗試盡快調用,以釋放您的php會話。盡快:當你確定你不會在你的php會話中寫入更多的數據。session_write_close

檢查這一點的一種簡單方法是嘗試使用2個瀏覽器或匿名/隱身模式:您的cookie不會被共享,您應該有2個會話,而不是相互阻止。


查看完整回答
反對 回復 2022-08-05
?
慕的地8271018

TA貢獻1796條經驗 獲得超4個贊

MySQL可以處理很多并行查詢,但你不能一次為每個連接做多個查詢。PHP通常的設置方式是每個請求轉到不同的線程/進程,因此每個進程都將具有與MySQL的自己的連接,從而避免了提到的問題。除非您在PHP中使用持久連接,否則您可能最終為每個請求使用相同的連接。如果是這種情況,應該很容易禁用它并返回到每個請求模型的標準一個數據庫連接。

我的第一個猜測是,端點 2 會觸發數據庫上的一些鎖定,這就是為什么端點 3 查詢排隊直到 enpoint2 的查詢完成的原因。這可以通過更改代碼中的邏輯(避免或最小化數據庫鎖定)或通過更改用于更好地滿足應用程序需求的數據庫配置或表引擎來解決。示例:InnoDB使用行級鎖定,而MyISAM鎖定整個表鎖定。

如果您不介意配置它,則分析將非常有用。我建議看看 Blackfire.io,New Relic或xdebug分析,如果你走這條路。您將能夠通過這種方式更快地找到瓶頸。


查看完整回答
反對 回復 2022-08-05
?
翻閱古今

TA貢獻1780條經驗 獲得超5個贊

嗯......評論太長。

稍微簡化一下,每個引擎都有一個隊列,它收集要計算的查詢,根據硬件的不同,它使用2或3甚至更多的線程來計算每個查詢。由于鎖,每個查詢需要的線程運行的時間更多,就像它使用自動增量插入新行時鎖定整個表一樣。(通過搜索,您會發現許多鎖的示例)。當然,每個查詢都需要內存和其他資源,它們必須與服務器上運行的所有計算機軟件的其余部分共享。

使用 clustes,您可以支付管理多個 sql 服務器的開銷。

所以從sql服務器端來看,它是并行的,但是你需要硬件來支持許多線程/許多引擎(應該非常小心地使用)

當然,你可以在sql中有很多用戶,但為了方便起見,你通常每個APP都有一個,有時甚至每個服務器一個。但是同一用戶可以同時訪問數據庫,但您當然可以禁用它。

你的php并行運行,因為Web服務器是為運行paparel請求而構建的,在那里,它是否運行php,Python(django)或javascript(nodejs),apache,IIS,nginx以及更多,每種技術都有好處,并且會導致更多的模塊添加到en引擎,它的速度要慢得多。

因此,一切都在一定程度上是平行的,您可以增加諸如在云提供商或虛擬服務器等中看到的此類系統的功能。

只有當口袋妖怪go的引入或新游戲甚至巨大的云提供商崩潰時,您才會注意到這些限制?;蛘邐W巴馬醫改的災難,沒有任何東西在那種規模上進行測試,無論哪種情況......負責,

并行化這些任務是很困難的,因為在Web服務器和sqlserver的情況下,它具有一定程度的緩存,它們在其中停放經常發出的請求,但通常每個請求都需要自己的數據。

實際上,一切都要復雜得多,從具有3個管道的cpu開始,多個內核和共享內存(導致Meltdown及其兄弟),包括僅駐留在內存中的表或數據庫以獲得高性能或僅在CPU緩存中運行的Web服務器,這比內存或硬盤驅動器快得多.....


查看完整回答
反對 回復 2022-08-05
  • 4 回答
  • 0 關注
  • 177 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號