另载于 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,每一个链接同时只能服务一个线程,有多少链接就有多少并发。若是有慢查询占住了链接,系统性能会急剧降低!缓存就能减轻对数据库链接的依赖。
本地缓存和分布式缓存各有千秋,通常建议用一致性更高的分布式缓存,当性能须要极端调优时,使用本地缓存。