日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > 互聯(lián)網(wǎng) > 使用HAProxy、PHP、Redis和MySQL支撐10億請求每周架構(gòu)細(xì)節(jié)

使用HAProxy、PHP、Redis和MySQL支撐10億請求每周架構(gòu)細(xì)節(jié)

來源:程序員人生   發(fā)布時(shí)間:2014-09-25 02:20:09 閱讀次數(shù):3857次

【編者按】在公司的發(fā)展中,保證服務(wù)器的可擴(kuò)展性對(duì)于擴(kuò)大企業(yè)的市場需要具有重要作用,因此,這對(duì)架構(gòu)師提出了一定的要求。Octivi聯(lián)合創(chuàng)始人兼軟件架構(gòu)師Antoni Orfin將向你介紹一個(gè)非常簡單的架構(gòu),使用HAProxy、PHP、Redis和MySQL就能支撐每周10億請求。同時(shí),你還能了解項(xiàng)目未來的橫向擴(kuò)展途徑及常見的模式。

以下為譯文:


在這篇文章中,我將展示一個(gè)非常簡單的架構(gòu),使用HAProxy、PHP、Redis和MySQL支撐每周10億請求。除此之外,我還將展示項(xiàng)目未來的橫向擴(kuò)展途徑及常見的模式,下面我們一起看細(xì)節(jié)。

狀態(tài):

  • 服務(wù)器

  1. 3個(gè)應(yīng)用程序節(jié)點(diǎn)
  2. 2個(gè)MySQL+1個(gè)備份
  3. 2個(gè)Redis

  • 應(yīng)用程序

  1. 應(yīng)用程序每周處理10億請求
  2. 峰值700請求每秒的單Symfony2實(shí)例(平均工作日約550請求每秒)
  3. 平均響應(yīng)時(shí)間30毫秒
  4. Varnish,每秒請求超過1.2萬次(壓力測試過程中獲得)

  • 數(shù)據(jù)存儲(chǔ)

  1. Redis儲(chǔ)存了1.6億記錄,數(shù)據(jù)體積大約100GB,同時(shí)它是我們的主要數(shù)據(jù)存儲(chǔ)
  2. MySQL儲(chǔ)存了3億記錄,數(shù)據(jù)體積大約300GB,通常情況下它作為三級(jí)緩存層

平臺(tái):


  • 監(jiān)視:

  1. Icinga
  2. Collectd

  • 應(yīng)用程序

  1. HAProxy + Keepalived
  2. Varnish
  3. PHP(PHP-FPM)+ Symfony2 Framework

  • 數(shù)據(jù)存儲(chǔ)

  1. MySQL(主從配置),使用HAProxy做負(fù)載均衡
  2. Redis (主從配置)

背景

大約1年前,一個(gè)朋友找到我并提出了一個(gè)苛刻的要求:它們是一個(gè)飛速發(fā)展的電子商務(wù)初創(chuàng)公司,而當(dāng)時(shí)已經(jīng)準(zhǔn)備向國際發(fā)展。介于那個(gè)時(shí)候他們?nèi)匀皇且粋€(gè)創(chuàng)業(yè)公司,初始解決方案必須符合所謂的成本效益,因此也就無法在服務(wù)器上投入更多的資金。遺留系統(tǒng)使用了標(biāo)準(zhǔn)的LAMP堆棧,因此他們擁有一個(gè)強(qiáng)力的PHP開發(fā)團(tuán)隊(duì)。如果必須引入新技術(shù)的話,那么這些技術(shù)必須足夠簡單,不會(huì)存在太多架構(gòu)上的復(fù)雜性;那么,他們當(dāng)下的技術(shù)團(tuán)隊(duì)就可以對(duì)應(yīng)用進(jìn)行長期的維護(hù)。

為了滿足他們擴(kuò)展到下一個(gè)市場的需求,架構(gòu)師必須使用可擴(kuò)展理念進(jìn)行設(shè)計(jì)。首先,我們審視了他們的基礎(chǔ)設(shè)施:



