Redis学习笔记
一、Nosql数据库简介
二、redis6概述和安装
与memcache的不同点
三、常用五大数据类型
1. Redis 字符串
String是Redis最基本的类型 是二进制安全的 value最多512M
incrby decrby 命令具有原子性,不会被线程调度机制打断。(将val增加或减少某值)
- 数据结构:String的数据结构为简单动态字符串。是可以修改的字符串,内部结构实现上类似于Java中的ArrayList,采用与分配冗余空间的方式来减少内存的频繁分配 如果字符串小于1M时,扩容都是加倍现有的空间,超过1M,每次只扩容1M的空间。最大的长度不允许超过512M
2. Redis 列表
Redis列表时简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部或者尾部
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差
lpush/rpush lpop/rpop
- 数据结构:quickList 首先在列表元素较少的情况下使用一块连续的内存存储,这个结构时ziplist,也就是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存;当数据链比较多的时候次才会改成quickList。因为普通的链表需要的附加指针空间太大,会比较浪费空间。结构上还需要两个额外的指针prev和next
- redis将链表和ziplist结合起来组成了quickList。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余
3. Redis 集合
Redis set是string类型的无序集合。它底层其实是一个value为null的hash表,所以添加,删除,查找的复杂度都是O(1)
sadd/smembers/sismember/scard(长度)/srem(删除)/spop(随机取)/srandmember(随机取,不会删除)/smove/sinter(交集)/sunion(并集)/sdiff(差集)
4. Redis 哈希
Redis hash是一个String类型的field和value的映射表,hash特别适合用户存储对象。类似Map<String, Object>
hset/hget/hmset/hmget/hexists/hkeys/hvals/
- 数据结构:hash类型对应的数据结构时两种,ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable
5. Redis 有序集合
Redis 有序集合zset与普通集合set,是一个没有重复元素的字符串集合。每个成员都关联了一个评分,集合的成员是唯一的,得分可以重复。
zadd()/zrange(
- 数据结构:
四、Redis配置文件详解
- units —> 单位,只支持bytes,大小写不敏感
- include
- network
- daemonize 是否支持后台启动
- pidfile 保存进程号的文件路径
- loglevel (日志级别)
- debug
- verbose
- notice
- warning
- Logfile 日志文件在哪
- databases 几号库
五、发布和订阅
Redis 发布订阅是一种消息通信模式:发送者发送消息,订阅者接受消息
六、Redis新数据类型
1. Bitmaps(类似 编程之美中用二进制数来存储象棋状态)
- Bitmaps 本身不是一种数据类型,实际上它就是字符串,但是它可以对字符串的位进行操作
- Bitmaps 单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同,可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量
2. HyperLogLog(占用内存小,类似set去重)
3. Geospatial
- 地理信息
七、Jedis操作Redis
自己看文档去!!!
八、Redis与Spring Boot整合
同上!!!
九、Redis的事务操作
1. Redis的事务定义
Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程汇总,不会被其他客户端发送来的命令请求所打断。
Redis事务的主要作用就是串联多个命令防止别的命令插队
2. Multi、Exec、discard
从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis才会将之前的命令队列中的命令依次执行。
组队的过程中可以通过discard来放弃组队。
3. 事务的错误处理
4. 事务冲突的问题
- 例子:类似超卖现象
- 悲观锁:阻塞
- 乐观锁:增加版本号 类似java(CAS)
- Watch key (类似CAS,监视这个key有没有被操作,被操作则执行失败)
- unwatch (不监视了)
十、Redis持久化之RDB
1. 是什么?
- 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里
2. 备份是如何执行的?
- Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
3. Fork
- Fork的作用是复制一个与当前进程一样的进程。新进程的所有数据数值和原进程一致,但是是一个全新的进程,并作为原进程的子进程
- 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后都会exec系统调用,处于效率考虑,Linux中引入了“写时复制技术”
- 一般情况父进程和子进程会共用同一个段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。
4. dump.rdb文件
5. 如何触发RDB快照;保持策略
-
rdb的备份
-
优点:
- 适合大规模的数据恢复
- 对数据完整性和一致性要求不高更适合使用
- 节省磁盘空间
- 恢复速度快
-
缺点:
十一、Redis持久化之AOF
1. 是什么?
- 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来,只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
2. AOF持久化流程
- 客户端的请求命令会被append追加到AOF缓冲区内
- AOF缓冲区根据AOF持久化策略将操作sync同步到磁盘的AOF文件中
- AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量
- Redis服务重启后,会重新load加载AOF文件中的写操作达到数据恢复的目的;
3. 重写原理
- AOF文件持续增长而过大时,会fork出一条新进程来将文件重写,redis4.0版本后的重写,实际上就是把rdb的快照,以二进制的形式附在新的aof文件头部,作为已有的历史数据,替换掉原来的流水账操作。
4. 优劣势
- 优势:
- 劣势:
- 比起RDB占用更多的磁盘空间
- 恢复备份速度要慢
- 每次读写都同步的话,有一定的性能压力
- 存在个别bug,造成不能恢复
5. 总结
- 用哪个
- 官方推荐两个都启用,如果对数据不敏感,可以选RDB,不建议单独用AOF,因为可能会出现bug。如果知识做纯内存缓存,可以都不用
- 官网建议
- RDB持久化方式能够在指定的时间间隔内对你的数据进行快照存储
- AOF持久化方式记录每次对服务器写的操作,当服务秋重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾
- Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
- 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式
- 同时开启两种持久化方式
- 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常的情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
- RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?
- 建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着座位一个万一的手段
- 性能建议
十二、Redis主从复制和集群
自己看文档!!!
十三、Redis应用问题解决
1. 缓存穿透
- key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会压到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
- 解决方案:
- 对空值缓存:如果一个查询返回的数据为空(不管是数据是否不存在),我们仍然把这个空结果进行缓存,设置空结果的过期时间会很短,最长不超过五分钟
- 设置可访问的名单:使用bitmaps类型定义一个可以访问的名单,名单id座位bitmaps的偏移量,每次访问和bitmap里面的id进行比较,如果访问id不在bitmaps里面,进行拦截,不允许访问。
- 采用布隆过滤器,布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。将所有可能存在的数据哈希到一个足够大的bitmaps中,一个一定个不存在的数据会被这个bitmaps拦截掉,从而避免了对底层存储系统的查询压力。
- 进行实时监控:当发现Redis的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制服务。
2. 缓存击穿
3. 缓存雪崩
- key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。缓存雪崩与缓存击穿的区别在于这里针对很多key缓存,前者则是某一个key。
- 解决方案:
4. 分布式锁
十四、Redis6.0新功能
一、Nosql数据库简介
二、redis6概述和安装
与memcache的不同点
三、常用五大数据类型
1. Redis 字符串
String是Redis最基本的类型 是二进制安全的 value最多512M
incrby decrby 命令具有原子性,不会被线程调度机制打断。(将val增加或减少某值)
- 数据结构:String的数据结构为简单动态字符串。是可以修改的字符串,内部结构实现上类似于Java中的ArrayList,采用与分配冗余空间的方式来减少内存的频繁分配 如果字符串小于1M时,扩容都是加倍现有的空间,超过1M,每次只扩容1M的空间。最大的长度不允许超过512M
2. Redis 列表
Redis列表时简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部或者尾部
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差
lpush/rpush lpop/rpop
- 数据结构:quickList 首先在列表元素较少的情况下使用一块连续的内存存储,这个结构时ziplist,也就是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存;当数据链比较多的时候次才会改成quickList。因为普通的链表需要的附加指针空间太大,会比较浪费空间。结构上还需要两个额外的指针prev和next
- redis将链表和ziplist结合起来组成了quickList。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余
3. Redis 集合
Redis set是string类型的无序集合。它底层其实是一个value为null的hash表,所以添加,删除,查找的复杂度都是O(1)
sadd/smembers/sismember/scard(长度)/srem(删除)/spop(随机取)/srandmember(随机取,不会删除)/smove/sinter(交集)/sunion(并集)/sdiff(差集)
4. Redis 哈希
Redis hash是一个String类型的field和value的映射表,hash特别适合用户存储对象。类似Map<String, Object>
hset/hget/hmset/hmget/hexists/hkeys/hvals/
- 数据结构:hash类型对应的数据结构时两种,ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable
5. Redis 有序集合
Redis 有序集合zset与普通集合set,是一个没有重复元素的字符串集合。每个成员都关联了一个评分,集合的成员是唯一的,得分可以重复。
zadd()/zrange(
- 数据结构:
四、Redis配置文件详解
- units —> 单位,只支持bytes,大小写不敏感
- include
- network
- daemonize 是否支持后台启动
- pidfile 保存进程号的文件路径
- loglevel (日志级别)
- debug
- verbose
- notice
- warning
- Logfile 日志文件在哪
- databases 几号库
五、发布和订阅
Redis 发布订阅是一种消息通信模式:发送者发送消息,订阅者接受消息
六、Redis新数据类型
1. Bitmaps(类似 编程之美中用二进制数来存储象棋状态)
- Bitmaps 本身不是一种数据类型,实际上它就是字符串,但是它可以对字符串的位进行操作
- Bitmaps 单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同,可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量
2. HyperLogLog(占用内存小,类似set去重)
3. Geospatial
- 地理信息
七、Jedis操作Redis
自己看文档去!!!
八、Redis与Spring Boot整合
同上!!!
九、Redis的事务操作
1. Redis的事务定义
Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程汇总,不会被其他客户端发送来的命令请求所打断。
Redis事务的主要作用就是串联多个命令防止别的命令插队
2. Multi、Exec、discard
从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis才会将之前的命令队列中的命令依次执行。
组队的过程中可以通过discard来放弃组队。
3. 事务的错误处理
4. 事务冲突的问题
- 例子:类似超卖现象
- 悲观锁:阻塞
- 乐观锁:增加版本号 类似java(CAS)
- Watch key (类似CAS,监视这个key有没有被操作,被操作则执行失败)
- unwatch (不监视了)
十、Redis持久化之RDB
1. 是什么?
- 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里
2. 备份是如何执行的?
- Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
3. Fork
- Fork的作用是复制一个与当前进程一样的进程。新进程的所有数据数值和原进程一致,但是是一个全新的进程,并作为原进程的子进程
- 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后都会exec系统调用,处于效率考虑,Linux中引入了“写时复制技术”
- 一般情况父进程和子进程会共用同一个段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。
4. dump.rdb文件
5. 如何触发RDB快照;保持策略
-
rdb的备份
-
优点:
- 适合大规模的数据恢复
- 对数据完整性和一致性要求不高更适合使用
- 节省磁盘空间
- 恢复速度快
-
缺点:
十一、Redis持久化之AOF
1. 是什么?
- 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来,只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
2. AOF持久化流程
- 客户端的请求命令会被append追加到AOF缓冲区内
- AOF缓冲区根据AOF持久化策略将操作sync同步到磁盘的AOF文件中
- AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量
- Redis服务重启后,会重新load加载AOF文件中的写操作达到数据恢复的目的;
3. 重写原理
- AOF文件持续增长而过大时,会fork出一条新进程来将文件重写,redis4.0版本后的重写,实际上就是把rdb的快照,以二进制的形式附在新的aof文件头部,作为已有的历史数据,替换掉原来的流水账操作。
4. 优劣势
- 优势:
- 劣势:
- 比起RDB占用更多的磁盘空间
- 恢复备份速度要慢
- 每次读写都同步的话,有一定的性能压力
- 存在个别bug,造成不能恢复
5. 总结
- 用哪个
- 官方推荐两个都启用,如果对数据不敏感,可以选RDB,不建议单独用AOF,因为可能会出现bug。如果知识做纯内存缓存,可以都不用
- 官网建议
- RDB持久化方式能够在指定的时间间隔内对你的数据进行快照存储
- AOF持久化方式记录每次对服务器写的操作,当服务秋重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾
- Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
- 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式
- 同时开启两种持久化方式
- 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常的情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
- RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?
- 建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着座位一个万一的手段
- 性能建议
十二、Redis主从复制和集群
自己看文档!!!
十三、Redis应用问题解决
1. 缓存穿透
- key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会压到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
- 解决方案:
- 对空值缓存:如果一个查询返回的数据为空(不管是数据是否不存在),我们仍然把这个空结果进行缓存,设置空结果的过期时间会很短,最长不超过五分钟
- 设置可访问的名单:使用bitmaps类型定义一个可以访问的名单,名单id座位bitmaps的偏移量,每次访问和bitmap里面的id进行比较,如果访问id不在bitmaps里面,进行拦截,不允许访问。
- 采用布隆过滤器,布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。将所有可能存在的数据哈希到一个足够大的bitmaps中,一个一定个不存在的数据会被这个bitmaps拦截掉,从而避免了对底层存储系统的查询压力。
- 进行实时监控:当发现Redis的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制服务。
2. 缓存击穿
3. 缓存雪崩
- key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。缓存雪崩与缓存击穿的区别在于这里针对很多key缓存,前者则是某一个key。
- 解决方案:
4. 分布式锁
十四、Redis6.0新功能
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。