Redis

1.redis高可用方案

a. 主从
哨兵模式:
sentinel,哨兵是 redis 集群中非常重要的一个组件,主要有以下功能:

  • 集群监控:负责监控 redis master 和 slave 进程是否正常工作。
  • 消息通知:如果某个 redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
  • 故障转移:如果 master node 挂掉了,会自动转移到slave node 上。
  • 配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。

哨兵用于实现 redis 集群的高可用,本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。

  • 故障转移时,判断一个 master node 是否宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的

  • 哨兵通常需要3个实例,来保证自己的健壮性。

  • 哨兵+redis 主从的部署架构,是不保证数据零丢失的,只能保证 redis 集群的高可用性。

  • 对于哨兵+redis 主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练。

    b.Redis sharding是Redis Cluster出来之前,业界普遍使用的多Redis实例集群方法。其主要思想是采用哈希算法将Redis数据的key进行散列,通过hash的数,特定的key会映射到特定的Redis节点上。Java redis客户端驱动jedis,支持Redis sharding功能,即Shardedjedis以及结合缓存池的ShardedjedisPool
    优点
    优势在于非常简单,服务端的Redis实例彼此独立,相互无关联,每个Redis实例像单服务器一样运行,非常容易线性扩展,系统的灵活性很强
    缺点
    由于sharding处理放到客户端,规模进一步扩大时给运维带来挑战,客户端sharding不支持动态增删节点。服务端Redis实例群拓扑结构有变化时,每个客户端都需要更新调整。连接不能共享,当应用规模增大时,资源浪费制约优化

c.Redis Cluster是一种服务端sharding技术,3.0版本开始正式提供。采用slot(槽)的概念,一共分成16384个槽。将请求发送到任意节点,接收到请求的节点会将查询请求发送到正确的节点上执行

方案说明

  • 通过哈希的方式,将数据分片,每个节点均分存储一定哈希槽(哈希值)区间的数据,默认分配了16384 个槽位
  • 每份数据分片会存储在多个互为主从的多节点上
  • 数据写入先写主节点,再同步到从节点(支持配置为阻塞同步)
  • 同一分片多个节点间的数据不保持强一致性
  • 读取数据时,当客户端操作的key没有分配在该节点上时,redis会返回转向指令,指向正确的节点
  • 扩容时需要需要把I日节点的数据迁移一部分到新节点

在 redis cluster 架构下,每个redis 要放开两个端口号,比如一个是6379,另外一个就是加1w的端口号,比如16379.

16379 端口号是用来进行节点间通信的,也就是 cluster bus 的通信,用来进行故障检测、配置更新、故障转移授权。cluster bus 用了另外一种二进制的协议,gossip协议,用于节点间进行高效的数据交换,占用重少的网络带宽和处理时间。

优点

  • 无中心架构,支持动态扩容,对业务透明
  • 具备Sentinel的监控和自动Failover(故障转移)能力
  • 客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。高性能,客户端直连redis服务,免去了proxy代理的损耗

缺点

  • 运维也很复杂,数据迁移需要人工干预
  • 只能使用0号数据库
  • 不支持批量操作(pipeline管道操作)
  • 分布式逻辑和存储模块耦合等

2.如何避免缓存穿透、缓存击穿、缓存雪崩?

缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉

解决方案:

  • 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  • 给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,如果缓存标记失效,则更新数据缓存。
  • 缓存预热
  • 互斥锁

缓存穿透是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决方案:

  • 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
  • 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-nul,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
  • 采用布降过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个bitmap 拦截掉,从而避免了对底层存储系统的查询压力

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由干并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力间增大,造成过大压力。和缓存雪崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决方案

  • 设置热点数据永远不过期
  • 加互斥锁

3.为什么使用缓存 ?

1、高性能

2、高可用

4.如何保证Redis与数据库的数据一致?

当我们对数据进行修改的时候,到底是先删缓存,还是先写数据库?

1、如果先删缓存,再写数据库: 在高并发场景下,当第一个线程删除了缓存,还没有来得及写数据库,第二个线程来读取数据,会发现缓存中的数据为空,那就会去读数据库中的数据(旧值,脏数据),读完之后,把读到的结果写入缓存(此时,第一个线程已经将新的值写到缓存里面了),这样缓存中的值就会被覆盖为修改前的脏数据。

总结:在这种方式下,通常要求写操作不会太频繁。

解决方案:1》先操作缓存,但是不删除缓存。将缓存修改为一个特殊值(-999)。客户端读缓存时,发现是默认值,就休眠一小会,再去查一次Redis。 -》 特殊值对业务有侵入。 休眠时间,可能会多次重复,对性能有影响。