老系統(tǒng)使用了單模塊化設(shè)計(jì)思路,底層是一些基于PHP的Web應(yīng)用程序。這個(gè)初創(chuàng)公司有許多所謂的前端網(wǎng)站,它們大多都使用了獨(dú)立的數(shù)據(jù)庫,并共享了一些支撐業(yè)務(wù)邏輯的通用代碼。毫不客氣的說,長期維護(hù)這種應(yīng)用程序絕對(duì)是一個(gè)噩夢:因?yàn)殡S著業(yè)務(wù)的發(fā)展,有些代碼必須被重寫,這樣的話,修改某個(gè)網(wǎng)站將不可避免導(dǎo)致業(yè)務(wù)邏輯上的不一致,這樣一來,他們不得不在所有Web應(yīng)用程序上做相同的修改。

通常情況下,這該歸結(jié)于項(xiàng)目管理問題,管理員必須對(duì)橫跨多個(gè)代碼庫的那些代碼負(fù)責(zé)?;谶@個(gè)觀點(diǎn),整改第一步就是提取核心的業(yè)務(wù)關(guān)鍵功能,并將之拆分為獨(dú)立的服務(wù)(這也是本文的一個(gè)重點(diǎn)部分),也就是所謂的面向服務(wù)架構(gòu),在整個(gè)系統(tǒng)內(nèi)遵循“separation of concern”原則。每個(gè)服務(wù)只負(fù)責(zé)一個(gè)業(yè)務(wù)邏輯,同時(shí)也要明確更高等級(jí)的業(yè)務(wù)功能。舉個(gè)形象的例子也就是,這個(gè)系統(tǒng)可能是個(gè)搜索引擎、一個(gè)銷售系統(tǒng)等。

前端網(wǎng)站通過REST API與服務(wù)交互,響應(yīng)則基于JSON格式。為了簡單起見,我們沒有選擇SOAP,一個(gè)開發(fā)者比較無愛的協(xié)議,因?yàn)檎l都不愿意解析一堆的XML。

提取一些不會(huì)經(jīng)常處理的服務(wù),比如身份驗(yàn)證和會(huì)話管理。這是非常必要的一個(gè)環(huán)節(jié),因?yàn)樗鼈兊奶幚淼燃?jí)比較高。前端網(wǎng)站負(fù)責(zé)這個(gè)部分,只有它們可以識(shí)別用戶。這樣一來我們可以保持服務(wù)的足夠簡單,在處理擴(kuò)展和代碼相關(guān)問題時(shí)都具有巨大的優(yōu)勢,可謂各司其職,完美無缺。

帶來的好處:

  • 獨(dú)立子系統(tǒng)(服務(wù))可以便捷的在不同團(tuán)隊(duì)中開發(fā),開發(fā)者互不干涉,效率理所當(dāng)然提升。
  • 身份驗(yàn)證和會(huì)話不會(huì)通過它們來管理,因此它們造成的擴(kuò)展問題不翼而飛。
  • 業(yè)務(wù)邏輯被區(qū)分,不同的前端網(wǎng)站不會(huì)再存在功能冗余。
  • 顯著地提高了服務(wù)的可用性。

共生的缺點(diǎn):

為系統(tǒng)管理員帶來更大的工作量。鑒于服務(wù)都使用了獨(dú)立的基礎(chǔ)設(shè)施,這將給管理員帶來更多需要關(guān)注的地方。

很難保持向后兼容。在一年的維護(hù)之后,API方法中發(fā)生了數(shù)不盡的變化。因此問題發(fā)生了,它們必將破壞向后兼容,因?yàn)槊總€(gè)網(wǎng)站的代碼都可能發(fā)生變化,還可能存在許多技術(shù)人員同時(shí)修改一個(gè)網(wǎng)站的情況……然而,一年后,所有方法匹配的仍然是項(xiàng)目開始時(shí)建立的文檔。

應(yīng)用程序?qū)?/b>


著眼請求工作流,第一層是應(yīng)用程序。HAProxy負(fù)載均衡器、Varnish和Symfony2應(yīng)用程序都在這一層。來自前端網(wǎng)站的請求首先會(huì)傳遞給HAProxy,隨后負(fù)載均衡器將把他分給不同的節(jié)點(diǎn)。

應(yīng)用程序節(jié)點(diǎn)配置

  • Xeon E5-1620@3.60GHz,64GB RAM,SATA
  • Varnish
  • Apache2
  • PHP 5.4.X(PHP-FPM),使用APC字節(jié)碼緩存

