php數(shù)據(jù)庫(kù)并發(fā)處理 php高并發(fā)實(shí)戰(zhàn)

php 高并發(fā)解決思路解決方案

php 高并發(fā)解決思路解決方案,如何應(yīng)對(duì)網(wǎng)站大流量高并發(fā)情況。本文為大家總結(jié)了常用的處理方式,但不是細(xì)節(jié),后續(xù)一系列細(xì)節(jié)教程給出。希望大家喜歡。

德惠ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書(shū)銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書(shū)合作)期待與您的合作!

一 高并發(fā)的概念

在互聯(lián)網(wǎng)時(shí)代,并發(fā),高并發(fā)通常是指并發(fā)訪問(wèn)。也就是在某個(gè)時(shí)間點(diǎn),有多少個(gè)訪問(wèn)同時(shí)到來(lái)。

二 高并發(fā)架構(gòu)相關(guān)概念

1、QPS (每秒查詢率) : 每秒鐘請(qǐng)求或者查詢的數(shù)量,在互聯(lián)網(wǎng)領(lǐng)域,指每秒響應(yīng)請(qǐng)求數(shù)(指 HTTP 請(qǐng)求)

2、PV(Page View):綜合瀏覽量,即頁(yè)面瀏覽量或者點(diǎn)擊量,一個(gè)訪客在 24 小時(shí)內(nèi)訪問(wèn)的頁(yè)面數(shù)量

--注:同一個(gè)人瀏覽你的網(wǎng)站的同一頁(yè)面,只記做一次 pv

3、吞吐量(fetches/sec) :?jiǎn)挝粫r(shí)間內(nèi)處理的請(qǐng)求數(shù)量 (通常由 QPS 和并發(fā)數(shù)決定)

4、響應(yīng)時(shí)間:從請(qǐng)求發(fā)出到收到響應(yīng)花費(fèi)的時(shí)間

5、獨(dú)立訪客(UV):一定時(shí)間范圍內(nèi),相同訪客多次訪問(wèn)網(wǎng)站,只計(jì)算為 1 個(gè)獨(dú)立訪客

6、帶寬:計(jì)算帶寬需關(guān)注兩個(gè)指標(biāo),峰值流量和頁(yè)面的平均大小

7、日網(wǎng)站帶寬: PV/統(tǒng)計(jì)時(shí)間(換算到秒) * 平均頁(yè)面大?。╧b)* 8

三 需要注意點(diǎn):

1、QPS 不等于并發(fā)連接數(shù)(QPS 是每秒 HTTP 請(qǐng)求數(shù)量,并發(fā)連接數(shù)是系統(tǒng)同時(shí)處理的請(qǐng)求數(shù)量)

2、峰值每秒請(qǐng)求數(shù)(QPS)= (總 PV 數(shù)*80%)/ (六小時(shí)秒數(shù)*20%)【代表 80%的訪問(wèn)量都集中在 20%的時(shí)間內(nèi)】

3、壓力測(cè)試: 測(cè)試能承受的最大并發(fā)數(shù) 以及測(cè)試最大承受的 QPS 值

4、常用的性能測(cè)試工具【ab,wrk,httpload,Web Bench,Siege,Apache JMeter】

四 優(yōu)化

1、當(dāng) QPS 小于 50 時(shí)

優(yōu)化方案:為一般小型網(wǎng)站,不用考慮優(yōu)化

2、當(dāng) QPS 達(dá)到 100 時(shí),遇到數(shù)據(jù)查詢瓶頸

優(yōu)化方案: 數(shù)據(jù)庫(kù)緩存層,數(shù)據(jù)庫(kù)的負(fù)載均衡

3、當(dāng) QPS 達(dá)到 800 時(shí), 遇到帶寬瓶頸

優(yōu)化方案:CDN 加速,負(fù)載均衡

4、當(dāng) QPS 達(dá)到 1000 時(shí)

優(yōu)化方案: 做 html 靜態(tài)緩存

5、當(dāng) QPS 達(dá)到 2000 時(shí)

優(yōu)化方案: 做業(yè)務(wù)分離,分布式存儲(chǔ)

五、高并發(fā)解決方案案例:

1、流量?jī)?yōu)化

防盜鏈處理(去除惡意請(qǐng)求)

2、前端優(yōu)化

(1) 減少 HTTP 請(qǐng)求[將 css,js 等合并]

(2) 添加異步請(qǐng)求(先不將所有數(shù)據(jù)都展示給用戶,用戶觸發(fā)某個(gè)事件,才會(huì)異步請(qǐng)求數(shù)據(jù))

(3) 啟用瀏覽器緩存和文件壓縮

(4) CDN 加速

(5) 建立獨(dú)立的圖片服務(wù)器(減少 I/O)

3、服務(wù)端優(yōu)化

(1) 頁(yè)面靜態(tài)化

(2) 并發(fā)處理

(3) 隊(duì)列處理

4、數(shù)據(jù)庫(kù)優(yōu)化

(1) 數(shù)據(jù)庫(kù)緩存

(2) 分庫(kù)分表,分區(qū)

(3) 讀寫(xiě)分離

(4) 負(fù)載均衡

5、web 服務(wù)器優(yōu)化

(1) nginx 反向代理實(shí)現(xiàn)負(fù)載均衡

(2) lvs 實(shí)現(xiàn)負(fù)載均衡

php 怎么處理 并發(fā)

和php關(guān)系并不大,和web服務(wù)軟件和數(shù)據(jù)庫(kù)連接關(guān)系最大,所以是web服務(wù)端采用nginx+fpm+apc or xcache,能在2g雙核,2g內(nèi)存下處理10000左右的并發(fā)。

