锅炉信息网 > 锅炉知识 > 锅炉百科

redis1

Redis有哪些数据结构?Redis 有 5 种基础数据结构,它们分别是:string(字符串)、list(列表)、hash(字典)、set(集 合) 和 zset(有序集

Redis有哪些数据结构?

Redis 有 5 种基础数据结构,它们分别是:string(字符串)、list(列表)、hash(字典)、set(集 合) 和 zset(有序集合)。
这 5 种是 Redis 相关知识中最基础、最重要的部分。

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

512M

单线程还是多线程?

Redis6.0采用多线程IO,不过命令的执行还是单线程的。
Redis6.0之前,IO线程和执行线程都是单线程的。


为什么 Redis 需要把所有数据放到内存中?

Redis 为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。
所以 redis 具有快速和数据持久化的特征,如果不将数据放在内存中,磁盘 I/O 速度为严重影 响 redis 的性能。
在内存越来越便宜的今天,redis 将会越来越受欢迎, 如果设置了最大使用的内存,则数据已 有记录数达到内存限值后不能继续插入新值。

Redis如何设置密码及验证密码?

设置密码:config set requirepass 123456
授权密码:auth 123456

缓存失效?缓存穿透?缓存雪崩?缓存并发?

  1. 缓存失效 缓存失效指的是大量的缓存在同一时间失效,到时DB的瞬间压力飙升。造成这种现象的 原因是,key的过期时间都设置成一样了。解决方案是,key的过期时间引入随机因素, 比如5分钟+随机秒这种方式。
  2. 缓存穿透 缓存穿透是指查询一条数据库和缓存都没有的一条数据,就会一直查询数据库,对数据 库的访问压力就会增大,缓存穿透的解决方案,有以下2种: 缓存空对象:代码维护较简单,但是效果不好。 布隆过滤器:代码维护复杂,效果很好。
  3. 缓存击穿 热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。

缓存击穿解决方案
解决缓存击穿的方法也有两种,

第一种是设置key永不过期;第二种是使用分布式锁,保证同一时刻只能有一个查询请求重新加载热点数据到缓存中,这样,其他的线程只需等待该线程运行完毕,即可重新从Redis中获取数据。
第一种方式比较简单,在设置热点key的时候,不给key设置过期时间即可。不过还有另外一种方式也可以达到key不过期的目的,就是正常给key设置过期时间,不过在后台同时启一个定时任务去定时地更新这个缓存。

  1. 缓存雪崩 缓存雪崩 是指在某一个时间段,缓存集中过期失效。此刻无数的请求直接绕开缓存,直 接请求数据库。 造成缓存雪崩的原因,有以下2种: reids宕机。 大部分数据失效。

对于缓存雪崩的解决方案有以下2种:
搭建高可用的集群,防止单机的redis宕机。
设置不同的过期时间,防止同意之间内大量的key失效。

  1. 缓存并发 有时候如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时 设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的 问题。 一般处理方案是在查DB的时候进行加锁,如果KEY不存在,就加锁,然后查DB入缓存, 然后解锁;其他进程如果发现有锁就等待,然后等解锁后再查缓存或者进入DB查询。

Redis中的热key怎么处理?

1、对热key进行分散处理。比如:在key上加上不同的前后缀,缓存多个key,使得各个key分 散到不同的节点上。
2、采用多级缓存。

大key怎么处理?

大key指的是value特别大的key。比如很长的字符串,或者很大的set等等。 大key会造成2个问题:
1、数据倾斜,比如某些节点内存占用过高。
2、当删除大key或者大 key自动过期的时候,会造成QPS突降,因为Redis是单线程的缘故。
处理方案:可以将一个大key进行分片处理,比如:将一个大set分成多个小的set。

统计网站的UV,应该怎么做?

UV与PV不同,UV需要去重。一般有2种方案:
1、用BitMap。存的是用户的uid,计算UV的时候,做下bitcount就行了。
2、用布隆过滤器。将每次访问的用户uid都放到布隆过滤器中。优点是省内存,缺点是无法得 到精确的UV。但是对于不需要精确知道具体UV,只需要大概的数量级的场景,是个不错的选 择。

事务机制了解过吗?

Redis事务的概念:
Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会 被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请 求不会插入到事务执行命令序列中。
Redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。
Redis事务没有隔离级别的概念:
批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询 要看到事务里的更新,事务外查询不能看到。
Redis不保证原子性:
Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执 行失败,其余的命令仍会被执行。
Redis事务的三个阶段:
开始事务
命令入队
执行事务
Redis事务相关命令:
watch key1 key2 … : 监视一或多个key,如果在事务执行之前,被监视的key被其他命令改动, 则事务被打断 ( 类似乐观锁 )
multi : 标记一个事务块的开始( queued )
exec : 执行所有事务块的命令 ( 一旦执行exec后,之前加的监控锁都会被取消掉 )
discard : 取消事务,放弃事务块中的所有命令
unwatch : 取消watch对所有key的监控

在什么情况下会触发key的回收?

2种情况:1、定时(抽样)清理;2、执行命令时,判断内存是否超过maxmemory。

在集群种查找key的时候,是怎么定位到具体节点的?

使用crc16算法对key进行hash 将hash值对16384取模,得到具体的槽位根据节点和槽位的映射信息(与集群建立连接后,客户端可以取得槽位映射信息),找到具体的节点地址 去具体的节点找key如果key不在这个节点上,则redis集群会返回moved指令,加上新的节点地址给客户端,同时,客户端会刷新本地的节点槽位映射关系如果槽位正在迁移中,那么redis集群会返回asking指令给客户端,这是临时纠正,客户端不会刷新本地的节点槽位映射关系

用Redis做延时队列,具体应该怎么实现?

可以使用Zset实现。member是任务描述,score是执行时间,然后用定时器定时去扫描,一 旦有执行时间小于或等于当前时间的任务,就立即执行。

持久化了解过吗?

Redis持久化有RDB和AOF这2种方式。
RDB:将数据库快照以二进制的方式保存到磁盘中。
AOF:以协议文本方式,将所有对数据库进行过写入的命令和参数记录到AOF文件,从而记录 数据库状态。

r过期键的删除策略?

  • (1) 定时删除:在设置键的过期时间的同时,创建一个定时器 timer). 让定时器在键的过期时间来临时,立即执行对键的删除操作。
  • (2) 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
  • (3) 定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。