我們購買了3個(gè)這樣的服務(wù)器,N+1冗余配置的active-active模式,備份服務(wù)器同樣處理請求。因?yàn)樾阅懿皇鞘滓蛩兀覀優(yōu)槊總€(gè)節(jié)點(diǎn)配置獨(dú)立的Varnish以降低緩存hit,同時(shí)也避免了單點(diǎn)故障(SPOF)。在這個(gè)項(xiàng)目中,我們更重視可用性。因?yàn)橐粋€(gè)前端網(wǎng)站服務(wù)器中使用了Apache 2,我們保留了這個(gè)堆棧。這樣一來,管理員不會(huì)困擾于太多新加入的技術(shù)。

Symfony2應(yīng)用程序

應(yīng)用程序本身基于Symfony2建立,這是一個(gè)PHP全堆??蚣?,提供了大量加速開發(fā)的組件。作為基于復(fù)雜框架的典型REST服務(wù)可能受到很多人質(zhì)疑,這里為你細(xì)說:

  • 對(duì) PHP/Symfony 開發(fā)者友好。客戶端IT團(tuán)隊(duì)由PHP開發(fā)者組成,添加新技術(shù)將意味必須招聘新的開發(fā)者,因?yàn)闃I(yè)務(wù)系統(tǒng)必須做長時(shí)間的維護(hù)。
  • 清晰的項(xiàng)目結(jié)構(gòu)。 PHP/Symfony雖然從來都不是必需品,但卻是許多項(xiàng)目的默認(rèn)選擇。引入新的開發(fā)者將非常方便,因?yàn)閷?duì)他們來說代碼非常友好。
  • 許多現(xiàn)成的組件。遵循DRY思想……沒有人愿意花力氣去做重復(fù)的工作,我們也不例外。我們使用了大量的Symfony2 Console Component,這個(gè)框架非常有利于做CLI命令,以及應(yīng)用程序性能分析(debug工具欄)、記錄器等。

在選用Symfony2之前,我們做了大量的性能測試以保證應(yīng)用程序可以支撐計(jì)劃流量。我們制定了概念驗(yàn)證,并使用JMeter執(zhí)行,我們得到了讓人滿意的結(jié)果――每秒700請求時(shí)響應(yīng)時(shí)間可以控制在50毫秒。這些測試給了我們足夠的信心,讓我們堅(jiān)信,即使Symfony2這樣復(fù)雜的框架也可以得到理想的性能。

應(yīng)用程序分析與監(jiān)控

我們使用Symfony2工具來監(jiān)視應(yīng)用程序,在收集指定方法執(zhí)行時(shí)間上表現(xiàn)的非常不錯(cuò),特別是那些與第三方網(wǎng)絡(luò)服務(wù)交互的操作。這樣一來,我們可以發(fā)現(xiàn)架構(gòu)中潛在的弱點(diǎn),找出應(yīng)用程序中最耗時(shí)的部分。

冗長的日志同樣是不可缺少的一部分,我們使用PHP Monolog庫把這些日志處理成優(yōu)雅的log-lines,便于開發(fā)者和管理員理解。這里需要注意的是盡可能多地添加細(xì)節(jié),越詳細(xì)越好,我們使用了不同的日志等級(jí):

  • Debug,可能會(huì)發(fā)生的事情。比如,請求信息在調(diào)用前會(huì)傳送給一個(gè)外部Web服務(wù);事情發(fā)生后從API調(diào)用響應(yīng)。
  • Error,當(dāng)錯(cuò)誤發(fā)生時(shí)請求流并未被終止,比如第三方API的錯(cuò)誤響應(yīng)。
  • Critical,應(yīng)用程序崩潰的瞬間。

因此,你可以清晰地了解Error和Critical信息。而在開發(fā)/測試環(huán)境中,Debug信息同樣被記錄。同時(shí),日志被存儲(chǔ)在不同的文件中,也就是Monolog庫下的“channels”。系統(tǒng)中有一個(gè)主日志文件,記錄了所有應(yīng)用程序級(jí)錯(cuò)誤,以及各個(gè)channel的短日志,從單獨(dú)的文件中記錄了來自各個(gè)channel的詳細(xì)日志。

擴(kuò)展性

擴(kuò)展平臺(tái)的應(yīng)用程序?qū)硬⒉焕щy,HAProxy性能并不會(huì)在短時(shí)間耗盡,唯一需要考慮的就是如何冗余以避免單點(diǎn)故障。因此,當(dāng)下需要做的只是添加下一個(gè)應(yīng)用程序節(jié)點(diǎn)。

數(shù)據(jù)層

