# 技术栈知识点巩固——Redis

Posted MarlonBrando1998

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了# 技术栈知识点巩固——Redis相关的知识,希望对你有一定的参考价值。

技术栈知识点巩固——Redis


Redis有哪些优缺点?为什么要用 Redis ?

优点

  • 读写性能优异(数据操作在内存中)

  • 支持数据持久化,支持AOFRDB两种持久化方式。

  • 支持事务,Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。

  • 数据结构丰富,除了支持string类型的value外还支持hashset、zset、list等数据结构。

  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

缺点

  • 数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

  • Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。

  • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。

  • Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。


Redis用过哪些数据类型,每种数据类型的使用场景

  • String:最大能存储512M,key-value缓存,常规计数

  • List:任务执行日志,列表的存储,可以进行List的追加,分页等操作

  • Set:元素不可重复,可以计算集合的交集,并集,差集

ZSet的常用命令

  • zadd:使用zset存储结构
zadd score 89 张三
zadd score 90 李四
zadd score 100 王五
zadd score 99 张三
zscore score 张三
  • zrevrank:排序查看
> zrevrange score 0 1 withscores
王五
100
张三
99
  • zincrby:命令格式:zincrby 排行榜名称 分数增量 玩家标识

Redis缓存穿透、缓存雪崩和缓存击穿原因

  • 缓存穿透:某个key的缓存会经常查询,有很高的并发一直在访问,如果该缓存失效,当从redis中取值的时候,会去查数据库。解决方法是对热门的key过期时间可以设置长一点。
  • 缓存雪崩:在某一个时间段,缓存集中失效,导致全部请求去查数据库,是整个服务瘫痪。对于缓存雪崩问题可以使用集群部署,在设置key过期的时候可以设置一个随机值,不要在同一个时间点同时过期。可以使用双缓存策略,原始缓存和备用缓存,原始缓存失效时候,访问备用缓存,备用缓存失效时间可以设置长点。

如何使用Redis来实现分布式锁

  • 查询Redis中对应keyvalue是否存在,如果存在则表示当前key被占用,如果为空则可以设置一个随机值进行获取锁的操作。
  • 使用命令SETNX
# 结果为 1 则表示获取锁成功
setnx test 张三
1
# 结果为 0 则表示获取锁失败
> setnx test 张三
0
# 释放锁
del test
0
  • 使用Redission实现加锁操作

Redis 持久化机制

RDB

RDB快照是某个时间点的一次全量数据备份,是二进制文件,在存储上非常紧凑。通过save命令手动触发或者配置自动触发。

特点

  • RDB文件小,RDB文件中直接存储的是内存数据速度比较块。

  • RDB无法做到实时持久化

AOF

特点

  • AOF日志是持续增量的备份,是基于写命令存储的可读的文本文件。
  • AOF生成的日志文件较大,需要不断AOF

如何选择合适的持久化方式

  • 在单机环境下,如果可以接受十几分钟或更多的数据丢失,选择快照持久化对Redis的性能更加有利;如果只能接受秒级别的数据丢失,应该选择AOF

Redis持久化数据和缓存怎么做扩容?

  • 如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。
  • 如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样。

Redis主从复制、哨兵、集群模式

  • Redis集群使用详见博客:https://blog.csdn.net/qq_37248504/article/details/113861502

为什么要用redis?为什么要用缓存,在哪些场景使用缓存

  • 使用Redis降低系统数据库的访问量,减小数据库的压力。使用缓存可以减少数据库的压力,提高系统的响应速度。
  • 缓存使用场景:查询结果变化较少的情况。

如何解决 Redis 的并发竞争Key问题

使用 watch

  • watch 命令可以方便的实现乐观锁。需要注意的是,如果你的 使用了数据分片的方式,那么这个方法就不适用了。

使用分布式锁

  • 使用相关的Redis操作API获取分布式锁,对操作加锁操作。

使用队列处理请求

把需要处理的数据放在队列中一个一个处理。


Redis为什么是单线程的,为什么单线程还这么快?

  • 基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中。
  • 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU

如何保证缓存与数据库双写时的数据一致性?

  • 读数据的时候先读取缓存,缓存没有的话就读数据库,取出数据放到缓存。
  • 更新的时候先删除缓存,在更新数据库。
  • 将读取数据和更新缓存的操作根据唯一标识放到队列中,如果发现内存中已经有一个,则轮询查看缓存是否有数据,若一段时间后还是没有数据则直接查询数据库值并返回。

redis的list结构相关的操作

  • List:是一个字符串链表,key存在链表添加内容,key不存在创建链表

  • Lpush:先进后出,在列表头部插入元素

  • Rpush:先进先出,在列表的尾部插入元素

  • Lrange:根据索引,获取列表元素

  • Lpop:获取列表的第一个元素

  • Rpop:获取列表的最后一个元素

  • Lindex:根据索引,取出元素

  • Llen:链表长度,元素个数


