豆瓣整個基礎架構可以粗略的分為在線和離線兩大塊。在線的部分和大部分網站類似:前面用LVS做HA,用Nginx做反向代理,形成負載均衡的一層;應用層主要是做運算,將運算結果返回給前面的用戶,DAE平臺是這兩年建起來的,現在大部分豆瓣的應用基本都跑在DAE上面了;應用后面的基礎服務也跟其他網站差不多,MySQL、memcached、redis、beanstalkd,不一樣的是NoSQL的選擇——BeansDB,這是我們在幾年前開源的KV數據庫,也是國內比較早開源的KV數據庫。
豆瓣的技術架構與主要組件
豆瓣作為一個早期就選擇以Python為主要編程語言的公司,網站所使用到的技術很多都與Python相關,包括主要框架quixote、自行實現的DPark等等。在其它技術的選擇上,并沒有太大不同:nginx、MySQL、memcached、BeansDB、redis……都是知名開源項目。在這些開源項目之上,豆瓣根據自己產品的特性,針對性地做了配置與部署設置。
除了使用開源項目,豆瓣也根據自身需要自主研發或實現了一些產品,比較有特色的如DAE、DPark等等。
DAE全名Douban Application Engine,顧名思義它是一個類似于GAE、SAE的內部PaaS系統。使用這樣的PaaS有很多好處,比如第三方庫數量豐富并且支持多個版本并存、資源配置靈活等等,能夠為工程師省去很多不必要的工作。
BeansDB是DAE中非常重要的一個組件,設計思想源于亞馬遜的Dynamo,但是簡化了Dynamo的一些復雜之處。BeansDB主要應用于小型文本和中型的圖片、音頻,它們的共同特點在于寫次數特別少,這也正是BeansDB所擅長的領域。
DPark類似于Spark,是豆瓣用Python實現Map-Reduce類似框架。雖然Python的性能低于基于JVM的Clojure,但這樣做避免了程序員程序員進入不熟悉的領域,而且豆瓣使用開源項目的原則是:如果無法完全掌握,寧可不用。“此外將Spark移植到Python上也很簡單,基本上是一對一的翻譯。
BeansDB項目可以說是一個簡化版的AWS DynamoDB,該項目在2008年啟動,2009年開源,第?版使?tokyo cabinet作為存儲引擎,2010年使?bitcask存儲格式重寫了存儲引擎,性能更好。BeansDB對key做哈希運算找到節點來實現分布和冗余, 一個寫操作會寫好幾個節點,而現在的配置是寫三份讀一份。BeansDB主要的特點是支持海量KV數據庫——相比Redis這種支持幾十個G到幾百個G的內存KV數據庫,BeansDB可以支持到上百T的數據。另外BeansDB最大的好處就是運維很簡單,性能、可用性、擴容都很好,也實現了最終一致性。
BeansDB中間的Proxy是用Go語言寫的,也是一個開源的組件。整體來說BeansDB的設計結構比較簡單,相比Redis那種有多種value 類型的方式,BeansDB的Value比較簡單一些。
在豆瓣內部建立了兩個不同的BeansDB集群,一個是doubandb,一個是doubanfs,分別針對不同的場景。doubandb主要存儲小型文本數據,如影評、用戶個人介紹、帖子內容等,這樣的好處是可以大大降低我們對MySQL的性能依賴,算是給MySQL減負;doubanfs主要存放圖片和音頻等中型數據。
DAE可以說是基于很多以前積累的、舊的組件做起來的。我們做的這種對內的PaaS,相比對外的PaaS而言做了很多簡化,尤其是安全方面如應用間隔離、權限管理方面,我們都不用像公有云那樣花大量精力去做,所以工作量其實還好。DAE現在在計劃開源,當然它現在只支持Python應用。以后我們也許會讓DAE支持Go語言。
上面是在線的部分,對高可用性和低時延有較大要求。離線部分則包括數據挖掘、數據分析等,技術組件分別是海量分布式文件系統MooseFS,這個文件系統的結構類似HDFS,用C語言編寫,其好處在于FUSE模塊實現的比較好,用文件系統就可以直接進行操作,而不需要專門的命令,可以支持的數據量也很大。另外就是自己開發的分布式計算平臺DPark。
DPark顧名思義是Spark的Python實現,不過現在已經跟Spark越來越不一樣了。和 Hadoop 相比,Spark可以使用內存做為緩存加速分布式計算,DPark繼承了這個優點,這對于大規模數據的迭代計算非常有用。在豆瓣的應用場景下,因為我們的離線計算很多是推薦算法計算,這種計算涉及大量的迭代算法,如果每次計算的結果都入磁盤再在下一輪計算加載,那性能是很差的,所以DPark能夠大幅提升性能。另外,因為DPark的編寫使用了函數式語言的特點,所以可以寫的非常簡潔: