一、什么是数据库缓存
MySQL 等一些常见的关系型数据库的数据都存储在磁盘当中,在高并发场景下,业务应用对 MySQL 产生的增、删、改、查的操作造成巨大的 I/O 开销和查询压力,这无疑对数据库和服务器都是一种巨大的压力,为了解决此类问题,缓存数据的概念应运而生。
- 极大地解决数据库服务器的压力
- 提高应用数据逇响应速度
常见的缓存形式:内存缓存、文件缓存
二、为什么要使用缓存
缓存数据是为了让客户端很少甚至不访问数据库服务器进行数据的查询,高并发下,能最大程度地降低对数据库服务器的访问压力。
用户请求~>数据查询~>连接数据库服务器并查询数据~>将数据缓存起来( HTML 、内存、 JSON 、序列化数据)一>显示给客户端
用户再次请求或者新用户访问一>数据查询一>直接从缓存中获取数据一>显示给客户端
缓存需要考虑的内容
- 1、缓存方式的选择
- 2、缓存场景的选择
- 3、缓存数据的实时性
- 4、缓存数据的稳定性
三、使用Mysql查询缓存
启用Mysql查询缓存
极大地降低CPU使用率
query_cache_type 查询缓存类型,有0、1、2 三个取值 0不使用,1表示始终使用,2表示按需使用
query_cache_type = 1时,也可以关闭查询缓存
select SQL_NO_CACHE * from tbl_name where condition;
query_cache_type = 2
select SQL_CACHE * from tbl_name where condition;
query_cache_size 默认为0,表示查询缓存预留的内存为0,则无法使用查询缓存
SET GLOBAL query_cache_size = 11312312
查询缓存可以看做是SQL文本和查询结果的映射
第二次查询的SQL和第一次查询的SQL完全相同,则会使用缓存
show status like “Qcache_hits” #查看命中次数
表的结构或数据发生变化是,查询缓存的数据不再有效
清理缓存
flush query cache;//清理查询缓存内存碎片
reset query cache;//从查询缓存中移出所有查询
flush tables;//关闭所有打开的表。同事清空上查询缓存中的内容
四、使用Memcache缓存
对于大型站点,如果没有中间缓存层,当流量打入数据库层时,即便有之前的几层为我们档住一部分流量,但是在大并发的情况下,还是会有大量请求涌入数据库层,这样对于数据库服务器的压力冲击很大,响应速度也会下降,因此添加中间缓存层很有必要。
memcache 是一套分布式的高速缓存系统,由 Livejournal 的 Brad Fitzpatrick 开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著
工作原理
Memcache 是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的 hash 表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存,然后从内存中读取,从而大大提高读取速度
工作流程
先检查客户端的请求数据是否在 memcached 中,如有,直接把请求数据返回,不再对数据库进行任何操作;如果请求的数据不在 m emcached 中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到 memcached 中
方法
- 获取 get(key)
- 设置 set (key, val,expire)
- 删除 delete(key)
- 通用缓存机制
- 用查询的方法名+参数作为查询时的key value 对应的key值
五、使用Redis缓存
1、什么是redis
redis是nosql(也是个巨大的map) 单线程,但是可处理1秒10w的并发(数据都在内存中)
使用java对redis进行操作类似jdbc接口标准对mysql,有各类实现他的实现类,我们常用的是druid
其中对redis,我们通常用Jedis(也为我们提供了连接池JedisPool)
在redis中,key就是byte
redis的数据结构(value):String,list,set,orderset,hash
2、 redis的使用
先安装好redis,然后运行,在pom文件中引入依赖,在要使用redis缓存的类的mapper.xml文件配置redis的全限定名。引入redis的redis.properties文件(如果要更改配置就可以使用)
应用场景:
- String :
- 存储json类型对象
- 计数器
- 优酷视频点赞等
- list(双向链表)
- 可以使用redis的list模拟队列,堆,栈
- 朋友圈点赞(一条朋友圈内容语句,若干点赞语句)
- 规定:朋友圈内容的格式:
- 内容: user:x:post:x content来存储;
- 点赞: post:x:good list来存储;(把相应头像取出来显示)
- hash(hashmap)
- 保存对象
- 分组
3、string与hash的数据差别
在网路传输时候,必须要进行进行序列化,才可以进行网路传输,那么在使用string类型的类型的时候需要进行相关序列化,hash也是要进行相关的系列化,所以会存在很多序列化,在存储的时候hash是可以存储的更加丰富,但是在反序列化的时候,string的反序列化相对较低,而hash的序列化和返序列化是相对hash类更加复杂,所以看业务场景,如果是数据经常修改的那种,为了性能可以使用string,如果是数据不是经常改的那种就可以使用hash,由于hash,存储数据时比较丰富,可以存储多种数据类型
4、redis的持久化方式:
能,将内存中的数据异步写入硬盘中,两种方式:RDB(默认)和AOF
RDB持久化原理:通过bgsave命令触发,然后父进程执行fork操作创建子进程,子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换(定时一次性将所有数据进行快照生成一份副本存储在硬盘中)
优点:是一个紧凑压缩的二进制文件,Redis加载RDB恢复数据远远快于AOF的方式。
缺点:由于每次生成RDB开销较大,非实时持久化,
AOF持久化原理:开启后,Redis每执行一个修改数据的命令,都会把这个命令添加到AOF文件中。
优点:实时持久化。
缺点:所以AOF文件体积逐渐变大,需要定期执行重写操作来降低文件体积,加载慢
5、redis单线程为什么这么快
redis是单线程的,但是为什么还是这么快呢,
原因1: 单线程,避免线程之间的竞争
原因2 :是内存中的,使用内存的,可以减少磁盘的io
原因3:多路复用模型,用了缓冲区的概念,selector模型来进行的
6、redis主挂了怎么操作
redis提供了哨兵模式,当主挂了,可以选举其他的进行代替,哨兵模式的实现原理,就是三个定时任务监控,
- 每隔10s,每个S节点(哨兵节点)会向主节点和从节点发送info命令获取最新的拓扑结构
- 每隔2s,每个S节点会向某频道上发送该S节点对于主节点的判断以及当前Sl节点的信息,同时每个Sentinel节点也会订阅该频道,来了解其他S节点以及它们对主节点的判断(做客观下线依据)
- 每隔1s,每个S节点会向主节点、从节点、其余S节点发送一条ping命令做一次心跳检测(心跳检测机制),来确认这些节点当前是否可达
当三次心跳检测之后,就会进行投票,当超过半数以上的时候就会将该节点当做主
7、redis集群
redis集群在3.0以后提供了ruby脚本进行搭建,引入了糙的概念,
Redis集群内节点通过ping/pong消息实现节点通信,消息不但可以传播节点槽信息,还可以传播其他状态如:主从状态、节点故障等。因此故障发现也是通过消息传播机制实现的,主要环节包括:主观下线(pfail)和客观下线(fail)
主客观下线:
主观下线:集群中每个节点都会定期向其他节点发送ping消息,接收节点回复pong消息作为响应。如果通信一直失败,则发送节点会把接收节点标记为主观下线(pfail)状态。
客观下线:超过半数,对该主节点做客观下线
主节点选举出某一主节点作为领导者,来进行故障转移。
故障转移(选举从节点作为新主节点)
8、内存淘汰策略
Redis的内存淘汰策略是指在Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。
noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。
9、缓存击穿的解决方案:
原因:就是别人请求数据的时候,很多数据在缓存中无法查询到,直接进入数据查询,
解决方法,对相关数据进行查询的数据只查询缓存,如果是一些特殊的可以进行数据库查询,也可以采用布隆过滤器进行查询
10、缓存雪崩的解决方案:
缓存雪崩的原因:一次性加入缓存的数据过多,导致内存过高,从而影响内存的使用导致服务宕机
解决方法:
- redis集群,通过集群方式将数据放置
- 后端服务降级和限流:当一个接口请求次数过多,那么就会添加过多数据,可以对服务进行限流,限制访问的数量,这样就可以减少问题的出现
11、与Memcache的区别
1、性能相差不大
2、Redis2.0版本后增加了自己的VM特性,突破物理内存的限制,Memecache可以修改最大可用内存,采用LRU算法
3、Redis依赖客户端实现分布式读写
4、Memcache本身没有数据冗余机制
5、Redis支持快照,AOF,依赖快照进行持久化,AOF增强了可靠性的同时,对性能有所影响
6、Memcache不支持持久化,通常做缓存,提升性能
7、Memcache在并发场景下,用cas保证一致性,redis事务处理比较弱,只能保证事务中的每个操作连续执行
8、Redis支持多种数据类型 字符串string,列表list,散列hash,集合set,有序集合sorted set
9、Redis用于数据量较小的高性能操作和运算上
10、Memecache用于在动态系统中减少数据库的负载,提升性能,适合做缓存,提高性能
六、缓存其他数据
Session
session_set_save_handle
网友评论