2》延时双删。 先删除缓存,然后再写数据库,休眠一小会,再次删除缓存。-》 如果数据写操作很频繁,同样还是会有脏数据的问题。

2、先写数据库,再删缓存: 如果数据库写完了之后,缓存删除失败,数据就会不一致。

总结: 始终只能保证一定时间内的最终一致性。

解决方案: 1》给缓存设置一个过期时间 问题:过期时间内,缓存数据不会更新。

2》引入MQ,保证原子操作。

解决方案:将热点数据缓存设置为永不过期,但是在value当中写入一个逻辑上的过期时间,另外起一个后台线程,扫描这些key,对于已逻辑上过期的缓存,进行删除。

5.redis 主从同步机制

  1. 从节点执行slaveof masterIp port,保存主节点信息

  2. 从节点中的定时任务发现主节点信息,建立和主节点的socket连接

  3. 从节点发送信号,主节点返回,两边能互相通信

  4. 连接建立后,主节点将所有数据发送给从节点(数据同步)

  5. 主节点把当前的数据同步给从节点后,便完成了复制过程。接下来,主节点就会持续的把写命令发

    送给从节点,保证主从数据一致性。

runId:每个redis节点启动都会生成唯一的uuid,每次redis重启后,runId都会发生变化。

offset:主从节点各自维护自己的复制偏移量offset,当主节点有写入命令时,offset=offset+命令的字

节长度。从节点在收到主节点发送的命令后,也会增加自己的offset,并把自己的offset发送给主节

点。主节点同时保存自己的offset和从节点的offset,通过对比offset来判断主从节点数据是否一致。

repl_backlog_size:保存在主节点上的一个固定长度的先进先出队列,默认大小是1MB。

全量复制:

  • 从节点发送psync命令,psync runid offset(由于是第一次,runid为?,offset为-1)

  • 主节点返回FULLRESYNC runId offset,runId是主节点的runId,offset是主节点目前的offset。

    从节点保存信息

  • 主节点启动bgsave命令fork子进程进行RDB持久化

  • 主节点将RDB文件发送给从节点,到从节点加载数据完成之前,写命令写入缓冲区

  • 从节点清理本地数据并加载RDB,如果开启了AOF会重写AOF

部分复制:

  1. 复制偏移量:psync runid offset
  2. 复制积压缓冲区:当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制。
  • 如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会继续尝试使用部分复制(到底能不能部分复制还要看offset和复制积压缓冲区的情况);
  • 如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的Redis节点并不是当前的主节点,只能进行全量复制。

过程原理:
在这里插入图片描述

6.简述Redis事务实现

1、事务开始

MULTI命令的执行,标识着一个事务的开始。MULTI命令会将客户端状态的flags 属性中打开

REDIS_MULTI标识来完成的。

2、命令入队

当一个客户端切换到事务状态之后,服务器会根据这个客户端发送来的命令来执行不同的操作。如果客

户端发送的命令为MULTI、EXEC、WATCH、DISCARD中的一个,立即执行这个命令,否则将命令放入一

个事务队列里面,然后向客户端返回 QUEUED 回复

  • 如果客户端发送的命令为 EXEC、DISCARD、WATCH、MULTI 四个命令的其中一个,那么服务器

    立即执行这个命令。

  • 如果客户端发送的是四个命令以外的其他命令,那么服务器并不立即执行这个命令。

    首先检查此命令的格式是否正确,如果不正确,服务器会在客户端状态(redisClient)的 flags 属

    性关闭 REDIS_MULTI 标识,并且返回错误信息给客户端。

    如果正确,将这个命令放入一个事务队列里面,然后向客户端返回 QUEUED 回复

事务队列是按照FIFO的方式保存入队的命令

3、事务执行

客户端发送 EXEC 命令,服务器执行 EXEC 命令逻辑。

  • 如果客户端状态的 flags 属性不包含 REDIS_MULTI 标识,或者包含 REDIS_DIRTY_CAS 或者

    REDIS_DIRTY_EXEC 标识,那么就直接取消事务的执行。

  • 否则客户端处于事务状态(flags 有 REDIS_MULTI 标识),服务器会遍历客户端的事务队列,然

    后执行事务队列中的所有命令,最后将返回结果全部返回给客户端;

redis 不支持事务回滚机制,但是它会检查每一个事务中的命令是否错误。

Redis 事务不支持检查那些程序员自己逻辑错误。例如对 String 类型的数据库键执行对 HashMap 类型

