MoSonic:对SubSonic的分布式存储、缓存改进方案尝试(1)
在公司內(nèi)部項目實(shí)現(xiàn)過程中團(tuán)隊對SubSonic增加了分布式存儲,透明對象緩存,透明查詢緩存的支持;內(nèi)部使用了兩三年,并且在持續(xù)改進(jìn)中。
MoSonic支持海量數(shù)據(jù)存儲,在web 2.0常見場景中其透明緩存層亦可帶來10倍以上的讀取性能提高。
這里寫blog記述一下。
改進(jìn)參考/使用了:
?
- FriendFeed Schemaless Database Design
- Twitter: Cache Money
- Facebook:Thrift
?
其中Cache Money影響較大,故內(nèi)部命名為MoSonic,Money-SubSonic。
=============
SubSonic是.net中一個相當(dāng)流行ORM庫,號稱零代碼。與其它ORM相比,SubSonic在易用性方面相當(dāng)突出。
但這也不意味著SubSonic,或者說ActiveRecord風(fēng)格的ORM僅能局限于中小網(wǎng)站的開發(fā)使用。
ActiveRecord實(shí)際上僅是Martin Fowler在《企業(yè)應(yīng)用架構(gòu)模式》一書中的一個小章節(jié)提出的,兩三頁紙而已。
但在Web 2.0時代,隨著被Ruby On Rails,Django等流行框架采用,而大放異彩。
Twitter建站之初也是采用Ruby On Rails,使用的也是RoR內(nèi)置的ActiveRecord風(fēng)格ORM。
隨著Twitter的發(fā)展,數(shù)據(jù)庫性能這塊也必然成為瓶頸。而Twitter對此的回答是Cache-Money,一個透明的ActiveRecord緩存層。
Cache-Money能夠透明的支持兩類緩存,Object Cache 跟 Vector Cache。
(當(dāng)然Cache-Money的作用不止這兩類緩存。)
=============
都是ActiveRecord,上層API風(fēng)格一致,Twitter可以在RoR的ORM中做的實(shí)現(xiàn),也一定可以在SubSonic上用c#做實(shí)現(xiàn)。
Object Cache比較好理解,它僅僅是基于對象主鍵緩存對象內(nèi)容。Object.FetchById(XXX) 這類函數(shù)中做下手腳,先查詢緩存,緩存不存在時,再去查詢數(shù)據(jù)庫。這也是所謂的Read-Through直讀緩存。
而Object.Save()在數(shù)據(jù)庫保存成功之后,也隨即更新Cache。這也是所謂的Write-Through直寫緩存。
Object的直讀/寫緩存實(shí)現(xiàn)非常簡單,對SubSonic的FetchById添加Object Cache的話,僅需要十來行代碼就可以使用單機(jī)內(nèi)存做緩存。
單機(jī)內(nèi)存非常有限,Web 2.0網(wǎng)站一般使用memecached做分布式緩存,解決單機(jī)緩存內(nèi)存有限的問題;這基本是標(biāo)配了。
就.Net而言,找個靠譜的memcached client的要比實(shí)現(xiàn)SubSonic的Object Cache更加重要。
我使用的是BeIt出品的memcached客戶端;據(jù)說性能更好的有EnyimMemcached,但我沒有詳細(xì)測試過,不好評論。
使用了Memcached做緩存的話,對象的序列化問題就變得非常突出了。
.Net內(nèi)置的BinaryFormatter性能非常差,必須另尋序列化方案。
考察過諸多序列化方案后,我最終選擇的是Facebook開源出來的Thrift;它的設(shè)計完備,跨語言/平臺支持能力非常好,性能不比Google開源出來的ProtoBuf差,也可以擴(kuò)展為進(jìn)程間RPC通訊方案。
為SubSonic添加對象Thrift序列化相對來說就比較麻煩些,但也不難,在SubSonic的代碼生成模板中修改即可。
Thrift本身實(shí)際上也有提供c#的對象序列化的代碼生成工具;但直接使用的話,意味著需要在Thrift對象/SubSonic對象間多增加一次轉(zhuǎn)換;修改代碼量雖然會少些,但不如直接修改SubSonic的代碼生成模板,直接將Thrift序列化的方法跟SubSonic對象做徹底的整合效率來得高。
使用Thrift做序列化跟使用.net默認(rèn)的BinaryFormater性能差別是巨大的。公司兩臺Web服務(wù)器,在使用BinaryFormater時CPU近乎100%,但改用Thrift做序列化后立刻下降至20%。
(團(tuán)隊倒不是在出現(xiàn)服務(wù)器性能問題后才做了Thrift序列化;提前一年就做了;只是因故做了次實(shí)際的性能測試。)
==========
既然修改了SubSonic的代碼生成模板,我也順便將其Object new()的API干掉了;強(qiáng)迫開發(fā)者必須使用FetchById風(fēng)格API獲得對象。
同時也增加了FetchByIds的新函數(shù),支持同時獲得多個對象,對應(yīng)select * from tables where id in (..., ...)的查詢,以及memcached multi_get的命令。
通過添加透明的Object cache在不增加額外的業(yè)務(wù)邏輯代碼情況下,已經(jīng)可以獲得顯著的性能改善,但它還不是本質(zhì)性的改進(jìn)。
Cache Money真正的神器是其Vector Cache,實(shí)際上,Twitter團(tuán)隊在開發(fā)Cache Money時,是優(yōu)先考慮了Vector Cache的實(shí)現(xiàn),然后再考慮Object Cache;因?yàn)樗麄冋J(rèn)為Vector Cache會性能影響更大,事實(shí)也證明他們判斷正確。
下篇會繼續(xù)講Vector Cache的實(shí)現(xiàn)。
?
轉(zhuǎn)載于:https://blog.51cto.com/wuvist/847729
總結(jié)
以上是生活随笔為你收集整理的MoSonic:对SubSonic的分布式存储、缓存改进方案尝试(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电力拖动计算机控制系统讲什么,电力拖动自
- 下一篇: 高职高考计算机网课app,本人准备高职高