但最重要的,是數(shù)據(jù)庫(kù)這塊,中間一定要有緩存,memcache是個(gè)不錯(cuò)選擇。如果在數(shù)據(jù)庫(kù)中間未加緩存,并發(fā)大后,你很快會(huì)發(fā)現(xiàn)都連最基本的發(fā)起連接都是難事。

如何處理PHP和MYSQL的并發(fā)以及優(yōu)化

sql優(yōu)化,數(shù)據(jù)緩存和頁(yè)面靜態(tài)化

首先各種優(yōu)化程序邏輯優(yōu)化數(shù)據(jù)庫(kù)優(yōu)化硬件橫向擴(kuò)展

數(shù)據(jù)hash、服務(wù)器提升性能、表hash、出錢(qián)找oraclec出解決方案

頁(yè)面靜態(tài)化:

Php頁(yè)面靜態(tài)化有兩種,第一,php模板,比如:smarty。第二,url偽靜態(tài),通過(guò)urlrewrite實(shí)現(xiàn)這種做法可以提高網(wǎng)站的排名和收索

像一些管理性質(zhì)的網(wǎng)站,比如:新聞發(fā)布系統(tǒng)、CMS等,使用php模板靜態(tài)化。一般的網(wǎng)站偽靜態(tài)就可以了

數(shù)據(jù)緩存:

php程序常規(guī)的獲取數(shù)據(jù)的流程是:

1.用戶向php程序發(fā)送請(qǐng)求

2.php請(qǐng)求從數(shù)據(jù)庫(kù)中取出數(shù)據(jù)

3.發(fā)送給用戶

但是當(dāng)網(wǎng)站的訪問(wèn)量非常大的時(shí)候數(shù)據(jù)庫(kù)往往成為制約系統(tǒng)性能的瓶頸,為了減輕大規(guī)模請(qǐng)求對(duì)數(shù)據(jù)庫(kù)造成的壓力,簡(jiǎn)單的方法可以采用數(shù)據(jù)緩存來(lái)減輕數(shù)據(jù)庫(kù)的壓力,下面就簡(jiǎn)單的介紹一下常規(guī)的數(shù)據(jù)緩存方法:

具體的步驟:

1.用戶請(qǐng)求

2.判斷緩存是否存在或者是否過(guò)期

3.如果緩存不存在或者緩存已經(jīng)過(guò)期,從數(shù)據(jù)庫(kù)中讀出數(shù)據(jù);如果沒(méi)有過(guò)期,讀取緩存

4.發(fā)送給用戶

php怎么處理高并發(fā)

以下內(nèi)容轉(zhuǎn)載自徐漢彬大牛的博客?億級(jí)Web系統(tǒng)搭建——單機(jī)到分布式集群?

當(dāng)一個(gè)Web系統(tǒng)從日訪問(wèn)量10萬(wàn)逐步增長(zhǎng)到1000萬(wàn),甚至超過(guò)1億的過(guò)程中,Web系統(tǒng)承受的壓力會(huì)越來(lái)越大,在這個(gè)過(guò)程中,我們會(huì)遇到很多的問(wèn)題。為了解決這些性能壓力帶來(lái)問(wèn)題,我們需要在Web系統(tǒng)架構(gòu)層面搭建多個(gè)層次的緩存機(jī)制。在不同的壓力階段,我們會(huì)遇到不同的問(wèn)題,通過(guò)搭建不同的服務(wù)和架構(gòu)來(lái)解決。

Web負(fù)載均衡?

Web負(fù)載均衡(Load Balancing),簡(jiǎn)單地說(shuō)就是給我們的服務(wù)器集群分配“工作任務(wù)”,而采用恰當(dāng)?shù)姆峙浞绞?,?duì)于保護(hù)處于后端的Web服務(wù)器來(lái)說(shuō),非常重要。

負(fù)載均衡的策略有很多,我們從簡(jiǎn)單的講起哈。

1.?HTTP重定向

當(dāng)用戶發(fā)來(lái)請(qǐng)求的時(shí)候,Web服務(wù)器通過(guò)修改HTTP響應(yīng)頭中的Location標(biāo)記來(lái)返回一個(gè)新的url,然后瀏覽器再繼續(xù)請(qǐng)求這個(gè)新url,實(shí)際上就是頁(yè)面重定向。通過(guò)重定向,來(lái)達(dá)到“負(fù)載均衡”的目標(biāo)。例如,我們?cè)谙螺dPHP源碼包的時(shí)候,點(diǎn)擊下載鏈接時(shí),為了解決不同國(guó)家和地域下載速度的問(wèn)題,它會(huì)返回一個(gè)離我們近的下載地址。重定向的HTTP返回碼是302

這個(gè)重定向非常容易實(shí)現(xiàn),并且可以自定義各種策略。但是,它在大規(guī)模訪問(wèn)量下,性能不佳。而且,給用戶的體驗(yàn)也不好,實(shí)際請(qǐng)求發(fā)生重定向,增加了網(wǎng)絡(luò)延時(shí)。

2. 反向代理負(fù)載均衡

反向代理服務(wù)的核心工作主要是轉(zhuǎn)發(fā)HTTP請(qǐng)求,扮演了瀏覽器端和后臺(tái)Web服務(wù)器中轉(zhuǎn)的角色。因?yàn)樗ぷ髟贖TTP層(應(yīng)用層),也就是網(wǎng)絡(luò)七層結(jié)構(gòu)中的第七層,因此也被稱為“七層負(fù)載均衡”??梢宰龇聪虼淼能浖芏?,比較常見(jiàn)的一種是Nginx。