的操作!

  • WATCH 命令是一个乐观锁,可以为 Redis 事务提供 check-and-set (CAS)行为。可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到EXEC命令。

  • MULTI命令用于开启一个事务,它总是返回OK。MULTI执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中,当EXEC命令被调用时,所有 队列中的命令才会被执行。

  • EXEC:执行所有事务块内的命令。返回事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值 nil 。

  • 通过调用DISCARD,客户端可以清空事务队列,并放弃执行事务, 并且客户端会从事务状态中出。

  • UNWATCH命令可以取消watch对所有key的监控。

7.redis分布式锁实现

setnx+setex :存在设置超时时间失败的情况,导致死锁

set(key,value,nx,px):将setnx+setex变成原子操作

问题:

  • 任务超时,锁自动释放,导致并发问题。使用redisson解决(看门狗监听,自动续期)
  • 以及加锁和释放锁不是同一个线程的问题。在value中存入uuid(线程唯一标识),删除锁时判断该标识(使用lua保证原子操作)
  • 不可重入,使用redisson解决(实现机制类似AQS,计数)
  • 异步复制可能造成锁丢失,使用redLock解决
  1. 顺序向五个节点请求加锁
  2. 根据一定的超时时间来推断是不是跳过该节点
  3. 三个节点加锁成功并且花费时间小于锁的有效期
  4. 认定加锁成功

8.简述redis九大数据结构

String:字符串

List:列表

Hash:哈希表

Set:无序集合

Sorted Set:有序集合

bitmap:布隆过滤器

GeoHash:坐标,借助Sorted Set实现,通过zset的score进行排序就可以得到坐标附近的其它元素,

通过将score还原成坐标值就可以得到元素的原始坐标

HyperLogLog:统计不重复数据,用于大数据基数统计

Streams:内存版的kafka

9.缓存过期都有哪些策略

定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立

即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响

应时间和吞吐量

惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省

CPU资源,但是很消耗内存、许多的过期数据都还存在内存中。极端情况可能出现大量的过期key没有

再次被访问,从而不会被清除,占用大量内存。

定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key(是随机的),

并清除其中已过期的key。该策略是定时过期和惰性过期的折中方案。通过调整定时扫描的时间间隔和

每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

分桶策略:定期过期的优化,将过期时间点相近的key放在一起,按时间扫描分桶。

10.分布式系统中常用的缓存方案有哪些

客户端缓存:页面和浏览器缓存,APP缓存,H5缓存,localStorage 和 sessionStorage

CDN缓存:内容存储:数据的缓存,内容分发:负载均衡

nginx缓存:静态资源

服务端缓存:本地缓存,外部缓存

数据库缓存:持久层缓存(mybatis,hibernate多级缓存),mysql查询缓存

操作系统缓存:Page Cache、Buffer Cache

11.布隆过滤器原理,优缺点

位图:int[10],每个int类型的整数是4*8=32个bit,则int[10]一共有320 bit,每个bit非0即1,初始化时都是0

添加数据时,将数据进行hash得到hash值,对应到bit位,将该bit改为1,hash函数可以定义多个,则一个数据添加会将多个(hash函数个数)bit改为1,多个hash函数的目的是减少hash碰撞的概率

查询数据:hash函数计算得到hash值,对应到bit中,如果有一个为0,则说明数据不在bit中,如果都为1,则该数据可能在bit中

优点:

  • 占用内存小
  • 增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无关
  • 哈希函数相互之间没有关系,方便硬件并行运算
  • 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势
  • 数据量很大时,布隆过滤器可以表示全集
  • 使用同一组散列函数的布隆过滤器可以进行交、并、差运算

缺点:

  • 误判率,即存在假阳性(False Position),不能准确判断元素是否在集合中
  • 不能获取元素本身
  • 一般情况下不能从布隆过滤器中删除元素

12.Redis集群策略

Redis提供了三种集群策略:

  1. 主从模式:这种模式比较简单,主库可以读写,并且会和从库进行数据同步,这种模式下,客户端直接连主库或菜个从库,但是但主库或从库宕机后,客户端需要手动修改IP,另外,这种模式也比较难进行扩容,整个集群所能存储的数据受到某台机器的内存容量,所以不可能支持特大数据量

  2. 哨兵模式:这种模式在主从的基础上新增了哨兵节点,但主库节点容机后,哨兵会发现主库节点容机,然后在从库中选择一个库作为进的主库,另外哨兵也可以做集群,从而可以保证但某一个销兵节点宕机后,还有其他哨兵节点可以继续工作,这种模式可以比较好的保证Redis集群的高可用,但是仍然不能很好的解决Redis的容量上限问颐。

  3. Custer模式:Custer模式是用得比较多的模式,它支持多主多从,这种模式会按照key进行槽位的分配,可以使得不同的key分散到不同的主节点上,利用这种模式可以使得整个集群支持更大的数据容量,同时每个主节点可以拥有自己的多个从节点,如果该主节点宕机,会从它的从节点中选举一个新的主节点。

    对于这三种模式,如果Redis要存的数据量不大,可以选择哨兵模式,如果Redis要存的数据量大,并且需要持续的扩容,那么选择Cluster模式。