回收策略(淘汰策略)

  • volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
  • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
  • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
  • allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
  • allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  • no-enviction(驱逐):禁止驱逐数据
    注意这里的 6 种机制,volatile 和 allkeys 规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的 lru、ttl 以及 random 是三种不同的淘汰策略,再加上一种 no-enviction 永不回收的策略。
    使用策略规则:
  • (1) 如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用 allkeys-lru
  • (2) 如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用 allkeys-random

同步机制了解么?

答:Redis 可以使用主从同步,从从同步。
第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存 buffer,待完成后将 rdb 文件全量同步到复制节点,复制节点接受完成后将 rdb 镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。

集群方案什么情况下会导致整个集群不可用?

有 A,B,C 三个节点的集群,在没有复制模型的情况下,如果节点 B 失败了,那么整个集群就会 以为缺少5501-11000 这个范围的槽而不可用。

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

答:理论上 Redis 可以处理多达 2的32次方 的 keys,并且在实际中进行了测试,每个实例至少存放了 2 亿 5 千万的 keys。我们正在测试一些较大的值。
任何list、set、和 sorted set 都可以放 232 个元素。换句话说,Redis 的存储极限是系统中的可用内存值。

管道有什么用?

一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应。这样就可以将多个命令发 送到服务器,而不用等待回复,最后在一个步骤中读取该答复。
这就是管道(pipelining),是一种几十年来广泛使用的技术。例如许多POP3协议已经实现 支持这个功能,大大加快了从服务器下载新邮件的过程。

高可用方案有哪些?

Redis 单副本

Redis 单副本,采用单个 Redis 节点部署架构,没有备用节点实时同步数据,不提供数据持久化和备份策略,适用于数据可靠性要求不高的纯缓存业务场景。

Redis 多副本(主从)

Redis 多副本,采用主从(replication)部署结构,相较于单副本而言最大的特点就是主从实例间数据实时同步,并且提供数据持久化和备份策略。主从实例部署在不同的物理服务器上,根据公司的基础环境配置,可以实现同时对外提供服务和读写分离策略。

Redis Sentinel(哨兵)

Redis Sentinel 是社区版本推出的原生高可用解决方案,其部署架构主要包括两部分:Redis Sentinel 集群和 Redis 数据集群。

其中 Redis Sentinel 集群是由若干 Sentinel 节点组成的分布式集群,可以实现故障发现、故障自动转移、配置中心和客户端通知。Redis Sentinel 的节点数量要满足 2n+1(n>=1)的奇数个。

Redis Cluster

Redis Cluster 是社区版推出的 Redis 分布式集群解决方案,主要解决 Redis 分布式方面的需求,比如,当遇到单机内存,并发和流量等瓶颈的时候,Redis Cluster 能起到很好的负载均衡的目的。

Redis Cluster 集群节点最小配置 6 个节点以上(3 主 3 从),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。

Redis Cluster 采用虚拟槽分区,所有的键根据哈希函数映射到 0~16383 个整数槽内,每个节点负责维护一部分槽以及槽所印映射的键值数据。

