為Symfony2和Redis正名,基於PHP的10億請求/周網站打造
【編者按】如果你還在Symfony2和Redis使用中存在這樣的錯誤觀念——不能使用Redis作為主要儲存;Symfony2的功能很多,以至於它的執行很慢,那麼不妨看向Octivi的高請求網站打造。雖然沒有底層細節,但詳細展示基於兩者應用的巨集觀特性,以及開發時的Symfony2特徵。
以下為譯文:有人說Symfony2像其它的複雜框架一樣,很慢,但是我們認為這一切都取決使用者的本身。本文將介紹基於Symfony2,每週執行10億多個請求的應用的軟體架構細節。
下面將展示tweeting之後的社交反饋:
本文將介紹基於Symfony2和Redis的應用。在此不會有過多的細節描述,相反我們將給你展示這些應用的巨集觀特性,以及開發時的Symfony2特徵。
對於低層次的Symfony2效能優化實踐,我們寫了專門的文章——掌握Symfony2效能系列——Internals 和Doctrine
首先是關於所描述應用的一些資料。
來自單個程式節點的效能統計:
- Symfony2例項每秒處理700個請求,每個請求平均響應時間30毫秒
- Varnish每秒處理12000多個請求(通過壓力測試獲得)
注意,如下面所描述的,整個平臺包括許多這種節點
Redis度量:
- 1.6億多個鍵(其中98%是永久儲存);
- 89% hits—也就是說,只有11%的交易到達MYSQL伺服器。
棧結構
應用
所有的流量都會流入HAProxy,HAProxy將流量分配給應用伺服器。
應用例項前是Varnish Reverse Proxy。
我們保持Varnish在每個應用的伺服器都保持高度可用性——沒有單點故障。單個Varnish分配流量可能導致風險。分離的Varnish例項可能降低快取hit,不過我們可以接受這個。我們對可用性的需求高於對效能的需要,不過你可以從這些數字中看到,效能也不是什麼問題。
應用的伺服器配置:
- Xeon [email protected], 64GB RAM, SATA
- Apache2 (我們甚至不用nginx)
- PHP5.4.X以PHP-FPM運作,伴隨APC
資料儲存
我們使用Redis和MySQL儲存資料,它們的數字還挺大的:
- Redis:
- 1.5萬次撞擊/秒
- 1.6億個鍵
- MySQL:
- 多於400 GB的資料
- 3億份記錄
我們即使用Redis作為永久儲存(用的最多的資源),又使用Redis作為MySQL上的快取層。與典型的快取相比,Redis儲存資料的比率很高——我們儲存1.55億多個永久型別鍵和僅500萬個緩衝鍵。實際上,我們可以使用Redis作為主要的資料儲存。
Redis配有主從設定。通過這種方式我們獲得HA——如果發生執行中斷我們可以很快的將主節點切換到某一個從節點。一些管理任務如升級也需要這些配置。在升級節點時,我們可以選擇新的主節點,然後升級先前的主節點,最後交換兩個節點。
我們仍在等待生產就緒的Redis叢集,這些叢集可以提供類似自動故障恢復(升級節點時即使是手動故障恢復也會方便的多)的功能。不過目前還沒有任何關於官方釋出日期的訊息。
MySQL通常用作非耗盡資源的第三層快取層(Varnish > Redis > MySQL)。所有的表都是InnoDB,最多的查詢是簡單的
SELECT ... WHERE 'id'={ID}這個查詢返回單個結果。我們還沒有發現這麼設定會有什麼效能問題。
與Redis設定不同,MySQL執行在主配置上,除高可用性外,這還提供了更好的寫效能(在Redis中這不是什麼問題,因為我們不會耗盡效能特性。)
Application’s Architecture
Symfony2功能
Symfony有一些很棒的功能,這些功能使開發過程變得更容易,下面我們紹開發者最喜歡的一些功能:
註釋
我們使用帶註釋的Symfony2標準分佈:
- 路由選擇——路由定義了應用的URL—我們也測試了Apache的愚蠢的路由規則,但它沒有任何的主要優化。
- 服務容器——我們使用JMSDiExtraBundle的服務註釋定義我們的DI容器—這加速了開發,允許我們用PHP程式碼處理服務定義,我們發現PHP程式碼更可讀。
因為應用用作REST API,所以我們主要不使用模板(例如Twig)。我們保留模板主要是為了一些內部的儀表盤面板。
我們還沒有發現不同的配置型別(YAML/XML)帶來的效能影響。因為所有的註釋都很好的儲存下來了,所以沒有什麼令人費解的地方—最後所有的東西都是純PHP程式碼。
下面是我們使用JMSDiExtraBundle獲得的服務配置樣例:
/** * Constructor uses JMSDiExtraBundle for dependencies injection. * * @InjectParams({ * "em" = @Inject("doctrine.orm.entity_manager"), * "security" = @Inject("security.context") * }) */ function __construct(EntityManager $em, SecurityContext $security) { $this->em = $em; $this->security = $security; }
通過這種方式,改變類依賴項只需要改變程式碼。
Symfony2監控—Monolog和Stopwatch
應用使用Monolog記錄意料之外的行為,捕獲錯誤資訊。我們使用多個通道獲取不同應用模組的分離的日誌。
因為FingersCrossed handler使用較多記憶體(可能導致記憶體洩漏),所以我們不再使用它。我們選用適當的StreamHandler。使用這種方式時我們需要在單行日誌資訊新增冗餘和額外的內容。
我們也在很多地方使用Stopwatch元件以控制一些典型的應用方法。通過這種方式我們可以發現客製化邏輯一些大塊中的弱點。
例如,我們追蹤一些外部網路服務的請求次數:
if (null !== $this->stopwatch) { $this->stopwatch->start('my_webservice', 'request'); } // Makes a CURL request to some my_webservice $response = $this->request($args); if (null !== $this->stopwatch) { $this->stopwatch->stop('my_webservice'); }
控制檯元件
開發和維護時,我們特別喜歡Symfony控制檯元件,這個元件為建立CLI工具提供了很好的面向物件介面。應用大概添加了50%的新功能,這些新功能基於CLI指令,主要用作管理或分析應用內部構件。
控制檯元件妥善的處理命令語句或選項—你可以設定預設值,可選值或所需的值。好的實踐總是將這些恰當的記錄為程式碼—你可以給命令和選項設定主要描述。命令通常是自我文件的,因為新增--help選項便能生成格式化的指令描述。
$ php app/console octivi:test-command --help Usage: octivi:test-command [-l|--limit[="..."]] [-o|--offset[="..."]] table Arguments: table Database table to process Options: --limit (-l) Limit per SQL query. (default: 10) --offset (-o) Offset for the first statement(default: 0)
我們必須牢記在準確設定的環境下執行指令。預設的dev可能會導致一些問題,如記憶體洩漏(因為更多冗長的日誌儲存和儲存除錯資訊)。
$ php app/console octivi:test-command --env=prod
想要更好的資訊顯示,新增-v選項。
$ php app/console octivi:test-command --env=prod -vvv
進度條是一個很好的幫手。進度條甚至考慮了資訊顯示詳細程度,當程度比較低時,只顯示基本資訊,程度比較高時,還可以顯示執行時間,記憶體消耗等資訊。
此外,我們還有一些耗時大約兩天的遷移過程—0記憶體洩漏—沒有進度條,監控它們將是災難。
資料層
對於Redis,資料層我們使用PredisBundle。
我們拒絕Doctrine ORM,因為它將新增額外費用,而且我們不需要任何高階的面向物件操作。我們使用Doctrine DBAL代替,Doctrine DBAL特徵如下:
- 查詢生成器
- 預處理語句
使用PredisBundle和Doctrine Bundle也允許我們在大量使用分析工具的時候監控弱查詢。
總結
多虧Symfony2,這種設定在保持高效能和高可用性的同時保持了友善的開發環境——可維持,穩定。實際上這是用作電商網站的關鍵子系統的關鍵業務需求。
因此本文的最後我們可以糾正一些錯誤觀點:
- 不能使用Redis作為主要儲存——如我們先前所說的,當然是可以的!Redis是一項很穩定的技術,有一些持續性機制,你不會丟失關鍵資料。
- Symfony2功能很多以至於它很慢——當你不使用例如ORM的一些耗時/記憶體的工具時,你可以獲得和Silex(是的,我們測試過它)微框架類似的效能。
相關推薦
為Symfony2和Redis正名,基於PHP的10億請求/周網站打造
【編者按】如果你還在Symfony2和Redis使用中存在這樣的錯誤觀念——不能使用Redis作為主要儲存;Symfony2的功能很多,以至於它的執行很慢,那麼不妨看向Octivi的高請求網站打造。雖然沒有底層細節,但詳細展示基於兩者應用的巨集觀特性,以及開發時的Symfony2特徵。 以下為譯文: 有
grad-cam 、cam 和熱力圖,基於keras的實現
abs guide ring 不一定 作用 自然 team 拍攝 類別 http://bindog.github.io/blog/2018/02/10/model-explanation/ http://www.sohu.com/a/216216094_473283 h
實現簡易字串壓縮演算法:由字母a-z或者A-Z組成,將其中連續出現2次以上(含2次)的字母轉換為字母和出現次數,
@Test public void test1(){ String content1 = "AAAAAAAAAAAAAAAAAAAAAAAAttBffgfaaddddddsCDaaaBBBBdddfdsgggggg"; String result = yasuo(content1);
為加密貨幣行業正名,烏克蘭制定四年監管計劃
據coindoo10月27日報道,烏克蘭政府正在著手批准旨在將數字貨幣合法化的政策,該政策由烏克蘭經濟發展和貿易部負責制定。 烏克蘭政府正尋求通過財政部啟動監管計劃,致力於制定明晰的監管條例以推動加密貨幣和代幣生態系統的發展。 在烏克蘭,加密貨幣的法律地位尚不明晰
spring 和 redis整合,並且使用redis做session快取伺服器
所需jar commons-pool2-2.0.jar jedis-2.9.0.jar spring-data-redis-1.6.2.RELEASE.jar spring-session-1.2.1.RELEASE.jar 一 . xml配
網頁搜取和部分擷取,基於Heritrix
本文由淺入深,詳細介紹了 Heritrix 在 Eclipse 中的配置、執行。最後對其進行擴充套件,介紹如何實現只抓取特定網站的頁面。 通過本文,讀者可以瞭解 Heritrix 的相關特點以及在 Eclipse 中的配置執行,能夠從零開始構建特定站點的專有爬蟲,從而為網站
struts2和spring整合,基於註解的方法
直接碼程式碼專案目錄1.匯入struts和spring各自需要的jar包, 再匯入兩者整合需要的jar包2.UserDao.javapackage com.ssh.dao; import org.springframework.stereotype.Repository;
給定函式返回01概率為p和1-p,根據這個函式建構函式使得返回01的概率一樣
分析 概率問題,並且讓返回值概率一樣,但是這個函式的返回值是不一樣的P(1)=1-p,P(0)=p; P(1)*P(0)=(1-p)*p=p-p^2; P(1)*P(1)=p*p P(0)*
redis 主從,基於sentinel 自動切換
#redis 主從 #gcc yum install gcc -y #授權 chmod -R 777 /usr/local/bin mkdir redis cd redis/ wget http://download.redis.io/releases/redis-3.2
jqgrid表頭合併和行合併,基於jquery指令碼外掛
下面的js是近期寫的一個jqgrid表頭與行合併指令碼。jqgrid也真是,表頭合併的功能都不提供,用起來好尷尬。 使用方法:在jqgrid的loadComplete或者gridComplete事件中使用。 程式碼不是最優化的,希望大家一起改進它。謝謝 /* * jQ
使用shiro和redis結合,管理SessionDAO的對Session的CRUD,並原始碼分析
SessionDAO的作用是為Session提供CRUD並進行持久化的一個shiro元件,將整合redis快取進行開發 由配置檔案可以知道sessionManager需要注入一個sessionDao <!-- 自定義會話管理配置 --> <bean i
5G未來十年將為傳媒和娛樂業帶來1.3萬億美元營收
據國外媒體報道,目前多個國家在加速推動5G的商用,5G未來也將給多個行業帶來可觀的經濟效益,研究報告就預計,5G在未來十年將為傳媒和娛樂產業帶來1.3萬億美元的新營收。 5G未來十年將為傳媒和娛樂產業帶來1.3萬億美元新營收,出自英特爾委託、Ovum具體進行的名為“5G娛樂
Redis分布式鎖,基於StringRedisTemplate和基於Lettuce實現setNx
timeout out light 代碼 efault enum img 時間 comm 使用redis分布式鎖,來確保多個服務對共享數據操作的唯一性一般來說有StringRedisTemplate和RedisTemplate兩種redis操作模板。 根據key-valu
關於Android手機MTP模式連接的一些設置(win7和ubuntu下,以紅米1s為例)
sta start .net eno bcm htm web date ati 有些手機的MTP模式在電腦上識別不了,須要一些設置才幹夠,以下就網上收集來的一些設置方法集中貼過來: 一、 win7下 參考:http://blog.ammrli.com/?p=11
虛擬機搭建redis單機版及redis-cluster,使用redis desktop manager和java(eclipse)連接redis過程遇到問題匯總
init clu centos 一律 有用 tex 保護模式 bin service 如果你看到這裏,我默認你已經安裝好了redis,並且已經成功的在虛擬機的Linux系統中ping通。 介紹一下我的環境:VMware虛擬機安裝centos 6.5版的Linux系統,red
在MySQL和PostgreSQL之外,為什麽阿裏要研發HybridDB數據庫?
出了 高性能 一點 兩個 服務 開放 增量 ews news http://www.infoq.com/cn/news/2016/12/MySQL-PostgreSQL-Greenplum 編者按 在大數據火遍IT界之前,大家對數據信息的挖掘通常聚焦在BI(Busine
通過pandoc,轉化markdown為docx和html
pandoc blog cnblogs brush -o doc true .html ocx 轉化為docx pandoc -f markdown -t docx collection.markdown -o api.docx 轉化為html pandoc coll
epoll的水平觸發和邊緣觸發,以及邊緣觸發為什麽要使用非阻塞IO
alt 開啟 本機 另一個 trigger stdio.h 什麽 我們 水平 轉自:http://www.cnblogs.com/yuuyuu/p/5103744.html 一.基本概念
redis安裝,語法和Python連接
redis程序下載http://down.51cto.com/data/2440789:點擊客戶端進行連接測試,出現下圖說明測試成功語法:redis的字符串操作 set(key,value,ex=None,px=None,nx=False,xx=False) 在redis中設置值,默認,不存在則創建,
redis的作用和redis為什麽那麽快
內存操作 red 操作 硬盤 不存在 如何 作用 快速 hashmap 1 redis的作用: 用redis做緩存,redis可以用作數據庫,緩存和消息中間件。 redis如何做持久化:可以每隔一定時間將數據集導出到磁盤(快照),或者追加到命令日誌中,會在執行寫命令時,