天天看點

CoolHash資料庫的産品宣言(Fourinone4.0版)

Fourinone4.0版新特性:一個高性能的資料庫引擎CoolHash(酷哈嘻)

[b]一、前言:如何寫一個資料庫[/b]

如果将作業系統和業務應用之間的軟體都統稱中間件的話,那麼最重要的軟體無疑是資料庫,它比web應用伺服器市場更大,幾乎所有的業務系統都需要資料庫,所有的企業都會購買資料庫。無論是早期的商業智能也好,資料分析挖掘也好,近年的分布式存儲也好,大資料也好...圍繞資料變着花樣的新理念新技術再多,都是“亂花漸欲迷人眼,淺草才能沒馬蹄”,其實最核心的還是資料庫技術。

就像華為想進軍軟體市場已經很久了,我腦海裡一直惦記着資料庫技術,幾年來不斷收集資料庫實作技術,但是一直不得要領,幾欲放棄,沒有碰到一個白胡子老頭傳授秘籍,國内也幾乎沒有這方面的書籍,找了幾本國外的教材,要麼翻譯的不好,要麼英文啃起來費勁,書裡更多是講資料庫相關的基礎知識,但是不會告訴你怎麼做,好比是你想學變臉,但是總在教你唱戲,其實你隻想知道變臉是用線拉的就行了。行業技術機密都是避而不談的,感覺從書本上是學不到的。

去年給一個銀行技術老總講解大資料方案,他突然問到,你們能不能不用别人的,自己寫個ORACLE這樣的資料庫出來,我們每年花在license和服務費非常昂貴,更新也很痛苦,但是也沒有辦法。我承諾可以抽業餘時間研究一下,不過他馬上又說,就算有也不會馬上用,可以先開源出來,可以看出他無比糾結的心态,也許他對太多架構師說過這樣的話,可能現在都忘了,但是這件事再次給了我觸動,言語之間能感受到客戶寄托出的一種期望,希望中國企業能成長為ORACLE、IBM這樣的角色。

要實作一個資料庫,首先不能不談起資料庫引擎。資料庫引擎和資料庫産品的關系,就像汽車發動機和汽車的關系,有了發動機,剩下的隻是裝配工作。知名的資料庫引擎有“ISAM、MyISAM、InnoDB、PostgreSQL、BerkeleyDB等”,另外也有些産品模糊在“資料庫引擎、資料庫server、資料庫管理系統”之間的,如近幾年的redis,還有JDK6.0起自帶一個java編寫的隻有2m大的關系資料庫Derby(由IBM捐獻),另外值得一提的還有SQLite,一個很輕量級嵌入式的資料庫(3萬c代碼,250k大小),但是功能齊全,實作了ACID和SQL标準,目前廣泛應用于蘋果的Mac作業系統和Android移動作業系統中,缺點是多使用者高并發承受能力較弱。

世界上大部分的資料庫産品都是圍繞部分資料庫引擎擴充出來的,比如大家熟悉的Mysql,它的資料庫引擎叫MyISAM,MyISAM是在ISAM發展而來,ISAM也是一個知名的資料庫引擎,最初被IBM開發,它讀的性能大于寫,但是索引功能和事務處理缺乏,MyISAM相對于ISAM做了很多改進,優化了表鎖和并發操作,但是由于繼承的原因,仍然傾向于多讀少寫操作。ISAM系列引擎的大緻設計原理:采用B樹設計,分成表中繼資料、表資料、表索引3部分存儲,讀的快是因為維持大量的索引結構指向資料存儲位置,但是由于删除更新容易導緻大量資料碎片和空間浪費,常常需要執行“OPTIMIZE TABLE”,進而又導緻索引常常需要重新計算。Mysql5.5以後預設采用InnoDB引擎,還可以使用BerkeleyDB,InnoDB和BerkeleyDB包括了對事務處理和外鍵的支援,這是ISAM系列引擎所沒有的特性,另外InnoDB的鎖設計的要精明一點,鎖到少數行的資料塊上,而不是整表鎖。

關于ISAM系列的發展有很多,IBM開發了VSAM代替ISAM,VSAM被IBM一個資料庫産品所使用 ,就是大名鼎鼎的DB2。雖然MySql的資料庫引擎換成了InnoDB,但是MySql的作者邁克爾(Michael Widenius)從MySql舊版本發展了另一個分支,并以自己的小女兒名字命名為MariaDB(瑪麗亞),MariaDB的資料庫引擎叫做Aria,但實際上還是MyISAM,隻是增加了些key緩存改進(Segmented Key Cache),MariaDB資料庫得到了google等企業的大力支援,普通的觀點認為oralce收購Mysql的最終目的是想其慢慢死亡,而不是想着如何把它發展更好。