Nginx是一種非常靈活的反向代理軟件,可以自由定制化轉(zhuǎn)發(fā)策略,分配服務(wù)器流量的權(quán)重等。反向代理中,常見(jiàn)的一個(gè)問(wèn)題,就是Web服務(wù)器存儲(chǔ)的session數(shù)據(jù),因?yàn)橐话阖?fù)載均衡的策略都是隨機(jī)分配請(qǐng)求的。同一個(gè)登錄用戶的請(qǐng)求,無(wú)法保證一定分配到相同的Web機(jī)器上,會(huì)導(dǎo)致無(wú)法找到session的問(wèn)題。

解決方案主要有兩種:

1.?配置反向代理的轉(zhuǎn)發(fā)規(guī)則,讓同一個(gè)用戶的請(qǐng)求一定落到同一臺(tái)機(jī)器上(通過(guò)分析cookie),復(fù)雜的轉(zhuǎn)發(fā)規(guī)則將會(huì)消耗更多的CPU,也增加了代理服務(wù)器的負(fù)擔(dān)。

2.?將session這類的信息,專門(mén)用某個(gè)獨(dú)立服務(wù)來(lái)存儲(chǔ),例如redis/memchache,這個(gè)方案是比較推薦的。

反向代理服務(wù),也是可以開(kāi)啟緩存的,如果開(kāi)啟了,會(huì)增加反向代理的負(fù)擔(dān),需要謹(jǐn)慎使用。這種負(fù)載均衡策略實(shí)現(xiàn)和部署非常簡(jiǎn)單,而且性能表現(xiàn)也比較好。但是,它有“單點(diǎn)故障”的問(wèn)題,如果掛了,會(huì)帶來(lái)很多的麻煩。而且,到了后期Web服務(wù)器繼續(xù)增加,它本身可能成為系統(tǒng)的瓶頸。

3. IP負(fù)載均衡

IP負(fù)載均衡服務(wù)是工作在網(wǎng)絡(luò)層(修改IP)和傳輸層(修改端口,第四層),比起工作在應(yīng)用層(第七層)性能要高出非常多。原理是,他是對(duì)IP層的數(shù)據(jù)包的IP地址和端口信息進(jìn)行修改,達(dá)到負(fù)載均衡的目的。這種方式,也被稱為“四層負(fù)載均衡”。常見(jiàn)的負(fù)載均衡方式,是LVS(Linux Virtual Server,Linux虛擬服務(wù)),通過(guò)IPVS(IP Virtual Server,IP虛擬服務(wù))來(lái)實(shí)現(xiàn)。

在負(fù)載均衡服務(wù)器收到客戶端的IP包的時(shí)候,會(huì)修改IP包的目標(biāo)IP地址或端口,然后原封不動(dòng)地投遞到內(nèi)部網(wǎng)絡(luò)中,數(shù)據(jù)包會(huì)流入到實(shí)際Web服務(wù)器。實(shí)際服務(wù)器處理完成后,又會(huì)將數(shù)據(jù)包投遞回給負(fù)載均衡服務(wù)器,它再修改目標(biāo)IP地址為用戶IP地址,最終回到客戶端。

上述的方式叫LVS-NAT,除此之外,還有LVS-RD(直接路由),LVS-TUN(IP隧道),三者之間都屬于LVS的方式,但是有一定的區(qū)別,篇幅問(wèn)題,不贅敘。

IP負(fù)載均衡的性能要高出Nginx的反向代理很多,它只處理到傳輸層為止的數(shù)據(jù)包,并不做進(jìn)一步的組包,然后直接轉(zhuǎn)發(fā)給實(shí)際服務(wù)器。不過(guò),它的配置和搭建比較復(fù)雜。

4. DNS負(fù)載均衡

DNS(Domain Name System)負(fù)責(zé)域名解析的服務(wù),域名url實(shí)際上是服務(wù)器的別名,實(shí)際映射是一個(gè)IP地址,解析過(guò)程,就是DNS完成域名到IP的映射。而一個(gè)域名是可以配置成對(duì)應(yīng)多個(gè)IP的。因此,DNS也就可以作為負(fù)載均衡服務(wù)。

這種負(fù)載均衡策略,配置簡(jiǎn)單,性能極佳。但是,不能自由定義規(guī)則,而且,變更被映射的IP或者機(jī)器故障時(shí)很麻煩,還存在DNS生效延遲的問(wèn)題。?

5. DNS/GSLB負(fù)載均衡

我們常用的CDN(Content Delivery Network,內(nèi)容分發(fā)網(wǎng)絡(luò))實(shí)現(xiàn)方式,其實(shí)就是在同一個(gè)域名映射為多IP的基礎(chǔ)上更進(jìn)一步,通過(guò)GSLB(Global Server Load Balance,全局負(fù)載均衡)按照指定規(guī)則映射域名的IP。一般情況下都是按照地理位置,將離用戶近的IP返回給用戶,減少網(wǎng)絡(luò)傳輸中的路由節(jié)點(diǎn)之間的跳躍消耗。

“向上尋找”,實(shí)際過(guò)程是LDNS(Local DNS)先向根域名服務(wù)(Root Name Server)獲取到頂級(jí)根的Name Server(例如.com的),然后得到指定域名的授權(quán)DNS,然后再獲得實(shí)際服務(wù)器IP。

CDN在Web系統(tǒng)中,一般情況下是用來(lái)解決大小較大的靜態(tài)資源(html/Js/Css/圖片等)的加載問(wèn)題,讓這些比較依賴網(wǎng)絡(luò)下載的內(nèi)容,盡可能離用戶更近,提升用戶體驗(yàn)。