我們使用Redis和MySQL存儲(chǔ)所有的數(shù)據(jù),MySQL更多作為三級(jí)緩存層,而Redis則是系統(tǒng)的主要數(shù)據(jù)存儲(chǔ)。

Redis

在系統(tǒng)設(shè)計(jì)時(shí),我們基于以下幾點(diǎn)來選擇滿足計(jì)劃需求的數(shù)據(jù)庫:

  • 在存儲(chǔ)大量數(shù)據(jù)時(shí)不會(huì)影響性能,大約2.5億記錄
  • 通常情況下多是基于特定資源的簡單GET請求,沒有查找及復(fù)雜的SELECT操作
  • 在單請求時(shí)盡可能多的獲得資源以降低延時(shí)

在經(jīng)過一些調(diào)查后,我們決定使用Redis

  • 大部分我們執(zhí)行的操作都具有 O(1)或O(N)復(fù)雜性, N是需要檢索鍵的數(shù)量,這意味著keyspace大小并不會(huì)影響性能。
  • 通常情況下會(huì)使用MGET命令行同時(shí)檢索100個(gè)以上的鍵,這樣可以盡可能的避免網(wǎng)絡(luò)延時(shí),而不是在循環(huán)中做多重GET操作。

我們當(dāng)下?lián)碛袃蓚€(gè)Redis服務(wù)器,使用主從復(fù)制模式。這兩個(gè)節(jié)點(diǎn)的配置相同,都是Xeon E5-2650v2@2.60GHz,128GB,SSD。內(nèi)存限制被設(shè)置為100GB,通常情況下使用率都是100%。


在應(yīng)用程序并沒有耗盡單個(gè)Redis服務(wù)器的所有資源時(shí),從節(jié)點(diǎn)主要作作備份使用,用以保證高有效性。如果主節(jié)點(diǎn)宕機(jī),我們可以快速的將應(yīng)用程序切換到從節(jié)點(diǎn)。在維護(hù)和服務(wù)器遷移時(shí),復(fù)制同樣被執(zhí)行――轉(zhuǎn)換一個(gè)服務(wù)器非常簡單。

你可能會(huì)猜想當(dāng)Redis資源被一直耗盡時(shí)的情景,所有的鍵都是持久化類型,大約占90% keyspace,剩余資源被全部被用于TTL過期緩存。當(dāng)下,keyspace已經(jīng)被分為兩個(gè)部分:一個(gè)是TTL集(緩存),另一個(gè)則是用于持久化數(shù)據(jù)。感謝“volatile-lru”最大化內(nèi)存設(shè)置的可行性,最不經(jīng)常使用緩存鍵會(huì)被移除。如此一來,系統(tǒng)就可以一直保持單Redis實(shí)例同時(shí)執(zhí)行兩個(gè)操作――主存儲(chǔ)和通用緩存。

使用這個(gè)模式必須一直監(jiān)視“期滿”鍵的數(shù)量:

db.redis1:6379> info keyspace

# Keyspace

db0:keys=16XXXXXXX,expires=11XXXXXX,avg_ttl=0

“期滿”鍵數(shù)量越接近0情況越危險(xiǎn),這個(gè)時(shí)候管理員就需要考慮適當(dāng)?shù)姆制蛘呤窃黾觾?nèi)存。

我們?nèi)绾芜M(jìn)行監(jiān)控?這里使用Icinga check,儀表盤會(huì)顯示數(shù)字是否會(huì)達(dá)到臨界點(diǎn),我們還使用了Redis來可視化“丟失鍵”的比率。


在一年后,我們已經(jīng)愛上了Redis,它從未讓我們失望,這一年系統(tǒng)從未發(fā)生任何宕機(jī)情況。

MySQL

在Redis之外,我們還使用了傳統(tǒng)RDBMS――MySQL。但是區(qū)別于他人,我們通常使用它作為三級(jí)緩存層。我們使用MySQL存儲(chǔ)一些不會(huì)經(jīng)常使用對(duì)象以降低Redis的資源使用率,因此它們被放到了硬盤上。這里沒有什么可說道的地方,我們只是盡可能地讓其保持簡單。我們使用了兩個(gè)MySQL服務(wù)器,配置是Xeon E5-1620@3.60GHz,64GB RAM,SSD。兩個(gè)服務(wù)器使用本地、異步的主-主復(fù)制。此外,我們使用一個(gè)單獨(dú)的從節(jié)點(diǎn)作為備份。

