Redis知识点总结

1,介绍

Redis:Remote Dictionary Server 远程字典服务。默认端口号:6379
是一个开源的,使用C语言编写,支持网络,可基于内存也可持久化的日志型,Key-Value数据库。

可以用于数据库,缓存,消息中间件MQ

官网:https://redis.io/
中文网:http://www.redis.cn/

Redis是单线程

redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。

为什么Redis是单线程的?

Redis是基于内存操作的,所以Redis是很快的,redis的瓶颈不是CPU,而是机器的内存和网络带宽,所以没有必要使用多线程,单线程就可以实现了。

redis单线程为什么这么快?

1,完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。
2,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU。
3,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。

功能:

1,内存存储,持久化,
2,效率高,可以用于高速缓存。
3,发布订阅系统。
4,地图信息分析。
5,计时器,计数器。
6,支持多种语言。
7,…

特性:

1,支持多样的数据类型
2,支持集群
3,支持持久化
4,支持事务

2,常用命令:

2.1 Reids工具命令

  • redis-server:Redis 服务器的 daemon 启动程序
  • redis-cli:Redis 命令行操作工具。当然,你也可以用 telnet 根据其纯文本协议来操作
  • redis-benchmark:Redis 性能测试工具,测试 Redis 在你的系统及你的配置下的读写性能
  • $redis-benchmark -n 100000 –c 50 :模拟同时由 50 个客户端发送 100000 个 SETs/GETs 查询
  • redis-check-aof:更新日志检查
  • redis-check-dump:本地数据库检查

2.2 Redis常用管理命令

  • dbsize 返回当前数据库 key 的数量。
  • info 返回当前 redis 服务器状态和一些统计信息。
  • monitor 实时监听并返回redis服务器接收到的所有请求信息。
  • shutdown 把数据同步保存到磁盘上,并关闭redis服务。
  • config get parameter 获取一个 redis 配置参数信息。(个别参数可能无法获取)
  • config set parameter value 设置一个 redis 配置参数信息。(个别参数可能无法获取)
  • config resetstat 重置 info 命令的统计信息。(重置包括:keyspace 命中数、
  • keyspace 错误数、 处理命令数,接收连接数、过期 key 数)
  • debug object key 获取一个 key 的调试信息。
  • debug segfault 制造一次服务器当机。
  • flushdb 删除当前数据库中所有 key,此方法不会失败。小心慎用
  • flushall 删除全部数据库中所有 key,此方法不会失败。小心慎用

2.3 Redis常用操作命令

  • 切换数据库命令:select <DB index>(0-15)
  • 查看数据库大小,DBSIZE
  • 查看当前数据库所有的key:keys *
  • 清空当前库:flushdb
  • 清空全部数据库:flushall
  • set值:set <key> <value>
  • 获取值:get <key>
  • 判断key是否存在:exists <key > (结果为1:存在,0:不存在)
  • 移动key到其他库: move <key> 1
  • 设置key的过期时间:expire <key> <time(seconds)>
  • 查看剩余过期时间:ttl <key>
  • 查看key的类型:type <key>

服务端启动命令:redis-server <***/redis.conf>
客户端启动命令:redis-cli -p <port>

3,五大数据类型

3.1 String

3.2 List

Lpush Lpop Rpush Rpop
底层通过链表实现。既可以作为队列,也可以作为栈。

3.3 Set

set中的值是不能重复的。无序,不重复集合。
sadd
srem
sdiff set1 set2 差集
sinter set1 set2 交集
sunion set1 set2 并集

3.4 Hash

更适合对象的存储,
hset myhash field value
hget myhash field
hmset myhash field value (field2 value2 …)
hmget myhash field (field2…)
hgetall myhash
hdel myhash field

3.5 Zset

有序集合。
在set的基础上,加了一个标志位,用来排序用。
set排序,存储班级成绩表,工资表排序
普通消息:1 重要消息:2 带权重进行判断。
排行榜应用实现。

4,三种特殊数据类型

4.1 geospatial 地理空间

底层实现原理是Zset。

4.2 Hyperloglog

基于基数统计的算法。
0.81%的错误率。

4.3 Bitmaps

位存储
统计用户信息,打卡记录,活跃不活跃等

5,事务

redis单条命令是保证原子性的,但是redis事务是不保证原子性的。

redis事务本质:一组命令的集合。一个事务中的所有命令都会被序列化,在事务执行的过程中,会按照顺序执行。

一次性,顺序性,排他性。
redis事务没有隔离级别的概念。

redis事务流程:
开启事务:multi
命令入队:…
执行事务:exec

放弃事务:discard

6,监控 Watch

使用watch相当于乐观锁操作。
在开启事务前用watch监视某个值,事务中操作这个值时,发现被其他线程修改了,则提交事务失败。

