Redis与缓存
# 为什么需要缓存
用缓存,主要有两个用途:高性能、高并发。
# 高性能
假设这么个场景,你有个操作,一个请求过来,吭哧吭哧你各种乱七八糟操作 mysql,半天查出来一个结果,耗时 600ms。但是这个结果可能接下来几个小时都不会变了,或者变了也可以不用立即反馈给用户。那么此时咋办?
缓存啊,折腾 600ms 查出来的结果,扔缓存里,一个 key 对应一个 value,下次再有人查,别走 mysql 折腾 600ms 了,直接从缓存里,通过一个 key 查出来一个 value,2ms 搞定。性能提升 300 倍。
就是说对于一些需要复杂操作耗时查出来的结果,且确定后面不怎么变化,但是有很多读请求,那么直接将查询出来的结果放在缓存中,后面直接读缓存就好。
# 高并发
mysql 这么重的数据库,压根儿设计不是让你玩儿高并发的,虽然也可以玩儿,但是天然支持不好。==mysql 单机支撑到 2000QPS
也开始容易报警了。==
所以要是你有个系统,高峰期一秒钟过来的请求有 1 万,那一个 mysql 单机绝对会死掉。你这个时候就只能上缓存,把很多数据放缓存,别放 mysql。缓==存功能简单,说白了就是 key-value
式操作,单机支撑的并发量轻松一秒几万十几万,支撑高并发 so easy。单机承载并发量是 mysql 单机的几十倍。==
缓存是走内存的,内存天然就支撑高并发。
# 为什么不使用本地缓存
目前本地缓存使用的方案有以下几种:
HashMap和ConcurrentHashMap
concurrentHashMap主要提供的是线程安全的map,他们的主要缺点就是功能太单一了,至少要有:过期时间、淘汰机制(内存达到阈值,触发淘汰机制)、命中率统计(判缓存失效机制设计是否合理)
一些本地缓存框架:Ehcache 、 Guava Cache 、 Spring Cache、Caffeine
这些框架可以简单了解一下其使用和原理,他们主要缺陷在于多个服务之间数据无法共享,甚至是数据存量也不够大,其实这也是本地缓存的通病。
总结一下本地缓存的局限性 :
对分布式架构支持不友好,如数据无法贡献
缓存容量受机器影响,使用的就是机器内存
高并发支持不佳,一般Mysql的QPS是1w左右,而redis可以达到10-30w,集群应该更高
# Redis与memcached缓存服务器
高性能键值缓存服务器memcached也经常被拿来与Redis进行比较:这两者都可用于存储键值映射,彼此的性能也相差无几,但是Redis能够自动以两种不同的方式将数据写入磁盘,并且Redis除了能存储普通的字符串键之外,还可以存储其他4种数据结构,而memcached只能存储普通的字符串键。这些及其他不同使得Redis可以用于解决更为广泛的问题,既可以作为主数据库(primary database)使用,又可以作为其他存储系统的辅助数据库(auxiliary database)使用。
具体地,它们两者的比较如下:
redis支持的数据类型更丰富,memcached只支持简单的k/v,而redis还支持list、set、zset、hash等
redis支持持久化,也就是支持将内存数据保存到磁盘中,保证了数据的安全,memcached就不可以
redis因为有持久化就可以实现灾难恢复,redis在遇到内存使用完成之后利用淘汰机制,将数据放到磁盘中,memcached则直接就抛异常了
redis是支持cluster模式的,memcached需要自己实现
Memcached 是多线程,非阻塞 IO 复用的网络模型;Redis 使用单线程****的多路 IO 复用模型(Redis 6.0 引入了多线程 IO )
redis提供更丰富的附加功能:发布订阅模型、Lua脚本、事务等
redis过期数据的删除策略有惰性删除和定期删除,而Memcached 只有惰性删除