例如,我訪問(wèn)了一張imgcache.gtimg.cn上的圖片(騰訊的自建CDN,不使用qq.com域名的原因是防止http請(qǐng)求的時(shí)候,帶上了多余的cookie信息),我獲得的IP是183.60.217.90。

這種方式,和前面的DNS負(fù)載均衡一樣,不僅性能極佳,而且支持配置多種策略。但是,搭建和維護(hù)成本非常高?;ヂ?lián)網(wǎng)一線公司,會(huì)自建CDN服務(wù),中小型公司一般使用第三方提供的CDN。

Web系統(tǒng)的緩存機(jī)制的建立和優(yōu)化

剛剛我們講完了Web系統(tǒng)的外部網(wǎng)絡(luò)環(huán)境,現(xiàn)在我們開(kāi)始關(guān)注我們Web系統(tǒng)自身的性能問(wèn)題。我們的Web站點(diǎn)隨著訪問(wèn)量的上升,會(huì)遇到很多的挑戰(zhàn),解決這些問(wèn)題不僅僅是擴(kuò)容機(jī)器這么簡(jiǎn)單,建立和使用合適的緩存機(jī)制才是根本。

最開(kāi)始,我們的Web系統(tǒng)架構(gòu)可能是這樣的,每個(gè)環(huán)節(jié),都可能只有1臺(tái)機(jī)器。

我們從最根本的數(shù)據(jù)存儲(chǔ)開(kāi)始看哈。

一、 MySQL數(shù)據(jù)庫(kù)內(nèi)部緩存使用

MySQL的緩存機(jī)制,就從先從MySQL內(nèi)部開(kāi)始,下面的內(nèi)容將以最常見(jiàn)的InnoDB存儲(chǔ)引擎為主。

1. 建立恰當(dāng)?shù)乃饕?/p>

最簡(jiǎn)單的是建立索引,索引在表數(shù)據(jù)比較大的時(shí)候,起到快速檢索數(shù)據(jù)的作用,但是成本也是有的。首先,占用了一定的磁盤(pán)空間,其中組合索引最突出,使用需要謹(jǐn)慎,它產(chǎn)生的索引甚至?xí)仍磾?shù)據(jù)更大。其次,建立索引之后的數(shù)據(jù)insert/update/delete等操作,因?yàn)樾枰略瓉?lái)的索引,耗時(shí)會(huì)增加。當(dāng)然,實(shí)際上我們的系統(tǒng)從總體來(lái)說(shuō),是以select查詢操作居多,因此,索引的使用仍然對(duì)系統(tǒng)性能有大幅提升的作用。

2. 數(shù)據(jù)庫(kù)連接線程池緩存

如果,每一個(gè)數(shù)據(jù)庫(kù)操作請(qǐng)求都需要?jiǎng)?chuàng)建和銷毀連接的話,對(duì)數(shù)據(jù)庫(kù)來(lái)說(shuō),無(wú)疑也是一種巨大的開(kāi)銷。為了減少這類型的開(kāi)銷,可以在MySQL中配置thread_cache_size來(lái)表示保留多少線程用于復(fù)用。線程不夠的時(shí)候,再創(chuàng)建,空閑過(guò)多的時(shí)候,則銷毀。

其實(shí),還有更為激進(jìn)一點(diǎn)的做法,使用pconnect(數(shù)據(jù)庫(kù)長(zhǎng)連接),線程一旦創(chuàng)建在很長(zhǎng)時(shí)間內(nèi)都保持著。但是,在訪問(wèn)量比較大,機(jī)器比較多的情況下,這種用法很可能會(huì)導(dǎo)致“數(shù)據(jù)庫(kù)連接數(shù)耗盡”,因?yàn)榻⑦B接并不回收,最終達(dá)到數(shù)據(jù)庫(kù)的max_connections(最大連接數(shù))。因此,長(zhǎng)連接的用法通常需要在CGI和MySQL之間實(shí)現(xiàn)一個(gè)“連接池”服務(wù),控制CGI機(jī)器“盲目”創(chuàng)建連接數(shù)。

建立數(shù)據(jù)庫(kù)連接池服務(wù),有很多實(shí)現(xiàn)的方式,PHP的話,我推薦使用swoole(PHP的一個(gè)網(wǎng)絡(luò)通訊拓展)來(lái)實(shí)現(xiàn)。

3. Innodb緩存設(shè)置(innodb_buffer_pool_size)

innodb_buffer_pool_size這是個(gè)用來(lái)保存索引和數(shù)據(jù)的內(nèi)存緩存區(qū),如果機(jī)器是MySQL獨(dú)占的機(jī)器,一般推薦為機(jī)器物理內(nèi)存的80%。在取表數(shù)據(jù)的場(chǎng)景中,它可以減少磁盤(pán)IO。一般來(lái)說(shuō),這個(gè)值設(shè)置越大,cache命中率會(huì)越高。

4. 分庫(kù)/分表/分區(qū)。

MySQL數(shù)據(jù)庫(kù)表一般承受數(shù)據(jù)量在百萬(wàn)級(jí)別,再往上增長(zhǎng),各項(xiàng)性能將會(huì)出現(xiàn)大幅度下降,因此,當(dāng)我們預(yù)見(jiàn)數(shù)據(jù)量會(huì)超過(guò)這個(gè)量級(jí)的時(shí)候,建議進(jìn)行分庫(kù)/分表/分區(qū)等操作。最好的做法,是服務(wù)在搭建之初就設(shè)計(jì)為分庫(kù)分表的存儲(chǔ)模式,從根本上杜絕中后期的風(fēng)險(xiǎn)。不過(guò),會(huì)犧牲一些便利性,例如列表式的查詢,同時(shí),也增加了維護(hù)的復(fù)雜度。不過(guò),到了數(shù)據(jù)量千萬(wàn)級(jí)別或者以上的時(shí)候,我們會(huì)發(fā)現(xiàn),它們都是值得的。?

