说说 JavaEye 网站架构
偶然看到了Robbin的一篇文章,說到了一些JavaEye的一些實現解密,那就來看看有哪些有意思的東西。
我正在參與做的一 個項目,在某某地方上線,需要幾十塊單板集群;在某某地方上線,又需要怎樣的一個集群組網。咋聽起來興許覺得能有怎樣的業務邏輯處理和怎樣的用戶量呢?可 是JavaEye讓我很吃驚,我先前只知道與CSDN比起來,JavaEye確實是一個小規模一些的網站,專業一些的網站,可是服務器呢?只有兩臺!
?
http://wenku.baidu.com/link?url=jWy8PbTw5mQQV4VMk0bQQqhh7wr0h3eDibkfKj4GgZzGGUKwb7FrJPlT2JvmKtqcfpi0AlEOd_zxk59XTgMZSn6Epvhabz-kMRVwirJrbMW
?
這是那臺Web Server:
? AMD Opteron 2.4GHz單核 * 2 顆
? 8G內存
? 146G SCSI硬盤
這是那臺DBServer:
? AMD Opteron 2.0GHz單核 * 2 顆
? 4G內存
? 73G SCSI硬盤
實在不能說有多么優秀的硬件配置,JavaEye又得面對怎樣的訪問量呢?
150萬動態請求/天
這個是JavaEye封殺網絡爬蟲的簡單匹配表達式:
JavaEye采用Ruby作為實現語言,看來Ruby很慢是沒有說頭的,看看Google Adplanner Data:
這張圖表就很有意思了:
CSDN擁有JavaEye的3.5倍訪問量,但使用了三十多臺服務器集群,中國最大的幾個IT站點,使用ASP.NET、Ruby、PHP的都有,但看起來JavaEye的性能或許是最佳的。
-----------------------------------------------------------------------------------------------------------------------------------------------------
JavaEye網站架構進化:
(1)2006年9月
? lighttpd
? ruby 1.8.4, rails 1.1.2, 以fastcgi方式運行
? mysql5.0
FastCGI 像是一個常駐(long-live)型的CGI,它可以一直執行著,只要激活后,不會每次都要花費時間去fork一次(這是CGI最為人詬病的fork- and-execute 模式)。因為是多進程,所以比CGI多線程消耗更多的服務器內存,舉例來說,PHP-CGI解釋器每進程消耗7至25兆內存,將這個數字乘以50或100 就是很大的內存數。
其實小網站來說,使用FastCGI+Lighttpd是一個非常優秀的組合。
(2)2007年1月
? 添加了第2臺服務器
? 把web和DB分開
? 系統瓶頸在數據庫IO端
系統瓶頸出現在DB IO上面是很正常的,我自己這邊的項目經常遇到在Java側鎖瓶頸,無疑是非常奇怪的,一方面是性能測試的用例未必能反映現網真實情況導致,另一方面我還是覺得當整個架構過于復雜,遠程方法過多,就會導致這樣的問題。
(3)2007年2月
? 把posts表的大字段剝離出來
? posts表的select count操作從30秒減少到
0.1秒
把大表的大字段剝離出來,這是一種基于性能考慮的常用的DB重構方法。
剝離前:
? posts(id, ..., body)
? 磁盤存儲空間2GB
剝離后:
? posts(id, post_text_id,...) 50MB
? post_texts(id, body) 2GB
(4)2007年3月
? 數據庫瓶頸仍然存在
? 引入memcached和CachedModel
? 自己編寫了簡單的查詢緩存
? 240 sql query/s 下降到 140 sql query/s
? memcached緩存命中率在75%
這一次的改進主要在緩存上面,其實在做性能優化的時候,需要經常關注的一個東西就是緩存命中率。
(5)2007年9月
? 引入全文檢索
? 使用ruby的ferret
? 中文分詞使用單字拆分法
主要是對搜索引擎的優化。
(6)2008年1月
? JavaEye網站代碼重寫
? 緩存框架改用cache_fu
? 緩存命中率上升到84%
? sql query下降到 50條/s
回去打算去了解一下cache_fu,這里有兩篇文章可以參考:
http://weekface.javaeye.com/blog/133797
http://iceskysl.1sters.com/?tag=cache_fu
? cache_fu不對AR對象進行任何攔截,全部交給用戶編程
? 用戶有完全的控制權,但所有的緩存代碼要自己手工編寫
(7)2008年5月
? 中文分詞算法改用rmmseg-cpp
(8)2008年10月
? 自制山寨cache plugin
? 緩存命中率上升到96%以上
? 拋棄ferret,自己編寫全文檢索服務器
? 使用Java的lucene作為全文檢索引擎
? 自己實現C/S架構的內部調用
(8)2008年11月
? 實現博客,新聞制作PDF功能
(9)2009年3月
? SNS feed功能
? twitter綁定功能
? 開放API
? 廢棄Google Analytics
? 自己編寫簡單的網站流量分析系統
(10)2009年12月
? 添加Web IM
? 添加一臺服務器
? 合理規劃服務器
一個生命周期較長的WEB應用每發展到一定階段一定要面對的是架構上的重組,有時哪怕犧牲一些性能的代價,有時則是犧牲可維護性的代價,帶來的是結構層次清晰,便于短期內擴展等好處。這個過程每次都可能是痛苦的,但又是不可避免的。同時,我認為,在項目初期不應當也不可能把架構的融合性和擴展性考慮得太遠,那樣反而作繭自縛。而在應用發展過程中不斷地重構卻是更有價值的。
-----------------------------------------------------------------------------------------------------------------------------------------------------
進化總結:
(1)對象緩存原則:
? 數據庫表的設計要細顆粒度
? 把有冗余字段的大表拆分為n個互相外鍵關聯的小表
? ORM的性能瓶頸不在于表關聯,而在于大表的全表掃描
? 盡量避免join查詢,多制造n+1條SQL
上面第一條我覺得還是要看表容量而定,第四條我深有體會,記得在iBatis的使用中還有這樣一個專題。
(2)對象緩存的意義:
? Web應用很容易通過集群方式實現橫向擴展,系統的瓶頸往往出現在數據庫
? 數據庫的瓶頸往往出現在磁盤IO讀寫
? 因此要避免數據庫的全表掃描和大表的數據掃描操作
? 如何避免:拆表和臭名昭著的n+1條SQL
……
? memcached緩存命中率96%
? cache get : sql query = 4 : 1
另外,Robbin還提到,Ruby的字符串處理,尤其是正則表達式處理性能不好,解決方法也是使用緩存。
cache_money:
? 出自twitter開發團隊之手
? 可能是目前最強大的ruby cache框架
? 支持分頁查詢緩存,支持條件查詢緩存
全文檢索:
總結
以上是生活随笔為你收集整理的说说 JavaEye 网站架构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: eXtremeComponents简单应
- 下一篇: OpenGL ——安装和环境配置