Redis基本概念



![在这里插入图片描述](https://img-blog.csdnimg.cn/20190814210142667.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FzYmJs,size_16,color_FFFFFF,t_70)

# 1.Redis入门

[说说NoSQL中的Redis](https://blog.csdn.net/qsbbl/article/details/82935416)
[【Redis】在java中的使用-存取string类型](https://blog.csdn.net/qsbbl/article/details/83651514)
[【Redis】基础问题答疑](https://blog.csdn.net/qsbbl/article/details/83652009)
[【Redis】连接池的使用](https://blog.csdn.net/qsbbl/article/details/83688327) ------ # 2.Redis的特点 ## 1)5种数据结构 redis支持多种数据结构:string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)等。其中常用的是string、list。今天我们说说list的常用命令。列表类型是有序的,是可重复的,我们可以通过访问下标来获取某个元素。对其的操作和对list集合的操作的思想是一致的。 ```java // 在右边插入元素,结果为(person,a b c) rpush person a b c // 删除指定元素b,1代表从左到右,最多删除1个元素,此处可取的值为: // 正数(从左到右)、负数(从右到左)、0(删除所有) lrem person 1 b // 获取指定元素b lindex person 1 // 修改指定元素b为p lset person 1 p ``` ## 2)基于内存 我们知道,像mysql这些关系型数据库是将数据存储在磁盘上的,速度慢,但是稳定。 像redis这些非关系型数据库是将数据存储在内存上的,速度快,但是不稳定,服务器一宕机,内存里的数据就没了。 还好redis配置了可持久化,可将内存中的数据定期存放到磁盘上去。 因为redis是基于内存的,所以其速度快,1s可进行10万次读写。 ## 3) 单线程 redis使用了单线程架构,预防了多线程可能产生的竞争问题。但也正是因为使用了单线程,其一旦发生阻塞,就将是致命的。 redis为什么选择使用单线程?redis的主要特点就是快,使用单线程能避免上下文切换等损耗。 ## 4)key-value 和map集合一样,redis集合的组织方式也是key-value型的。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190814203252721.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FzYmJs,size_16,color_FFFFFF,t_70) ------ # 3.持久化 Redis是内存数据库,如果不将内存的数据库状态保存到磁盘,那么一旦服务器进程退出,数据库状态也会消失。redis提供了2种持久化的方式:RDB和AOF。持久化就是将内存里的数据同步到磁盘里,进行“持久”保存。 ## RDB RDB持久化是把当前线程数据生成快照保存到磁盘的过程。 ![](E:\gp_c\3118004958郭沛\暑期训练营\Redis\微信截图_20200731090421.png) ``` 优点: 1、适合大规模的数据恢复; 2、对数据完整性不高,则可以使用 缺点: 1、需要一定的实践间隔进程操作,如果redis意外宕机,最后一次修改的数据可能就没有了; 2、fork进程的时候,会占用一定的内存空间。 适用场景: 一般用于数据冷备和复制传输。 啥叫数据冷热备?热备指为了保证服务正常运行,用两台服务器作为服务机器,一台用于实际数据库操作应用,另一台用于从前者获取数据以保持数据一致。如果当前服务器宕机,有另一台继续提供服务。 冷备是指在数据库关闭后,进行备份。 ``` ## AOF ![](E:\gp_c\3118004958郭沛\暑期训练营\Redis\微信截图_20200731091017.png) AOF持久化是以独立日志的方式记录每次写命令,重启时再重新执行一遍此命令,从而恢复数据。其工作流程如下: ![img](https://img-blog.csdnimg.cn/20190814205556503.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FzYmJs,size_16,color_FFFFFF,t_70) (1)所有的写命令会追加到aof缓冲区。
(2)aof缓冲区根据对应的策略向磁盘做同步操作。
(3)随着aof文件越来越大,需要定期对aof文件进行重写,以达到压缩的目的。
(4)当redis服务器重启时,可以加载aof文件进行数据恢复。 ``` 优点: 1、每一次修改都同步,文件的完整会更加好; 2、每秒同步一次,可能会丢失一秒的数据; 3、从不同步,效率最高的 缺点: 1、相对于数据文件来说,aof远远大于rdb,修复速度也比rdb慢; 2、aof运行效率也比rdb慢 ``` ------ # 4. 阻塞 因为redis是单线程架构,所有的读写操作都是在一条主线程中完成的,所以一旦出现阻塞,将是致命的。 ## 内在原因 (1)API或数据结构使用不合理 ``` // 获取最近的10条慢查询 slowlog get 10 ``` (2)CPU饱和
(3)持久化相关的阻塞:fork阻塞、aof刷盘阻塞、hugepage写操作阻塞 ## 外在原因 (1)CPU竞争
(2)内存交换
(3)网络问题:连接拒绝、网络延迟、网卡软中断 ## 解决措施 (1)在应用方加入异常监控,并要定位到具体的出问题的结点
(2)Redis的监控 ------ # 5.缓存相关 ## 更新策略 redis中的数据通常都是有生命周期的,需要在特定时间后被删除或更新,这样可以保证缓存空间在一个可控的范围。有3种缓存更新策略。 (1)LRU/LFU/FIFO算法剔除 当缓存使用量超过了预设的最大值时,会启动策略对数据进行清除。 ``` LRU:最近最久未使用 LFU:最近最少使用 FIFO:先进先出 ``` (2)超时剔除 在将数据放入缓存时,已经设置了过期时间,当到时间后,自动将其删除。使用命令expire来实现。 (3)主动更新 对数据进行“增删改”操作后,立即清除redis中的相关数据 ## 缓存穿透 ### 1、概念 缓存穿透是指查询一个数据库不存在的数据,每次都去查询数据库,而每次查询都是空,每次又都不会进行缓存。假如有大量请求进来,可能会压垮数据库。 ### 2、产生的原因 (1)自身业务代码或者数据出现问题 (2)一些恶意攻击,爬虫等造成大量空命中 ### 3、解决措施 (1)缓存空对象 当数据库不命中后,仍然将空对象保留到缓存层中,之后再访问这个数据,将会从缓存中获取,这样就保护了后端数据源。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2019081609380612.png) ```java String get(String key){ //从缓存中获取数据 String cacheValue=cache.get(key); //缓存为空 if(StringUtils.isBlank(cacheValue)){ //从存储中获取 String storageValue=storage.get(key); cache.set(key,storageValue); //如果存储数据为空,需要设置一个过期时间(300秒) if(storageValue==null){ cache.expire(key,60*5); } return storageValue; }else{ //缓存非空 return cacheValue; } } ``` 此解决办法的使用场景为:数据命中不高且数据频繁变化实时性高。 (2)布隆过滤器拦截 将存在的key放入布隆过滤器中。当一个查询请求过来时,先经过此过滤器,如果此过滤器认为该数据不存在,就直接丢弃,不再继续访问缓存层和存储层。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190816093824788.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FzYmJs,size_16,color_FFFFFF,t_70) 此解决办法的适用场景为:数据命中不高,数据相对固定、实时性低 ## 无底洞 ### 1、概念 为了满足业务需求,大量添加redis集群的节点,但是性能没提升反而下降。 ### 2、产生的原因 在单机操作中,如果想批量获取多个key,只需一次网络操作即可,在集群中,节点越多,涉及的网络IO就越多,性能就可以能会下降。 ### 3、解决办法 (1)串行命令
(2)串行IO
(3)并行IO
(4)hash_tag实现 ## 缓存雪崩 ### 1、概念 缓存雪崩是指在设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,导致所有的查询都落在数据库上,造成了缓存雪崩。 ### 2、解决办法 (1)不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
(2)如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中。
(3)设置热点数据永远不过期。
(4)做二级缓存。
(5)在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
posted @ 2020-08-01 00:20  AllForward  阅读(81)  评论(0)    收藏  举报