13.常见的缓存淘汰算法

FIFO(First In First Out,先进先出),根据缓存被存储的时间,离当前最远的数据优先被淘汰;

LRU(Least Recently Used,最近最少使用),根据最近被使用的时间,离当前最远的数据优先被淘汰;

LFU(Least Frequently Used,最不经常使用),在一段时间内,缓存数据被使用次数最少的会被淘汰。

14.redis主从复制的核心原理

通过执行slaveof命令或设置slaveof选项,让一个服务器去复制另一个服器的敏据,生数倨库可以进行读写操作,当写操作导致数据变化时会自动将数据同步给从数据库。而从数据库一般是只读的,并接受主数据库同步过来的数据。一个主数据库可以拥有多个从数据库,而一个从数据库只能拥有一个主数据库。
全量复制:

  1. 主节点通过bgsave命令fork子进程进行RDB持久化,该过程是非常消耗CPU、内存(页表复制)、硬盘I0的
  2. 主节点通过网络将RDB文件发送给从节点,对主从节点的带宽都会带来很大的消耗
  3. 从节点清空老数据、载入新RDB文件的过程是阻塞的,无法响应客户端的命令;如果从节点执行bgrewriteaof,也会带来额外的消耗

部分复制:

  1. 复制偏移量:执行复制的双方,主从节点,分别会维护一个复制移量offset
  2. 复制积压缓冲区:主节点内部维护了一个固定长度的、先进先出(FIFO)队列 作为复制积压缓冲区,当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制。
  3. 服务器运行ID(runid):每个Redis节点,都有其运行ID,运行ID由节点在启动时自动生成,主节点会将自己的运行ID发送给从节点,从节点会将主节点的运行ID存起来。从节点Redis断开重连的时候,就是根据运行ID来判断同步的进度:
  • 如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会继续尝试使用部。分复制(到底能不能部分复制还要看offset和复制积压缓冲区的情况);
  • 如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的Redis节点并不是当前的主节点,只能进行全量复制。

在这里插入图片描述

15.Redis的数据结构及使用场景

  1. 字符串:可以用来做展简单的数据缓存,可以须存某个简单的字符串,也可以缓存某个son格式的字符串,Reds分布式铁的实现就利用了这种数据结构,还包括可以实现计数器、Session共享、分布式ID
  2. 哈希表:可以用来存储一些key-value对,更适合用来存储对象
  3. 列表:Redis的列表通过命令的组合,既可以当做栈,也可以当做队列来使用,可以用来缓存类似微信公众号、微博等消息流数据
  4. 集合:和列表类似,也可以存储多个元素,但是不能重复,集合可以进行交集、并集、差集操作,从而可以实现类似,我和某人共同关注的人、朋友圈点替等功能
  5. 有序集合:集合是无序的,有序集合可以设置顺序,可以用来实现排行榜功能

16.redis的持久化机制

RDB:Redis DataBase 将某一个时刻的内存快照(Snapshot),以二进制的方式写入磁盘。

手动触发:

  • save命令,使 Redis 处于阻塞状态,直到 RDB 持久化完成,才会响应其他客户端发来的命令,所 以在生产环境一定要慎用
  • bgsave命令,fork出一个子进程执行持久化,主进程只在fork过程中有短暂的阻塞,子进程创建 之后,主进程就可以响应客户端请求了

自动触发:

  • save m n :在 m 秒内,如果有 n 个键发生改变,则自动触发持久化,通过bgsave执行,如果设置多个、只要满足其一就会触发,配置文件有默认配置(可以注释掉)
  • flushall:用于清空redis所有的数据库,flushdb清空当前redis所在库数据(默认是0号数据库),会 清空RDB文件,同时也会生成dump.rdb、内容为空
  • 主从同步:全量同步时会自动触发bgsave命令,生成rdb发送给从节点

优点:

  1. 整个Redis数据库将只包含一个文件 dump.rdb,方便持久化。
  2. 容灾性好,方便备份。
  3. 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进 程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
  4. 相对于数据集大时,比 AOF 的启动效率更高。