PostgreSQL和BerkeleyDB都是來源于加州伯克利分校,一個面向關系資料,一個面向k/v資料,雖然知名和流行程度不如Mysql,但是也各有優勢,PostgreSQL的關系資料庫功能實作的比較完整,包括了很多進階特性,并且采用BSD/MIT開源協定,是以比較适合用來封裝成資料庫産品,這種協定允許任何人使用修改代碼,但是要保留版權聲明,BerkeleyDB提供了一個高并發通路的k/v資料庫引擎,但不是一個資料庫server,不提供網絡通路,不支援sql,但可以支援函數式操作,資料庫産品HyperTable和MemcacheDB内部都使用了BerkeleyDB。

[b]綜上所述,我們可以看出:

1、大部分資料庫産品都是都是近親結婚,由少數資料庫引擎(如ISAM、PostgreSQL、BerkeleyDB等)發展而來。(但是oracle和sqlserver的資料庫引擎是内置的,鮮有人知)

2、你會驚奇的發現,MyISAM、BerkeleyDB、InnoDB等大部分資料庫引擎的vendor都是oracle,oracle公司一直處心積慮的收購着市場上有競争力的資料庫引擎,用來捍衛自己的壟斷地位,

3、幾乎所有的資料庫引擎都是GPL協定,擅自閉源用于商業将承擔法律責任。[/b]

是以,要寫一個資料庫,首先要從實作資料庫引擎入手,掌握資料庫引擎技術有重要意義,因為無論是“關系資料庫還是K/V資料庫,SQL資料庫還是NOSQL資料庫,分布式資料庫還是并行資料庫,列資料庫還是對象資料庫...”,存儲引擎部分都有着相似的實作原理,掌握了資料庫引擎技術後,隻要公司願意投資,就可以長足拓展到任何資料庫領域,一切隻是工作量問題,資料庫引擎一經研發成功,就值得長期放養,哪怕是5年10年。同時對個人職業意義來說,對一個玩了一輩子軟體技術的架構師,沒有寫過資料庫是一種遺憾,就跟喜歡女優的工程師沒有見過真人一樣。

[b]二、CoolHash是個什麼樣的資料庫[/b]

[b]1、CoolHash是一個資料庫引擎[/b]

CoolHash隻做資料庫最基礎核心的引擎部分,支援大部分資料類型的“插入、擷取、更新、删除、批量插入、批量擷取、批量更新、批量删除、高效查詢(精确查、模糊查、按樹節點查、按key查、按value查)、分頁,排序、and操作、or操作、事務處理、key指針插入和查詢、緩存持久互轉”等操作和遠端操作。

其他的“監控、管理、安全、備份、指令行操作、運維工具”等外圍特性都剝離出去不做,開發者可以根據自己需求擴充這些功能,CoolHash也不做自動擴容,CoolHash認為分布式叢集特性也可以在外圍通過“分庫分表”或者“分布式擴容”等中間件技術去做,目前國内很多企業都具備基于開源軟體做外圍中間件的能力,這樣,CoolHash隻維持一個高性能又輕量級的最小存儲引擎。

CoolHash高度産品化,易用性強,容易嵌入使用和複制傳播(200k大小),采用apache2.0開源協定,使用java實作(jdk1.7),對外提供java接口,同時支援windows和linux(unix-like),由于依賴底層作業系統,windows和linux的實作稍有不同。

[b]2、CoolHash是一個k/v資料庫[/b]

實作資料庫存儲結構索引有多種方法,有比較平衡減少深入的b樹、b+樹系列,結合記憶體再合并的LSM-tree系列(bigTable),借鑒字典索引技術的Trie樹(字首樹、三叉樹)等,不過對于key/value結構,感覺最合适的還是Hash,不過java裡的Hash算法是實作在記憶體元件裡,無法持久化,隻能快速讀寫,但是無法模糊查詢,傳統的Hash不是一個“cool”的Hash,需要進行改進。