二、 MySQL數(shù)據(jù)庫(kù)多臺(tái)服務(wù)搭建

1臺(tái)MySQL機(jī)器,實(shí)際上是高風(fēng)險(xiǎn)的單點(diǎn),因?yàn)槿绻鼟炝耍覀僕eb服務(wù)就不可用了。而且,隨著Web系統(tǒng)訪問(wèn)量繼續(xù)增加,終于有一天,我們發(fā)現(xiàn)1臺(tái)MySQL服務(wù)器無(wú)法支撐下去,我們開(kāi)始需要使用更多的MySQL機(jī)器。當(dāng)引入多臺(tái)MySQL機(jī)器的時(shí)候,很多新的問(wèn)題又將產(chǎn)生。

1. 建立MySQL主從,從庫(kù)作為備份

這種做法純粹為了解決“單點(diǎn)故障”的問(wèn)題,在主庫(kù)出故障的時(shí)候,切換到從庫(kù)。不過(guò),這種做法實(shí)際上有點(diǎn)浪費(fèi)資源,因?yàn)閺膸?kù)實(shí)際上被閑著了。

2. MySQL讀寫(xiě)分離,主庫(kù)寫(xiě),從庫(kù)讀。

兩臺(tái)數(shù)據(jù)庫(kù)做讀寫(xiě)分離,主庫(kù)負(fù)責(zé)寫(xiě)入類的操作,從庫(kù)負(fù)責(zé)讀的操作。并且,如果主庫(kù)發(fā)生故障,仍然不影響讀的操作,同時(shí)也可以將全部讀寫(xiě)都臨時(shí)切換到從庫(kù)中(需要注意流量,可能會(huì)因?yàn)榱髁窟^(guò)大,把從庫(kù)也拖垮)。

3. 主主互備。

兩臺(tái)MySQL之間互為彼此的從庫(kù),同時(shí)又是主庫(kù)。這種方案,既做到了訪問(wèn)量的壓力分流,同時(shí)也解決了“單點(diǎn)故障”問(wèn)題。任何一臺(tái)故障,都還有另外一套可供使用的服務(wù)。

不過(guò),這種方案,只能用在兩臺(tái)機(jī)器的場(chǎng)景。如果業(yè)務(wù)拓展還是很快的話,可以選擇將業(yè)務(wù)分離,建立多個(gè)主主互備。

三、 MySQL數(shù)據(jù)庫(kù)機(jī)器之間的數(shù)據(jù)同步

每當(dāng)我們解決一個(gè)問(wèn)題,新的問(wèn)題必然誕生在舊的解決方案上。當(dāng)我們有多臺(tái)MySQL,在業(yè)務(wù)高峰期,很可能出現(xiàn)兩個(gè)庫(kù)之間的數(shù)據(jù)有延遲的場(chǎng)景。并且,網(wǎng)絡(luò)和機(jī)器負(fù)載等,也會(huì)影響數(shù)據(jù)同步的延遲。我們?cè)?jīng)遇到過(guò),在日訪問(wèn)量接近1億的特殊場(chǎng)景下,出現(xiàn),從庫(kù)數(shù)據(jù)需要很多天才能同步追上主庫(kù)的數(shù)據(jù)。這種場(chǎng)景下,從庫(kù)基本失去效用了。

于是,解決同步問(wèn)題,就是我們下一步需要關(guān)注的點(diǎn)。

1. MySQL自帶多線程同步

MySQL5.6開(kāi)始支持主庫(kù)和從庫(kù)數(shù)據(jù)同步,走多線程。但是,限制也是比較明顯的,只能以庫(kù)為單位。MySQL數(shù)據(jù)同步是通過(guò)binlog日志,主庫(kù)寫(xiě)入到binlog日志的操作,是具有順序的,尤其當(dāng)SQL操作中含有對(duì)于表結(jié)構(gòu)的修改等操作,對(duì)于后續(xù)的SQL語(yǔ)句操作是有影響的。因此,從庫(kù)同步數(shù)據(jù),必須走單進(jìn)程。

2. 自己實(shí)現(xiàn)解析binlog,多線程寫(xiě)入。

以數(shù)據(jù)庫(kù)的表為單位,解析binlog多張表同時(shí)做數(shù)據(jù)同步。這樣做的話,的確能夠加快數(shù)據(jù)同步的效率,但是,如果表和表之間存在結(jié)構(gòu)關(guān)系或者數(shù)據(jù)依賴的話,則同樣存在寫(xiě)入順序的問(wèn)題。這種方式,可用于一些比較穩(wěn)定并且相對(duì)獨(dú)立的數(shù)據(jù)表。

國(guó)內(nèi)一線互聯(lián)網(wǎng)公司,大部分都是通過(guò)這種方式,來(lái)加快數(shù)據(jù)同步效率。還有更為激進(jìn)的做法,是直接解析binlog,忽略以表為單位,直接寫(xiě)入。但是這種做法,實(shí)現(xiàn)復(fù)雜,使用范圍就更受到限制,只能用于一些場(chǎng)景特殊的數(shù)據(jù)庫(kù)中(沒(méi)有表結(jié)構(gòu)變更,表和表之間沒(méi)有數(shù)據(jù)依賴等特殊表)。?

四、 在Web服務(wù)器和數(shù)據(jù)庫(kù)之間建立緩存

