redis 知识汇总
2023-04-21 09:17:34 1 举报
AI智能生成
redis 知识汇总,不断补充更新
作者其他创作
大纲/内容
9、redis 6 与 springboot 整合
10、redis 6的事务操作
redis事务定义
是一个单独的隔离操作,串联多个命令防止别的命令插队
Multi、Exec、discard
Multi:命令组队(开启事务),命令组队时出错,则全部都不执行
Exec:执行(类似提交事务),执行命令时出错,只有出错的命令不执行,其他都执行
discard:放弃执行(类似回滚)
事务冲突的问题
乐观锁
悲观锁
watch key
unwatch
redis事务三特性
单独的隔离操作
没有隔离级别的概念
不保证原子性
redis事务秒杀案例
lua脚本
11、redis 6持久化之RDB
配置文件
dbfilename 持久化后的文件名
dir 持久化后文件路径
stop-writes-on-bgsave-error yse|no yes配置当Redis无法写入磁盘,直接关掉redis的写操作
rdbcompressopn yes|no 是否对持久化文件进行LZF算法压缩
rdbchecksum yes|no 持久化前,对数据检查完整性(会增大约10%性能消耗,希望获取最大性能提升,可以关闭此功能)
save 秒 大于等于修改次数,1分钟内改了1万次则进行持久化,5分钟内改了10次则进行持久化,配置的时候多少时间内达到多少修改次数触发持久化(持久化时,只管持久化,其他访问全部阻塞,直到rdb文件创建完成,不建议)
# 900秒内如果超过1个key改动,则发起快照保存
save 900 1
# 300秒内如果超过10个key改动,则发起快照保存
save 300 10
# 60秒内如果超过1W个key改动,则发起快照保存
save 60 10000
save 900 1
# 300秒内如果超过10个key改动,则发起快照保存
save 300 10
# 60秒内如果超过1W个key改动,则发起快照保存
save 60 10000
bgsave 异步持久化,非阻塞
备份恢复
1.停掉redis
2.找出.rdb文件所在目录
3.将持久化的文件名改为dump.rdb
4.重启Redis
备份原理
https://blog.csdn.net/weixin_44305700/article/details/123462878
https://blog.csdn.net/weixin_44305700/article/details/123462878
问题所在
12、redis 6持久化之AOF
配置文件
appendonly yes|no 是否开启aof备份
appendfilename "文件名.aof" 备份文件的文件名
生成路径和rdb一致
备份恢复
和RDB差不多,只是持久化文件名改为 appendonly.aof
异常恢复
1. 修改appendonly no 为 yes
2. 如果遇到AOF文件损坏,通过 /usr/local/bin目录下执行 redis-check-aof --fix appendonly.aof 命令进行恢复
备份频率
appendfsync always 始终同步,每次redis的写入都会立刻记入日志,性能较差但数据完整性比较好
appendfsync everysec 每秒同步,每秒记入日志一次,如果宕机,本秒数据可能丢失
appendfsync no 不主动进行同步,把同步时机交给操作系统
Rewrite压缩
触发机制
当AOF文件大小是之前的一倍且大于64M时触发
auto-aof-rewrite-percentage 增长百分比,文件达到增长百分比时开始重写,如:100 表示增长达到原来的2倍
auto-aof-rewrite-min-size 重写的基准值 最小64MB,达到这个值开始重写
备份原理
问题所在
优点
同时开启 AOF 和 RDB ,则默认取AOF数据,因为RDB数据不完整。
https://blog.csdn.net/BushQiang/article/details/122869503
https://blog.csdn.net/BushQiang/article/details/122869503
13、redis 6的主从复制
读写分离 ,容灾快速恢复
当主机出现问题,则需要使用集群来解决,每个集群都是主从结构,且集群间会有联系
配置(1主两从)
1. 创建/myredis文件夹
2. 设置appendonly no,复制redis.conf配置文件到文件夹中
3. 创建3份配置文件,redis6379.conf、redis6380.conf、redis6381.conf
4. 在这三个配置文件中分别添加
include /myredis/redis.conf
pidfile /var/run/redis_6379[6380|6381].pid
port 6379[6380|6381]
dbfilename dump6379[6380|6381].rdb
include /myredis/redis.conf
pidfile /var/run/redis_6379[6380|6381].pid
port 6379[6380|6381]
dbfilename dump6379[6380|6381].rdb
5. 使用命令 redis-server redis6379[6380|6381].conf 启动3个redis
6. 使用命令 redis-cli -p 6379[6380|6381] 开启客户端
6. 使用命令 info replication 查看当前redis 信息,是主还是从
7. 在 6380 和 6381 上执行 slaveof 127.0.0.1[master地址] 6379[master 端口] 命令,将6379设置为master
原理
全量同步
增量同步
特点
1主多从
从服务器宕机,重启后,不会自动绑定主服务器,需要重新绑定,绑定后主服务器会将所有数据同步到该从服务器中;
主服务器宕机,则从服务器仍然是从服务器,不需要重新绑主服务器;
主服务器宕机,则从服务器仍然是从服务器,不需要重新绑主服务器;
薪火相传
1台从服务器可以再挂多台从服务器, 主->从1->从2,从2的主机是从1(此时从1还是不能写操作)
主服务器挂掉后,从服务器仍然是从服务器
反客为主
主服务器挂了,后面的一台从服务器晋级为主服务器,也是其麾下从机的master
手动:在从服务器执行命令 slaveof no one,把其升级为master
redis.conf配置文件中优先级默认 slave-priority 100,值越小优先级越高,被选中为主机的概率就越大,redis6.2.1 版本配置是 replica-priority
自动:通过哨兵模式
配置
1. 在/myredis 目录下创建 sentinel.conf 文件,名字必须是这个,不能改
2. 在配置文件中,写入 sentinel monitor mymaster[监控对象起的服务器名称] 127.0.0.1[主机地址] 6379[主机端口] 1[至少有1个哨兵同意,才允许迁移]
3. 执行启动命令: redis-sentinel sentinel.conf
java 配置
复制延时
由于所有的写操作都是先在master上操作,然后同步更新到slave上,所以从master同步到slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,slave机器数量的增加也会使这个问题更加严重。可以限制一个master上子节点数量,如果实在太多slave,可以采用 主-从-从(让从节点成为另一个从节点的主节点) 链式结构来减少主节点压力。
选中策略
1. 根据各子机配置文件优先级,越小优先级越高,优先级相同会按照下面策略2
2. 根据偏移量,主机有10条数据,从1有10条,从2有9条(数据还没同步完成)则从1会成为主机,偏移量相同会按照下面策略3
3. runid越小,优先级越高,runid是每个redis实例启动后随机生成一个40位的id
14、redis 6集群
代理主机集群(不推荐)
通过代理服务器进行分发到各redis节点,各节点和代理服务器都要做主从节点容灾,比较麻烦和浪费资源
无中心化集群(推荐)
没有代理服务器进行分发,通过任一redis节点都可以访问其他节点
配置
删除.rdb文件
每个节点配置文件添加
cluster-enabled yes 打开集群模式
cluster-config-file nodes-端口名.conf 设定节点配置文件名
cluster-node-timeout 15000 设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换
cluster-enabled yes 打开集群模式
cluster-config-file nodes-端口名.conf 设定节点配置文件名
cluster-node-timeout 15000 设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换
启动每个节点,命令:redis-server 配置文件
把这些节点组成集群, 找一台安装了redis的服务器,必须进入redis根目录src文件夹下 cd /opt/redis-6.2.1/src
执行命令 redis-cli --cluster create --cluster-replicas 1[表示最简单方式配置集群,一主一从,这里正好三组] 192.168.11.101:6379 192.168.11.101:6380 192.168.11.101:6381 192.168.11.101:6389 192.168.11.101:6390 192.168.11.101:6391 注意:哪怕是本地也不能用127.0.0.1表示,必须用真实地址
执行命令 redis-cli --cluster create --cluster-replicas 1[表示最简单方式配置集群,一主一从,这里正好三组] 192.168.11.101:6379 192.168.11.101:6380 192.168.11.101:6381 192.168.11.101:6389 192.168.11.101:6390 192.168.11.101:6391 注意:哪怕是本地也不能用127.0.0.1表示,必须用真实地址
任何一个节点服务器都可以作为入口,连接集群中的redis节点 redis-cli -c -p 端口
查看节点信息 cluster nodes
slots
cluster keyslot key|组名 计算key被放在哪个插槽上
cluster countkeysinslot 插槽值 计算此插槽值中有多少个key,只能看自己管理插槽范围的值
cluster getkeysinslot 插槽值 key数量 获得这个插槽中的键
特点
当主机挂掉后,其从机会马上升为主机,而挂掉的主机重启后就成为从机
如果某一段插槽的主从节点都宕机,redis服务是否还能继续?
(默认整个集群不可用)
如果配置文件cluster-require-full-coverage yes 则整个集群挂掉
如果配置文件cluster-require-full-coverage no 则该插槽数据全都不能使用也无法存储
(默认整个集群不可用)
如果配置文件cluster-require-full-coverage yes 则整个集群挂掉
如果配置文件cluster-require-full-coverage no 则该插槽数据全都不能使用也无法存储
java操作集群
15、 redis 6应用问题解决
缓存穿透
解决方案
对空值缓存
设置可访问的名单(白名单)
采用布隆过滤器
进行实时监控
缓存击穿
解决方案
预先设置热门数据
实时调整
使用锁
缓存雪崩
解决方案
构建多级缓存架构
使用锁或队列
设置过期标志更新缓存
将缓存失效时间分散开
分布式锁
实现方案
基于数据库实现分布式锁
基于缓存(redis等)(性能最高)
通过setnx k1 v1 特性来实现,释放锁就 删除 k1;
另外可以同时设置 过期时间,防止锁一直没释放;
上锁和设置过期时间 需要是原子操作,使用命令 set k1 v1 nx ex 秒数 实现,避免上锁后,服务器挂了,没来得及设置过期时间
另外可以同时设置 过期时间,防止锁一直没释放;
上锁和设置过期时间 需要是原子操作,使用命令 set k1 v1 nx ex 秒数 实现,避免上锁后,服务器挂了,没来得及设置过期时间
java实现
误删锁
使用uuid防误删
删除锁操作不是原子性
使用lua脚本解决
Watch Dog 机制
基于zookeeper(可靠性最高)
并发控制
单命令
就是一个命令带有多个操作,如 INCR / DECR
缺点:不能进行逻辑判断
Lua脚本
就是多个命令一起执行,原子操作
缺点:脚本命令越多,执行时间越长
缓存一致性问题
有数据新增时,直接更新数据库
有数据改动时
先删缓存,再更新数据库
无并发请求
缓存删除成功,但更新数据库失败,再次读取的时候仍然是旧数据
有并发请求
缓存删除成功,数据库更新失败,并发请求读取到旧数据更新到缓存,导致后续的请求都读取到旧数据
缓存删除成功,数据库没来的及更新,并发请求读取到旧数据更新到缓存,导致后续的请求都读取到旧数据
先更新数据库,再删除缓存
无并发请求
更新数据库成功,但缓存删除失败,再次读取的时候仍然是旧数据
有并发请求
更新数据库成功,但缓存删除失败,后续并发请求读取到缓存旧数据
更新数据库成功,但缓存没来的及删除,后续部分并发请求读取到缓存旧数据,数据短暂不一致
只更新缓存,再由缓存自己同步更新到数据库
只更新缓存,再由缓存自己异步更新到数据库
过期键删除策略
定时删除
惰性删除
定期删除
扩展:定时任务
AOF/RDB和复制功能对过期键的处理
RDB
AOF
主从复制
内存淘汰机制
全局的键空间选择性移除
noeviction:内存不足,写入报错
allkeys-lru:内存不足,移除最近最少用的key (默认)
allkeys-lfu:内存不足,移除最近最不频繁使用的key
allkeys-random:内存不足,随机移除一个key
有过期时间的键空间选择性移除
volatile-lru:内存不足,在设置了过期时间的键中,移除最近最少使用的key
volatile-lfu:内存不足,在设置了过期时间的键中,移除最近最不频繁使用的key
volatile-random:内存不足,在设置了过期时间的键中,随机移除一个key
volatile-ttl:内存不足,在设置了过期时间的键中,移除最早过期的key
近似LRU 和 LFU 算法
近似LRU(淘汰第一次和第二次使用时间间隔最长的key)
每次内存清洗都 规定循环maxmemory-samples * 10 次获取抽样数据
LFU(淘汰使用频率最低的key)(4.0及以上版本可用)
定时任务函数什么时候执行?
redis.conf中,hz配置控制
16、redis 6新功能
ACL
【acl list】 展现用户权限列表
【acl cat】查看添加权限指令类别
【acl whoami】查看当前用户名
【acl setuser user1】创建新用户user1
【acl setuser user1 on >password ~cached:* +get】设置用户名、密码、权限、并启用用户
这里是 key 必须带 " cached: ",且只能 使用get命令
这里是 key 必须带 " cached: ",且只能 使用get命令
【auth user1 password】切换用户
IO多线程
配置
io-thread-do-redis no 默认不开启
io-threads 4 ,4个线程
工具支持Cluster
17、补充的一些概念
键空间
键空间和 用户 看到的 redis 数据库是一样的
redis存储结构
布隆过滤器
1、nosql数据库简介
技术发展
技术的分类
解决功能性问题
java、jsp、RDBMS、Tomcat、HTML、Linux、JDBC、SVN
解决扩展性问题
Struts、Spring、SpringMVC、Hibernate、MyBatis
解决性能问题
nosql、Java线程、Hadoop、Nginx、MQ、ElasticSearch
nosql数据库
nosql “不仅仅是sql”,泛指非关系型数据库
特点:不遵循SQL标准、不支持事务的特性ACID、远超SQL的性能
作用
解决CPU及内存压力
分布式部署,登录session存储问题
解决IO压力
数据库读写问题
场景
对数据高并发的读写、海量数据的读写、对数据高扩展性
不适合:需要事务支持,基于sql的结构化查询,处理复杂关系的查询
常见的nosql数据库
Memcache
不能持久化、支持类型单一(KV)
redis
支持持久化、支持多种数据结构
MongoDB
文档型数据库,支持二进制数据及大型对象存储
行式数据库
一行数据对应一个内存块,查询快,统计慢
列式数据库
一列数据对应一个内存块,查询慢,统计快
图关系型数据库
数据库排名
2、redis 6概述和安装
单线程+多路IO复用
https://blog.csdn.net/weixin_44479862/article/details/126512100
安装
1、官网下载 tar.gz压缩包
2、进入linux 服务器 创建新文件夹 把 压缩包 上传进去
3. tar -zxvf 压缩包 解压
4. gcc --version 检查是否安装环境
5、无安装: yum install centos-release-scl scl-utils-build
yum install -y devtoolset-8-toolchain
scl enable devtoolset-8 bash
gcc --version
yum install -y devtoolset-8-toolchain
scl enable devtoolset-8 bash
gcc --version
5. 进入解压后的文件夹 执行 make 命令进行编译
出现 --Jemalloc/jemalloc.h:没有那个文件 编译失败
解决办法:执行 make distclean
6. make install
7. make test
8. 默认安装到 /usr/local/bin/
9. 修改配置文件 daemonize yes
10. server-server 路径/配置文件 守护进程启动
3、常用5大数据类型
字符串string
set key value
get key
【append key value】将value 追加到原值末尾
【strlen key】获得key的value值长度
【setnx key value】只有在key不存在时,才设置
【incr key】给数字值+1,如果值为空,则新增值为1(原子性)
【decr key】给数字值-1,如果值为空,则新增值为-1(原子性)
【incrby key 步长】【decrby key 步长】将key对应的数字值按步长增减
【mset key1 value1 key2 value2 ...】同时设置多个键值对
【mget key1 key2 key3 ...】同时获取多个键对对应的值
【msetnx key1 value1 key2 value2...】只有在全部key不存在时,才设置
【getrange key 起始位置 结束位置】获取范围值,例如 set k1 lucy ; getrange k1 0 1 =》lu
【setrange key 起始位置 value】在起始位置设置值,例如 set k1 1 lucy ; setrange k1 0 hi =》hiucy
【setex key 过期时间 value】设置键值的同时设置过期时间
【getset key value】以新换旧,设置了新值同时返回旧值
列表list
【lpush key value1 value2...】从左边插入值
【rpush key value1 value2...】从右边插入值
【lpop key】从左边吐出一个值,当没值时,键就消失
【rpop key】从右边吐出一个值,当没值时,键就消失
【rpoplpush key1 key2】从key1列表右边吐一值插入到key2列表左边
【lrange key start stop】按照索引下标范围获取元素,从左到右(0 -1 表示取所有)
【lindex key index】按照索引下标从左到右获取元素
【llen key】获得列表长度
【linsert key before/after value newvalue】在value前面/后面插入newvalue
【lrem key n value】从左到右删除n个value(value是相同的)
【lset key index value】将列表key下标为index的值替换成value
集合set
【sadd key value1 value2...】添加多个元素到 key集合中,已存在的就不添加
【smembers key】取出key集合所有值
【sismember key value】判断key集合是否有value值,1有,0没有
【scard key】返回该集合的元素个数
【srem key value1 value2...】删除集合中的value值
【spop key】随机从该集合中吐出一个值,吐出后值不在集合中了
【srandmember key n】随机从key集合中取出n个值,但不是删除
【smove key1 key2 value】把key1集合中的值移到key2集合
【sinter key1 key2】返回两个集合的交集元素
【sunion key1 key2】返回两个集合的并集元素
【sdiff key1 key2】返回两个集合的差集元素(key1中的,不包含key2中的)
哈希hash
【hset key field value】给key集合中添加 元素
【hget key field】给key集合中取出field对应值
【hmset key field1 value1 field2 value2...】给key集合设置多个元素
【hexists key field】查看key中 field是否存在
【hkeys key】列出key集合中所有field
【hvals key】列出key集合中所有value
【hincrby key field increment】为key中的field值 加 数字
【hsetnx key field value】将key中的field值设为value,当field不存在时
有序集合zset
【zadd key score1 value1 score2 value2...】将一个或多个元素及其评分存到key 集合中
【zrange key start stop [withscores]】返回下标在start stop之间的元素,带withscores可以将分数一并返回
【zrangebyscore key min max[withscores]】返回有序集key,所有score值介于min和max之间(包括min 或max)的成员,从小到大排列
【zrevrangebyscore key max min [withscores]】同上,从大到小排列
【zincrby key increment value】为元素的score加上增量
【zrem key value】删除key中的指定的元素,如果set为空,则key也不存在
【zcount key min max】统计该集合,分数区间内的元素个数
【zrank key value】返回该值在key集合中的排名,从0开始
4、redis 6操作
redis-cli -p 6380
【keys *】 查看当前库所有key
【set key value】存放值
【select 1】 切换到库1
【exists key】 判断某个key是否存在
【type key】 查看你的key是什么类型
【del key】 删除指定的key数据
【unlink key】 根据key非阻塞删除,真正的删除会在后续异步操作
【expire key 10】 给key设置10秒过期时间
【ttl key】 查看还有多少秒国企,-1表示永不过期,-2表示已过期
【dbsize】查看当前数据库的key数量
【flushdb】清空当前库
【flushall】通杀全部库
5、redis 6配置文件详解
bind 配置 ip 后,就不能允许远程访问,只能允许绑定的ip访问
protected-mode 配置yes 后,开启访问保护模式,禁止远程访问
tcp-backlog 配置,backlog队列综合=三次握手队列+已经完成三次握手队列中,在高并发下需要一个高backlog值来避免慢客户端链接问题
timeout 配置 0 代表永不超时,秒为单位
tcp-keepalive 配置 代表检测是否有在操作redis,没有则释放链接,默认300秒检测1次
daemonize 配置 yes 代表守护进程启动
pidfile 配置 保存redis的进程号
loglevel 配置 redis日志文件级别
logfile 配置日志文件输出路径
databases 配置 redis数据库数量
maxclients 配置 redis同时可以与多少个客户端进行链接,默认10000个
maxmemory 配置 redis可以使用的内存量
maxmemory-policy 配置 达到redis可以使用的内存量时采用何种处理规则
volatile-lru:使用lru算法移除key,只对设置了过期时间的键;
allkeys-lru:在所有集合key中,使用lru算法移除key
volatile-random:在过期集合中移除随机的key,只对设置了过期时间的键
allkeys-random:在所有集合key中,移除随机的key
volatile-ttl:移除那些ttl值最小的key,即那些最近要过期的key
noeviction:不进行移除,针对写操作,只返回错误信息
6、redis 6的发布和订阅
打开一个客户端,执行【subscribe channel1】订阅一个频道channel1
打开另一客户端,执行【publish channel1 message】发布message信息到频道channel1
7、redis 6新数据模型
bitmaps
【setbit key offset value】设置bitmaps中某个偏移量的值(value只能是0或1)
【getbit key offset】获取某个偏移量的值,从0开始算
【bitcount key [start end]】统计字符串从start字节到end 字节 比特值为1的数量
【bitop and(or/not/xor) destkey key1 key2... 】将多个key集合的 and(交集)、or(并集)、not(非)、xor(异或)后的结果存到destkey中
hyperLogLog
【pfadd key element...】添加多个指定元素,已存在的就不会添加
【pfcount key...】统计多个hyperLogLog元素
【pfmerge destkey sourcekey...】将一个或多个hyperLogLog合并后的结果存到destkey中
geospatial
【geoadd key longitude latitude member [longitude latitude member] 】添加经纬度和名称,例如:geoadd china 121.47 31.23 shanghai,已经存在则不能再添加
【geopos key member...】获得指定地区的坐标,例如:geopos china shanghai
【geodist key member1 member2 [m|km|ft|mi]】获取两个位置之间的直线距离,例如:geodist china shanghai beijing km
【georadius key longitude latitude radius m|km|ft|mi】以给定的经纬度为中心找出某一半径内的元素,例如:georadius china 110 30 1000 km
8、jedis 操作 redis 6
https://www.bilibili.com/video/BV1Rv41177Af/?p=18&spm_id_from=pageDriver&vd_source=9f251517936a55a0bc8436ce8cc1e766
Jedis jedis =new Jedis(host,pord);
String value = jedis.ping(); //测试链接redis,连接成功则有返回值,否则异常
String value = jedis.ping(); //测试链接redis,连接成功则有返回值,否则异常
0 条评论
下一页