watch key 加锁
unwatch 解锁(事务提交成功后自动解锁,事务提交失败后需手动解锁)。

7,Jedis

redis的Java连接开发工具。使用Java操作redis的中间件。
导入jedis的依赖,new一个jedis的对象即可。

8,spring boot整合redis

springBoot操作数据:Spring-Data
(Spring Data JDBC,Spring Data MongoDB,Spring Data JPA,Spring Data Redis,…)

说明:在spring boot2.x后,原来使用的jedis被替换成了lettuce
jedis:采用的直连,多个线程操作的话不安全。如果要解决该问题,可使用jedis pool连接池。
lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全情况。

9,redis.conf配置文件分析

(待分析)

10,持久化

Redis是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失,所以redis提供了持久化功能。

Redis提供的数据持久化方式主要有2种:

  • RDB:产生一个数据快照文件
  • AOF:实时追加命令的日志文件

10.1 RDB(Redis Database Backup file)

Redis数据备份文件,也被叫做Redis数据快照。

在指定的时间间隔内,将内存中的数据集快照写入磁盘,恢复时将快照文件直接读到内存中。

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,等持久化过程结束了,再用这个临时文件替换上次持久化好的文件。

整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。

如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效。

redis默认使用的是RDB,保存的文件是dump.rdb,可通过配置redis.conf修改

RDB触发规则,触发后自动生成dump.rdb文件:

  • save 的规则满足。(save 60 3 60秒内修改3次后,进行一次持久化)
  • 执行flushall命令。
  • 退出redis。

恢复rdb文件:
将dump.rdb文件放在redis的启动目录即可。redis启动时会自动检查dump.rdb文件,恢复数据。

优点:

  • 适合大规模的数据恢复。
  • RDB文件数据是被压缩写入的,因此RDB文件的体积要比整个实例内存要小
  • 当实例宕机恢复时,加载RDB文件的速度很快,能够在很短时间内迅速恢复文件中的数据

缺点:

  • 由于是某一时刻的数据快照,因此它的数据并不全。
  • 生成RDB压缩文件的代价是比较大的,它会消耗大量的CPU和内存资源

适用场景:

  • 主从全量同步数据
  • 数据库备份
  • 对于丢失数据不敏感的业务场景,实例宕机后快速恢复数据

10.2 AOF(Append Only File)

以日志的形式记录每一个命令的详细信息,包括完整的命令类型、参数等。只要产生写命令,就会实时写入到AOF文件中。

redis启动时会读取该文件重新构建数据。

如果同时存在RDB文件和AOF文件,Redis会优先使用AOF文件进行数据恢复。

通过配置文件开启AOF

# 开启AOF
appendonly yes

# AOF文件名
appendfilename "appendonly.aof"

# 文件刷盘方式(持久化触发机制)
appendfsync everysec # 1秒刷一次盘,对性能影响相对较小,节点宕机时最多丢失1秒的数据(默认)
# appendfsync always 每次写入都刷盘,对性能影响最大,占用磁盘IO比较高,数据安全性最高
# appendfsync no 按照操作系统的机制刷盘,对性能影响最小,数据安全性低,节点宕机丢失数据取决于操作系统刷盘机制

优点:

  • AOF数据文件更新比较及时,比RDB保存更完整的数据
  • 能够恢复尽量完整的数据,降低丢失数据的风险。

缺点:

  • 数据文件比rdb文件大
  • 恢复数据慢
  • AOF文件刷盘会增加磁盘IO的负担,可能影响Redis的性能(开启每秒刷盘时)

使用场景:

  • 对丢失数据很敏感的业务场景,例如涉及金钱交易的业务。

10.3 RDB和AOF的总结

#RDBAOF
持久化方式生成某一时刻的数据快照文件实时记录每一个写命令到文件
数据完整性不完整,取决于备份周期相对完整性高,取决于文件刷盘方式
文件大小压缩二进制写入,文件较小原始的操作命令,文件大
宕机恢复时间
恢复优先级
持久化代价高,消耗大量CPU和内存低,只占用磁盘IO资源
使用场景数据备份、主从全量复制、对丢数据不敏感的业务场景快速数据恢复对于丢失数据敏感的场景,例如涉及金钱交易相关的业务

10.4 fork系统调用

fork系统调用会产生一个子进程,它与父进程共享相同的内存地址空间,这样子进程在这一时刻就能拥有与父进程的相同的内存数据。

11,Redis主从复制

主从复制,读写分离。
将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点master,后者成为从节点slave,数据的复制是单向的,只能从主节点到从节点。mater以写为主,slave以读为主。
主从复制作用:
1,数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
2,故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复。
3,负载均衡:在主从复制的基础上,配合读写分离,分担服务器负载。
4,哨兵和集群实现的基础。