CoolHash改進後的Hash算法是一個完整的key樹結構,我們知道傳統Hash的key和key之間沒有關系,互相獨立,但是在CoolHash裡,key可以表示為“user.001.name”的用“.”分開的樹層次結構,如“user.001.age”和“user.001.name”都屬于“user.001.*”分支,既可獨立擷取,也可以從父節點查詢,還可以“user.*.name”方式隻查詢所有子節點。

提出key指針的概念:CoolHash的key可以是一個指針,指向其他樹的key,這樣能将兩棵key樹連起來,這樣的設計能避免大量join操作,如果兩棵key樹沒有直接關系,需要動态join将會非常耗時,但有了key指針可以很好的描述資料之間“1對1、1對多、多對多”的關聯關系。key指針也不同于資料庫外健,它可以模糊指,比如隻模糊指向一個key字首“user.001”,再補充需要擷取的屬性形成一個完整key;還能連續指,比如一個key指針指向另一個key指針再指向其他key指針,連續指可以将更多的樹聯系起來形成一個大的資料森林。CoolHash能很好的控制key指針最終值傳回、key指針死循環、讀寫死鎖等問題。

我們知道關系資料庫的資料表是一個行列的二維矩陣的資料結構,表和表之間沒有層次感,一個表不會是另一個表的父子節點,這就導緻需要大量關聯,從一個表擷取另一個表的資料需要通過join操作,同時由于表和表之間彼此獨立,又導緻資料量大後join性能不好,多個矩陣需要動态的“求并”“求或”擷取主健,再傳回所有屬性。很多朋友是開發業務系統出身,複雜一點的業務邏輯通常需要關聯7-8個資料庫表甚至更多,是相當頭疼的事情。

[img]http://dl2.iteye.com/upload/attachment/0096/8371/9baed608-140b-3e27-8755-377c6a3ae168.png[/img]

這種矩陣行列式結構還有個不好,就是一加全加,一減全減,一行加了一列屬性,所有行都要跟着加,假如有個“子女”屬性,有的人有1個子女,有的人有2-3個子女,這個屬性應該有時是1列,有時是3列,有時沒有才好。CoolHash的父節點下的key值可以任意添加和減少,或者再任意向下擴充葉子結點,也可以任意查詢,能夠非常靈活,比如“子女”屬性可以這樣表示第一個小孩:“user.001.children.001”。

關系資料庫還容易産生資料碎片,需要經常執行“OPTIMIZE TABLE”或者“壓縮資料庫”等操作回收空間,CoolHash對此做了設計和算法改進,對于大量資料頻繁寫入和删除能很好重複利用存儲空間。

key和value的資料格式:CoolHash的key隻能是字元串,預設最大長度為256位元組。value能支援非常廣泛的資料類型,基本資料類型“String(變長字元)、short(短整形)、int(整型)、long(長整形)、 double(雙精度浮點型)、 float(浮點型)、Date(日期型)”,進階資料類型的大部分的java集合都能支援(List、Map、Set等),以及任意可序列化的自定義java類型,底層資料類型也可以支援二進制型。基本資料類型的value可支援按内容查詢,進階資料類型和二進制類型不支援按内容查詢。所有類型的value預設最大長度為2M,預設配置保證一對key/value長度不會太大,能夠容易加載到記憶體進行處理,但是key和value的最大長度、以及region大小都是可以根據計算機性能進行配置。

CoolHash還支援HashMap緩存和持久化的統一和互相轉換,并共用一套API,可以将資料放入CoolHashMap,也可以放入持久化,可以将CoolHashMap對象轉成持久化,也可以從持久化資料裡直接擷取CoolHashMap對象。

[b]3、CoolHash是一個并行資料庫(mpp)[/b]

前幾年有篇文章,國外的資料庫大牛猛烈抨擊map/reduce,讓重複造輪子的人應該去學習一下關系資料庫幾十年的理論和實踐積累,一個借助蠻力而不善于設計索引的資料庫系統是愚蠢和低效的。這一方面說明了map/reduce技術已經侵犯到了傳統資料庫領域的核心利益,另一方面也暴露了分布式存儲技術的某些不足。

這裡的蠻力就是并行計算,在CoolHash的底層,會維持一個資料勞工程序組,根據計算機性能少則幾個多則上百個,對于資料庫的每種操作,資料勞工們像演奏交響樂一樣,時而獨奏,時而合奏,統一排程,緊密協作的完成任務,CoolHash從一開始就是高度并行化的設計,資料庫引擎本質就是在尋求cpu、記憶體、硬碟的充分利用和均衡利用,“一力勝十巧”,在大量資料的讀寫和查詢中并行計算的效果猶為明顯。

