1、概述
-
是一个由C语言开发的基于key-value形式的非关系型数据库
-
key-value:键值对【键:String,值:五种数据类型】
-
非关系数据库:NoSQL【Not Only SQL】
-
关系型数据库:由二维表的形式来存储数据
-
不是关系型数据库,就是非关系型数据库
-
-
-
-
存储介质
-
默认是内存
-
可以持久化到磁盘上
-
五种数据类型
string:字符串
hash:对象
list:有序列表:在操作list时
向list中增加数据【有两种方式,推荐使用右压栈】
左边增加数据【左压栈,后增加的数据会把之前增加的数据向右挤】,在读取时是反向的
右边增加数据【右压栈,后增加的数据会把之前增加的数据向左挤】,在读取时是正向的
从list中获取数据
获取的数据是从左到右的
set:无序集合
zset:有序集合
1、Redis的五种数据类型及应用场景?
string:验证码、计数器,文章阅读数、 缓存热点数据
hash:购物车、学习计划
list:队列,消息队列,保证顺序消费,头条中的redis实现延迟队列中就使用到了list
set:抽奖、微信朋友圈点赞、微博的共同关注
zset:排行榜、天梯排行榜
-
Jedis:Redis官方提供的一个Java操作Redis的API
-
RedisTemplate:SpringBoot集成Redis提供的API
2、Redis持久化机制
1、Redis数据存储在内存,一般不是重要的数据,可能会丢失
2、持久化机制 持久化:把数据保存磁盘上 分类:不持久化 RDB:会根据配置的规则进行定时快照备份 优点:快照数据以二进制存储,文件小,恢复速度快 缺点:因为有时间间隔,会丢失一定的数据 原理:手动执行 bgsave 命令,来触发RDB。主进程会fork一个子进程在后台完成RDB【读取内存的数据,形成一个dump.rdb,更换旧的rdb文件】
AOF:以日志的形式记录key发生变化的指令,默认是关闭的,记录到一个文件中:appendonly.aof
优点:数据以命令的形式存储,数据不容易丢失,文件会重写:去重无用指令,优化数据最终得到的结果是多少即可,手动重写:bgrewriteaof
缺点:文件大、恢复速度慢,AOF文件可能会被篡改
RDB + AOF:AOF + aof文件在压缩以RDB二进制的方式去存储,配置文件可以配置 RDB和AOF的区别:RDB的占用空间小 ,而AOF的占用空间比较大,RDB的储存速度比较慢,AOF的速度比较快,恢复速度则相反,在数据安全性方面RDB会丢失数据,而AOF则是根据策略决定,RDB的资源消耗比较高属于是重量级的,而AOF的戏院小号比较低,属于是轻量级的,启动优先级的话RDB是比较低的,而AOF则是比较高的 数据恢复:先恢复AOF,再补充RDB
3、Redis淘汰策略
Redis数据存储在内存,如果内存被打满了?就会触发淘汰策略 淘汰: 定期淘汰【主动】:一般会选择 volatile-lru,取样基数:5,Redis会把内存所有的key分为5个一组,在5个中淘汰一个满足条件的key 隋性淘汰: redis中的key如果过期了,是不会立即被删除,客户端来查询一个key,redis会先判断该key是否过期,不过期直接返回。过期就删除,再返回一个null
4、高可用
1、单点故障:单台服务器运行的项目,如果服务器宕机了,项目就挂了 2、主从:主从架构可以提升redis的读的性能
一般情况下,redis能够达到
11W/S
的读的性能,能够达到8W/S
写的性能
-
主节点可以进行读写,从节点只能读
-
主节点默认情况下只负责写,不负责读。所有的读请求交给从节点。除非从节点达到读的瓶颈,这个时候主节点才有可能会去执行读请求
-
从节点会同步主节点的数据【全量复制、增量复制】
-
数据同步的原理
默认情况下,优先选择增量复制,如果失败,则会使用全量复制
-
全量复制
-
从节点初次连接主节点
-
从节点增量复制失败,就会使用全量复制
-
从节点主动发起全量复制
-
-
增量复制【部分复制】
-
从节点在复制主节点数据时,会维护偏移量,同时主节点也会维护这个偏移量。
-
当从节点因为某些原因突然跟主节点断开后,那么重连上主节点后就会向主节点发起同步数据的请求,这个时候就是通过该偏移量来决定是哪些数据开始进行增量复制
-
3、哨兵:职责,是为了提升主从架构的可用性,用来监控主从架构的是否可用 选举:当主节点宕机后,哨兵就会监控到,然后通知两个从节点说主节点挂了,那么两从节点就会去跟主节点进行通信,判断主节点是否挂了,如果认为主节点挂了,那么进行投票,如果票数大于节点数的一半,则认为主节点真的挂了,这么时候会触发选举机制。 主节点选举:谁的数据多,谁当主节点,谁的数据新,谁当主节点 3、redis-cluster
原理
搭建redis-cluster时,redis-cluster会形成一个一致性hash环。
这个hash环会分配16384个槽位【0-16383】,redis-cluster会根据redis节点的数量平均的把16384个槽位分配给每个redis主节点。
为了保证高可用,应该为每个redis主节点配置一个从节点
从节点在主节点正常工作时,不参与处理读写请求的,只负责把主节点的数据同步过来。当主节点宕机后,从节点才会顶上去工作
redis-cluster是一个无中心的集群,所以hash环上的节点如果不可用【并且在一段时间内,该节点的从节点也没有顶上来】,那么就会由hash环其他节点进行投票决定,投票超过半数则认为该节点挂了,这个时候会把这个节点踢出hash环。当hash环上的节点宕机的数量达到一半,那么整个集群就挂了
在连接集群时,只需要连接上集群中一个节点,就代表连接上整个集群了
在向集群中set数据时,redis-cluster会对插入数据的key进行hash运算【首先对key进行hash,然后对16384取模,得到一个0-16383之间的数】,得到一个0-16383的范围之间的值,那么会对该key插入到对应的槽位。如果这个槽位不在当前连接的节点上,那么自动重定向到该槽位对应的节点。注意:这不代表说当前redis-cluster只能存储16384个数据,因为一个槽位可以存储多个数据
5、分布式锁
1、分布式锁 传统锁:Synchronized是通过关键字进行加锁的没办法手动释放锁 Lock通过提供的api来进行加锁可以手动释放锁 分布式锁 2、热点数据【key】重建问题 没锁 分布式锁: 死锁:线程在上锁后,没有释放锁。导致其他线程没有办法拿到锁,一直尝试去拿锁,就产生了死锁 解决方案:设置过期时间,把释放锁的代码放到finally中 误删锁:当前线程删掉了别的线程上的锁 解决方案:在上锁时,把锁的值设置成唯一值,在删除锁时,进行验证是否删除的是自己的锁 3、redisson redission实现分布式锁的原理
-
线程一尝试去获取锁,拿到锁之后【锁的有效是30S】
-
在后台开启一个子线程【定时(每过10秒)去查询当前线程是否还持有锁,如果有,则给锁续命(延长锁到30S)】,直到主线程执行结束,手动释放锁。同时可以指定给锁续命的次数,如果超过了,则可以主动删除锁
-
线程二尝试去获取锁,拿锁失败,会进行自旋【每隔一定时间去拿锁】,直到拿锁成功后去执行2
-
-
6、Redis使用问题
1、穿透:概念:访问缓存中没有,数据库中也没有的数据,感觉像穿透了缓存层,直达数据库,可能会造成数据库宕机。这个其实是一种恶意手段
解决: 1、查一个不存在的数据时,设置一个具备过期间的假数据,存入缓存 简单粗暴
2、布隆过滤器:查询缓存前,先判断当前key在布隆过滤器中是否存在,一定不存在:直接返回,有可能存在:再查询缓存,没有,再查询数据库,Redisson直接有实现方案
2、击穿 概念:某一个热点数据的key突然过期,造成大量请求直达数据库
解决: 1、分布式锁
2、热点数据永不过期
3、接口限流
3、雪崩 概念:缓存中在同一个时间点有大量的key同时过期,请求查询缓存中没有,直达数据库
解决方案: 1、随机过期时间
2、热点数据永不过期
4、多个命令如何保证原子性
使用LUA脚本
Redis的事务
标签:Redis,redis,key,RDB,数据,节点 From: https://www.cnblogs.com/zcj-gh/p/17742683.html