Redis学习笔记
2021-11-07 14:38:02 29 举报
AI智能生成
Redis学习笔记
作者其他创作
大纲/内容
简介
背景
架构演变:文件缓存->Memcache->Mysql主从读写分离->分表分库
新要求
3V
Volume:海量数据
Variety:数据类型、终端设备的多样
Velocity:实时
3高
高可扩:不断扩展现有功能与新功能
高性能
高并发
NoSQL
含义:Not Only SQL->不仅仅是SQL
对比
关系型数据库
高度组织化、结构化数据
结构化查询语言->SQL
数据和关系都存储在单独的表中
数据操纵语言,数据定义语言
严格的一致性
基础事务
NoSQL数据库
没有声明性查询语言
没有预定义的模式
最终一致性,非ACID
非结构化和不可预知的数据
CAP定理:分布式系统中,对于一致性、可用性、分区容错这三个特性,不可能同时满足。
高性能、高可用、可伸缩
优势
易扩展:去关系型数据,易扩展
高性能:缓存粒度小(记录),效率高
数据模型灵活
Redis->Remote Dictionary Server(远程字典服务器)
官网
安装
安装Redis
安装gcc环境(C语言编译环境)
配置
单位说明:1k(1000bytes)!=1kb(1024bytes)
include:引入公共配置文件
network
bind:限定访问的主机地址
protected-mode:是否开启安全防护模式
port:指定redis实例端口号,默认6379
tcp-backlog:指定高并发时访问排队的长度,超过后就阻塞。
timeout:超时时间
tcp-keepalive:对客户端的心跳检测间隔时间
general
daemonize:是否开启守护线程模式运行
pidfile:指定进程id文件保存的路径
loglevel:指定日志级别
debug
verbose
notice
warning
logfile:指定日志文件路径
syslog-enabled:是否记录到系统日志
syslog-ident:设置系统日志的id
syslog-facility:指定系统日志设置,必须为user或local0-local7之间的值
databases:设置数据库数量,默认为16(0-15)
其他
requirepass:设定访问密码
maxclients:最大连接数
maxmemory:最大占用多少内存
maxmemory-policy:缓存清理策略
volatile-lru
allkeys-lru
volatile-random
allkeys-random
volatile-ttl
noeviction
启动
应用场景
缓存
需要实时读写数据库时,例如评论数、点赞数
分布式锁
分布式会话
消息中间件
基本操作
数据库操作
select <dbid>:切换数据库
flushdb:清空当前数据库
dbsize:查看数据库数据个数
flushall:清空所有数据库
move key index:将键值对从当前db移动到目标db
lastsave:获取最后一次持久化操作的时间
key操作
keys pattern:查看符合指定表达式的所有key,pattern可以为*,?等
type key:查看key对应值的类型
exists key:查看key是否存在
del key:删除key
randomkey:随意选取key
expire key seconds:为键值设置过期时间
TTL key:查看key还有多久过期,-1->永不过期,-2->已过期
rename key newkey:重命名key,强制执行
renamex key newkey:重命名key,非强制执行,如果newkey存在则语句不生效
数据操作
数据类型介绍
string:字符串
list:可重复集合
hash:键值对
set:不可重复集合
zset:有序set
string操作
list操作
set操作
hash操作
zset操作
持久化
RDB
简介
1、在指定时间间隔内将内存中的数据集快照写入磁盘,恢复时将快照文件直接读到内存中;
2、默认开启
3、Redis 会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束
了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何 IO 操作的,这就确保了极高
的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那 RDB 方式要比 AOF 方式更加
的高效。
了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何 IO 操作的,这就确保了极高
的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那 RDB 方式要比 AOF 方式更加
的高效。
4、最后一次持久化的数据可能丢失
保存策略
save second count:second秒内如果至少有count个key值变化,则进行保存
save "":禁用RDB模式
属性配置
save:保存策略
dbfilename:RDB快照文件名
dir:指定RDB快照保存的目录
stop-writes-on-bgsave-error:备份出错时,是否继续接受写操作,默认会停止
rdbcompression:是否压缩存储快照,若压缩则会采用LZF算法进行压缩
rdbchecksum:是否进行数据校验,若校验则会采用CRC64算法来校验,会增加10%的性能消耗
触发机制
自动保存
执行save/bgsave命令,执行过程中redis会阻塞
执行flushdb,也会产生dump.rdb,但为空文件
执行shutdown命令
优缺点
优点
(1)redis主进程调用fork()方法创建一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
(2)RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
缺点:快照持久化期间修改的数据不会被保存,可能丢失数据。
AOF
简介
AOF 是以日志的形式来记录每个写操作,将每一次对数据进行修改,都把新建、修改数据的命令保存到指
定文件中。Redis 重新启动时读取这个文件,重新执行新建、修改数据的命令恢复数据。
定文件中。Redis 重新启动时读取这个文件,重新执行新建、修改数据的命令恢复数据。
默认关闭
AOF 文件的保存路径,同 RDB 的路径一致。
AOF 在保存命令的时候,只会保存对数据有修改的命令
当 RDB 和 AOF 存的不一致的情况下,按照 AOF 来恢复
如果AOF文件中出现了残余命令,会无法重启服务,需要使用redis-check-aof工具来修复:redis-check-aof -fix 文件
保存策略
appendfsync always:每次执行写操作都保存
appendfsync everysec(默认):每秒保存一次,可能会丢失1秒的数据
appendfsync no:从不保存
属性配置
appendonly:是否开启AOF
appendfilename:AOF备份文件的名称
appendfsync:保存策略
no-appendfsync-on-rewrite:重写时,是否执行保存策略
auto-aof-rewrite-percentage:指定重写与否的aof文件大小比例
auto-aof-rewrite-min-size:设置允许重写的最小aof文件大小
aof-load-truncated:是否截断
优缺点
优点
备份机制稳健,丢失数据概率低
可读的日志文本,可以处理误操作
缺点
比RDB占用更多的磁盘空间
恢复备份较慢
总结
最好两种策略配合使用
可以单独使用RDB,不建议单独使用AOF
若只是将Redis作为纯内存缓存,可以都不使用
事务
简介
Redis中的事务指单独的隔离操作
事务中所有命令都会按顺序执行,不会被其他命令打断
主要作用是串联多个命令防止其他命令打断
没有回滚机制,事务中错误的命令无法执行,正确的命令会全部执行
命令
multi:标记一个事务块的开始
watch:标记所有指定的 key 被监视起来,在事务中有条件的执行(乐观锁)
exec:执行事务中所有在排队等待的指令并将连接状态恢复到正常 当使用
WATCH 时,只有当被监视的键没有被修改,且允许检查设定机制时,EXEC
会被执行
WATCH 时,只有当被监视的键没有被修改,且允许检查设定机制时,EXEC
会被执行
discard:刷新一个事务中所有在排队等待的指令,并且将连接状态恢复到正常。
如果已使用 WATCH,DISCARD 将释放所有被 WATCH 的 key。
如果已使用 WATCH,DISCARD 将释放所有被 WATCH 的 key。
锁
简介
悲观锁(Redis不支持):假设当前操作很大几率会被打断
乐观锁:假设当前操作不会被打断,做操作前不会锁定资源,万一被打断,则操作被放弃
Redis中的锁策略
通过watch实现乐观锁,多读少写,unwatch命令可以取消枷锁
事务之前执行了watch(加锁),在exec/discard命令执行后锁会自动释放
消息订阅
简介:消息订阅是进程间的一种消息通信方式,即发送者发布消息(pub),订阅者(sub)接收消息,Redis支持消息订阅机制。
命令
subscribe 频道:订阅频道
publish 频道 消息:向指定频道发布消息
主从
主从复制
简介
1、为了读写分离,提高Redis性能;保证数据安全
2、主(master)redis以写操作为主,从(slave)redis以读为主,主从之间自动同步数据
3、每次从机联通后,都会给主机发送 sync 指令,主机立刻进行存盘操作,发送 RDB 文件,给从机
从机收到 RDB 文件后,进行全盘加载。之后每次主机的写操作,都会立刻发送给从机,从机执行相同的命令
从机收到 RDB 文件后,进行全盘加载。之后每次主机的写操作,都会立刻发送给从机,从机执行相同的命令
主从建立
临时建立:执行slaveof ip:port命令(可以通过info replication命令查看当前redis的主从策略)
永久建立:配置master配置文件
salveof no noe:执行该命令去除主从配置
常见问题
1、从机完全复制主机的信息
2、从机无法进行写操作
3、主机shutdown以后,从机原地待命
哨兵模式
简介
作用:检测master状态,若异常则选取一个从机升为主机,原主机降为从机
下线
①主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个 redis 服务器做出的
下线判断。
下线判断。
②客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对 Master Server 做出
SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的 Master Server 下线
判断,然后开启 failover.
SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的 Master Server 下线
判断,然后开启 failover.
工作原理
①每个 Sentinel 以每秒钟一次的频率向它所知的 Master,Slave 以及其他 Sentinel 实例发送一个 PING 命
令 ;
令 ;
②如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所
指定的值, 则这个实例会被 Sentinel 标记为主观下线;
指定的值, 则这个实例会被 Sentinel 标记为主观下线;
③如果一个 Master 被标记为主观下线,则正在监视这个 Master 的所有 Sentinel 要以每秒一次的频率确认
Master 的确进入了主观下线状态
Master 的确进入了主观下线状态
④当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认 Master 的确进入了主
观下线状态, 则 Master 会被标记为客观下线 ;
观下线状态, 则 Master 会被标记为客观下线 ;
⑤在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有 Master,Slave 发送 INFO 命令
⑥当 Master 被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的
频率会从 10 秒一次改为每秒一次 ;
频率会从 10 秒一次改为每秒一次 ;
⑦若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除;
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除
总结:挑选出新的master后,sentinel向原master的从服务发送slaveof新master的命令,当下线的原master上线时,sentinel会发送slaveof命令让其成为新master的slaver
配置
配置哨兵:sentinel monitor mymaster 127.0.0.1 6379 1
启动哨兵:redis-sentinel sentinel.conf
新master选取策略
1、依据优先级,配置文件中配置slave-priority属性
2、偏移量最大(获取原master数据最多的从机)
3、选择runid最小的(每个redis实例启动后都会随机生成一个40位的runid)
集群
简介:对Redis水平扩容
创建集群
安装ruby环境
安装redis gem
配置文件
集群写入数据
slot(插槽)
1、一个Redis集群包含16384个插槽(hash slot)
2、数据库中每个键都属于16384个插槽中的一个
3、集群使用公式CRC16(KEY)%16384来计算key属于哪个槽
4、每个slot可以存储一批键值对
数据操作
客户端重定向
1、不使用重定向,则操作数据的key不属于当前客户端插槽德华,redis会报错提示前往对应的redis实例客户端操作数据;
2、使用重定向:redis-cli -c -p 6379
其中 -c 使命令自动重定向
其中 -c 使命令自动重定向
多键操作
1、不在一个slot下的键值,不能进行mget/mset等多键操作
2、通过{}来定义组的概念,从而使key中{}内相同内容的键值对放到同一个slot中去
举例:mset {group}k1 v1 {group}k2 v2
读取数据
cluster keyslot key:计算key应该被放在哪个槽上
cluster countkeysinslot slot:返回槽slot目前包含的键值对数量->cluster countkeysinslot 12539
cluster getkeysinslot slot count:返回count个slot槽中的键
常见问题
主节点下线,从节点自动升为主节点
主节点恢复后,变为从节点
redis.conf中属性cluster-require-full-coverage控制当某一段插槽的主从节点都宕机以后,redis服务是否还继续。
优缺点
优点
实现扩容
分摊压力
去中心化配置
缺点
多键操作不被支持
多键redis事务不被支持,lua脚本不被支持
Java整合Redis
Jedis
简介:通过Java连接Redis
配置
常规配置
连接池配置
单机开发
集群开发
Lua
1、常用作嵌入式脚本语言
2、将复杂的redis操作,写为一个脚本,交于redis执行,减少连接redis的次数
3、具有一定的原子性,不被其他命令插队,可以完成事务操作
4、redis2.6以上的版本才可以使用
案例
手机验证码
秒杀
商品超卖
使用乐观锁解决
秒杀富余
使用lua脚本解决
使用Redis需要解决的问题
缓存使用过程:前台请求,先从缓存中查询数据,缓存中没有则从数据库查询,查询数据后更新缓存,然后返回,下次查询直接从缓存中取值;如果缓存和数据库中都没有直接返回空值。
缓存穿透
描述:缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决:接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
记忆:关键字“透”,是指透过了缓存、数据库
缓存击穿
描述:缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
解决
设置热点数据永不过期
加互斥锁
缓存雪崩
描述:缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决
缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
设置热点数据永远不过期。
脑裂问题
描述:由于redis master节点和redis salve节点和sentinel处于不同的网络分区,使得sentinel没有能够心跳感知到master,所以通过选举的方式提升了一个salve为master,这样就存在了两个master,就像大脑分裂了一样,这样会导致客户端还在old master那里写入数据,新节点无法同步数据,当网络恢复后,sentinel会将old master降为salve,这时再从新master同步数据,这会导致大量数据丢失。
解决:min-replicas-to-write 3
min-replicas-max-lag 10
第一个参数表示最少的salve节点为3个,第二个参数表示数据复制和同步的延迟不能超过10秒
配置了这两个参数:如果发生脑裂:原master会在客户端写入操作的时候拒绝请求。这样可以避免大量数据丢失。
min-replicas-max-lag 10
第一个参数表示最少的salve节点为3个,第二个参数表示数据复制和同步的延迟不能超过10秒
配置了这两个参数:如果发生脑裂:原master会在客户端写入操作的时候拒绝请求。这样可以避免大量数据丢失。
Redis淘汰策略
描述:Redis是基于内存结构进行数据缓存的,当内存资源消耗完毕,想要有新的数据缓存进来,要从现有的Redis内存结构中释放一些数据
8种淘汰策略
# volatile-lru -> 从设置了过期时间的数据中淘汰最久未使⽤的数据.
# allkeys-lru -> 从所有数据中淘汰最久未使⽤的数据.
# volatile-lfu -> 从设置了过期时间的数据中淘汰使⽤最少的数据.
# allkeys-lfu -> 从所有数据中淘汰使⽤最少的数据.
# volatile-random -> 从设置了过期时间的数据中随机淘汰⼀批数据.
# allkeys-random -> 从所有数据中随机淘汰⼀批数据.
# volatile-ttl -> 淘汰过期时间最短的数据.
# noeviction -> 不淘汰任何数据,当内存不够时直接抛出异常.
0 条评论
下一页