性能&分布式&NewLife.XCode對無限數(shù)據(jù)的支持
上周發(fā)布了《改進版CodeTimer及XCode性能測試》,展示了NewLife.XCode在性能上的表現(xiàn)。實際上NewLife.XCode是一個很平凡的ORM,只是在分頁和緩存方面多下點功夫,注意每一個細節(jié),才能保證在數(shù)據(jù)量大、業(yè)務繁忙的環(huán)境中得以保持良好的性能。
NewLife.XCode所經(jīng)歷過的比較忙的一個系統(tǒng)是一個網(wǎng)吧行業(yè)的核心系統(tǒng),為五千家網(wǎng)吧,一百萬客戶端提供服務,每天大概有十幾萬會員多次登錄客戶端。當然這一百萬客戶端不可能同時全部登錄。因為業(yè)務需要,每個客戶端每隔一段時間(幾秒)Ping一次服務端,刷新在線記錄。只有一臺服務器運行服務端,windows2003,雙核CPU,4G內(nèi)存,自組裝共花費7kRMB。因為擔心TCP鏈接數(shù)限制,沒有采用TCP通訊,而直接使用WebService+IIS。開了三四個IIS站點,緩存全開的情況下,每個進程占用200M到500M內(nèi)存。數(shù)據(jù)庫是windows2008R2+MSSQL2008,四核CPU,32G內(nèi)存,自組裝共花費14kRMB,MSSQL進程占了10G多內(nèi)存。
這次的主角是一位個人站長使用NewLife.XCode做的系統(tǒng)(采集+整理+網(wǎng)站),我們先看現(xiàn)狀
服務器配置(國外,64位平臺,2G內(nèi)存少了些)
網(wǎng)站建立時間:20天
每日訪問量:14000IP 12000PV
IIS CPU:0(因為網(wǎng)站的緩存命中率極高)
IIS 內(nèi)存:200,000k * 3(3個進程)
MSSQL
CPU:0(數(shù)據(jù)整理子系統(tǒng)寫入,網(wǎng)站讀取)
內(nèi)存:500,000k
重要表個數(shù):400(表結構一致,因為數(shù)據(jù)量大才分表)
重要表數(shù)據(jù)量:20,000,000(20M*400=8B?80億?)
數(shù)據(jù)增長速度:每2小時1萬條
SQLite
重要表個數(shù):7
重要表數(shù)據(jù)量:20,000,000
數(shù)據(jù)增長速度:每1小時2萬條
1,采集子系統(tǒng),采集到的數(shù)據(jù)寫入一個SQLite,采集過程中也需要查詢
2,數(shù)據(jù)整理子系統(tǒng),分析整理SQLite中的數(shù)據(jù),歸檔到MSSQL中
3,網(wǎng)站根據(jù)用戶的查詢,讀取MSSQL中的數(shù)據(jù)來展現(xiàn)
這個系統(tǒng)是個什么樣的規(guī)模?昨天站長告訴我,截止下午四點,當天廣告收人173刀。
現(xiàn)在才不到一個月,數(shù)據(jù)還是很少的。站長所苦惱的地方在于:如何存儲這些會無限增長的數(shù)據(jù)?
以下是站長目前使用的手段:
1,拆分表。XCode有個武藝(詳見《充血模型的ORM能做什么?——ORM組件XCode(十八般武藝)》),可以動態(tài)改變實體類所映射的表名。于是根據(jù)數(shù)據(jù)類別來分表,重載實體類的數(shù)據(jù)操作方法,查詢和寫入前,根據(jù)當前數(shù)據(jù)類別計算表名并修改,實現(xiàn)了一個實體類對應多個相同結構的數(shù)據(jù)表。并且,如果該名稱的數(shù)據(jù)表不存在,XCode的反向工程會自動創(chuàng)建。使用者一點都不用關心,上層使用代碼就跟使用單表一樣。
2,采集和網(wǎng)站數(shù)據(jù)庫分離,開始的時候采集也是寫入MSSQL,顯然,這會讓MSSQL變得很忙,并且會帶來因采集而導致網(wǎng)站不正常的風險。
3,緩存。網(wǎng)站對數(shù)據(jù)的實時性要求不高,采集而來的數(shù)據(jù),可以在一兩個小時之后才反映到網(wǎng)站上來。因此,網(wǎng)站打開一級緩存,緩存時間可以設置為1小時。一級緩存這里不能設為永久,否則就再也拿不到采集到的新數(shù)據(jù)了,除非進程重啟。期間也遇到緩存經(jīng)常失效的問題,經(jīng)查是IIS應用程序池回收所致,設為固定時間回收就可以了。
static void TestLog() { NewLog log = new NewLog(); log.Action = "Test"; log.Category = "SystemLog"; log.Save(); log = new NewLog(); log.Action = "Test"; log.Category = "UserLog"; log.Save(); } class NewLog : Log<NewLog> { public override int Insert() { Meta.TableName = Category; return base.Insert(); } }
這么做,幾千張表,每張表兩千萬的數(shù)據(jù),應該是沒有問題的了。
當然,這其中還是有一些問題的
1,SQLite寫入頻繁,偶爾發(fā)生多線程沖突,XCode中的SQLite提供者增加了失敗重試機制,降低了沖突幾率,大概萬分之一
2,SQLite數(shù)據(jù)增長過快,顯然,這個問題很嚴重,但也不是不能解決,XCode除了能動態(tài)改變表名,還能動態(tài)改變連接名,也就是說,跟拆分表一樣,能夠輕易的實現(xiàn)拆分庫。
3,拆分庫又會帶來IO的問題,這個時候,只能使用更多的數(shù)據(jù)庫服務器。
4,如果網(wǎng)站使用的MSSQL成為瓶頸怎么辦?可以使用多個MSSQL服務器,假如10個,配置文件中配置10個對應的連接字符串,重載實體類的查詢方法,查詢之前動態(tài)修改連接名。至于該使用哪一個連接名,就看自己實現(xiàn)的算法了,最簡單的就是輪詢或者隨機。這樣子就很輕易的實現(xiàn)了簡單的分布式。新版本內(nèi)置了分布式的提供者,可以根據(jù)權重隨機分發(fā)查詢,還可以把數(shù)據(jù)同時寫入到多個目標數(shù)據(jù)庫中去,而這些,都不需要修改業(yè)務實現(xiàn)代碼。
不要怪我們狠(臃腫?),因為我們是充血模型!






浙公網(wǎng)安備 33010602011771號