實(shí)際上,解決大訪問(wèn)量的問(wèn)題,不能僅僅著眼于數(shù)據(jù)庫(kù)層面。根據(jù)“二八定律”,80%的請(qǐng)求只關(guān)注在20%的熱點(diǎn)數(shù)據(jù)上。因此,我們應(yīng)該建立Web服務(wù)器和數(shù)據(jù)庫(kù)之間的緩存機(jī)制。這種機(jī)制,可以用磁盤(pán)作為緩存,也可以用內(nèi)存緩存的方式。通過(guò)它們,將大部分的熱點(diǎn)數(shù)據(jù)查詢,阻擋在數(shù)據(jù)庫(kù)之前。

1. 頁(yè)面靜態(tài)化

用戶訪問(wèn)網(wǎng)站的某個(gè)頁(yè)面,頁(yè)面上的大部分內(nèi)容在很長(zhǎng)一段時(shí)間內(nèi),可能都是沒(méi)有變化的。例如一篇新聞報(bào)道,一旦發(fā)布幾乎是不會(huì)修改內(nèi)容的。這樣的話,通過(guò)CGI生成的靜態(tài)html頁(yè)面緩存到Web服務(wù)器的磁盤(pán)本地。除了第一次,是通過(guò)動(dòng)態(tài)CGI查詢數(shù)據(jù)庫(kù)獲取之外,之后都直接將本地磁盤(pán)文件返回給用戶。

在Web系統(tǒng)規(guī)模比較小的時(shí)候,這種做法看似完美。但是,一旦Web系統(tǒng)規(guī)模變大,例如當(dāng)我有100臺(tái)的Web服務(wù)器的時(shí)候。那樣這些磁盤(pán)文件,將會(huì)有100份,這個(gè)是資源浪費(fèi),也不好維護(hù)。這個(gè)時(shí)候有人會(huì)想,可以集中一臺(tái)服務(wù)器存起來(lái),呵呵,不如看看下面一種緩存方式吧,它就是這樣做的。

2. 單臺(tái)內(nèi)存緩存

通過(guò)頁(yè)面靜態(tài)化的例子中,我們可以知道將“緩存”搭建在Web機(jī)器本機(jī)是不好維護(hù)的,會(huì)帶來(lái)更多問(wèn)題(實(shí)際上,通過(guò)PHP的apc拓展,可通過(guò)Key/value操作Web服務(wù)器的本機(jī)內(nèi)存)。因此,我們選擇搭建的內(nèi)存緩存服務(wù),也必須是一個(gè)獨(dú)立的服務(wù)。

內(nèi)存緩存的選擇,主要有redis/memcache。從性能上說(shuō),兩者差別不大,從功能豐富程度上說(shuō),Redis更勝一籌。

3. 內(nèi)存緩存集群

當(dāng)我們搭建單臺(tái)內(nèi)存緩存完畢,我們又會(huì)面臨單點(diǎn)故障的問(wèn)題,因此,我們必須將它變成一個(gè)集群。簡(jiǎn)單的做法,是給他增加一個(gè)slave作為備份機(jī)器。但是,如果請(qǐng)求量真的很多,我們發(fā)現(xiàn)cache命中率不高,需要更多的機(jī)器內(nèi)存呢?因此,我們更建議將它配置成一個(gè)集群。例如,類似redis cluster。

Redis cluster集群內(nèi)的Redis互為多組主從,同時(shí)每個(gè)節(jié)點(diǎn)都可以接受請(qǐng)求,在拓展集群的時(shí)候比較方便??蛻舳丝梢韵蛉我庖粋€(gè)節(jié)點(diǎn)發(fā)送請(qǐng)求,如果是它的“負(fù)責(zé)”的內(nèi)容,則直接返回內(nèi)容。否則,查找實(shí)際負(fù)責(zé)Redis節(jié)點(diǎn),然后將地址告知客戶端,客戶端重新請(qǐng)求。

對(duì)于使用緩存服務(wù)的客戶端來(lái)說(shuō),這一切是透明的。

內(nèi)存緩存服務(wù)在切換的時(shí)候,是有一定風(fēng)險(xiǎn)的。從A集群切換到B集群的過(guò)程中,必須保證B集群提前做好“預(yù)熱”(B集群的內(nèi)存中的熱點(diǎn)數(shù)據(jù),應(yīng)該盡量與A集群相同,否則,切換的一瞬間大量請(qǐng)求內(nèi)容,在B集群的內(nèi)存緩存中查找不到,流量直接沖擊后端的數(shù)據(jù)庫(kù)服務(wù),很可能導(dǎo)致數(shù)據(jù)庫(kù)宕機(jī))。

4. 減少數(shù)據(jù)庫(kù)“寫(xiě)”

上面的機(jī)制,都實(shí)現(xiàn)減少數(shù)據(jù)庫(kù)的“讀”的操作,但是,寫(xiě)的操作也是一個(gè)大的壓力。寫(xiě)的操作,雖然無(wú)法減少,但是可以通過(guò)合并請(qǐng)求,來(lái)起到減輕壓力的效果。這個(gè)時(shí)候,我們就需要在內(nèi)存緩存集群和數(shù)據(jù)庫(kù)集群之間,建立一個(gè)修改同步機(jī)制。

先將修改請(qǐng)求生效在cache中,讓外界查詢顯示正常,然后將這些sql修改放入到一個(gè)隊(duì)列中存儲(chǔ)起來(lái),隊(duì)列滿或者每隔一段時(shí)間,合并為一個(gè)請(qǐng)求到數(shù)據(jù)庫(kù)中更新數(shù)據(jù)庫(kù)。