同時一個好的資料庫引擎應該是蠻力和技巧的結合,Hbase的一個重要啟示,就是可以靈活設計它的key達到近似索引的效果,CoolHash将此特性發揮的更深入,樹型結構的key本身就是最好的索引,除外CoolHash幾乎不需要另外再建立索引,隻需要按照業務資料特點設計好你的key。并行計算和索引的結合會得到一個很好的互補,讓你的索引結構不需要維持的太精準而節省開銷,舉個例子:我們從一個城市找一個人,一種方法是我們有精确的索引,知道他在哪個區哪個樓那個房間,另一種是我們隻大緻知道他在哪棟樓,但是我們有幾百個勞工可以每間房同時去找,這樣也能很快找到。

[b]4、CoolHash是一個nosql資料庫[/b]

nosql不等于沒有sql的功能,關系資料庫的sql仍然是非常友善的互動語言,而且有專門的标準,CoolHash通過函數方式實作大部分sql的功能,如果需要擴充sql支援,在外圍用正規表達式做一個sql解析,然後調用CoolHash的函數支援即可。

由于CoolHash沒有關系資料庫的“db、table、row、col”等概念,使用樹型key取代了,是以sql create語句功能就不需要了。

“put()函數”對應于“sql insert、update”語句

“remove()函數”對應于“sql delete...where”語句

“put(map)函數”對應于“sql insert/update into...select...”語句

“get()函數”對應于“sql select...where id=?”語句

“get(map)”函數對應于“sql select *...”語句

“find(*,filter)”函數對于于“sql select * where col=%x%”語句

“and()函數”對應于“sql and”語句

“or()函數”對應于“sql or”語句

“sort(comp)函數”對應于“sql desc/group”語句

[b]5、CoolHash實作了事務處理[/b]

CoolHash實作了ACID事務屬性,對寫入、更新、删除的基本操作提供事務處理,在程式裡調用begin()、commit()、rollback()等事務方法。

原子性(Atomic):事務内操作要麼送出全部生效,要麼復原全部撤消。

一緻性(Consistent):事務操作前後的資料狀态保持一緻,一緻性跟原子性密切相關,比如銀行轉賬前後,兩個賬戶累加總和保持一緻。

隔離性(Isolated):多個事務操作時,互相不能有影響,保持隔離。

持續性(Durable) :事務送出後需要持久化生效。

另外,對于多個事務并發操作資料的情況,JDBC規範歸納出“髒讀(dirty read)、不可重複讀(non-repeatable read) 、幻讀(phantom read) ”三種問題,并提出了4種事務隔離級讓軟體制造商去實作,按照不同等級去容忍這三個問題,其實這種逐級容忍大部分都不實用,一個事務操作未送出時,按照事務隔離級,其他通路應該是讀取到該事務開始前的資料,而不應該把事情搞複雜,CoolHash實作的是“TRANSACTION_SERIALIZABLE”,禁止容忍三種讀取問題。

[b]6、CoolHash是一個資料庫Server[/b]

CoolHash支援遠端網絡通路,服務端釋出一個IP和監聽端口,用戶端連接配接該IP端口即可進行遠端操作,CoolHash可承受多使用者高并發的網絡連接配接通路,來源于服務端設計的相似之處,大家知道Apache HTTP Server是一個多程序模型+共享記憶體方式實作,在前面講到的CoolHash會維持一個資料勞工的程序組,資料勞工不僅是并行計算的執行者,同時也是網絡請求的響應者,資料勞工身兼多職能很好的将服務端設計統一起來,避免重複設計,是以CoolHash也是一個很好的網絡Server.

[b]7、CoolHash的測試性能[/b]

有句話叫做“人生如白駒過隙”,用來形容性能就是一瞬間,資料庫性能最好能接近緩存,或者直接可以當作緩存來用,能在瞬間完成讀寫和各種查詢,這個瞬間就是秒。隻有在幾秒内完成操作才能做到實時互動沒有等待感,否則就要離線互動。

CoolHash的單條寫入和讀取速度都在毫秒級别,寫和讀差别不大,讀略快于寫。