1,通过命令配置:从机上执行slaveof ip port 暂时的
2,通过配置文件配置,永久的

主机可以写,从机只能读不能写。如果从机进行写操作,会报错。
主机中的所有数据,都会被从机保存。

12,Sentinel哨兵模式

Redis原生提供master-slave数据复制,保证slave永远与master数据保持一致。

在master发生问题时,我们需要把slave提升为master,继续提供服务。而这个提升新master的操作,如果是人工处理,必然无法保证及时性,所以Redis提供了哨兵节点,用来管理master-slave节点,并在master发生问题时,能够自动进行故障恢复操作。

  • 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
  • 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

工作流程

  • 状态感知
  • 心跳检测
  • 选举哨兵领导者
  • 选择新的master
  • 故障恢复
  • 客户端感知新master

优点:
1,缺点:Redis不好在线扩容,集群容量一旦到达上限,在线扩容很麻烦。
2,实现哨兵模式的配置比较繁琐。

13,Redis缓存穿透和雪崩

13.1 缓存穿透

用户查询数据,发现缓存中没有,于是向数据库查询,发现也没有,于是本次查询失败。
当用户很多时,缓存都没有命中,于是请求都去了数据库,这就给数据库造成了很大压力,即缓存穿透。

13.1.1 布隆过滤器

布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先校验,不符合则丢弃,从而避免了对底层存储系统的查询压力。

13.1。2 缓存空对象

当存储层不命中后,即没有查询到,或者返回一个空对象,也把它存储起来,同时设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源。
存在问题:
1,如果空值被缓存起来,会需要更多的空间存储这些健,可能会出现大量的空值的健。
2,即使对控制设置了过期时间,还是会存在缓存层和存储层有一段时间的不一致,对一致性产生影响。

13.2 缓存击穿

一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库。

当某个key在过期的瞬间,有大量的并发访问,由于缓存过期,会同时访问数据库来查询最新数据,并且写回缓存,会导致数据库瞬间压力过大。
解决方案:

13.2.1 设置热点数据永不过期

从缓存层面来看,没有设置过期时间,所以不会出现热点key过期后产生的问题。

13.2.2 加互斥锁

分布式锁:使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁,处于等待即可。
这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大。

13.3 缓存雪崩

某一个时间段,缓存集中过期失效。或者缓存服务器宕机。
解决方案:
1,redis高可用
多增设几台redis,搭建集群。
2,限流降级

3,数据预热

14,Redis的过期键删除策略

14.1 定时删除

在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。

14.2 惰性删除

放任过期键不管,每次从键空间中获取键时,检查该键是否过期,如果过期,就删除该键,如果没有过期,就返回该键。

过期键的惰性删除策略由expireIfNeeded函数实现,所有读写数据库的Redis命令在执行之前都会调用expireIfNeeded函数对输入键进行检查:

  • 如果输入键已经过期,那么将输入键从数据库中删除;
  • 如果输入键未过期,那么不做任何处理。

14.3 定期删除

每隔一段时间,程序对数据库进行一次检查,删除里面的过期键,至于要删除哪些数据库的哪些过期键,则由算法决定。

过期键的定期删除策略由activeExpireCycle函数实现,每当Redis服务器的周期性操作serverCron函数执行时,activeExpireCycle函数就会被调用,它在规定的时间内,分多次遍历服务器中的各个数据库,从数据库的expires字典中随机检查一部分键的过期时间,并删除其中的过期键。

其中定时删除和定期删除为主动删除策略,惰性删除为被动删除策略。

15,Redis中使用Lua脚本

15.1 Redis中为什么引入Lua脚本?

Redis提供了非常丰富的指令集,官网上提供了200多个命令。但是某些特定领域,需要扩充若干指令原子性执行时,仅使用原生命令便无法完成。
Redis 为这样的用户场景提供了 lua 脚本支持,用户可以向服务器发送 lua 脚本来执行自定义动作,获取脚本的响应数据。Redis 服务器会单线程原子性执行 lua 脚本,保证 lua 脚本在处理的过程中不会被任意其它请求打断。

15.2 优点

  • 减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延。
  • 原子操作。Redis会将整个脚本作为一个整体执行,中间不会被其他请求插入。因此在脚本运行过程中无需担心会出现竞态条件,无需使用事务。
  • 复用。客户端发送的脚本会永久存在redis中,这样其他客户端可以复用这一脚本,而不需要使用代码完成相同的逻辑。

15.3 Redis中Lua的常用命令

  • EVAL
  • EVALSHA
  • SCRIPT LOAD - SCRIPT EXISTS
  • SCRIPT FLUSH
  • SCRIPT KILL
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页