轉自:http://www.cnblogs.com/lovecindywang/archive/2010/05/19/1739025.htmlphp
先說說本身對Memcache和Mongodb的一些見解。主要是拋磚引玉了,但願看到你們的意見和補充。 html
Memcache前端
Memcache的優點我認爲總結下來主要體現在:數據庫
1) 分佈式。可以由10臺擁有4G內存的機器,構成一個40G的內存池。假設認爲還不夠大可以添加機器,這樣一個大的內存池,全然可以把大部分熱點業務數據保存進去。由內存來阻擋大部分對數據庫讀的請求。對數據庫釋放可觀的壓力。緩存
2) 單點。安全
假設Webserver或Appserver作負載均衡的話,在各自內存中保存的緩存可能各不一樣樣。假設數據需要同步的話,比較麻煩(各自本身過時,仍是分發數據同步?)。即便數據並不需要同步。用戶也可能因爲數據的不一致而產生用戶體驗上的不友好。網絡
3) 性能強。不用懷疑和數據庫相比確實是。根源上仍是內存的讀寫和磁盤讀寫效率上幾個數量級的差距。有的時候咱們在抱怨數據庫讀寫太差的狀況下可以看看磁盤的IO,假設確實是瓶頸的話裝啥強勁的數據庫預計也檔不了,強不強無非是這個數據庫多少充分的利用了內存。多線程
但是也不太建議在不論什麼狀況下使用Memcache替代不論什麼緩存:負載均衡
1) 假設Value特別大,不太適合。因爲在默認編譯下Memcache僅僅支持1M的Value(Key的限制到不是最大的問題)。事實上從實踐的角度來講也不建議把很大的數據保存在Memcache中,因爲有序列化反序列化的過程。別小看它消耗的CPU。講到這個就要提一下,我一直認爲Memcache適合面向輸出的內容緩存,而不是面向處理的數據緩存,也就是不太適合把大塊數據放進去拿出來處理以後再放進去。而是適合拿出來就直接給輸出了。或是拿出來不需要處理直接用。分佈式
2) 假設不一樣意過時,不太適合。
Memcache在默認狀況下最大30天過時,而且在內存達到使用限制後它也會回收最少使用的數據。所以,假設咱們要把它看成static變量的話就要考慮到這個問題,必須有又一次初始化數據的過程。事實上應該這麼想,既然是緩存就是拿到了存起來。假設沒有必然有一個又一次獲取又一次緩存的過程,而不是想着它永遠存在。
在使用Memcache的過程當中固然也會有一些問題或者說最佳實踐:
1) 清除部分數據的問題。
Memcache僅僅是一個Key/Value的池,一個公共汽車誰都可以上。我認爲對於相似的公共資源。假設用的人都依照本身的規則來的話很是easy出現故障。
所以。最好在Key值的規範上上使用相似命名空間的概念。 每一個用戶都能很是明白的知道某一塊功能的Key的範圍。或者說前綴。帶來的優勢是咱們假設需要清空的話可以依據這個規範找到咱們本身的一批Key而後再去清空,而不是清空所有的。固然有人是採用版本號升級的概念。老的Key就讓它過去吧。到時候天然會清空,這也是一種辦法。只是Key有規範老是有優勢的,在統計上也方便一點。
2) Value的組織問題。
也就是說咱們存的數據的粒度,比方要保存一個列表。是一個保存在一個鍵值仍是統一保存爲一個鍵值,這取決於業務。
假設粒度很是小的話最好是在獲取的時候能批量獲取,在保存的時候也能批量保存。對於跨網絡的調用次數越少越好,可以想一下,假設一個頁面需要輸出100行數據,每一個數據都需要獲取一次。一個頁面進行上百次鏈接這個性能會不會成問題。
那麼Memcache主要用在哪些功能上呢?
事實上我認爲平時能想到在內存中作緩存的地方咱們都可以考慮下是否是可以去適用分佈式緩存,但是基本的用途仍是用來在前端或中部擋一下讀的需求來釋放WebserverAppserver以及DB的壓力。
Mongodb
Mongodb是一款比較優良的非關係型數據庫的文檔型的數據庫。它的優點主要體現在:
1) 開源。意味着即便咱們不去改也可以充分挖掘它,MS SQL除了看那些文檔。誰又知道它內部怎樣實現。
2) 免費。意味着咱們可以在大量垃圾server上裝大量的實例。即便它性能不怎麼高,也架不住許多的點啊。
3) 性能高。其餘沒比較過。和MS SQL相比,相同的應用(主要是寫操做)一個撐500用戶就掛了,一個可以撐到2000。
在數據量上到百萬以後。即便沒索引,MS SQL的插入性能降低的也一塌糊塗。事實上不論什麼事物都有相對性的,在變得複雜變得無缺了以後會犧牲一部分的性能,MS SQL體現的是很強的安全性數據完整性,這點是Mongodb辦不到的。
4) 配置簡單並且靈活。在生產環境中對數據庫配置故障轉移羣集和讀寫分離的數據庫複製是非常常見的需求,MS SQL的配置繁瑣的步驟仍是很是恐怖的。而Mongodb可以在五分鐘以內配置本身所需要的故障轉移組,讀寫分離更是僅僅需要一分鐘。靈活性體現在,咱們可以配置一個M一個S。兩個M一個S(兩個M寫入的數據會合併到S上供讀取),一個M兩個S(一個M寫入的數據在兩個S上有鏡像),甚至是多個M多個S(理論上可以建立10個M。10個S,咱們僅僅需要經過輪詢方式隨便往哪一個M上寫,需要讀的時候也可以輪訓隨意一個S。固然咱們要知道不可能保證在同一時間所有的S都有一致的數據)。那麼也可以配置兩個M的對做爲一套故障轉移羣集,而後這種羣集配置兩套。再相應兩個S,也就是4個M相應2個S,保證M點具備故障轉移。
5) 使用靈活。
在以前的文章中我提到甚至可以經過SQL到JS表達式的轉換讓Mongodb支持SQL語句的查詢,不管怎麼說Mongodb在查詢上仍是很是方便的。
以前也說過了。並不是所有數據庫應用都使用採用Mongodb來替代的,它的主要缺點是:
1) 開源軟件的特色:更新快,應用工具不無缺。由於更新快,咱們的client需要隨着它的更新來升級才幹享受到一些新功能,更新快也意味着很是可能在某一階段會缺少某個重要功能。另外咱們知道MS SQL在DEV/DBA/ADM多個維度都提供了很是好的GUI工具對數據庫進行維護。而Mongodb儘管提供了一些程序。但是並不是很是友好。
咱們的DBA可能會很是鬱悶,去優化Mongodb的查詢。
2) 操做事務。Mongodb不支持內建的事務(沒有內建事務不意味着全然不能有事務的功能),對於某些應用也就不適合。只是對於大部分的互聯網應用來講並不存在這個問題。
在使用Mongodb的過程當中主要遇到如下的問題:
1) 真正的橫向擴展?在使用Memcache的過程當中咱們已經體會到這樣的爽了,基本可以無限的添加機器來橫向擴展。因爲什麼,因爲咱們是經過client來決定鍵值保存在那個實例上,在獲取的時候也很是明白它在哪一個實例上。即便是一次性獲取多個鍵值,也是相同。而對於數據庫來講,咱們經過各類各樣的方式進行了Sharding,不說其餘的。在查詢的時候咱們依據必定的條件獲取批量的數據,怎麼樣去處理?比方咱們依照用戶ID去分片,而查詢根本不在意用戶ID,在意的是用戶的年齡和教育程度,最後依照姓名排序。到哪裏去取這些數據?不管是基於client仍是基於服務端的Sharding都是很是難作的,並且即便有了本身主動化的Sharding性能不必定能有保障。
最簡單的是儘可能依照功能來分。再下去就是歷史數據的概念,真正要作到實時數據分散在各個節點,仍是很是困難。
2) 多線程,多進程。在寫入速度達不到預期的狀況下咱們多開幾個線程同一時候寫。或者多開幾個Mongodb進程(同一機器),也就是多個數據庫實例,而後向不一樣的實例去寫。
這樣可否提升性能?很是遺憾,很是有限。甚至可以說根本不能提升。爲何使用memcache的時候多開線程可以提升寫入速度?那是因爲內存數據交換的瓶頸咱們沒達到,而對於磁盤來講,IO的瓶頸每秒那麼幾十兆的是很是easy達到的,一旦達到這個瓶頸了,不論是開多少個進程都沒法提升性能了。
還好Mongodb使用內存映射,看到內存使用的多了。事實上我對它的信心又多了一點(內存佔用多了我認爲CPU更easy讓它不閒着),怕就怕某個DB不使用什麼內存。看着IO瓶頸到了,內存和CPU仍是吃不飽。
Memcache和Mongodb的配合
事實上有了Memcache和Mongodb咱們甚至可以讓80%以上的應用擺脫傳統關係型數據庫。
我能想到它們事實上可以互相配合彌補對方的不足:
Memcache適合依據Key保存Value,那麼有的時候咱們並不知道需要讀取哪些Key怎麼辦呢?我在想是否是可以把Mongodb或說數據庫看成一個原始數據。這份原始數據中分爲需要查詢的字段(索引字段)和普通的數據字段兩部分。把大量的非查詢字段保存在Memcache中。小粒度保存,在查詢的時候咱們查詢數據庫知道要獲取哪些數據,通常查詢頁面也就顯示20-100條吧。而後一次性從Memcache中獲取這些數據。也就是說。Mongodb的讀的壓力主要是索引字段,而數據字段僅僅是在緩存失效的時候才實用,使用Memcache擋住大部分實質數據的查詢。
反過來講,假設咱們要清空Memcache中的數據也知道要清空哪些Key。
附錄:
對於Memcached自己對value值大小的限制,筆者在這裏單獨強調下,踩過坑。可以查看這個文章:http://blog.csdn.net/billfeller/article/details/17200245
案例分析:公司使用LimeSurvey開源問卷調查系統進行用戶調查,但是上線一段時間後出現用戶明確提交了問題答案。系統卻總是提示該題必填,追蹤結果代表是因爲LimeSurvey把大量問卷相關信息寫到會話時。而php會話配置是存儲到memcached的。當信息超過1M時就會出現數據丟失。致使系統以爲用戶未提交問題。因此需要強調下Memcached用法——Memcached僅僅是分佈式緩存,請儘可能不要將其作爲數據容器進行業務數據存儲。