1. 程式人生 > >為Symfony2和Redis正名,基於PHP的10億請求/周網站打造

為Symfony2和Redis正名,基於PHP的10億請求/周網站打造

【編者按】如果你還在Symfony2和Redis使用中存在這樣的錯誤觀念——不能使用Redis作為主要儲存;Symfony2的功能很多,以至於它的執行很慢,那麼不妨看向Octivi的高請求網站打造。雖然沒有底層細節,但詳細展示基於兩者應用的巨集觀特性,以及開發時的Symfony2特徵。

以下為譯文:


有人說Symfony2像其它的複雜框架一樣,很慢,但是我們認為這一切都取決使用者的本身。本文將介紹基於Symfony2,每週執行10億多個請求的應用的軟體架構細節。

下面將展示tweeting之後的社交反饋:


本文將介紹基於Symfony2和Redis的應用。在此不會有過多的細節描述,相反我們將給你展示這些應用的巨集觀特性,以及開發時的Symfony2特徵。

對於低層次的Symfony2效能優化實踐,我們寫了專門的文章——掌握Symfony2效能系列——InternalsDoctrine

首先是關於所描述應用的一些資料。

來自單個程式節點的效能統計:

  • 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. 1.5萬次撞擊/秒
  2. 1.6億個鍵
  • MySQL:
  1. 多於400 GB的資料
  2. 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(是的,我們測試過它)微框架類似的效能。

相關推薦

Symfony2Redis正名基於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 中的配置執行,能夠從零開始構建特定站點的專有爬蟲,從而為網站

struts2spring整合基於註解的方法

直接碼程式碼專案目錄1.匯入struts和spring各自需要的jar包, 再匯入兩者整合需要的jar包2.UserDao.javapackage com.ssh.dao; import org.springframework.stereotype.Repository;

給定函式返回01概率p1-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

使用shiroredis結合管理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模式連接的一些設置(win7ubuntu下以紅米1s例)

sta start .net eno bcm htm web date ati 有些手機的MTP模式在電腦上識別不了,須要一些設置才幹夠,以下就網上收集來的一些設置方法集中貼過來: 一、 win7下 參考:http://blog.ammrli.com/?p=11

虛擬機搭建redis單機版及redis-cluster使用redis desktop managerjava(eclipse)連接redis過程遇到問題匯總

init clu centos 一律 有用 tex 保護模式 bin service 如果你看到這裏,我默認你已經安裝好了redis,並且已經成功的在虛擬機的Linux系統中ping通。 介紹一下我的環境:VMware虛擬機安裝centos 6.5版的Linux系統,red

在MySQLPostgreSQL之外什麽阿裏要研發HybridDB數據庫?

出了 高性能 一點 兩個 服務 開放 增量 ews news http://www.infoq.com/cn/news/2016/12/MySQL-PostgreSQL-Greenplum 編者按 在大數據火遍IT界之前,大家對數據信息的挖掘通常聚焦在BI(Busine

通過pandoc轉化markdowndocxhtml

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如何做持久化:可以每隔一定時間將數據集導出到磁盤(快照),或者追加到命令日誌中,會在執行寫命令時,