MoSonic:對SubSonic的分佈式存儲、緩存改進嘗試(2)

上文html

Cache Money真正牛X的地方是在Vector Cache。在生產環境中,它不只相對Object Cache命中率較更高,帶來的性能飛躍更是可觀。java

在MoSonic的性能測試中,獲得了有10倍的性能提升。web

Vector Cache性能恐怖,但它對錶結構,查詢類型,有至關的嚴格的要求;列舉以下:算法

  • 表必須以自增數字(int / long)id爲主鍵
  • 查詢的where中必須是 = 等於條件,如where user_id=1
  • 多個where條件的話,相互關係必須是And,如where user_id=1 and id_deleted=0
  • 查詢結果僅能是數據id,如 select id from users where ... 不能夠是 select user_name from users where ...
    • 也能夠是 select count(*) from users where ...
    • 查詢結果支持分頁
  • 查詢結果必須以id排倒序,也就是order by id desc

只有徹底符合上面五個條件,Vector Cache才能夠生效;幸運的是,在web 2.0網站中,這類結構/查詢正好是最多見的。數據庫

以博客爲例,博客文章列表顯示,分類文章數量,評論顯示等等,基本都符合上述的查詢。緩存

比方說,要得到等級爲1的用戶時,須要使用下面的兩個查詢:ruby

 

  • select id from users where level=1
  • select * from users where id in (....)

 

兩個查詢cache money均可以徹底緩存,若是直接使用:架構

 

  • select * from users where level=1

 

的話,cache money則會徹底失效。併發

對於兩種風格的查詢孰優孰劣,能夠參考JavaEye老大Robin以前寫的:爲何ORM性能比iBATIS好數據庫設計

=============

由於要求了查詢結果必須是id,而且排倒序,Vector Cache其實是能夠作到實時自動更新,而不是自動過時。

考慮這樣的調用:

 

  1. select count(id) from photos where album_id=1 order by id desc limit 1, 100
  2. select id from photos where album_id=1 order by id desc limit 1, 100
  3. insert into photos (album_id)values(1)
  4. select count(id) from photos where album_id=1 order by id desc limit 1, 100
  5. select id from photos where album_id=1 order by id desc limit 1, 100

 

顯示列表,插入數據,再次顯示列表;這是至關典型調用。

第1/2步查詢會有緩存(即使是沒有緩存,查詢以後,緩存也會自動被生成,也就是所謂的直讀)。

第3步插入數據時,得到數據庫自增的ID後,能夠直接將此id追加到第1/2步查詢緩存結果中。

第4/5步查詢直接命中第3步寫數據時更新的緩存;徹底無需查詢數據庫。

在查詢、應用場景符合的理想狀況下,有了Vector Cache,數據庫讀能夠變成恐怖的0讀取

數據庫僅須要承擔寫壓力,100%的讀都有Memcache的自動緩存。

這纔是Cache Money的Vector Cache帶來讀性能飛躍的緣由。

全部的數據庫查詢都變成了memcache get;memcache單機時在讀能力,併發負荷能力上都要比傳統關係型數據庫高一個數量級;並且其shared nothing的架構,又能夠水平擴張。

在高併發,多機緩存的狀況下,能夠預料Cache Money帶來的讀性能提升遠不止10倍。

==============

Twitter的工程師對Cache Money的實現至關巧妙,他們針對一個限制多多的場景作到了100%的讀緩存;而這個「限制多多」又偏偏是web 2.0網站中的最典型場景。

我在MoSonic中實現Vector Cache時,徹底照搬了Cache Money的實現算法;就是C#的代碼量比ruby膨脹了幾倍。

:)

下篇會繼續講MoSonic對FriendFeed分佈式數據庫設計的引用。

相關文章
相關標籤/搜索