另載於 http://www.qingjingjie.com/blogs/13數據庫
大略談一下,各位輕拍哦!緩存
服務端性能優化,除了重構,最經常使用的手段就是緩存。緩存主要分爲本地緩存和分佈式緩存兩種。性能優化
根據咱們每日千萬次訪問的經驗來看,緩存不是必須的。優化充足的狀況下,SQL平均耗時1ms。這是由於命中了索引,而且命中了MySQL緩衝池(內存中)。若是命中索引但不命中緩衝池,且查詢數據量不大,磁盤併發量不高,則大約耗時10ms(磁盤尋道)。若是這些都不知足,耗時就大了。網絡
因此首先要建設的是索引,一切供查詢的字段能索引就索引。有的字段取值多樣性很小,好比布爾值、枚舉值,就不適合索引(就算命中索引也可能要全盤掃描),查詢時要聯合其餘字段過濾下,纔會快。Replication, Sharding也是好辦法,能用就用上。併發
本地緩存是應用程序在同一JVM內的緩存,一般是ConcurrentHashMap或Guava Cache。優勢是耗時低得忽略不計,缺點是佔用本地內存、多機會冗餘、數據不一樣步。當集羣裏每一個App Server都有個緩存,會有不少數據是重複的,並且某臺機器更新了一條數據,別的機器不知道啊,只能等緩存過時。分佈式
同步問題能夠用消息隊列來解決,一臺有更新,廣播消息給其餘機器,準實時同步。性能
Guava Cache有expire或refresh兩種過時方式,expire是過時就丟棄,refresh是過時先留着舊值,取到新值再更新。expire會有點性能波動,爲了響應性能夠選擇refresh方式。另外建議設個上限,量太多會影響GC的。優化
根據Jim Gray的經驗數字,過時時間一般以5分鐘爲宜(主要仍是看你業務哦)。線程
分佈式緩存是Memcached/Couchbase, Redis這類,訪問要通過網絡,多少會有一點點開銷。Memcached或Redis自己就要有集羣,不然一旦扛不住併發,還不如數據庫呢。某臺App Server更新了一條數據,就通知緩存把這條更新或丟棄,確保其餘Server能拿到最新結果。blog
查詢操做要有超時設置。注意耗時,若是超過10ms就有點很差了。
緩存服務用來存複雜查詢的結果卻是極合適的,這時候比數據庫快得多。
緩存除了加快訪問之外,也能提升負載能力。由於數據庫鏈接是有限的資源——不支持NIO,每一個鏈接同時只能服務一個線程,有多少鏈接就有多少併發。若是有慢查詢佔住了鏈接,系統性能會急劇降低!緩存就能減輕對數據庫鏈接的依賴。
本地緩存和分佈式緩存各有千秋,通常建議用一致性更高的分佈式緩存,當性能須要極端調優時,使用本地緩存。