MySQL的高可用性

在應(yīng)用程序中,數(shù)據(jù)庫永遠(yuǎn)是最難的瓶頸。當(dāng)前,這里還不需要考慮橫向擴(kuò)展操作,我們多是縱向擴(kuò)展Redis和MySQL服務(wù)器。當(dāng)下這個(gè)策略還存在一定的發(fā)展空間,Redis運(yùn)行在一個(gè)126GB內(nèi)存的服務(wù)器上,擴(kuò)展到256GB也并不困難。當(dāng)然,這樣的服務(wù)器也存在劣勢,比如快照,又或是是簡單的啟動(dòng)――Redis服務(wù)器啟動(dòng)需要很長的時(shí)間。

在縱向擴(kuò)展失效后進(jìn)行的必然是橫向擴(kuò)展,值得高興的是,項(xiàng)目開始時(shí)我們就為數(shù)據(jù)準(zhǔn)備了一個(gè)易于分片的結(jié)構(gòu):

在Redis中,我們?yōu)橛涗浭褂昧?個(gè)“heavy”類型。基于數(shù)據(jù)類型,它們可以分片到4個(gè)服務(wù)器上。我們避免使用哈希分片,而是選擇基于記錄類型分片。這種情況下,我們?nèi)匀豢梢赃\(yùn)行MGET,它始終在一種類型鍵上執(zhí)行。

在MySQL上,結(jié)構(gòu)化的表格非常易于向另一臺(tái)服務(wù)器上遷移――同樣基于記錄類型(表格)。當(dāng)然,一旦基于記錄類型的分片不再奏效,我們將轉(zhuǎn)移至哈希。

學(xué)到的知識(shí)

  • 不要共享你的數(shù)據(jù)庫。一旦一個(gè)前端網(wǎng)站期望切換會(huì)話處理到Redis,Redis緩存空間將被耗盡,同時(shí)它會(huì)拒絕應(yīng)用程序保存下一個(gè)緩存鍵。這樣一來所有的緩存將轉(zhuǎn)至MySQL服務(wù)器,這將導(dǎo)致大量開銷。
  • 日志越詳細(xì)越好。如果log-lines中沒有足夠的信息,快速Debug問題定位將成為難點(diǎn)。如此一來,你不得不等待一個(gè)又一個(gè)問題發(fā)生,直到找到根結(jié)所在。
  • 架構(gòu)中使用復(fù)雜的框架并不意味著低性能。許多人驚訝我們使用全堆棧框架來支撐如此流量應(yīng)用程序,其秘訣在于更聰明的使用工具,否則即使是Node.js也可能變得很慢。選擇一個(gè)提供良好開發(fā)環(huán)境的技術(shù),沒有人期望使用一堆不友好的工具,這將降低開發(fā)團(tuán)隊(duì)士氣。

原文鏈接: The Easy Way Of Building A Growing Startup Architecture Using HAProxy, PHP, Redis And MySQL To Handle 1 Billion Requests A Week(翻譯/童陽 責(zé)編/仲浩)

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 国产又爽又黄免费视频 | 久久精品麻豆 | av网站在线免费观看 | 综合久久精品 | 日韩欧美在线免费 | 国产日韩欧美在线 | 久久久午夜视频 | 免费日韩av在线 | 精品欧美一区二区三区在线观看 | 图片区自拍偷拍 | 国产亚洲欧美另类一区二区三区 | 中文字幕不卡在线观看 | 国产三级久久久 | 午夜国产视频 | 欧美日韩在线免费观看 | 激情视频国产 | 久热导航| 日韩高清免费在线 | 91久久精品国产91久久 | 日韩欧美激情电影 | 日韩精品在线观看一区 | 久久久电影 | 精品国产一二三区 | 亚洲综合成人网 | 国产精品中文字幕在线观看 | 中文字字幕一区二区三区四区五区 | 成人精品毛片 | 久久久一区二区三区 | 欧洲视频一区 | 成人欧美一区二区三区视频xxx | 综合久久综合 | 欧美日韩一区二区三区不卡 | av一级免费观看 | 一级特黄录像免费观看 | 亚洲欧美中文日韩在线v日本 | 久久婷婷丁香 | 6080av | 欧美性一区二区 | 国产激情久久久久影院小草 | 国产一区二区三区免费在线观看 | 国产二区久久 |