缺点:

  1. 数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢 失。所以这种方式更适合数据要求不严谨的时候)
  2. 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导 致整个服务器停止服务几百毫秒,甚至是1秒钟。会占用cpu

AOF:Append Only File 以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录,调操作系统命令进程刷盘

  1. 所有的写命令会追加到 AOF 缓冲中。
  2. AOF 缓冲区根据对应的策略向硬盘进行同步操作。
  3. 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
  4. 当 Redis 重启时,可以加载 AOF 文件进行数据恢复。

同步策略:

  • 每秒同步:异步完成,效率非常高,一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢 失
  • 每修改同步:同步持久化,每次发生的数据变化都会被立即记录到磁盘中,最多丢一条
  • 不同步:由操作系统控制,可能丢失较多数据

优点:

  1. 数据安全
  2. 通过 append 模式写文件,即使中途服务器宕机也不会破坏已经存在的内容,可以通过 redis-check-aof 工具解决数据一致性问题。
  3. AOF 机制的 rewrite 模式。定期对AOF文件进行重写,以达到压缩的目的

缺点:

  1. AOF 文件比 RDB 文件大,且恢复速度慢。
  2. 数据集大的时候,比 rdb 启动效率低。
  3. 运行效率没有RDB高

AOF文件比RDB更新频率高,优先使用AOF还原数据。

AOF比RDB更安全也更大

RDB性能比AOF好

如果两个都配了优先加载AOF

17.redis集群方案

同 1.redis高可用方案

18.Redis线程模型,单线程为什么快

Redis基于Reactor模式开发了网络事件处理器、文件事件处理器 file event handler。它是单线程的, 所以 Redis 才叫做单线程的模型,它采用IO多路复用机制来同时监听多个Socket,根据Socket上的事件 类型来选择对应的事件处理器来处理这个事件。可以实现高性能的网络通信模型,又可以跟内部其他单 线程的模块进行对接,保证了 Redis 内部的线程模型的简单性。

文件事件处理器的结构包含4个部分:多个Socket、IO多路复用程序、文件事件分派器以及事件处理器 (命令请求处理器、命令回复处理器、连接应答处理器等)。

多个 Socket 可能并发的产生不同的事件,IO多路复用程序会监听多个 Socket,会将 Socket 放入一个 队列中排队,每次从队列中有序、同步取出一个 Socket 给事件分派器,事件分派器把 Socket 给对应的 事件处理器。

然后一个 Socket 的事件处理完之后,IO多路复用程序才会将队列中的下一个 Socket 给事件分派器。文 件事件分派器会根据每个 Socket 当前产生的事件,来选择对应的事件处理器来处理。

  1. Redis启动初始化时,将连接应答处理器跟AE_READABLE事件关联。
  2. 若一个客户端发起连接,会产生一个AE_READABLE事件,然后由连接应答处理器负责和客户端建立连接,创建客户端对应的socket,同时将这个socket的AE_READABLE事件和命令请求处理器关联,使得客户端可以向主服务器发送命令请求。 当客户端向Redis发请求时(不管读还是写请求),客户端socket都会产生一个AE_READABLE事 件,触发命令请求处理器。处理器读取客户端的命令内容, 然后传给相关程序执行。
  3. 当Redis服务器准备好给客户端的响应数据后,会将socket的AE_WRITABLE事件和命令回复处理器 关联,当客户端准备好读取响应数据时,会在socket产生一个AE_WRITABLE事件,由对应命令回复处理器处理,即将准备好的响应数据写入socket,供客户端读取。
  4. 命令回复处理器全部写完到 socket 后,就会删除该socket的AE_WRITABLE事件和命令回复处理器 的映射。

单线程快的原因:

1)纯内存操作

2)核心是基于非阻塞的IO多路复用机制

3)单线程反而避免了多线程的频繁上下文切换带来的性能问题

19.Redis如何设置key的过期时间

redis设置key的过期时间:1、EXPIRE。2、SETEX

实现原理:

  1. 定期删除: 每隔一段时间,执行一次删除过期key的操作。
  2. 懒汉式删除: 当使用get、getset等指令去获取数据时,判断key是否过期。过期后,就先把key删除,再执行后面的操作。

Redis是将两种方式结合来使用。

懒汉式删除

定期删除:平衡执行频率和执行时长。

定期删除时会遍历每个database(默认16个),检查当前库中指定个数的key(默认是20个)。随机抽查这些key,如果有过期的,就删除。

  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值