CoolHash的批量寫入和讀取速度都控制在秒級别,100萬資料寫入基準測試,普通桌上型電腦或者筆記本(4核4g)需要5-6秒,标準pc server(24核256g)需要2-3秒;批量讀、批量删除和批量寫入的速度差不多。

CoolHash寫入緩存和寫入持久的速度差别不大,100萬資料寫入緩存基準測試,普通桌上型電腦或者筆記本(4核4g)需要5秒左右,标準pc server(24核256g)需要2秒左右。如果是10萬級别的資料讀寫,緩存和持久的速度大緻接近等同。

CoolHash的查詢速度控制在秒級别,100萬資料的模糊查詢(如like%str%)在沒有建構索引情況下,普通桌上型電腦或者筆記本(4核4g)需要2-3秒,标準pc server(24核256g)需要1-2秒;如果是重複查詢,由于CoolHash内部做了資料記憶體映射,第二次以後隻需要毫秒級完成。

高并發多用戶端的吞吐量總體速度要快于單用戶端,但是受伺服器cpu、記憶體、io等性能限制,會傾向于一個平衡值。

資料庫引擎的性能通常也會受“key/value資料大小、資料類型、勞工數量、硬體配置(記憶體大小、cpu核數、硬碟io、網絡耗用)”等等因素影響。

比如同樣數量但是單條key/value資料很大,整體速度要慢一些;

基本資料類型的讀寫速度要快過進階資料類型(如java集合類);

勞工數量也有影響,對于單條寫入讀取單勞工和多勞工差不多,但是批量操作和查詢多勞工要好過單勞工,普通桌上型電腦或者筆記本(4核4g)維持在8-10個勞工可以打滿cpu,标準pc server(24核256g)最大可以維持到100個左右勞工,但是勞工數量就算能打滿cpu,也受限于後端硬碟io,到一定程度速度不再增長;

硬體配置對于性能的影響很大,普通筆記本的測試效果明顯不如标準pc server,筆記本記憶體較小,硬碟io弱,不适合做資料庫伺服器。記憶體大的伺服器測試效果好,加載資料和jvm垃圾回收速度會更快,目前測試采用的都是傳統SAS/SATA硬碟,如果采用固态硬碟進行硬體更新,随機IO性能會得到進一步提升;

另外,由于存在網絡耗用和序列化傳送,遠端網絡操作的速度要比本地速度慢,但是區域網路内速度會接近本地速度,這是因為遠端網絡操作涉及帶寬接入限制和線路共享等複雜消耗,而區域網路内主要取決于實體裝置速度。

關于CoolHash性能的更多體驗,歡迎有興趣的朋友根據demo在各自的機器環境下,模拟各種極端條件下去壓測。

[b]三、如何使用CoolHash[/b]

ch追求極簡的程式設計體驗,不需要安排配置,服務端啟動CoolHashServer,指定好ip和端口,

用戶端大緻程式設計步驟如下:

CoolHashClient chc = BeanContext.getCoolHashClient("localhost",2014);//連接配接CoolHashServer

chc.put("user.001.name","zhang");//寫入字元

chc.put("user.001.age",20);//寫入整數

chc.put("user.001.weight",50.55f);//寫入浮點數

chc.put("user.001.pet",new ArrayList());//寫入集合對象

String name = (String)chc.get("user.001.name");//讀取字元

int age = (int)chc.get("user.001.age");//讀取整數

float weight = (float)chc.get("user.001.weight");//讀取浮點數

ArrayList pet = (ArrayList)chc.get("user.001.pet");//讀取集合對象

chc.put("user.002.name","Li");

chc.put("user.002.age",25);

chc.put("user.002.weight",60.55f);

CoolKeyResult keyresult = chc.findKey("user.001.*");//查找使用者001的所有屬性

CoolKeySet ks = keyresult.nextBatchKey(4);//分頁擷取前4條結果

System.out.println(ks);//輸出[user.001.weight, user.001.age, user.001.name, user.001.pet]

CoolHashResult mapresult = chc.find("user.*.age", ValueFilter.greater(18));//查找年齡大于18歲的使用者

CoolHashMap hm = mapresult.nextBatch(10);

System.out.println(hm);//輸出[user.001.age=20, user.002.age=25]

......

更多的功能使用請去參考開發包裡的demo

[b]四、Fourinone到底是什麼?[/b]

Fourinone1.0是一個并行計算架構,2.0是一個分布式檔案系統(Fttp),4.0是一個資料庫引擎(CoolHash)...那麼Fourinone到底是什麼?

