Redis本质上是一个Key-Value类型的内存数据库,整个数据库加载在内存当中操作,定期通过异步操作把数据库中的数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value 数据库。
高性能:Redis能读的速度是110000次/s,写的速度是81000次/s 内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
String字符串类型:存储一些数字,验证码、时间戳、一些配置项字典表的数据 Hash(HashMap):可以存储实体类型的数据,比如存储用户的登陆信息 List(链表类型):存储一些集合数据,可重复 Set(集合元素不重复):存储一些集合数据,不可重复 SortedSet(集合元素不重复,排序):存储一些集合数据,不可重复,可以排序,比如榜单,投票排行
缓存雪崩是指缓存中的key大批量到达了过期时间,这个时候这个大量的请求都需要到数据库请求去拿数据,这个时候数据的压力暴增引起down机。
解决办法:
如果Redis在途中突然down机,这个时候也可能导致雪崩。 解决办法:1、针对小业务量级,我们可以采用 redis 的 sentinel 哨兵机制 2、针对大业务量级,我们可以采用 redis 的 cluster 集群方案
缓存中没有,数据库中也没有 缓存穿透是指恶意频繁查询一个缓存中不存在的数据。缓存中不存在这个数据,所以请求就会访问数据库,数据库中也没有这个数据,也就不会把数据存入到缓存,所以如果恶意访问数据量大的话就会一直增大数据库的压力,从而导致数据库down机。
解决办法:
缓存中没有,数据库有 缓存中没有但数据库中有的数据,假如是热点数据,那key在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力增大。
1、先更新数据库,在更新缓存 2、先更新缓存在更新数据库 3、先删除缓存在更新数据库 4、先更新数据库在删除缓存(推荐) 四种策略都可能会导致数据的不一致,所以在第四种策略添加一个过期时间,就可以完美解决数据不一致问题,达到最终一致性。 或者通过mq去监听数据库binlog日志如果发生修改或者新增删除都去更新redis缓存。
lru/lfu/random/ttl
Redis是一个内存数据库,如果没有配置持久化,redis重启后数据就全丢失 因此开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。
在指定的时间间隔内将内存中的数据集快照写入磁盘。 优点
缺点
默认情况下 Redis 没有开启 AOF(append only file)方式的持久化,可以 通过 appendonly 参数开启:appendonly yes。 开启 AOF 持久化后每执行一条会更改 Redis 中的数据的命令,Redis 就会将 该命令写入硬盘中的 AOF 文件。AOF 文件的保存位置和 RDB 文件的位置相同,都 是 通 过 dir 参 数 设 置 的 , 默 认 的 文 件 名 是 appendonly.aof , 可 以 通 过 appendfilename 参数修改:appendfilename appendonly.aof.
优点:
缺点:
引入:单个Redis如果因为某种原因宕机的话,可能会导致Redis服务不可用,可以使用主从复制实现一主多从,主节点负责写的操作,从节点负责读的操作,主节点会定期将数据同步到从节点中,保证数据一致性的问题。
原理:redis cluster 集群默认 16384 个 hash 槽,集群搭建成功之后,需要给每一个 主节点,分配 hash 槽。当外部数据插入的时候,会对 key 进行 crc16 然后对 16384 取模,这样就计算出哪个节点对该数据进行管理。 在项目当中可以采用的 3 主 3 从的结构,主从之间通过哨兵,出现故障自动切换.
为了防止分布式系统中的多个进程之间相互干扰,我们需要一种分布式协调技术来对这些进程进行调度,利用互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题
Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而是开发者能将精力更集中地放在业务上。 Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格(In-Memory Data Grid)。 Redission作为redis的分布式客户端,同样基于netty采用异步非阻塞式IO,是线程安全的,优点是提供了很多redis的分布式操作和高级功能,缺点是api抽象,学习成本高。
setnx 的含义就是 SET if Not Exists,有两个参数 setnx(key, value),该方法是原子性操作。 如果 key 不存在,则设置当前 key 成功,返回 1; 如果当前 key 已经存在,则设置当前 key 失败,返回 0; 需要注意加锁key的粒度,解锁需要注意锁的线程必须是当前线程的锁。锁续期需要主要给锁分配的时间。
使用 lua脚本+redis可以保证业务的原子性。
无论是哪个版本redis的工作线程都是一条。 在6.x以后io有多线程。
redis可以保障内部串型,外界使用的要自行保障线程安全。
select poll都是基于连接轮训的方式完成多路复用的