日升时奋斗,日落时自省
目录
edis安装及配置
Redis基础认识就从安装Redis来了解
这里就下载在Linux服务器上,当前可以安装在Windows上,但是我们基本都是将项目架在服务器上的,这里也是针对Redis在服务器上的使用
(1)使用命令将redis 安装到 linux服务器:
yum -y install redis
如果当前不能进行安装,进行操作:
安装一个压缩功能
yum install -y lrzsz
(2)启动redis
以后台的运行方式启动redis:
redis-server /etc/redis.conf &
(3)操作redis
命令启动redis客户端:
redis-cli
前两步就不在进行演示,我这里已经安装好了,这里来看一下redis启动怎么样
回车之后就会体现回环IP和端口号(当前端口号“6379”是独有的)
(4)设置远程连接
<1>将redis配置文件下载到本地:redis配置文件是Linux下的/etc/redis.conf;
<2>将redis.conf中的“bind 127.0.0.1”注释掉;(解决访问本机)
<3>将redis.conf中的“protected-mode yes”改为“protected-mode no”;(关闭保护模式)
<4>将修改后的redis.conf上传至linux下的/etc目录
<5>使用命令“redis-cli shutdown”先关闭redis服务,在使用“redis-server /etc/redis.conf &” 启动redis服务
以上服务进行演示,在演示之前这里给友友们提供一个比较方便的linux终端软件,FinalShell下载和安装过程也比较简单,所以这里就不在进行演示,一直下一步就可以,可以设置安装位置;
以上配置好以后,将redis关闭,重新启动就可以了;
注:这里先给友友们推荐一个软件Another Redis Desktop Manager 找个3.0以上版本就够用了,方便我们看设置的信息
2、缓存简介
在程序中,也无非就是直接调用数据库取数据在很早之前,一个两个访问数据库没事,但是多个人访问数据库呢,数据库的资源也有限,也很昂贵,因此为防止数据库被过度的浪费,就有了缓存
缓存也就是部分常用数据存在这里,每次程序调用的时候会先走缓存,如果缓存没有在去访问数据库,下面通过图来分析
使用缓存之后:
注:所有的程序不会直接调用数据库,而是会先调用缓存,当缓存中有数据时会直接返回,当缓存中没有数据时才去查询数据库,这样就大大的降低了数据库的压力,并加速了程序的响应速度。
2.1、缓存优点
相比于数据库而言,缓存的操作性能更高,缓存性能高的主要原因:
<1>缓存一般都是key-value查询数据的,因为不像数据库一样还有查询的条件等因素,所以查询的性能一般会比数据库高
<2>缓存的数据是存储在内存中的,而数据库的数据是存在磁盘中,因为内存的操作性能远远大于磁盘,因此缓存的查询效率会高很多
<3>缓存更容易做分布式部署(当一台服务器变成多台相连的服务器集群),而数据库一般比较难实现分布式部署,因此缓存的负载和性能更容易平行扩展和增加
2.2、缓存分类
缓存大致可以分为两大类:
<1>本地缓存
本地缓存也叫单机缓存,也就是说可以应用在单机环境下的缓存。所谓的单机环境是指,将服务部署到一台,本地缓存的优点是读取速度快,但是不能进行大数据量存储,本地缓存的特征是只适用于当前系统
<2>分布式缓存
分布式缓存是指可以应用在分布式系统中的缓存。所谓的分布式系统是指将一套服务器部署到多台服务器,并且通过负载分发将用户的请求按照一定的规则分发到不同的服务器
2.3、常见缓存使用
本地缓存常见使用:Spring Cache 、MyBatis 缓存
分布式缓存常见使用:Redis 和 Memcached
2.3.1、Spring Cache
在Spring Boot 项目,可以直接使用Spring 的内置Cache(本地缓存),只需要完成以下是哪个个步骤就可以正常使用了(这里没有代码分析)。
<1>开启缓存
<2>操作缓存
<3>调用缓存
2.3.2、Redis
在Spring 框架中我们也可以直接操作Redis缓存
项目是不同的操作同一个Redis,因此Redis对于整个项目来说是全局的(分布式)
Redis和Memcached区别:
Redis和Memcached都是基于内存的数据存储系统,但是有一些区别。
存储方式:Memcached是高性能分布式内存缓存服务,而Redis是一个开源的key-value存储系统。与Memcached类似,Redis将大部分数据存储在内存中(不是全部);
数据类型:Memcached支持字符串、哈希表、链表等数据类型的相关操作。但是,Redis还提供了一些其他的功能,例如:事务支持、持久化、Lua脚本支持等等(相对比较丰富)
存储大小:Redis最大可以达到512mb,memcache只有1mb
3、Redis数据类型和使用
Redis有5个基础数据类型:String(字符串类型)、Hash(哈希类型)、List(列表类型)、Set(集合类型)、ZSet有序集合类型
注:常用类型:字符串和哈希类型
3.1、字符串类型
使用方法:
创建操作:
set user hello
set添加数据键值key-value 这里的user 就是key值 ,hello就是value
获取操作:
get user
get获取key对应的value 这里就是获取user的value值
字符串使用场景:
<1>存放用户登录信息
<2>存放文章详情和列表信息
<3>存放和累计网页的统计信息
3.2、哈希类型
哈希类型又成为散列类型或者是哈希表类型,它是将一个键值和一个特殊的“哈希表"关联起来,这个“哈希表”表包含两列数据:字段的和值它就相当于Java中的Map<String,Map<String,String>>结构这里的字典类型,下面图解一下
我们用字典类型存储用户信息,并且使用字典类型来存储此类信息就无需手动序列化和反序列化数据了,使用起来更加高效和方便
使用方法:
哈希类型的的数据结构就类似于一个哈希表,每个数组后都是一个链表,这里再图解一下
注:这里只是为了演示其数据结构,不是次都使用链表的方式来存储的,一般情况下都是采用哈希方式存储的,但发生哈希冲突时才会使用链表结构来存储数据
3.3、列表类型
列表类型(List)是一个使用链表结构存储的有序结构,它的元素插入会按照先后顺序存储到链表结构中,因此它的元素操作中插入和删除的时间复杂度为O(1),相对来说速度上还是比较快的,但是它查询的时间复杂度为O(n),查询就会比较慢了
使用方法:
插入操作:
lpush list 2 3 4
就lpush就是给list赋值可以赋值多个,用空格隔开,所以这里就是给list赋值了2 3 4 这三个值
查询操作:
lrange list start stop
lrange就是查询的关键词 list就是我们存储值的名称,start就是从几开始查询 ,stop就是截止位置
删除操作:
lpop list
lpop是删除的关键词 list就是删除列表的名称,这里没有具体的删除值,因为只能删除第一个元素
使用场景:
消息队列:列表类型使用rpush实现先进先出的功能,同时有可以使用lpop轻松弹出,拥来实现消息队列
文章列表:对于自己的文章列表就可以使用List存储,是有序的结构,所以这样又可以完美的实现分页功能,从而加快程序的响应速度
3.4、集合类型
集合类型(set)是一个无序并唯一的键值集合
添加键值集合:
sadd myset 2 3 4
查询集合:
smembers myset
集合类型的经典使用场景如下:
<1> “关注”这个词是现在很常见一个词,但是关注者是不能重复的,这里就可以使用集合来存储
<2>身份证信息也可以类似于这样存储,因为身份证也是独一份的
集合类型(Set)和列表类型(List)区别:
<1>列表可以存储重复的元素,集合只能存储非重复元素
<2>列表存储是有顺序的,而集合存储是没有顺序的
3.5、有序集合类型
有序集合类型(Sorted Set)相比于集合类型多了一个排序属性score(分值),对于有序集合ZSet,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个排序值。有序集合的存储元素值也是不能重复的,但分值是可以重复的
添加元素:
zadd zset1 分值 元素值 (可以有多个分值和元素值)
查询所有元素:
zrange zset1 start stop
查询和之前基本没有什么不同,从start对应的分值开始,stop是结束分值,查询也是依据分值进行查询的
4、持久化
持久化:将数据从内存保存到磁盘的过程,目的就是为了防止数据丢失
Redis与Memcached的主要区别之一也是持久化,Redis支持持久化而Memcached不支持
Redis有这三种持久化方式:快照方式(RDB),文件追加方式(AOF),混合持久化方式
注:redis-cli命令行中执行config set aof-use-rdb-preamble yes 来开启混合持久化,当
开启混合持久化时 Redis 就以混合持久化⽅式来作为持久化策略;当没有开启混合持久化的情况下,使⽤ config set appendonly yes 来开启 AOF 持久化的策略,当 AOF 和混合持久化都没开启的情况下默认会是 RDB 持久化的⽅式
4.1、RDB
快照方式:将某一一个时刻的内存数据,以二进制的方式写入磁盘
4.1.1、RDB优点
存储方式:为二进制的数据,占用内存小,适合备份
传输效率:文件紧凑,传输到远程服务器更快
相比于AOF格式,RDB可以更快的重启,减少重启的时间
4.1.2、RDB缺点
<1>保存数据受限,只是一段时间的数据,如果中途Redis服务器意外终止,会丢失一段时间的数据
<2>需要经常fork()才能使用子进程持久化到磁盘上,如果数据集很大,fork很多次耗时很多,cpu性能降低,可能导致Redis停止为客户端服务几毫秒长可达一秒钟
4.2、AOF
文件追加方式:记录所有操作命令,并以文本的形式追加到文件中
4.2.1、AOF优点
<1>AOF持久化保存的数据更加完整,AOF提供了三种保存策略,每次操作保存,每秒钟保存一次,跟随系统的持久化策略保存,Redis进程挂了,最多丢掉1秒钟的数据
<2>AOF 采⽤的是命令追加的写⼊⽅式,所以不会出现⽂件损坏的问题,即使由于某些意外原因,也可以通过 redis-check-aof ⼯具轻松的修复,AOF日志文件以append-only模式写入,写入性能比较稳定;
<3>它是把所有 Redis 键值操作命令,以⽂件的⽅式存⼊了磁盘。即使不⼩⼼使⽤ flushall 命令删除了所有键值信息,只要使⽤ AOF ⽂件,删除最后的 flushall 命令,重启 Redis 即可恢复之前误删的数据
4.2.2、AOF缺点
<1>AOF文件比RDB文件大,因为它会记录所有的写操作,而不仅仅是最近一次的快照。
<2>AOF的速度可能会比RDB慢,因为它需要执行fsync操作来保证数据的一致性。
4.3、混合持久化
优点:混合持久化结合了 RDB 和 AOF 持久化的优点,可以在保证数据安全性的同时,提高Redis的读写性能
缺点:AOF ⽂件中添加了 RDB 格式的内容,使得 AOF ⽂件的可读性变得很差,版本限制4.0之前版本使用不了
5、缓存相关问题
5.1、缓存雪崩
缓存雪崩是指在一个时间段内,缓存中大量的数据同时失效,导致请求都落在了数据库上,从而引起数据库压力过大,甚至崩溃(这里有点绕,我们进行图解)
5.1.1、解决方案
<1>加锁排队:在缓存失效时,先将请求加入到一个队列中,然后通过加锁的方式,依次从队列中取出请求并访问数据库,直到所有请求都处理完毕,这是以降低部分用户体验的一种缓冲方法(相对比较影响性能)
<2>设置不同的过期时间,避免缓存在同一时间过期(减少访问数据库访问量)
<3>采用多级缓存、异步更新缓存(实际举例理解:在一级缓存中访问不到的话,就会去访问二级缓存,异步其实与多级缓存比较相仿)
5.2、缓存穿透
缓存穿透是指查询一个缓存和数据库中都没有的数据,由于大部分缓存策略是被动加载的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义
红色路径就是缓存穿透的执行路径
5.2.1、解决方案
我们可以把每次从数据库查询的数据都保存到缓存中,为了提⾼前台⽤户的使⽤体验 (解
决⻓时间内查询不到任何信息的情况),我们可以将空结果的缓存时间设置的短⼀些
5.3、缓存击穿
缓存击穿是指当一个请求无法从缓存中得到响应时,它会导致服务器不断地进行数据库查询,从而使应用程序的性能大幅降低。 缓存击穿的原因主要有热点数据、缓存过期和高并发等
5.3.1、解决方案
<1>加锁排队:与缓存雪崩加锁排队的方法类似,都是在查询数据库时加锁排队,缓冲操作请求以此来减少服务器运行压力(但是会降低性能)
<2>设置redis过期时间为永不过期,保证缓存的稳定性,但是也有弊端就是,热点数据需要及时更新到缓存中,否则查询结果可能有误差
5.4、缓存预热
<1>缓存预热是一种主动加载热点数据到缓存的策略,旨在提高缓存命中率、保持应用程序性能稳定和优化用户体验。
<2>在系统上线之前,将需要缓存的热点数据加载到缓存中,以避免在用户请求时,先查询数据库,然后再将数据缓存的问题。
注:其实就是程序启动之初就将部分数据查询缓存起来,应用程序都通过redis缓存进行
缓存预热的实现思路有以下三种
<1>提前给缓存中嵌入部分数据,再提供服务。
<2>根据当天的具体访问情况,试试统计出频率较高的热数据。(设置定时)
<3>将热点数据持久化下来,然后在模块更新的时候预热下缓存。(手动触发预热)
6、Redis集群
Redis多机服务主要包含以下3个内容:
<1>Redis主从同步
<2>Redis哨兵模式
<3>Redis集群服务(3.0及以后版本)
6.1、主从同步
Redis主从同步是指将一个Redis实例作为主节点,其他Redis实例作为从节点,通过复制主节点的数据来实现数据同步。
在Redis主从同步中,主节点负责写入数据,从节点负责读取数据。当主节点写入数据时,会将数据发送给所有从节点,从节点接收到数据后进行同步。当从节点接收到数据后,会将数据写入自己的内存中,并等待下一次同步
优点:提高数据的可用性和可靠性,同时也可以提高系统的读写性能,当主服务器磁盘坏掉之后,其他从服务器还保留着相关的数据,不⾄于数据全部丢失。
缺点:需要额外的网络带宽和存储空间,并且在主节点出现故障时,可能会导致整个系统不可用
6.2、哨兵模式
专注于对Redis实例(主节点、从节点)运行状态的监控,并能够在主节点发生故障时通过一系列的机制实现选主及主从切换,实现故障转移,确保整个Redis系统的可用性,哨兵模式(Redis Sentinel)
使用哨兵模式可以用来监控主从同步服务器节点,并在主从服务器出现问题的时候实现自动容灾恢复
注:一个哨兵模式的最小分配单位一主一从
原理:
哨兵会不断地检查主节点和从节点是否正常工作,如果出现问题,哨兵可以通过API通知系统管理员或者其他程序。当主节点发生故障时,哨兵会自动将从节点切换为主节点,并将新主节点的信息写入配置文件中
6.3、Redis集群服务
Redis 集群(Redis Cluster)是 Redis 多机运⾏最完美的终极⽅案,它是 Redis 3.0 之后推出的服
务,它的出现可以让我们完全抛弃主从同步和哨兵模式来实现 Redis 多机运⾏。
优点:Redis集群通过分区来提供一定程度的可用性:即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求