除了上述通過(guò)改變系統(tǒng)架構(gòu)的方式提升寫(xiě)的性能外,MySQL本身也可以通過(guò)配置參數(shù)innodb_flush_log_at_trx_commit來(lái)調(diào)整寫(xiě)入磁盤(pán)的策略。如果機(jī)器成本允許,從硬件層面解決問(wèn)題,可以選擇老一點(diǎn)的RAID(Redundant Arrays of independent Disks,磁盤(pán)列陣)或者比較新的SSD(Solid State Drives,固態(tài)硬盤(pán))。

5. NoSQL存儲(chǔ)

不管數(shù)據(jù)庫(kù)的讀還是寫(xiě),當(dāng)流量再進(jìn)一步上漲,終會(huì)達(dá)到“人力有窮時(shí)”的場(chǎng)景。繼續(xù)加機(jī)器的成本比較高,并且不一定可以真正解決問(wèn)題的時(shí)候。這個(gè)時(shí)候,部分核心數(shù)據(jù),就可以考慮使用NoSQL的數(shù)據(jù)庫(kù)。NoSQL存儲(chǔ),大部分都是采用key-value的方式,這里比較推薦使用上面介紹過(guò)Redis,Redis本身是一個(gè)內(nèi)存cache,同時(shí)也可以當(dāng)做一個(gè)存儲(chǔ)來(lái)使用,讓它直接將數(shù)據(jù)落地到磁盤(pán)。

這樣的話,我們就將數(shù)據(jù)庫(kù)中某些被頻繁讀寫(xiě)的數(shù)據(jù),分離出來(lái),放在我們新搭建的Redis存儲(chǔ)集群中,又進(jìn)一步減輕原來(lái)MySQL數(shù)據(jù)庫(kù)的壓力,同時(shí)因?yàn)镽edis本身是個(gè)內(nèi)存級(jí)別的Cache,讀寫(xiě)的性能都會(huì)大幅度提升。

國(guó)內(nèi)一線互聯(lián)網(wǎng)公司,架構(gòu)上采用的解決方案很多是類似于上述方案,不過(guò),使用的cache服務(wù)卻不一定是Redis,他們會(huì)有更豐富的其他選擇,甚至根據(jù)自身業(yè)務(wù)特點(diǎn)開(kāi)發(fā)出自己的NoSQL服務(wù)。

6. 空節(jié)點(diǎn)查詢問(wèn)題

當(dāng)我們搭建完前面所說(shuō)的全部服務(wù),認(rèn)為Web系統(tǒng)已經(jīng)很強(qiáng)的時(shí)候。我們還是那句話,新的問(wèn)題還是會(huì)來(lái)的??展?jié)點(diǎn)查詢,是指那些數(shù)據(jù)庫(kù)中根本不存在的數(shù)據(jù)請(qǐng)求。例如,我請(qǐng)求查詢一個(gè)不存在人員信息,系統(tǒng)會(huì)從各級(jí)緩存逐級(jí)查找,最后查到到數(shù)據(jù)庫(kù)本身,然后才得出查找不到的結(jié)論,返回給前端。因?yàn)楦骷?jí)cache對(duì)它無(wú)效,這個(gè)請(qǐng)求是非常消耗系統(tǒng)資源的,而如果大量的空節(jié)點(diǎn)查詢,是可以沖擊到系統(tǒng)服務(wù)的。

在我曾經(jīng)的工作經(jīng)歷中,曾深受其害。因此,為了維護(hù)Web系統(tǒng)的穩(wěn)定性,設(shè)計(jì)適當(dāng)?shù)目展?jié)點(diǎn)過(guò)濾機(jī)制,非常有必要。

我們當(dāng)時(shí)采用的方式,就是設(shè)計(jì)一張簡(jiǎn)單的記錄映射表。將存在的記錄存儲(chǔ)起來(lái),放入到一臺(tái)內(nèi)存cache中,這樣的話,如果還有空節(jié)點(diǎn)查詢,則在緩存這一層就被阻擋了。

異地部署(地理分布式)

完成了上述架構(gòu)建設(shè)之后,我們的系統(tǒng)是否就已經(jīng)足夠強(qiáng)大了呢?答案當(dāng)然是否定的哈,優(yōu)化是無(wú)極限的。Web系統(tǒng)雖然表面上看,似乎比較強(qiáng)大了,但是給予用戶的體驗(yàn)卻不一定是最好的。因?yàn)闁|北的同學(xué),訪問(wèn)深圳的一個(gè)網(wǎng)站服務(wù),他還是會(huì)感到一些網(wǎng)絡(luò)距離上的慢。這個(gè)時(shí)候,我們就需要做異地部署,讓W(xué)eb系統(tǒng)離用戶更近。

一、 核心集中與節(jié)點(diǎn)分散

有玩過(guò)大型網(wǎng)游的同學(xué)都會(huì)知道,網(wǎng)游是有很多個(gè)區(qū)的,一般都是按照地域來(lái)分,例如廣東專區(qū),北京專區(qū)。如果一個(gè)在廣東的玩家,去北京專區(qū)玩,那么他會(huì)感覺(jué)明顯比在廣東專區(qū)卡。實(shí)際上,這些大區(qū)的名稱就已經(jīng)說(shuō)明了,它的服務(wù)器所在地,所以,廣東的玩家去連接地處北京的服務(wù)器,網(wǎng)絡(luò)當(dāng)然會(huì)比較慢。

當(dāng)一個(gè)系統(tǒng)和服務(wù)足夠大的時(shí)候,就必須開(kāi)始考慮異地部署的問(wèn)題了。讓你的服務(wù),盡可能離用戶更近。我們前面已經(jīng)提到了Web的靜態(tài)資源,可以存放在CDN上,然后通過(guò)DNS/GSLB的方式,讓靜態(tài)資源的分散“全國(guó)各地”。但是,CDN只解決的靜態(tài)資源的問(wèn)題,沒(méi)有解決后端龐大的系統(tǒng)服務(wù)還只集中在某個(gè)固定城市的問(wèn)題。