哨兵机制?

答:Redis的哨兵(sentinel) 系统用于管理多个 Redis 服务器,该系统执行以下三个任务:

监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。

提醒(Notification):当被监控的某个 Redis出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。

自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master; 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master。

哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。

每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称sdown).

若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master"彻底死亡"(即:客观上的真正down机,Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置。

虽然哨兵(sentinel) 释出为一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel)。

哨兵(sentinel) 的一些设计思路和zookeeper非常类似

redis锁

面试官:这样设置会不会有问题呢?如果加锁成功的客户端挂了怎么办?

我:比如上图中的客户端1挂了,这个锁就不能释放了。可以设置一个过期时间,命令如下:

SET key value [EX seconds] [PX milliseconds] NX

面试官:设置了过期时间,如果业务还没有执行完成,但是redis锁过期了,怎么办?

我:需要对锁进行续约。

面试官:能说一下具体怎么操作吗?

我:设置锁成功后,启动一个watchdog,每隔一段时间(比如10s)为当前分布式锁续约,也就是每隔10s重新设置当前key的超时时间。命令如下:

EXPIRE <key> <seconds>

面试官:watchdog怎么实现呢?

我:当客户端加锁成功后,可以启动一个定时任务,每隔10s(最好支持配置)来检测业务是否处理完成,检测的依据就是判断分布式锁的key是否还存在,如果存在,就进行续约。

面试官:如果当前线程已经处理完,这个key是被其他客户端写入的呢?

我:可以为每个客户端指定一个clientID,在VALUE中增加一个clientID的前缀,这样在续锁的时候,可以判断当前分布式锁的value前缀来确定是不是当前客户端的,如果是再续锁,否则不做处理。

面试官:你们的续锁功能是自己实现的吗?

我:我们用的redisson的分布式锁方案,使用redisson获取分布式锁非常简单,代码如下:

RLock lock = redisson.getLock("client-lock");nlock.lock();ntry {n//处理业务n} catch (Exception e) {n//处理异常n} finally {nlock.unlock();n}


具体原理是:如果客户端1加锁成功,这个分布式锁超时时间默认是30秒(可以通过Config.lockWatchdogTimeout来修改)。加锁成功后,就会启动一个watchdog,watchdog是一个后台线程,会每隔10秒检查一下客户端1是否还持有锁key,如果是,就延长锁key的生存时间,延长操作就是再次把锁key的超时时间设置成30s。

面试官:redisson里的定时器怎么实现的?

我:redisson定时器使用的是netty-common包中的HashedWheelTime来实现的。

面试官:如果client1宕机了,这时分布式锁还可以续期吗?

我:因为分布式锁的续期是在客户端执行的,所以如果client1宕机了,续期线程就不能工作了,也就不能续期了。这时应该把分布式锁删除,让其他客户端来获取。

面试官:那如果client1宕机了,其他客户端需要等待30s才能有机会获取到锁,有办法立刻删除锁吗?

我:因为client1宕机了,只能等到超时时间后锁被自动删除。如果要立刻删除,需要增加额外的工作,比如增加哨兵机制,让哨兵来维护所有redis客户端的列表。哨兵定时监控客户端是否宕机,如果检测到宕机,立刻删除这个客户端的锁。如下图:

这里的哨兵并不是redis的哨兵,而且为了检测客户端故障业务系统自己做的哨兵。

面试官:如果不用redisson,怎么实现分布式锁续锁呢?比如springboot2.0默认使用redis客户端是Lettuce。

我:Lettuce并没有提供像redisson这样的watchdog机制,所以续锁需要业务系统自己实现。可以分为以下几步来实现:

加锁的命令,我们参照spring包里的分布式锁代码,如果锁存在并且是当前客户端加的锁,那就续锁,如果锁不存在,则加锁。代码如下:

private static final String OBTAIN_LOCK_SCRIPT =n"local lockClientId = redis.call('GET', KEYS[1])n" +n"if lockClientId == ARGV[1] thenn" +n" redis.call('PEXPIRE', KEYS[1], ARGV[2])n" +n" return truen" +n"elseif not lockClientId thenn" +n" redis.call('SET', KEYS[1], ARGV[1], 'PX', ARGV[2])n" +n" return truen" +n"endn" +n"return false";

把锁保存在一个数据结构里,比如HashMap,定时任务定时扫描这个map,对每个锁进行续锁操作。代码如下:

redisTemplate.execute(renewLockScript,nCollections.singletonList(lockKey), clientId,nString.valueOf(expireAfter));

无相关信息

上一篇:一研为定

下一篇:15kw柴油发电机

锅炉资讯

锅炉资讯

锅炉学习

锅炉学习

锅炉视频

锅炉视频

锅炉百科

锅炉百科