我們把Fourinone打開,其實就是純java程式,除外什麼都沒有,通篇展示如何用最基礎的java實作上面的功能。

其實不用關注Fourinone的産品定位究竟是什麼,Fourinone就是四不象,雖然功能衆多,跨度很大,但是仍然長自同一個身體,由同一個腦袋指揮,隻要各項機理運作正常健康就好。

Fourinone就是俄羅斯套娃裡最小的一個,2.0是1.0的應用,3.0是2.0的應用,4.0是3.0的應用,層層擴充沒有止境,展現軟體搭建精髓思想。

Fourinone隻收集最核心的技術,hadoop的開發者去使用spark需要重新學習,反之亦然,因為他永遠隻是一個使用者,但是Fourinone可以從一個簡單MQ演變成一個複雜資料庫,隻有掌握核心技術,才具備強大的變通能力。

Fourinone4.0雖然新增加了一個完整的資料庫引擎,但是依然保持着苗條身材,整體大小隻有220k,用不到1萬行java代碼實作,所有的設計都是原創和創新。

除外,4.0版本還增加了以下特性:

1、多程序多線程的無縫融合,同一套接口,改改參數,從多程序變為多線程,開發者無需改寫程式邏輯;

2、提供高容錯任務配置設定算法API:doTaskCompete(m勞工,n任務),将n個任務分給m個勞工并行完成,根據任務大小設定勞工數量,勞工間能者多勞,性能好的勞工機器争搶幹更多的任務,同時跟現實工作一樣,如果有勞工生病請假(故障),那麼他的任務活由其餘勞工代幹,除非所有勞工出故障,否則就算隻剩一個勞工也應該加班把其他所有勞工的活幹完,對整體計算來說,部分勞工故障對計算結果來說不受影響,隻是計算時間會延長。

[b]五、結束語:将技術做酷是一種生活态度[/b]

就像搖滾樂手騎行哈雷是一種生活态度一樣,把技術和産品做酷也是一種生活态度。

用很多代碼體積臃腫實作出來也可以,但是不夠酷,用很少代碼實作功能更強才酷;

用很多人花很多時間做出一個産品也可以,但是不夠酷,用很少人花很少時間做出來才酷;

全靠整合依賴太多也可以,但是不夠酷,沒有任何依賴才酷;

最核心的元件都是用别人的也可以,但是不夠酷,自己做的更好才酷;

産品隻有專業人士會用也可以,但是不夠酷,沒文化的人都會用才酷;

跳水自由落水也可以,但是不夠酷,翻幾個跟頭不冒一點水花才酷;

演死屍直接倒下也可以,但是不夠酷,多晃悠幾下再死才酷;

不玩創新也可以,那樣的人生不夠酷,玩創新挨整才酷。

基礎軟體也能像網際網路産品餘額寶、微信那樣做到很酷,追求傻瓜式的客戶體驗和黏性,把草根程式員當做客戶群體,做他們踮踮腳就能夠的到的軟體。基礎軟體相對于業務創新産品來說有一定技術門檻,不容易被複制,觀察我們身邊的網際網路産品,“從網遊到偷菜到手遊到微網誌到微信...”或者是“從b2b到c2c到b2c到團購到o2o...”總在不斷的進行業務模式創新,保鮮期不超過2年,而且容易遭到山寨,但是微軟的作業系統和office、oracle的資料庫賣了20多年,不需要什麼創新好像也沒有競争對手。

很多畢業生踏入這個行業時最初的夢想也是想寫一個很酷的作業系統或者資料庫,但是無數次的現實磨滅了他的夢想,很多人最後變成一個在職場政治和項目扯皮中尋求着人生價值,并且總是把“技術不是問題”挂在嘴邊,是否還記的你曾經的夢想,把技術做酷。

Fourinone4.0(CoolHash)開源位址:[url]http://code.google.com/p/fourinone/[/url]

svn位址(浏覽器可以直接下載下傳):[url]http://fourinone.googlecode.com/svn/trunk/[/url]

關于Fourinone的所有架構、指南、demo,可以參考[url=http://item.jd.com/11417660.html?utm_source=baidu&utm_medium=cpc&utm_campaign=&utm_term=baidu_266874792_0_s182753677d6bd44cb2.61438135]《大規模分布式系統架構與設計實戰》[/url]一書

繼續閱讀