Redis(参阅狂神说视频,整理)
2021-07-09 09:40:54 18 举报
AI智能生成
redis基础入门
作者其他创作
大纲/内容
Redis(Remote Dictionary Server ),即远程字典服务
是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
概述
效率高,可以用于高速缓存
内存存储,持久化,内存中是断电即失,所以持久化很重要(A)F,RDB)
发布订阅系统
地图信息分析
计时器、计数器
能做些什么
持久化
事务
集群
多样的数据类型
......
特性
Redis中文
Redis官网(英文)
Redis英文
Redis官网
学习工具
从github上查找redis下载
1、下载安装包
2、下载获得压缩包,解压到自己电脑目录下就可以
3、开启redis,运行服务server即可
4、使用redis客户端Client,连接redis(服务server不能关)
5、测试连接ping,返回‘PONG’就是成功
6、设置值set name value
redis
官方推荐使用Linux部署
window安装
1、下载安装包,直接从官网下载,首页‘Download it’,获得安装包
2、使用XShell连接服务器,使用Xftp将安装包上传
3、解压redis的安装包,放入/opt目录下
4、进入到redis文件中,可以看到redis.conf配置文件
5、使用前的操作
/usr/local/bin
6、redis默认安装路径
7、可以在bin路径下找到server、client,操作如同window一样
8、可将bin目录下文件redis.conf拷贝到当前目录下
进入redis.conf中,将daemonize no 改成yes
9、redis默认不是后台启动的,修改配置文件
通过指定的配置文件启动服务
redis-server kconfig/redis.conf
10、启动redis 服务
redis-cli -p 6379
11、启动客户端
12、测试如同window安装一样
命令:ps -ef|grep redis
13、查看redis进程是否存在
命令:shutdown
14、如何关闭redis服务呢?
linux安装
安装
redis-benchmark是一个压力测试工具
简单测试
进入usr/local/bin
测试性能
默认使用16个数据库,默认使用第0个
可以使用select进行切换数据库
清除数据库
redis是基于内存操作的,CPU不是redis性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽
1、高性能的服务器一定是多线程
2、多线程(CPU上下文切换)一定比单线程效率高
误区
1、redis是将所有数据放入内存中的,所以使用单线程操作效率就是最高的
2、多线程(CPU上下文切换:耗时操作),对于内存来讲,如果没有上下文切换效率是最高的
3、多次读写都在一个CPU上操作的,在内存情况下,单线程就是最佳方案
核心
redis为什么单线程还这么快?
Redis是C语言写的,官方提供的数据QPS为100000+,完全不必同样是使用key-value的Memecache差
Redis是单线程的
基础知识
入门
redis命令
命令操作
Rerdis-key
APPEND 拼接
STRLEN 字符串长度
INCR 自增
DECR 自减
INCRBY 设置步长,指定增量
DECRBY
GETRANGE key 0 2
GETRANGE 范围,截取字符串
SETRANGE 替换指定位置的字符串
setex key 30 xxx(30->指时间)
setex (set with expire) 设置过期时间
setnx key xxx(若存在key,则将xxx设置进去,若不存在,则不会设置)
setnx (set if not exist) 不存在再设置
mset k1 v1 k2 v2 k3 v3
mset 批量设置
mget k1 k2 k3
mget 批量获得
msetnx 是一个原子性的操作,要么一起成功,要么一起失败
msetnx k1 v1 k4 v4
msetnx 批量判断是否存在
msetex 批量设置过期时间
实战使用 set key:{id}:{filed}
getset key value 如果不存在值则返回null,再设置新值;若存在,返回原来的值,并设置新指
getset 先get再set
计数器
统计多单位的数量
String类型使用场景:vlaue除了是字符串还可以是数字
String(字符串)
在redis里面,我们可以把list完成 栈、队列、阻塞队列
所有list命令都是用L开头的
Redis不区分大小写命令
详情
LPUSH list one
LPUSH 将一个值或者多个值,插入到列表的头部(左-left)
RPUSH list one
RPUSH 将一个值或者多个值,插入到列表的尾部(右-right)
LPUSH 插入到第一个元素
LRANGE list 0 1 通过区间获取具体的值
LRANGE list 0 -1 查看列表中的值
LRANGE 获取范围内的值
LPOP list 左边的值移除,移除list的第一个元素
RPOP list 右边的值移除,移除list的最后一个元素
LPOP 移除第一个元素
Lindex list 1
Lindex 通过下标获得 list 中的某一个值
Llen 获得list的长度
Lrem list 1(表示个数) one(表示对应的值) 移除list集合中指定个数的value,精确匹配
Lrem 移除固定的值
Ltrim list 1 2 通过下标截取指定的长度,list改变,只剩下截取的元素
Ltrim 通过下标截取指定的长度
rpoplpush list list2
rpoplpush source destination
rpopLpush 移除列表最后一个元素,并且移动到新列表
Lset 将列表中指定下标的值替换成另一个值,更新操作
Linsert list before/after value value1 往list中value的位置before或after插入value1
Linsert 将某个具体的value插入到别表中某个元素的前面或者后面
list 实际上是一个链表,before node after,left,right都可以插入
如果key不存在,创建新的链表
如果key存在,新增内容
如果移除所有的值,形成空链表,也代表不存在
在两边插入或者改动值,效率最高!中间元素,相对来说效率较低写
Lpush Rpop 左近右出
类似 消息队列
Lpush Lpop 先进先出
类似 栈
小结
List(列表)
set的命令以s开头,set中的值不能重复,类似java里的方法;
sadd myset value
sadd set集合中添加元素
SMEMBERS set
SMEMBERS 查看指定set中所有的值
SISMEMEBER myset value
SISMEMBER 判断某个值是否存在set集合中
scard myset
scard 获取set集合中的内容元素个数
srem myset value
srem 移除set集合中指定的值
srandmember myset 随机抽选出set中一个元素
srandmember myset 2 随机抽选出指定个数的元素
srandmember 随机抽选出set集合中元素
spop 随机移除set集合中的元素
smove myset myset2 value 将指定value从myset移动到myset2中
smove 将一个指定的值,移动到另外一个set集合
SDIFF key1 key2
差集 SDIFF
SINTER key1 key2
交集 SINTER
SUNION key1 key2
并集 SUNION
集合
Set(集合)
Map集合,key-value键值对,和string的差不多,只不过命令开头用h开头
hset myhash key1 value1
hmset 多个设置值 hmset myhash k1 v1 k2 v2
hset 单个设置值
hget myhash key
hmget myhash key1 key2 获取多个值
hget
hgetall myhash
hgetall 获取所有值
hdel myhash k1
hdel 删除hash指定的key,对应的value也被删除
hlen myhash
hlen 获取hash的size
hexsits myhash key
hexists 判断hash中指定key是否存在
hkeys myhash
hkeys 获取hash所有key
hvals myhash
hvals 获取hash所有值
hincr
hincrby
hincr 指定增量
hdecr
hdecrby
hdecr 自减
hsetnx myhash key value
hsetnx 如果不存在则设置,如果不存在者不设置
hash变更的数据 user name age ,尤其是用户信息子类的,经常变动的信息!hash 更适合对象的存储,String更加适合字符串存储
Hash(哈希)
在set的基础上增加了一个值,zset k1 score v1,score排序;不会重复
zadd myset k1 v1
zadd
ZrangeByScore myset -inf +inf 显示全部用户,从小到大
-inf 负无穷 +inf 正无穷
zrangebyscore myset min max withscores
ZrangeByScore myset -1 0 withscores
可以排序
升序
zrevrange myset max min
zrevrange
降序
zset排序
排序如何实现
zrem myset key
zrem
zrange
zcard 获取有序集合的个数
zcount myset 0 3 获取指定区间的数量
zcount
Zset(有序集合)
指令大全
五大基础类型
geo这个功能可以推算出地理位置的信息,两地之间的举例
有效的经度从-180度到180度。有效的纬度从-85.05112878度到85.05112878度。
GEO底层是zset命令,可以使用zset的命令操作geo
GEOADD Sicily 13.361389 38.115556 \"Palermo\" 15.087269 37.502669 \"Catania\"
GEOADD china:city px py name
添加到sorted set元素的数目,但不包括已更新score的元素。
geoadd官方文档
GEOADD 添加地理位置
GEODIST Sicily Palermo Catania 默认单位m
GEODIST Sicily Palermo Catania km
指定单位的参数 unit 必须是以下单位的其中一个:m 表示单位为米。km 表示单位为千米。mi 表示单位为英里。ft 表示单位为英尺。
计算出的距离会以双精度浮点数的形式被返回。 如果给定的位置元素不存在, 那么命令返回空值。
GEODIST 两个城市之间的距离
GEOHASH Sicily Palermo Catania
一个数组, 数组的每个项都是一个 geohash 。 命令返回的 geohash 的位置与用户给定的位置元素的位置一一对应。
该命令将返回11个字符的Geohash字符串,所以没有精度Geohash,损失相比,使用内部52位表示。返回的geohashes具有以下特性:他们可以缩短从右边的字符。它将失去精度,但仍将指向同一地区。它可以在 geohash.org 网站使用,网址 http://geohash.org/<geohash-string>。查询例子:http://geohash.org/sqdtr74hyu0.与类似的前缀字符串是附近,但相反的是不正确的,这是可能的,用不同的前缀字符串附近。返回值一个数组, 数组的每个项都是一个 geohash 。 命令返回的 geohash 的位置与用户给定的位置元素的位置一一对应。
GEOHASH 返回一个或多个位置元素的 Geohash 表示
GEOPOS Sicily Palermo Catania NonExisting
GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成: 第一个元素为给定位置元素的经度, 而第二个元素则为给定位置元素的纬度。当给定的位置元素不存在时, 对应的数组项为空值。
GEOPOS 获取指定城市的经纬度
GEORADIUS Sicily 15 37 100 km
范围可以使用以下其中一个单位:m 表示单位为米。km 表示单位为千米。mi 表示单位为英里。ft 表示单位为英尺。
withdist 显示到中间距离的位置
withcoord 显示他人的定位信息
GEORADIUS china:city 100 30 500 km withdis withcoord count 1 以100,30这个经纬度为中心,寻找方圆500km内的城市
可以搜索半径之内的所有城市
GEORADIUS 以给定的经纬度为中心, 找出某一半径内的元素
GEORADIUSBYMEMBER Sicily Agrigento 100 km
找出位于指定元素周围的其他元素
子主题
GEORADIUSBYMEMBER 找出位于指定范围内的元素,中心点是由给定的位置元素决定
六个命令
geospatial 地理位置
用于基数统计的算法
优点:占用的内存是固定的,2^64不同的元素的技术,只需要费12kb内存!如果要从内存角度比较的化,Hyperloglog首选!
命令将所有元素参数添加到 HyperLogLog 数据结构中
PFADD key element [element ...] 返回值:整型,如果至少有个元素被添加返回 1, 否则返回 0。
redis 127.0.0.1:6379> PFADD mykey a b c d e f g h i j(integer) 1redis 127.0.0.1:6379> PFCOUNT mykey(integer) 10
Pfadd
命令返回给定 HyperLogLog 的基数估算值。
PFCOUNT key [key ...] 返回值:整数,返回给定 HyperLogLog 的基数值,如果多个 HyperLogLog 则返回基数估值之和。
redis 127.0.0.1:6379> PFADD hll foo bar zap(integer) 1redis 127.0.0.1:6379> PFADD hll zap zap zap(integer) 0redis 127.0.0.1:6379> PFADD hll foo bar(integer) 0redis 127.0.0.1:6379> PFCOUNT hll(integer) 3redis 127.0.0.1:6379> PFADD some-other-hll 1 2 3(integer) 1redis 127.0.0.1:6379> PFCOUNT hll some-other-hll(integer) 6redis>
Pfcount
命令将多个 HyperLogLog 合并为一个 HyperLogLog ,合并后的 HyperLogLog 的基数估算值是通过对所有 给定 HyperLogLog 进行并集计算得出的
PFMERGE destkey sourcekey [sourcekey ...]
redis 127.0.0.1:6379> PFADD hll1 foo bar zap a(integer) 1redis 127.0.0.1:6379> PFADD hll2 a b c foo(integer) 1redis 127.0.0.1:6379> PFMERGE hll3 hll1 hll2OKredis 127.0.0.1:6379> PFCOUNT hll3(integer) 6redis>
Pfmerge(并集)
hyperloglog
bit位,位存储
位图,数据结构,操作二进制位进行记录,只有0和1两个状态
setbit sign 0 0
使用bitmaps记录一周七天,打卡上班的例子周1:1 周二:0 周三:0......
setbit
getbit sign 3
getbit
bitcount sign 统计数量
bitmaps
三种特殊数据类型
Redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行一次性、顺序性、排他性
没有隔离级别的概念
所有命令在事务中,并没有直接执行!只有发起执行命令的时候才会执行!Exec
Redis单条命令是保证原子性,但是事务不保证原子性
开启事务
事务队列中命令都不会被执行
discard 放弃事务
开启事务(multi)
命令入队(......)
执行事务(exec)
redis事务命令
乐观锁
悲观锁
redis监视成功
获取最新的值version,监视,select version 获取版本
watch xx
如果事务执行失败,就先解锁
unwatch xx
监控 Watch
是redis官方推荐的java连接开发工具!使用java操作redis中间件!如果要使用java操作redis,那么一定要对Jedis十分熟悉
什么是Jedis
jedis依赖包
导入jedis依赖包
导入fastjson依赖包,阿里巴巴的
jedis就可以使用所有指令方法
连接数据库
基础
操作命令
断开连接
编码测试
项目使用
String
List
Set
Hash
Zset
常用API
Jedis
springboot 2.x之后默认使用lettuce,若使用jedis配置,因为源码中许多类没有注入,类不存在,因此别使用jedis,有可能导致配置不成功
jedis 不安全,需要使用 pool 池化,像BIO
lettuce 安全,像NIO,现在比较常用
注意
redisTemlpate.opsForXXX() opsFor->operation for 操作
除了基本的操作,常用的方法也可以直接使用 redisTemplate 操作,比如事务
connection.flushDB()
connection.flushAll()
获取连接 redisTemplate.getConnectionFactory().getConnection()
使用
序列化配置,JDK序列化
开发中需要序列化,否则存入后取值会报错
实现Serialized接口
对应的实现的序列化
序列化方式
序列化
自己开发方便,一般直接使用String
定义后,可以使用@Qualifer(\"reidsTemplate\")
使用最好自己封装好工具包util
springBoot整合
进入服务器找到redis安装的目录,找到redis.conf 文件进行配置
进入方式
单位
1、配置文件unit单位 对大小写不敏感
bind 127.0.0.1 # 绑定的ip
protected-mode yes # 保护模式
port 6379 # 端口设置
网络
daeminize yes # 以守护进程的方式运行,默认是no,我们需要自己开启为yes
pidfile /var/run/redis_6379.pid # 如果以后台的方式运行,我们就需要指定一个 pid
日志 loglevel notice 四个层级
logfile \"\" # 日志的文件位置名
databases 16 #数据库的数量,默认是 16 个数据库
always-show-log yes # 是否总是显示log,默认为yes
通用General
持久化,在规定的时间内,执行了多少次操作,则会持久化到文件.rdb .aof
redis是内存数据库,如果没有持久化,那么断电数据既失
# 如果 900s 内,如果至少有一个1 key进行了修改,我们及进行持久化操作save 900 1# 如果 300s 内,如果至少有一个10 key进行了修改,就会进行持久化save 300 10# 如果 60s 内,如果至少有一个10000 key进行了修改,就会进行持久化save 60 10000
stop-writes-on-bgsave-error yes # 持久化如果出错,是否还需要继续工作
rdbcompression yes #是否压缩redb文件,需要消耗一些cpu资源
rdbchecksum yes # 保存rdb文件的时候,进行错误的检查校验
dir ./ # rdb文件保存的目录
快照
设置密码,这是通过在配置文件中设置的
命令设置密码 config get requirepassconfig set requirepass \"123456\"(password)auth加权限
SECURIT 安全
maxclients 10000 # 设置能连接上的redis的最大客户端数量
maxmemory <bytes> # redis 配置最大的内存容量
maxmemory-policy noeviction #内存到达上限后的处理策略
处理策略
CLIENTS 限制
appendonly on # 默认是不开启aof模式的,默认是使用rdb方式持久化的,大部分所有的情况下,rdb够用了
appendfilename “appendonly.aof” 持久化文件的名字
基本配置
APPEND Only模式 aof配置
Redis.conf详解
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话说的snapshot快照,恢复时是将快照文件直接读到内存里
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化的文件。整个过程中,主进程时不进行任何IO操作的。确保了极高的性能。如果需要大规模数据的恢复,且对数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点就是最后一次持久化的数据可能丢失
步骤:1、操作redis时,创建fork子进程进行持久化2、将内存内容以快照的形式写入临时RDB文件中(rdb保存的文件是dump.rdb)3、快照写入完成后,替换原来的快照rdb文件4、子进程退出
rdb的dump.rdb文件触发规则:1、save的规则满足的情况下,会自动触发rdb规则2、执行flushall命令,也会触发我们的rdb规则3、退出redis,也会产生rdb文件备份就会自动生成一个dump.rdb文件
如何恢复rdb文件?1、只需要将rdb文件放到redis启动目录就可以,redis启动的时候会自动检查dump.rdb恢复数据2、查看需要存在的位置config get dir 就能直到对应的redis启动目录
优点:1、适合大规模的数据恢复2、如果对数据的完整性要求不高!因为rdb这边有一个配置save 900 10类型的配置,有一个最低要求,如果再这期间宕机,就不会生成文件,导致文件丢失3、父进程无须执行任何磁盘的IO操作,因此恢复数据比AOF快
缺点:1、需要一定的时间间隔进程操作!如果redis意外宕机了,这个最后一次修改的数据就没有了2、创建fork子进程的时候,也会占用一定的内容空间(只要是进程都会占用空间)3、RDB文件时特定的格式,阅读性差,格式固定,可能存在不兼容的情况
注意:一般在工作中,生产环境使用redis时,会将redis的rdb文件进行备份,以防止数据丢失
RDB(Redis DataBase)
将在redis操作的所有命令全部记录下来,以日志的形式,恢复的时候,将这些文件全部执行一遍!
以日志的形式记录每个写操作,将redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据redis重启的化,就根据日志文件的内容将指令从头开始执行一遍,以完成数据恢复的工作
AOF保存的文件是appendonly.aof
默认是不开启AOF模式的,需要手动进行配置修改;appendonly yes其他的aof配置可以保持默认的,默认aof命令是无限追加的触发机制:当前aof文件的大小是上次rewrite后的两倍且大于64M具体大小配置 :auto-aof-rewrite-min-size 64mb 生产环境下要配置的比较大auto-aof-rewrite-percentage: 100 增长的百分比也可使用命令bgwriteaof设置同步策略:appendfsysnc: 保存操作记录的模式always: 每次有数据修改时添加记录 性能差everysecond:每秒记录一次 默认 最多丢失1s的数据即每秒把缓冲区的数据写入磁盘no: 由OS决定何何时同步,linux通常是30s
恢复数据,重启redis就可以生效了,不需要固定的位置保存
如果aof文件出现错误,这时候redis时启动不起来的,就需要修复aof文件redis给我们提供一个工具:redis-check-aof --fix appendonly.aof
优点:1、每一次修改都同步,文件的完整性更好2、默认开启的策略是,每秒开启一次,可能会丢失一秒的数据3、从不同步,效率最高的!缺点:1、相对于数据文件来说,aof远远大于rdb,修复的速度也比rdb慢2、Aof运行效率也比rdb慢,因此redis默认的配置是rdb持久化
AOF(Append Only File)
当AOF和RDB同时开启,优先读取aof文件(数据安全性)缺点:同时开启,性能开销大,内存消耗更快,会同时生产rdb文件和aof文件
redis先加载AOF文件来恢复原始数据,因为AOF数据比rdb更完整但是aof存在潜在的bug,如把错误的操作记录写入了aof,会导出数据恢复失败所以可以把RDB作为后备数据为了考虑性能,可以只在Slave上开启RDB,并且15min备份一次 如果为了避免AOF rewite的IO以及阻塞,可以在Redis集群中不开启AOF,靠集群的备份机制来保证可用性,在启动时选取较新的RDB文件如果集群全部崩溃,会丢失15min前的数据
同时开启两种持久化机制
redis4.0开始支持该模式为了解决的问题: redis在重启时通常是加载AOF文件,但加载速度慢因为RDB数据不完整,所以加载AOF开启方式: aof-use-rdb-preamble true开启后,AOF在重写时会直接读取RDB中的内容运行过程: 通过bgrwriteaof完成,不同的是当开启混合持久化后, 1 子进程会把内存中的数据以RDB的方式写入aof中, 2 把重写缓冲区中的增量命令以AOF方式写入到文件 3 将含有RDB个数和AOF格数的AOF数据覆盖旧的AOF文件新的AOF文件中,一部分数据来自RDB文件,一部分来自Redis运行过程时的增量数据
混合模式
Redis持久化
Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接受消息
Redis客户端可以订阅任意数量的频道’
订阅/发布消息图
什么是发布订阅?
实现原理
# 订阅一个或多个符合给定模式的频道psubsribe pattern [pattern......] # 查看订阅与发布系统状态pubsub subcommand [argument [argument ...]]# 将信息发送到指定的频道publish channel message# 退订所有给定模式的频道punsubscribe [pattern......] # 订阅给定的一个或者多个频道的信息subscribe channel [channel ...]# 指推定给定的频道unsubscribe [channel [channel...]]
命令
订阅/发送
场景:1、实时消息系统!2、实时聊天!(可以将频道当聊天室,将消息回显示给所有人即可!)3、订阅、关注系统都是可以的!
Redis发布订阅
是将一台redis服务器的数据,复制到其他的redis服务器
数据的复制都是单向的,只能由主节点到从节点
Master以写为主,Slave以读为主
主从复制,读写分离;读的操作都分给从机上,而写只需要写给主机,就能缓减服务器压力
概念
主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
数据冗余
当主节点出现问题时,可以 由从节点提供服务,实现快速的故障恢复;实际上时一种服务的冗余
故障恢复
在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务,分担服务器负载
写redis数据时,应用连接主节点;读redis数据时,应用连接从节点
在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量
负载均衡
除了上诉的作用外,主从复制还是哨兵和集群能够实施的基础,因此主从复制时redis高可用的基础
高可用基石
主要作用
要用redis运用与工程中,只使用一台redis是万万不能的(因为会出现宕机问题,导致数据丢失,因此一般会准备3太,一主二从)
从结构上,单个redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大
从容量上,单个redis服务器内存容量有限,就算一台redis服务器内存容量为256G,也不能将所有内存用作与redis存储内存。一般来说,单个redis最大使用内存不应该超过20G
注意事项
电商网站上的商品,一般都是一次上传,无数次浏览
使用场景
了解
只配置从库,不用配置主库
端口 port
pid 名字
log日志文件名字
dump.rdb文件名字
appendonlyfile.aof文件名字
一般修改配置redis.conf
我们就需要配置从机就可以了,主机不用配置
集群命令,通过命令实现SlaveOF host porthost:就是主库的ipport:就是主库的端口port就是从机需要跟随的老大
也可以通过配置redis.conf里面配置REPLICATION
通过配置实现
默认情况下,每台redis服务器都是主节点
环境配置
主机负责写,从机负责读
主机中所有的数据和命令,都会自动被从机保存
当主机断了,从机仍然运行连接主机,但是没有写操作,这个时候,如果主机回来了,从机依旧可以直接获取到主机写的信息
如果使用命令行,来配置的主从,这个时候如果重启,就会变成主机!主要变为从机,立马就会从主机中获取值
细节
Slave启动成功连接到master后会发送一个sync同步命令
Master 接受命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master 将传送整个数据文件到slave,并完成一次完成同步
slave服务在接受到数据库文件数据后,将其存盘并加载到内存中
全量复制
Master 继续将新的所有收到的修改命令依次传给slave,完成同步
增量复制
但只要重新连接master,一次完全同步(全量复制)将被自动执行!数据一定可以再从机上看到
全量和增量简易理解:当主机服务器重启后,redis从机会将主机的命令及数据全部复制(全量),等后面再操作时,redis从机再一个一个将主机的命令和数据复制(增量)
当一个B是A的从机,是C的主机,那么B还是从机,无法写入,但是还是可以完成主从复制
复制原理
以前:当主机断了,从机可以通过命令手动变为主节点,slaveof no one,变为主节点;但当这是主机又回来了,那就只能重新配置,重新连接
哨兵模式是一种特殊的模式,首先redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,他会独立运行。其原理就是哨兵通过发送命令,等待redis服务器相应,从而监控运行的多个redis实例
运行图例
通过发送命令,让redis服务器返回监控其运行状态,包括主服务器和从服务器
当哨兵检测到master宕机,会自动将slave切换程master,然后通过发布订阅模式,通知其他的从服务器,修改配置文件,让他们切换主机
作用
一个哨兵进程对redis服务器进行监控,可能会出现问题,为此,可以使用多个哨兵及逆行监控,各个哨兵之间还会进行监控,这样就形成多哨兵的模式
1、配置哨兵配置文件:vim sentinel.conf2、最核心的配置,和最基础的 sentinel monitor myredis 127.0.0.1 6379 1 # sentinel monitor 被监控的名字 host port 1后面的数字1,代表主机挂了,slave投票看让谁接替称为主机,票数最对的,就会称为主机3、启动哨兵4、如果主机挂了,哨兵自动从从机中选择一个当主机,但当原主机回来了,只能当从机
优点:1、哨兵集群,基于主从复制模式,所有的主从配置优点,他全由2、主从可以切换,故障可以转移,系统的可用性就会更好3、哨兵模式就主从模式的升级,手动到自动缺点:1、redis不好在线扩容,集群容量一旦达到上限,在线扩容就特别麻烦2、实现哨兵模式,配置很麻烦
第一部分
第二部分
第三部分
哨兵全部配置
哨兵模式(自动选举老大,只要发现老大没了,就会选举新的老大)
Redis主从复制
用户想要查一个数据,发现redis内存数据库没有(也就是缓存没有命中),于是向持久层数据库查询(类似mysql)。发现持久层数据也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中(举例场景:秒杀活动),于是都去请求持久层数据库,最终持久层数据库带来压力,就相当于缓存穿透
布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免对底层存储系统的查询压力
布隆过滤器
当存储层不命中,及时返回空对象也将其缓存起来,同时会设置一个过期时间,之后在访问这个数据将会从缓存中获取,保护了后端数据源
1、如果控制能够被缓存,这就意味着缓存需要更多的空间存储来存储更多的键
2、及时对空值设置了过期时间,还是会存在缓存层和存储层的数据,会出现一段时间窗口不一致,这对保持一致性的业务有影响
可能存在两个问题
缓存空对象
解决方案
出现场景:秒杀活动
缓存穿透
是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开一个洞。当某个key在过期的瞬间,有大量的请求并发访问,这类数据一般就是热点数据,由于缓存过期,会同时访问数据库来查询最新数据,并且回写缓存,会导致数据库瞬间压力过大!
从缓存层面来看,没有设置过期时间,所以不会出现热点key过期后产生的问题
存在问题:需要更多空间存储
设置热点数据永不过期
分布式锁:使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务器,其他线程没有获得分布式锁的权限,因此需要等待即可。这种方式将高并发的压力转移到分布式锁,因此对分布式 锁的考验很大
加互斥锁
出现场景:微博热搜
缓存击穿
是指在某一个时间段,缓存集体过期失效或者redis宕机
既然redis可能挂掉,那么就多增设几台redis,这样一台挂了,其他还可以工作,其实就搭建的集群
redis高可用
在缓存失效后,通过加锁或者队列来控制读数据数据库写缓存的线程数量,比如对某个key只允许一个线程查询数据和写数据,其他线程等待
先停掉一些服务,保证其他服务可用
限流降级
数据加热的含义:在正式部署之前,先把可能的数据选预先访问一边,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀
数据预热
集中过期倒不是最致命的,最终名的雪崩,是缓存服务器某个节点宕机或断网,自然形成的雪崩;因为是缓存服务器节点宕机,对数据库造成压力是不可以预知的,谁也不知道下一秒是不是就会导致数据库压垮
使用场景:双十一期间,为了保证高效,可能为关闭当天退款的功能,等第二天或者等其他时候可以退款
出现场景:淘宝双十一抢购,假设商品集体缓存过期,导致缓存查不到,压力全部压到数据库上
缓存雪崩
击穿 -> 量大!key存在,但缓存过期!(热点)
穿透 -> key不存在
缓存击穿和缓存穿透区别
区别
Redis缓存穿透、击穿和雪崩
Redis(参阅狂神说视频,整理)
收藏
0 条评论
回复 删除
下一页