Facebook用戶量大的問題由它的分佈式緩存系統主要解決,剩下的天然是開源的mysql更合適了php
上圖是Facebook的photo訪問服務圖,實際上你能夠看見,數據庫是在最末端,Cache層已經服務了90%的需求,對於熱點圖片命中率接近100%,不是說數據庫已經不重要了,而是這種重要性下降了,數據庫並非直接與用戶進行交互,中間隔了好幾層高速Cache,在這種狀況下,用本身定製的(注意是定製的)免費的Mysql已經足以知足這彙總需求,何須再去花更多的錢了?html
\n前端
同時,Facebook上全部用戶進行讀的操做遠大於其寫的操做,所以Cassandra這樣的寫很是快的NoSQL數據庫,Facebook並無採用。node
Craigslist使用了Mongodb,Amazon使用了SimpleDB,Facebook使用了HBase;58同城根據本身的業務特色,在分類信息,電子商務,社會化網絡等領域,除了使用自有存儲技術以外,也在使用Redist,Mongodb,Hbase等開源存儲技術。
最牛B的數據庫Oracle,在阿里內部已經徹底用不了了,替代成爲本身開發的OceanBase和改造過的MySQL;IBM的小型機,一直是高性能計算的標誌,但已經徹底由阿里本身定製的硬件代替;EMC的存儲設備在工業界應用也很普遍,但在阿里也去掉了;阿里內部有個專門的團隊在對Linux內核進行優化和修改,定製出適合阿里的Linux系統;支付寶天天百億級的交易額,幾千萬筆交易,也必須有獨特的安全解決方案mysql
本文是整理的關於優酷、YouTube、Twitter及JustinTV幾個視頻網站的架構或筆記,對於無論是視頻網站、門戶網站或者其它的網站,在架構上都有必定的參考意義,畢竟成功者的背後總有值得學習的地方,雖然有些文章的發表時間有點久了,可是看看對開闊視野仍是有幫助的。
ios
1、網站基本數據概覽
據2010年統計,優酷網日均獨立訪問人數(uv)達到了8900萬,日均訪問量(pv)更是達到了17億,優酷憑藉這一數據成爲google榜單中國內視頻網站排名最高的廠商。
硬件方面,優酷網引進的戴爾服務器主要以 PowerEdge 1950與PowerEdge 860爲主,存儲陣列以戴爾MD1000爲主,2007的數據代表,優酷網已有1000多臺服務器遍及在全國各大省市,如今應該更多了吧。
2、網站前端框架
從一開始,優酷網就自建了一套CMS來解決前端的頁面顯示,各個模塊之間分離得比較恰當,前端可擴展性很好,UI的分離,讓開發與維護變得十分簡單和靈活,下圖是優酷前端的模塊調用關係:
這樣,就根據module、method及params來肯定調用相對獨立的模塊,顯得很是簡潔。下面附一張優酷的前端局部架構圖:
3、數據庫架構
應該說優酷的數據庫架構也是經歷了許多波折,從一開始的單臺MySQL服務器(Just Running)到簡單的MySQL主從複製、SSD優化、垂直分庫、水平sharding分庫,這一系列過程只有經歷過纔會有更深的體會吧,就像MySpace的架構經歷同樣,架構也是一步步慢慢成長和成熟的。
一、簡單的MySQL主從複製:
MySQL的主從複製解決了數據庫的讀寫分離,並很好的提高了讀的性能,其原來圖以下:
其主從複製的過程以下圖所示:
可是,主從複製也帶來其餘一系列性能瓶頸問題:
-寫入沒法擴展
-寫入沒法緩存
-複製延時
-鎖表率上升
-表變大,緩存率降低
那問題產生總得解決的,這就產生下面的優化方案,一塊兒來看看。
二、MySQL垂直分區
若是把業務切割得足夠獨立,那把不一樣業務的數據放到不一樣的數據庫服務器將是一個不錯的方案,並且萬一其中一個業務崩潰了也不會影響其餘業務的正常進行,而且也起到了負載分流的做用,大大提高了數據庫的吞吐能力。通過垂直分區後的數據庫架構圖以下:
然而,儘管業務之間已經足夠獨立了,可是有些業務之間或多或少總會有點聯繫,如用戶,基本上都會和每一個業務相關聯,何況這種分區方式,也不能解決單張表數據量暴漲的問題,所以爲什麼不試試水平sharding呢?
三、MySQL水平分片(Sharding)
這是一個很是好的思路,將用戶按必定規則(按id哈希)分組,並把該組用戶的數據存儲到一個數據庫分片中,即一個sharding,這樣隨着用戶數量的增長,只要簡單地配置一臺服務器便可,原理圖以下:
如何來肯定某個用戶所在的shard呢,能夠建一張用戶和shard對應的數據表,每次請求先從這張表找用戶的shard id,再從對應shard中查詢相關數據,以下圖所示:
可是,優酷是如何解決跨shard的查詢呢,這個是個難點,據介紹優酷是儘可能不跨shard查詢,實在不行經過多維分片索引、分佈式搜索引擎,下策是分佈式數據庫查詢(這個很是麻煩並且耗性能)
4、緩存策略
貌似大的系統都對「緩存」情有獨鍾,從http緩存到memcached內存數據緩存,但優酷表示沒有用內存緩存,理由以下:
避免內存拷貝,避免內存鎖
如接到老大哥通知要把某個視頻撤下來,若是在緩存裏是比較麻煩的
並且Squid 的 write() 用戶進程空間有消耗,Lighttpd 1.5 的 AIO(異步I/O) 讀取文件到用戶內存致使效率也比較低下。
但爲什麼咱們訪問優酷會如此流暢,與土豆相比優酷的視頻加載速度略勝一籌?這個要歸功於優酷創建的比較完善的內容分發網絡(CDN),它經過多種方式保證分佈在全國各地的用戶進行就近訪問——用戶點擊視頻請求後,優酷網將根據用戶所處地區位置,將離用戶最近、服務情況最好的視頻服務器地址傳送給用戶,從而保證用戶能夠獲得快速的視頻體驗。這就是CDN帶來的優點,就近訪問,有關CDN的更多內容,請你們Google一下。git
這是一個完整的PDF:http://www.blogkid.net/qconppt/youkuqiudanqconbeijing-090423080809-phpapp01.pdfgithub
轉自:http://www.kaiyuanba.cn/html/1/131/147/7541.htmweb
YouTube發展迅速,天天超過1億的視頻點擊量,但只有不多人在維護站點和確保伸縮性。這點和PlentyOfFish相似,少數人維護龐大系統。是什麼緣由呢?放心絕對不是靠人品,也不是靠寂寞,下面就來看看YouTube的總體技術架構吧。
平臺
一、Apache
二、Python
三、Linux(SuSe)
四、MySQL
五、psyco,一個動態的Python到C的編譯器
六、lighttpd代替Apache作視頻查看
狀態
一、支持天天超過1億的視頻點擊量
二、成立於2005年2月
三、於2006年3月達到天天3千萬的視頻點擊量
四、於2006年7月達到天天1億的視頻點擊量
五、2個系統管理員,2個伸縮性軟件架構師
六、2個軟件開發工程師,2個網絡工程師,1個DBA
Web服務器
1,NetScaler用於負載均衡和靜態內容緩存
2,使用mod_fast_cgi運行Apache
3,使用一個Python應用服務器來處理請求的路由
4,應用服務器與多個數據庫和其餘信息源交互來獲取數據和格式化html頁面
5,通常能夠經過添加更多的機器來在Web層提升伸縮性
6,Python的Web層代碼一般不是性能瓶頸,大部分時間阻塞在RPC
7,Python容許快速而靈活的開發和部署
8,一般每一個頁面服務少於100毫秒的時間
9,使用psyco(一個相似於JIT編譯器的動態的Python到C的編譯器)來優化內部循環
10,對於像加密等密集型CPU活動,使用C擴展
11,對於一些開銷昂貴的塊使用預先生成並緩存的html
12,數據庫裏使用行級緩存
13,緩存完整的Python對象
14,有些數據被計算出來併發送給各個程序,因此這些值緩存在本地內存中。這是個使用不當的策略。
應用服務器裏最快的緩存將預先計算的值發送給全部服務器也花不了多少時間。只需弄一個代理來監聽更改,預計算,而後發送。
視頻服務
1,花費包括帶寬,硬件和能源消耗
2,每一個視頻由一個迷你集羣來host,每一個視頻被超過一臺機器持有
3,使用一個集羣意味着:
-更多的硬盤來持有內容意味着更快的速度
-failover。若是一臺機器出故障了,另外的機器能夠繼續服務
-在線備份
4,使用lighttpd做爲Web服務器來提供視頻服務:
-Apache開銷太大
-使用epoll來等待多個fds
-從單進程配置轉變爲多進程配置來處理更多的鏈接
5,大部分流行的內容移到CDN:
-CDN在多個地方備分內容,這樣內容離用戶更近的機會就會更高
-CDN機器常常內存不足,由於內容太流行以至不多有內容進出內存的顛簸
6,不太流行的內容(天天1-20瀏覽次數)在許多colo站點使用YouTube服務器
-長尾效應。一個視頻能夠有多個播放,可是許多視頻正在播放。隨機硬盤塊被訪問
-在這種狀況下緩存不會很好,因此花錢在更多的緩存上可能沒太大意義。
-調節RAID控制並注意其餘低級問題
-調節每臺機器上的內存,不要太多也不要太少
視頻服務關鍵點
1,保持簡單和廉價
2,保持簡單網絡路徑,在內容和用戶間不要有太多設備
3,使用經常使用硬件,昂貴的硬件很難找到幫助文檔
4,使用簡單而常見的工具,使用構建在Linux裏或之上的大部分工具
5,很好的處理隨機查找(SATA,tweaks)
縮略圖服務
1,作到高效使人驚奇的難
2,每一個視頻大概4張縮略圖,因此縮略圖比視頻多不少
3,縮略圖僅僅host在幾個機器上
4,持有一些小東西所遇到的問題:
-OS級別的大量的硬盤查找和inode和頁面緩存問題
-單目錄文件限制,特別是Ext3,後來移到多分層的結構。內核2.6的最近改進可能讓 Ext3容許大目錄,但在一個文件系統裏存儲大量文件不是個好主意
-每秒大量的請求,由於Web頁面可能在頁面上顯示60個縮略圖
-在這種高負載下Apache表現的很是糟糕
-在Apache前端使用squid,這種方式工做了一段時間,可是因爲負載繼續增長而以失敗了結。它讓每秒300個請求變爲20個
-嘗試使用lighttpd可是因爲使用單線程它陷於困境。遇到多進程的問題,由於它們各自保持本身單獨的緩存
-如此多的圖片以至一臺新機器只能接管24小時
-重啓機器須要6-10小時來緩存
5,爲了解決全部這些問題YouTube開始使用Google的BigTable,一個分佈式數據存儲:
-避免小文件問題,由於它將文件收集到一塊兒
-快,錯誤容忍
-更低的延遲,由於它使用分佈式多級緩存,該緩存與多個不一樣collocation站點工做
-更多信息參考Google Architecture,GoogleTalk Architecture和BigTable
數據庫
1,早期
-使用MySQL來存儲元數據,如用戶,tags和描述
-使用一整個10硬盤的RAID 10來存儲數據
-依賴於信用卡因此YouTube租用硬件
-YouTube通過一個常見的革命:單服務器,而後單master和多read slaves,而後數據庫分區,而後sharding方式
-痛苦與備份延遲。master數據庫是多線程的而且運行在一個大機器上因此它能夠處理許多工做,slaves是單線程的而且一般運行在小一些的服務器上而且備份是異步的,因此slaves會遠遠落後於master
-更新引發緩存失效,硬盤的慢I/O致使慢備份
-使用備份架構須要花費大量的money來得到增長的寫性能
-YouTube的一個解決方案是經過把數據分紅兩個集羣來將傳輸分出優先次序:一個視頻查看池和一個通常的集羣
2,後期
-數據庫分區
-分紅shards,不一樣的用戶指定到不一樣的shards
-擴散讀寫
-更好的緩存位置意味着更少的IO
-致使硬件減小30%
-備份延遲下降到0
-如今能夠任意提高數據庫的伸縮性
數據中心策略
1,依賴於信用卡,因此最初只能使用受管主機提供商
2,受管主機提供商不能提供伸縮性,不能控制硬件或使用良好的網絡協議
3,YouTube改成使用colocation arrangement。如今YouTube能夠自定義全部東西而且協定本身的契約
4,使用5到6個數據中心加CDN
5,視頻來自任意的數據中心,不是最近的匹配或其餘什麼。若是一個視頻足夠流行則移到CDN
6,依賴於視頻帶寬而不是真正的延遲。能夠來自任何colo
7,圖片延遲很嚴重,特別是當一個頁面有60張圖片時
8,使用BigTable將圖片備份到不一樣的數據中心,代碼查看誰是最近的
學到的東西
1,Stall for time。創造性和風險性的技巧讓你在短時間內解決問題而同時你會發現長期的解決方案
2,Proioritize。找出你的服務中核心的東西並對你的資源分出優先級別
3,Pick your battles。別怕將你的核心服務分出去。YouTube使用CDN來分佈它們最流行的內容。建立本身的網絡將花費太多時間和太多money
4,Keep it simple!簡單容許你更快的從新架構來回應問題
5,Shard。Sharding幫助隔離存儲,CPU,內存和IO,不只僅是得到更多的寫性能
6,Constant iteration on bottlenecks:
-軟件:DB,緩存
-OS:硬盤I/O
-硬件:內存,RAID
7,You succeed as a team。擁有一個跨越條律的瞭解整個系統並知道系統內部是什麼樣的團隊,如安裝打印機,安裝機器,安裝網絡等等的人。
With a good team all things are possible。ajax
轉自:http://www.kaiyuanba.cn/html/1/131/147/7540.htm
1、twitter網站基本狀況概覽
截至2011年4月,twitter的註冊用戶約爲1.75億,並以天天300000的新用戶註冊數增加,可是其真正的活躍用戶遠遠小於這個數目,大部分註冊用戶都是沒有關注者或沒有關注別人的,這也是與facebook的6億活躍用戶不能相提並論的。
twitter每個月有180萬獨立訪問用戶數,而且75%的流量來自twitter.com之外的網站。天天經過API有30億次請求,天天平均產生5500次tweet,37%活躍用戶爲手機用戶,約60%的tweet來自第三方的應用。
平臺:Ruby on Rails 、Erlang 、MySQL 、Mongrel 、Munin 、Nagios 、Google Analytics 、AWStats 、Memcached
下圖是twitter的總體架構設計圖:
2、twitter的平臺
twitter平臺大體由twitter.com、手機以及第三方應用構成,以下圖所示:
其中流量主要以手機和第三方爲主要來源。
Ruby on Rails:web應用程序的框架
Erlang:通用的面向併發的編程語言,開源項目地址:http://www.erlang.org/
AWStats:實時日誌分析系統:開源項目地址:http://awstats.sourceforge.net/
Memcached:分佈式內存緩存組建
Starling:Ruby開發的輕量級消息隊列
Varnish:高性能開源HTTP加速器
Kestrel:scala編寫的消息中間件,開源項目地址:http://github.com/robey/kestrel
Comet Server:Comet是一種ajax長鏈接技術,利用Comet能夠實現服務器主動向web瀏覽器推送數據,從而避免客戶端的輪詢帶來的性能損失。
libmemcached:一個memcached客戶端
使用mysql數據庫服務器
Mongrel:Ruby的http服務器,專門應用於rails,開源項目地址:http://rubyforge.org/projects/mongrel/
Munin:服務端監控程序,項目地址:http://munin-monitoring.org/
Nagios:網絡監控系統,項目地址:http://www.nagios.org/
3、緩存
講着講着就又說到緩存了,確實,緩存在大型web項目中起到了舉足輕重的做用,畢竟數據越靠近CPU存取速度越快。下圖是twitter的緩存架構圖:
大量使用memcached做緩存
例如,若是得到一個count很是慢,你能夠將count在1毫秒內扔入memcached
獲取朋友的狀態是很複雜的,這有安全等其餘問題,因此朋友的狀態更新後扔在緩存裏而不是作一個查詢。不會接觸到數據庫
ActiveRecord對象很大因此沒有被緩存。Twitter將critical的屬性存儲在一個哈希裏而且當訪問時遲加載
90%的請求爲API請求。因此在前端不作任何page和fragment緩存。頁面很是時間敏感因此效率不高,但Twitter緩存了API請求
在memcached緩存策略中,又有所改進,以下所述:
一、建立一個直寫式向量緩存Vector Cache,包含了一個tweet ID的數組,tweet ID是序列化的64位整數,命中率是99%
二、加入一個直寫式行緩存Row Cache,它包含了數據庫記錄:用戶和tweets。這一緩存有着95%的命中率。
三、引入了一個直讀式的碎片緩存Fragmeng Cache,它包含了經過API客戶端訪問到的sweets序列化版本,這些sweets能夠被打包成json、xml或者Atom格式,一樣也有着95%的命中率。
四、爲頁面緩存建立一個單獨的緩存池Page Cache。該頁面緩存池使用了一個分代的鍵模式,而不是直接的實效。
4、消息隊列
大量使用消息。生產者生產消息並放入隊列,而後分發給消費者。Twitter主要的功能是做爲不一樣形式(SMS,Web,IM等等)之間的消息橋
使用DRb,這意味着分佈式Ruby。有一個庫容許你經過TCP/IP從遠程Ruby對象發送和接收消息,可是它有點脆弱
移到Rinda,它是使用tuplespace模型的一個分享隊列,可是隊列是持久的,當失敗時消息會丟失
嘗試了Erlang
移到Starling,用Ruby寫的一個分佈式隊列
分佈式隊列經過將它們寫入硬盤用來挽救系統崩潰。其餘大型網站也使用這種簡單的方式
5、總結
一、數據庫必定要進行合理索引
二、要儘量快的認知你的系統,這就要你能靈活地運用各類工具了
三、緩存,緩存,仍是緩存,緩存一切能夠緩存的,讓你的應用飛起來。
Justin.TV每個月有3000萬個獨立訪問量,在遊戲視頻上傳領域戰勝了YouTube ,他們天天每分鐘新增30個小時的視頻,而YouTube只有23。
下面從Justin.TV的實時視頻系統使用到的平臺,他們的架構細節,從他們身上應該學到的東西等幾個方面逐一展開。
使用到的平臺
Justin.TV的一些統計數據
實時視頻結構詳述
實時視頻結構
1.使用了P2P和CDN
通常人認爲,只須要不斷提升帶寬,把傳來的數據都放入內存,不斷的接收數據流就能夠了,事實並不是如此。實時視頻要求不能打斷,這就意味着你不能夠超負荷的使用帶寬。YouTube只須要讓播放器緩衝一下,就能夠用8G的帶寬解決10G通道的需求,但在實時視頻裏,你不能緩衝,若是在信道上的流量超過了它的傳輸能力,哪怕只是一瞬間,那麼全部的正在看的用戶在那一刻都會卡。若是你在它的極限能力上再加入了一點兒負載,全部人馬上就會進入緩衝狀態。
Justin.TV使用了點對點的結構來解決這個問題,固然他們也有更好的解決辦法,CDN(內容分發網絡)即是之一。當用戶的流量負載超過Justin.TV的負載能力時,Justin.TV便很巧妙的將超標流量引入到一個CDN中去,Usher控制着這個處理邏輯,一旦接到了超標用戶的負載請求,Usher便馬上將這些新用戶轉發到CDN中去。
2.100%可用時間和維護的矛盾
實時視頻構建的系統既要保證100%的可用時間,又要保證機器能夠進行維護。與通常網站不一樣,通常網站維護時出現的問題只有少數人會發現、關注,而實時視頻網站不一樣,用戶很快就會發現維護時帶來的任何問題,而且互相傳播的很是快。這就使得沒有什麼問題能夠隱瞞用戶,面對如今用戶的挑剔,你必須避免維護時出問題。對一個服務器維護時,你不能主動結束用戶的進程,必須等待全部在這個服務器上的用戶本身結束服務才能開始,而這個過程每每很是緩慢。
3.Usher與負載均衡
Justin.TV遇到的最大的麻煩是即時擁塞,當大量的用戶同時看同一個欄目的時候,便會忽然產生突發網絡擁塞。他們開發了一個實時的服務器和數據中心調度系統,它就是Usher。
Justin.TV的系統在突發的高峯擁塞上作了不少。他們的網絡每秒能夠處理大量的鏈入鏈接。用戶也參與了負載均衡,這也是Justin.TV須要用戶使用Justin.TV本身的播放器的緣由之一。至於TCP,因爲它的典型處理速度就是百kbps級的,因此也不用對TCP協議作什麼修改。
相對於他們的流量,他們的視頻服務器看來來有些少,緣由是他們能夠使用Usher把每一個視頻服務器的性能發揮到最好,負載均衡能夠確保流量從不會超過他們的負載極限。負載大部分是在內存中,所以這個系統可讓網絡的速度發揮到極限。服務器他們是一次從Rackable(SGI服務器的一個系列)買了一整套,他們作的僅僅是從全部預置的裏面作了下挑選。
Usher是Justin.TV開發的一款定製化軟件,用來管理負載平衡,用戶認證和其餘一些流播放的處理邏輯。Usher經過計算出每一個流須要多少臺服務器提供支持,從而分配資源,保證系統處於最優狀態,這是他們的系統和別家不一樣之處。Usher一般會從下面幾個指標計算、衡量某個流媒體所須要的服務器:
Usher使用這些指標即可以在服務淨成本上來優化,把服務放在比較空閒的服務器上,或者把服務放在離用戶較近的服務器上,從而給用戶帶來更低的延遲和更好的表現。Usher有不少個能夠選擇的模式從而達到很細的控制粒度。
Justin.TV系統的每一個服務器均可以作邊緣服務器,直接爲用戶輸出視頻流,同時每一個服務器也能夠作源服務器,爲其餘服務器傳遞視頻流。這個特性,使得視頻流的負載結構成了動態的,常常改變的一個過程。
4.服務器造成了加權樹
服務器之間由視頻流的拷貝而產生的聯繫和加權樹很是類似。數據流的數量常常被系統取樣、統計,若是觀看某個視頻流的用戶數量飛速上漲,系統便將其拷貝不少份到一些其餘的服務器上去。這個過程反覆執行,最終就造成了一個樹狀的結構,最終會將網絡中全部的服務器都畫在裏面。Justin.TV的視頻流從源服務器出發,被拷貝到其餘服務器,或者拷貝到用戶的整個過程當中,都處於內存中,沒有硬盤路徑的概念。
5.RTMP和HTTP
Justin.TV儘量的使用了Flash,由於它使用RTMP協議,對每一個視頻流,系統都有一個獨立的Session去維護它。因爲使用這個協議,成本就至關高。因爲ISP不支持下載流,於是沒法使用多路廣播和P2P技術。Justin.TV確實想過用多路廣播在內部服務器之間拷貝數據流,然而因爲他們的系統控制覆蓋整個網絡,並且內部有大量的很便宜的帶寬能夠使用,這樣使用多路廣播的技術就並無產生多少效益。同時,因爲他們的優化算法是將每一個服務器上的流數都最小化,這就使得在很細的力度上作些事情會很是麻煩,甚至超過了他們能獲得收益。
Justin.TV的Usher使用HTTP請求去控制某個服務器負載哪一個視頻流,從而控制了服務的拓撲結構。Justin.TV在流數據上使用HTTP,但存在的一個問題是它沒有延遲和實時方面的性能。有些人說實時的定義就是5-30秒,然而,面對數千人作實時視頻的時候這顯然不行,由於他們還須要實時的討論,交流,這意味着延遲不能高於1/4秒。
6.從AWS到本身的數據中心
起初Justin.TV使用AWS,後來遷移到Akamai(雲服務供應商),最後到了本身的數據中心。
離開AWS到Akamai的緣由有:1,成本;2,網速不能知足他們的需求。視頻直播對帶寬很是敏感,所以有一個快速的,可靠的,穩定的和低延遲的網絡很是關鍵。使用AWS時,你不能控制這些,它是一個共享的網絡,經常超負載,AWS的網速不會比300Mbps更快。他們對動態範圍改動和雲API很重視,然而在性能和成本問題上沒有作什麼。
3年前,Justin.TV計算他們每一個用戶的成本,CDN是$0.135,AWS是0.0074,Datacenter是$0.001現在,他們的CDN成本下降了,但他們的數據中心的成本卻仍然同樣。
擁有多個數據中心的關鍵是爲了可以接近全部的主要交換節點,他們選擇國內最好的位置從而使得他們爲國內最多的節點提供了入口,並且節約了成本,構建了這些數據中心後,他們就直接連入了這些其餘的網絡,從而就省去了以前處理這些中轉流量的費用,還提升了性能,他們直接連入了他們所謂的"eyeball"網絡,這個網絡中包含了大量的cable/DSL用戶,和"content"網絡鏈接有些相似,Justin.TV的"eyeball"鏈接的流量主要來自終端用戶,在大多數狀況下,這些都是免費的,不用任何花一分錢,要作的就是連進來就行。Justin.TV有一個主幹網,用於在不一樣的數據中心傳輸視頻流,由於要到一個可用節點的選拔過程是去找願意和你作對等節點的過程,這一般是很困難的。
7.存儲
視頻流不是從磁盤造成,而是要存到磁盤上去。源服務器將一個傳入的視頻流在本地磁盤上覆制一份,以後便將這個文件上傳到長期存儲器上,視頻的每一秒都被錄下來而且存檔了。
存儲設備和YouTube相似,就是一個磁盤庫,使用XFS文件系統。這個結構用於記錄經過服務器傳播的廣播。默認的視頻流是保存7天,用戶能夠手動的設置,甚至你能夠保存到永遠(若是公司沒有倒閉的話)。
8.實時轉碼
增長了實時的轉碼功能,能夠將任何一種流式數據轉化爲傳輸層數據或者是代碼,而且能夠用新的格式將它從新編爲流媒體。有一個轉碼集羣,用來處理轉換工做轉,換的會話使用job系統進行管理。若是須要的轉碼服務超過了集羣的處理能力,那全部的服務器均可以用做轉碼服務器。
Web結構
Web 結構
1.Justin.TV前端使用Ruby on Rails。
2.用Twice作緩存
系統個每一個頁面都使用了他們本身定製的Twice緩存系統,Twice扮演的角色是輕量級反向代理服務器和模板系統的合併角色。思路是對每個用戶,緩存每個頁面,而後將每一個頁面的更新再併入其中。使用Twice之後,每一個進程每秒能夠處理150條請求,同時能夠在後臺處理10-20個請求,這就擴展了7-10倍以前的服務器能夠處理的網頁的數量。大部分動態網頁訪問都在5ms之內。Twice有一個插件結構,因此它能夠支持應用程序的一個特色,例如添加地理信息。
不用觸及應用服務器,便能自動緩存像用戶名同樣的數據。
Twice是一個爲Justin.TV的需求和環境而定製化開發的。若是開發一個新的Rails應用,使用Varnish或許是一個更好的主意。
3.網絡流量由一個數據中心服務,其餘的數據中心爲視頻服務。
4.Justin.TV 對全部的操做都作了監控.每個點擊,查看頁面和每個動做都被記錄下來,這樣就能夠不斷提升服務。前端,網絡呼叫或者一個應用服務器的日誌消息都被轉換成系統日誌消息,經過syslog-ngto轉發。他們掃描全部的數據,將它裝入MongoDB,使用Mongo執行查詢。
5.Justin.TV的API來自網站的應用服務器,它使用相同緩衝引擎,經過擴展網站來擴展他們的API。
6.PostegreSQL是他們最主要的數據庫。結構是簡單的主從結構,由一個主機和多個從屬讀數據庫組成。
因爲他們網站的類型,他們不須要許多寫數據庫,緩衝系統控制着這些讀數據庫。他們發現PostgreSQL並不擅長處理寫操做,所以Justin.TV就是用MemcachedDB去處理那些常常要寫的數據,例如計數器。
7.他們有一個聊天服務器集羣,專門用來爲聊天功能服務。若是用戶進入了一個頻道,用戶就會有5個不一樣的聊天服務器爲他服務,擴展聊天功能要比擴展視頻功能簡單的多,用戶能夠被劃分到不一樣的房間,這些房間又由不一樣的服務器負載。他們也不會讓100,000我的同時在一塊兒聊天。他們限制每一個房間200人,這樣就能夠在一個小組裏進行更有意義的交談。這同時對擴展也頗有幫助,這真的是一個很聰明的策略。
8.AWS用於存儲文檔鏡像。他們沒有爲存儲許多小鏡像而開發專門的系統,他們使用了S3。它很是方便,並且很便宜,這就不用在他們上面花更多的時間了。他們的鏡像使用頻率很高,全部他們是可緩衝的,也沒有留下什麼後續問題。
網絡拓撲結構設計
網絡拓撲結構很是簡單,每一個服務器機架頂都有一對1G的卡,每一個機架都有多個10G的接口,接口鏈接到外部的核心路由器。他們使用Dell Power Edge交換機,這些交換機對L3(TCP/IP)並非徹底支持,可是比L2(ethernet)要好的多。每一個交換機天天要傳輸20G的數據,並且很便宜。核心路由器是思科的6500的系列。Justin.TV想要將節點最小化,從而讓延遲下降,而且下降每一個packet的處理時間。Usher管理着全部的接入控制和其餘的邏輯,而不只僅限於網絡硬件。
使用多個數據中心能夠充分利用對等網的優點,把流量轉移到離用戶最近的地方。和其餘的網絡和節點的鏈接很是多。這樣就有多個可選的傳輸途徑,因此能夠使用最好的那個路徑。若是他們遇到了網絡的擁塞,就能夠選擇一條別的路。他們能夠經過IP地址和時間,找到對應的ISP。
開發和部署
他們使用Puppet服務器主機,有20中不一樣種類的服務器。從數據庫中出來的任何東西都要通過緩存器,使用Puppet他們能夠把這個緩存器變成他們想要的任何東西。
他們有兩個軟件隊伍。一個是產品隊伍,另外一個是硬件基礎設施隊伍。他們的隊伍很是小,大概每一個隊伍只有7-8我的,每一個隊伍都有一個產品經理。他們僱傭通常的技術員,但卻僱傭了網絡結構和數據庫相關的專家。
他們使用了基於網絡的開發系統,因此每一個新的改動都會在幾分鐘內完成。QA必須在變成產品以前完成,在這裏一般須要5-10分鐘。
Justin.TV使用Git管理源代碼。Justin.TV喜歡Git的這個功能,你能夠寫一個程序副本,20-30行,而後它能夠融合到其餘人手裏正在修改的副本。這個工做是獨立的,模塊化的。在你不得不撤銷你提交的副本時,你能夠很容易就修改或者撤銷你的代碼。每過幾天每一個人都會試着將本身的代碼副本融入到主代碼中去消除衝突。他們天天對軟件作5-15個修改,範圍從1行代碼中的bug到大範圍的測試都有。
數據庫模式經過手動更新完成。將他們複製的數據庫副本遷移到一塊兒就會造成一個最新的動態記錄的版本。在把改動最終應用到產品以前會在許多不一樣的環境下對其進行測試。
Puppet管理配置文件。每一個小的改動基本上就是一個實驗,他們會追蹤每一個對核心文件的改動的影響和以前的版本。這些測試很重要,由於經過它他們能夠找出哪些改動是真正提升他們關心的指標。
Justin.TV的將來
他們的目標是增長一個數量級。首先要切分他們的視頻元數據系統,因爲流數據和服務器的大幅增加,他們的元數據負載也指數級的爆發增加,所以,他們須要將其大範圍進行切分,對於網絡數據庫,將使用Cassandra對其進行拆分。其次,爲了災後恢復,要對核心數據中心進行備份。
學到的東西