這個(gè)時(shí)候,異地部署就開(kāi)始了。異地部署一般遵循:核心集中,節(jié)點(diǎn)分散。

·?核心集中:實(shí)際部署過(guò)程中,總有一部分的數(shù)據(jù)和服務(wù)存在不可部署多套,或者部署多套成本巨大。而對(duì)于這些服務(wù)和數(shù)據(jù),就仍然維持一套,而部署地點(diǎn)選擇一個(gè)地域比較中心的地方,通過(guò)網(wǎng)絡(luò)內(nèi)部專線來(lái)和各個(gè)節(jié)點(diǎn)通訊。

·?節(jié)點(diǎn)分散:將一些服務(wù)部署為多套,分布在各個(gè)城市節(jié)點(diǎn),讓用戶請(qǐng)求盡可能選擇近的節(jié)點(diǎn)訪問(wèn)服務(wù)。

例如,我們選擇在上海部署為核心節(jié)點(diǎn),北京,深圳,武漢,上海為分散節(jié)點(diǎn)(上海自己本身也是一個(gè)分散節(jié)點(diǎn))。我們的服務(wù)架構(gòu)如圖:

需要補(bǔ)充一下的是,上圖中上海節(jié)點(diǎn)和核心節(jié)點(diǎn)是同處于一個(gè)機(jī)房的,其他分散節(jié)點(diǎn)各自獨(dú)立機(jī)房。?

國(guó)內(nèi)有很多大型網(wǎng)游,都是大致遵循上述架構(gòu)。它們會(huì)把數(shù)據(jù)量不大的用戶核心賬號(hào)等放在核心節(jié)點(diǎn),而大部分的網(wǎng)游數(shù)據(jù),例如裝備、任務(wù)等數(shù)據(jù)和服務(wù)放在地區(qū)節(jié)點(diǎn)里。當(dāng)然,核心節(jié)點(diǎn)和地域節(jié)點(diǎn)之間,也有緩存機(jī)制。?

二、 節(jié)點(diǎn)容災(zāi)和過(guò)載保護(hù)

節(jié)點(diǎn)容災(zāi)是指,某個(gè)節(jié)點(diǎn)如果發(fā)生故障時(shí),我們需要建立一個(gè)機(jī)制去保證服務(wù)仍然可用。毫無(wú)疑問(wèn),這里比較常見(jiàn)的容災(zāi)方式,是切換到附近城市節(jié)點(diǎn)。假如系統(tǒng)的天津節(jié)點(diǎn)發(fā)生故障,那么我們就將網(wǎng)絡(luò)流量切換到附近的北京節(jié)點(diǎn)上??紤]到負(fù)載均衡,可能需要同時(shí)將流量切換到附近的幾個(gè)地域節(jié)點(diǎn)。另一方面,核心節(jié)點(diǎn)自身也是需要自己做好容災(zāi)和備份的,核心節(jié)點(diǎn)一旦故障,就會(huì)影響全國(guó)服務(wù)。

過(guò)載保護(hù),指的是一個(gè)節(jié)點(diǎn)已經(jīng)達(dá)到最大容量,無(wú)法繼續(xù)接接受更多請(qǐng)求了,系統(tǒng)必須有一個(gè)保護(hù)的機(jī)制。一個(gè)服務(wù)已經(jīng)滿負(fù)載,還繼續(xù)接受新的請(qǐng)求,結(jié)果很可能就是宕機(jī),影響整個(gè)節(jié)點(diǎn)的服務(wù),為了至少保障大部分用戶的正常使用,過(guò)載保護(hù)是必要的。

解決過(guò)載保護(hù),一般2個(gè)方向:

·?拒絕服務(wù),檢測(cè)到滿負(fù)載之后,就不再接受新的連接請(qǐng)求。例如網(wǎng)游登入中的排隊(duì)。

·?分流到其他節(jié)點(diǎn)。這種的話,系統(tǒng)實(shí)現(xiàn)更為復(fù)雜,又涉及到負(fù)載均衡的問(wèn)題。

小結(jié)

Web系統(tǒng)會(huì)隨著訪問(wèn)規(guī)模的增長(zhǎng),漸漸地從1臺(tái)服務(wù)器可以滿足需求,一直成長(zhǎng)為“龐然大物”的大集群。而這個(gè)Web系統(tǒng)變大的過(guò)程,實(shí)際上就是我們解決問(wèn)題的過(guò)程。在不同的階段,解決不同的問(wèn)題,而新的問(wèn)題又誕生在舊的解決方案之上。

系統(tǒng)的優(yōu)化是沒(méi)有極限的,軟件和系統(tǒng)架構(gòu)也一直在快速發(fā)展,新的方案解決了老的問(wèn)題,同時(shí)也帶來(lái)新的挑戰(zhàn)。

php如何處理高并發(fā)

并發(fā)讀方面,多用內(nèi)存緩存。減少數(shù)據(jù)庫(kù)查詢次數(shù)。多加幾臺(tái)數(shù)據(jù)庫(kù)從服務(wù)器。

并發(fā)寫(xiě)方面,數(shù)據(jù)先走內(nèi)存隊(duì)列

分享名稱:php數(shù)據(jù)庫(kù)并發(fā)處理 php高并發(fā)實(shí)戰(zhàn)
標(biāo)題來(lái)源:http://www.muchs.cn/article2/docsgoc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、全網(wǎng)營(yíng)銷推廣Google、網(wǎng)站制作動(dòng)態(tài)網(wǎng)站、域名注冊(cè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

小程序開(kāi)發(fā)