Reids的主从复制机制原理

  • Redis的主从复制机制是指可以让从服务器能精确复制主服务器的数据,

  • 一个master可以有多个slave节点

  • slave之间可以互相同步。

  • 可以用于读写分离和恢复丢失的数据需要手动配置主从节点,假如主从节点挂了,需要重新定义主节点。


Redis 一个字符串类型的值能存储最大容量是多少?

  • 一个字符串类型键允许存储的数据的最大容量是512M

为什么Redis的操作是原子性的,怎么保证原子性

  • 一个操作不可以再分,操作要么执行,要么不执行。

  • Redis的操作之所以是原子性的,是因为Redis是单线程的。


Redis和Redisson有什么关系

  • Redission是一个基于分布式环境下具有分布式锁的redis客户端
<!-- redisson -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.5.0</version>
</dependency>

Redis中的管道有什么用

​ 当频繁的存储获取Redis数据库中的数据时,可以使用Redis的管道功能,将多个相互没有依赖关系的读写操作,放到队列中,使用管道对象一次性执行,可以很大程度上减少与数据库建立TCP连接的性能损耗。


Redis事务

  • MULTI :开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来提交事务。
  • EXEC:执行事务中的所有操作命令。
  • DISCARD:取消事务,放弃执行事务块中的所有命令。
  • WATCH:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。
  • UNWATCH:取消WATCH对所有key的监视。

Redis事务相关命令

  • MULTI :开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令系列。
  • EXEC:执行事务中的所有操作命令。
> 127.0.0.1@6379 connected!
> set keyone "张三"
OK
> set keytow "李四"
OK
> multi
OK
> set keyone "王五"
QUEUED
> set keytow "test"
QUEUED
> exec
OK
OK
  • DISCARD:取消事务,放弃执行事务块中的所有命令。
  • WATCH:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。
  • UNWATCH:取消WATCH对所有key的监视。

Redis事务的三个阶段

  • 事务开始 MULTI

  • 命令入队

  • 事务执行 EXEC

  • 事务执行过程中,如果服务端收到有 EXEC、DISCARD、WATCH、MULTI 之外的请求,将会把请求放入队列中排队


Redis事务保证原子性吗,支持回滚吗?

  • Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。

Redis事务隔离性

  • Redis 是单进程程序,并且它保证在执行事务时,不会对事务进行中断,事务可以运行直到执行完所有事务队列中的命令为止。因此,Redis 的事务是总是带有隔离性的。

Redis key的过期时间和永久有效设置

  • EXPIREEXPIRE key seconds

​ 设置一个key在当前时间seconds(秒)之后过期。返回1代表设置成功,返回0代表key不存在或者无法设置过期时间。

  • PEXPIREPEXPIRE key milliseconds

​ 设置一个key在当前时间milliseconds(毫秒)之后过期。返回1代表设置成功,返回0代表key不存在或者无法设置过期时间。

  • PERSISTPERSIST key

​ 移除key的过期时间,将其转换为永久状态。如果返回1,代表转换成功。如果返回0,代表key不存在或者之前就已经是永久状态。


Redis回收算法


一个Redis实例最多能存放多少的keys?List、Set、Sorted Set他们最多能存放多少元素?

  • 一个Redis实例最多能存放理论上2的32次方个keys

  • String:最大512MB

  • List: 2^32-1个数据

  • Set: 2^32-1个数据

  • Hash:2^32-1个键值对

  • Sorted set:与Sets类型类似,没有明确说明。应该也是2^32-1个数据


为什么要用Redis 而不用 map/guava 做缓存?

  • MapGuaua使用的是本地缓存,应用重启缓存丢失。生命周期随着jvm的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性。

  • Redis 可以实现分布式的缓存,Map 只能存在创建它的程序里。

  • Redis可以实现持久化、可以缓存大量的数据,Redis缓存功能更加强大。


用 Redis 统计独立用户访问量

方法1

  • 使用hsethlen命令
> HSET key field value
1
> HLEN key
1

Redis 全局命令

命令作用
keys *查看所有键
dbsize查看键总个数
exists key检查 key 是否存在
delete key删除某些键
expire key seconds设置过期时间
type key获取键的数据结构类型

以上是关于# 技术栈知识点巩固——Redis的主要内容,如果未能解决你的问题,请参考以下文章

# 技术栈知识点巩固——Mybatis

# 技术栈知识点巩固——Nginx

# 技术栈知识点巩固——Nginx

# 技术栈知识点巩固——Css

# 技术栈知识点巩固——Css

# 全栈开发学习文档