面试题(四)

目录

61.简述MyISAM和InnoDB的区别

62.Explain语句结果中各个字段分表表示什么

 63.索引覆盖是什么

64.最左前缀原则是什么

65.Innodb是如何实现事务的

66.B树和B+树的区别,为什么Mysql使⽤B+树

67.Mysql锁有哪些,如何理解

68.Mysql慢查询该如何优化?

69.什么是RDB和AOF

70.Redis的过期键的删除策略

71.简述Redis事务实现

72.Redis 主从复制的核⼼原理

73.Redis有哪些数据结构?分别有哪些典型的应⽤场景?

74.Redis分布式锁底层是如何实现的?

75.Redis主从复制的核⼼原理

76.Redis集群策略

77.缓存穿透、缓存击穿、缓存雪崩分别是什么

78.Redis和Mysql如何保证数据⼀致

79.Redis的持久化机制

80.Redis单线程为什么这么快


61.简述MyISAM和InnoDB的区别

MyISAM和InnoDB是Mysql数据库的存储引擎,但不止这两个

MyIASM:

  • 不支持事务,但是每次查询都是原子的
  • 支持表级锁,每次操作都是对整个表锁住
  • 生成 fri(表结构文件),MYI(索引文件),MYD(数据文件) 文件
  • 存储表的总行数
  • 非聚簇索引,索引文件的数据与存储的是数据文件中的指针。辅助索引与主索引基本一致,但是辅索引不用保证唯一性。 

InnoDB:

  •  支持ACID事务,支持事务的四种隔离级别
  • 支持行锁及外键约束,因此可以支持写并发
  • 不存储总行数
  • 一个InnoDB引擎储存在一个文件空间
  • 生成idb文件,存储的是数据和索引,frm表结构文件
  • 采用聚集索引,数据和索引是保存在一起的,建议使用主键自增,维持B+树

62.Explain语句结果中各个字段分表表示什么

 63.索引覆盖是什么

        索引覆盖就是⼀个SQL在执⾏时,可以利⽤索引来快速查找,并且此SQL所要查询的字段在当前索引对 应的字段中都包含了,那么就表示此SQL⾛完索引后不⽤回表了,所需要的字段都在当前索引的叶⼦节 点上存在,可以直接作为结果返回了

64.最左前缀原则是什么

当⼀个SQL想要利⽤索引是,就⼀定要提供该索引所对应的字段中最左边的字段,也就是排在最前⾯的 字段,⽐如针对a,b,c三个字段建⽴了⼀个联合索引,那么在写⼀个sql时就⼀定要提供a字段的条件,这 样才能⽤到联合索引,这是由于在建⽴a,b,c三个字段的联合索引时,底层的B+树是按照a,b,c三个字段 从左往右去⽐较⼤⼩进⾏排序的,所以如果想要利⽤B+树进⾏快速查找也得符合这个规则

65.Innodb是如何实现事务的

Innodb通过Buffer Pool,LogBuffer,Redo Log,Undo Log来实现事务,以⼀个update语句为例:
1. Innodb在收到⼀个update语句后,会先根据条件找到数据所在的⻚,并将该⻚缓存在Buffer Pool 中
2. 执⾏update语句,修改Buffer Pool中的数据,也就是内存中的数据
3. 针对update语句⽣成⼀个RedoLog对象,并存⼊LogBuffer中
4. 针对update语句⽣成undolog⽇志,⽤于事务回滚
5. 如果事务提交,那么则把RedoLog对象进⾏持久化,后续还有其他机制将Buffer Pool中所修改的数 据⻚持久化到磁盘中
6. 如果事务回滚,则利⽤undolog⽇志进⾏回滚

66.B树和B+树的区别,为什么Mysql使⽤B+树

B树的特点:
1. 节点排序
2. ⼀个节点了可以存多个元素,多个元素也排序了
B+树的特点:
1. 拥有B树的特点
2. 叶⼦节点之间有指针
3. ⾮叶⼦节点上的元素在叶⼦节点上都冗余了,也就是叶⼦节点中存储了所有的元素,并且排好顺序 Mysql索引使⽤的是B+树,因为索引是⽤来加快查询的,⽽B+树通过对数据进⾏排序所以是可以提⾼查 询速度的,然后通过⼀个节点中可以存储多个元素,从⽽可以使得B+树的⾼度不会太⾼,在Mysql中⼀ 个Innodb⻚就是⼀个B+树节点,⼀个Innodb⻚默认16kb,所以⼀般情况下⼀颗两层的B+树可以存2000 万⾏左右的数据,然后通过利⽤B+树叶⼦节点存储了所有数据并且进⾏了排序,并且叶⼦节点之间有指 针,可以很好的⽀持全表扫描,范围查找等SQL语句。

67.Mysql锁有哪些,如何理解

按锁粒度分类:
1. ⾏锁:锁某⾏数据,锁粒度最⼩,并发度⾼
2. 表锁:锁整张表,锁粒度最⼤,并发度低
3. 间隙锁:锁的是⼀个区间
还可以分为:
1. 共享锁:也就是读锁,⼀个事务给某⾏数据加了读锁,其他事务也可以读,但是不能写
2. 排它锁:也就是写锁,⼀个事务给某⾏数据加了写锁,其他事务不能读,也不能写
还可以分为:
1. 乐观锁:并不会真正的去锁某⾏记录,⽽是通过⼀个版本号来实现的
2. 悲观锁:上⾯所的⾏锁、表锁等都是悲观锁
在事务的隔离级别实现中,就需要利⽤锁来解决幻读

68.Mysql慢查询该如何优化?

1. 检查是否⾛了索引,如果没有则优化SQL利⽤索引
2. 检查所利⽤的索引,是否是最优索引
3. 检查所查字段是否都是必须的,是否查询了过多字段,查出了多余数据
4. 检查表中数据是否过多,是否应该进⾏分库分表了
5. 检查数据库实例所在机器的性能配置,是否太低,是否可以适当增加资源

69.什么是RDB和AOF

RDB:Redis DataBase,在指定的时间间隔内将内存中的数据集快照写⼊磁盘,实际操作过程是fork⼀ 个⼦进程,先将数据集写⼊临时⽂件,写⼊成功后,再替换之前的⽂件,⽤⼆进制压缩存储。
优点:
1. 整个Redis数据库将只包含⼀个⽂件 dump.rdb,⽅便持久化。
2. 容灾性好,⽅便备份。
3. 性能最⼤化,fork ⼦进程来完成写操作,让主进程继续处理命令,所以是 IO 最⼤化。使⽤单独⼦ 进程来进⾏持久化,主进程不会进⾏任何 IO 操作,保证了 redis 的⾼性能
4. 相对于数据集⼤时,⽐ AOF 的启动效率更⾼。
缺点:
1. 数据安全性低。RDB 是间隔⼀段时间进⾏持久化,如果持久化之间 redis 发⽣故障,会发⽣数据丢 失。所以这种⽅式更适合数据要求不严谨的时候)
2. 由于RDB是通过fork⼦进程来协助完成数据持久化⼯作的,因此,如果当数据集较⼤时,可能会导 致整个服务器停⽌服务⼏百毫秒,甚⾄是1秒钟。
AOF:Append Only File,以⽇志的形式记录服务器所处理的每⼀个写、删除操作,查询操作不会记 录,以⽂本的⽅式记录,可以打开⽂件看到详细的操作记录
优点:
1. 数据安全,Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也 是异步完成的,其效率也是⾮常⾼的,所差的是⼀旦系统出现宕机现象,那么这⼀秒钟之内修改的 数据将会丢失。⽽每修改同步,我们可以将其视为同步持久化,即每次发⽣的数据变化都会被⽴即 记录到磁盘中。。
2. 通过 append 模式写⽂件,即使中途服务器宕机也不会破坏已经存在的内容,可以通过 redis
check-aof ⼯具解决数据⼀致性问题。
3. AOF 机制的 rewrite 模式。定期对AOF⽂件进⾏重写,以达到压缩的⽬的
缺点:
1. AOF ⽂件⽐ RDB ⽂件⼤,且恢复速度慢。
2. 数据集⼤的时候,⽐ rdb 启动效率低。
3. 运⾏效率没有RDB⾼
AOF⽂件⽐RDB更新频率⾼,优先使⽤AOF还原数据,AOF⽐RDB更安全也更⼤,RDB性能⽐AOF好, 如果两个都配了优先加载AOF。

70.Redis的过期键的删除策略

Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间。Redis的过期策略就是指当 Redis中缓存的key过期了,Redis如何处理。
惰性过期:只有当访问⼀个key时,才会判断该key是否已过期,过期则清除。该策略可以最⼤化地 节省CPU资源,却对内存⾮常不友好。极端情况可能出现⼤量的过期key没有再次被访问,从⽽不 会被清除,占⽤⼤量内存。
定期过期:每隔⼀定的时间,会扫描⼀定数量的数据库的expires字典中⼀定数量的key,并清除其 中已过期的key。该策略是⼀个折中⽅案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可 以在不同情况下使得CPU和内存资源达到最优的平衡效果。 (expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的 指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有 键。)
Redis中同时使⽤了惰性过期和定期过期两种过期策略。

71.简述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的监控。\

72.Redis 主从复制的核⼼原理

通过执⾏slaveof命令或设置slaveof选项,让⼀个服务器去复制另⼀个服务器的数据。主数据库可以进⾏读写操作,当写操作导致数据变化时会⾃动将数据同步给从数据库。⽽从数据库⼀般是只读的,并接 受主数据库同步过来的数据。⼀个主数据库可以拥有多个从数据库,⽽⼀个从数据库只能拥有⼀个主数 据库。
全量复制:
1. 主节点通过bgsave命令fork⼦进程进⾏RDB持久化,该过程是⾮常消耗CPU、内存(⻚表复制)、硬 盘IO的
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节点并不
是当前的主节点,只能进⾏全量复制。

73.Redis有哪些数据结构?分别有哪些典型的应⽤场景?

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

74.Redis分布式锁底层是如何实现的?

1. ⾸先利⽤setnx来保证:如果key不存在才能获取到锁,如果key存在,则获取不到锁
2. 然后还要利⽤lua脚本来保证多个redis操作的原⼦性
3. 同时还要考虑到锁过期,所以需要额外的⼀个看⻔狗定时任务来监听锁是否需要续约
4. 同时还要考虑到redis节点挂掉后的情况,所以需要采⽤红锁的⽅式来同时向N/2+1个节点申请锁, 都申请到了才证明获取锁成功,这样就算其中某个redis节点挂掉了,锁也不能被其他客户端获取到

75.Redis主从复制的核⼼原理

Redis的主从复制是提⾼Redis的可靠性的有效措施,主从复制的流程如下:
1. 集群启动时,主从库间会先建⽴连接,为全量复制做准备
2. 主库将所有数据同步给从库。从库收到数据后,在本地完成数据加载,这个过程依赖于内存快照
RDB
3. 在主库将数据同步给从库的过程中,主库不会阻塞,仍然可以正常接收请求。否则,redis的服务就被中断 了。但是,这些请求中的写操作并没有记录到刚刚⽣成的RDB⽂件中。为了保证主从库的数据⼀致性,主库会在内存中⽤专⻔的replication buffer,记录RDB⽂件⽣成收到的所有写操作。
4. 最后,也就是第三个阶段,主库会把第⼆阶段执⾏过程中新收到的写命令,再发送给从库。具体的操作 是,当主库完成RDB⽂件发送后,就会把此时replocation buffer中修改操作发送给从库,从库再执⾏这些 操作。这样⼀来,主从库就实现同步了
5. 后续主库和从库都可以处理客户端读操作,写操作只能交给主库处理,主库接收到写操作后,还会将写操 作发送给从库,实现增量同步

76.Redis集群策略

Redis提供了三种集群策略:
1. 主从模式:这种模式⽐较简单,主库可以读写,并且会和从库进⾏数据同步,这种模式下,客户端 直接连主库或某个从库,但是但主库或从库宕机后,客户端需要⼿动修改IP,另外,这种模式也⽐较难进⾏扩容,整个集群所能存储的数据受到某台机器的内存容量,所以不可能⽀持特⼤数据量
2. 哨兵模式:这种模式在主从的基础上新增了哨兵节点,但主库节点宕机后,哨兵会发现主库节点宕机,然后在从库中选择⼀个库作为进的主库,另外哨兵也可以做集群,从⽽可以保证但某⼀个哨兵 节点宕机后,还有其他哨兵节点可以继续⼯作,这种模式可以⽐较好的保证Redis集群的⾼可⽤,但 是仍然不能很好的解决Redis的容量上限问题。
3. Cluster模式:Cluster模式是⽤得⽐较多的模式,它⽀持多主多从,这种模式会按照key进⾏槽位的分配,可以使得不同的key分散到不同的主节点上,利⽤这种模式可以使得整个集群⽀持更⼤的数据 容量,同时每个主节点可以拥有⾃⼰的多个从节点,如果该主节点宕机,会从它的从节点中选举⼀ 个新的主节点。
对于这三种模式,如果Redis要存的数据量不⼤,可以选择哨兵模式,如果Redis要存的数据量⼤,并且需要持续的扩容,那么选择Cluster模式。

77.缓存穿透、缓存击穿、缓存雪崩分别是什么

缓存中存放的⼤多都是热点数据,⽬的就是防⽌请求可以直接从缓存中获取到数据,⽽不⽤访问
Mysql。
1. 缓存雪崩:如果缓存中某⼀时刻⼤批热点数据同时过期,那么就可能导致⼤量请求直接访问Mysql 了,解决办法就是在过期时间上增加⼀点随机值,另外如果搭建⼀个⾼可⽤的Redis集群也是防⽌缓存雪崩的有效⼿段
2. 缓存击穿:和缓存雪崩类似,缓存雪崩是⼤批热点数据失效,⽽缓存击穿是指某⼀个热点key突然失 效,也导致了⼤量请求直接访问Mysql数据库,这就是缓存击穿,解决⽅案就是考虑这个热点key不设过期时间
3. 缓存穿透:假如某⼀时刻访问redis的⼤量key都在redis中不存在(⽐如⿊客故意伪造⼀些乱七⼋糟 的key),那么也会给数据造成压⼒,这就是缓存穿透,解决⽅案是使⽤布隆过滤器,它的作⽤就是 如果它认为⼀个key不存在,那么这个key就肯定不存在,所以可以在缓存之前加⼀层布隆过滤器来 拦截不存在的key

78.Redis和Mysql如何保证数据⼀致

  1. 在并发环境下,两个线程同时操作数据库,线程1对redis进行删除,然后再更新数据库,但此时由于网络等原因导致Mysql数据库还没有更新好的时候,此时线程2就回去查redis,发现redis里面没有数据,就去查Myql,此时Mysql的数据还没有更新,查出来的是老数据,那么线程2就把老数据有缓存到redis里面了,此时现在线程2缓存到redis里面的时候就会出现存入速度慢等原因,如果此时线程1已经吧Mysql更新完毕,读取时把数据缓存到redis,这时redis里面的数据是线程1缓存的新的,此时线程2正好也来缓存redis,就会导致线程1的新数据被线程2的老数据覆盖,所以可以借助MQ和Canal来更好的解决此问题。
  2. Canal用来监听Mysql中的binlog中的日志,将变更得数据通知canal客户端,然后通过MQ来实现延迟删除redis,因为不延迟的话有可能会被老数据覆盖,如果删除失败,发送需要删除的key到MQ,Canal监听MQ,重试删除

79.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

80.Redis单线程为什么这么快

Redis基于Reactor模式开发了⽹络事件处理器、⽂件事件处理器 fileeventhandler。它是单线程的, 所 以 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事件和命令请求处理 器关联,使 得客户端可以向主服务器发送命令请求。
3. 当客户端向Redis发请求时(不管读还是写请求),客户端socket都会产⽣⼀个AE_READABLE事 件,触发命令请求处理器。处理器读取客户端的命令内容, 然后传给相关程序执⾏。
4. 当Redis服务器准备好给客户端的响应数据后,会将socket的AE_WRITABLE事件和命令回复处理器 关联,当客户端准备好读取响应数据时,会在socket产⽣⼀个AE_WRITABLE事件,由对应命令回 复处 理器处理,即将准备好的响应数据写⼊socket,供客户端读取。
5. 命令回复处理器全部写完到 socket 后,就会删除该socket的AE_WRITABLE事件和命令回复处理 器的映射。
单线程快的原因:
1. 纯内存操作
2. 核⼼是基于⾮阻塞的IO多路复⽤机制
3. 单线程反⽽避免了多线程的频繁上下⽂切换带来的性能问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/496018.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【JavaWeb】Day18.Vue组件库Element

什么是Element Element:是饿了么团队研发的,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。组件:组成网页的部件,例如 超链接、按钮、图片、表格、表单、分页条等等。官网:Element - The worlds…

每日汇评:复活节假期前,欧元保持在关键技术位之间

周四欧洲早盘,欧元兑美元小幅下跌至1.0800; 谨慎的市场情绪帮助美元在数据发布前守住了阵地; 美联储理事沃勒表示,他们并不急于降低政策利率; 周四欧洲早盘,欧元兑美元受到温和的看跌压力,并跌向…

Python算法100例-4.6 歌星大奖赛

完整源代码项目地址,关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.完整的程序6.问题拓展7.知识点补充 1.问题描述 在歌星大奖赛中,有10个评委为参赛的选手打分,分数为1~100分。选手最…

【Vue3之computed属性(四)】

文章目录 前言一、computed属性有缓存二、使用方法三、修改全名 前言 理解computed属性,实现输入姓和名得出全名并双向绑定,区分单向绑定和双向绑定。测试computed属性和方法的区别 一、computed属性有缓存 先引入computed,写箭头函数定义并…

Windows安装Odoo结合内网穿透实现公网访问本地企业管理系统

文章目录 前言1. 下载安装Odoo:2. 实现公网访问Odoo本地系统:3. 固定域名访问Odoo本地系统 前言 Odoo是全球流行的开源企业管理套件,是一个一站式全功能ERP及电商平台。 开源性质:Odoo是一个开源的ERP软件,这意味着企…

springboot实战---5.最简单最高效的后台管理系统开发

🎈个人主页:靓仔很忙i 💻B 站主页:👉B站👈 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:SpringBoot 🤝希望本文对您有所裨益,如有不足之处&…

网络编程之流式套接字

流式套接字(SOCK_STREAM)是一种网络编程接口,它提供了一种面向连接的、可靠的、无差错和无重复的数据传输服务。这种服务保证了数据按照发送的顺序被接收,使得数据传输具有高度的稳定性和正确性。通常用于那些对数据的顺序和完整性…

Backend - gitea 首次建库(远端本地)

目录 一、建立远端储存库 1. 进入新增画面 2. 填写储存库名称(如book),点击“建立”即可 二、本地关联远端储存库 1. 本地初始化储存库代码 (1)新建文件夹 (2)获取远端储存库 2. 本地编写…

Linux:基础IO

回顾C文件接口 stdin & stdout & stderr C 默认会打开三个输入输出流&#xff0c;分别是 stdin, stdout, stderr 仔细观察发现&#xff0c;这三个流的类型都是 FILE*, fopen 返回值类型&#xff0c;文件指针 系统文件I/O 接口介绍 open man open #include <sy…

FCP270 P0917YZ 兼容性如何

FCP270 P0917YZ 是一种现场控制处理器&#xff0c;通常应用于工业自动化和过程控制系统中。 这款现场控制处理器的主要职责是监测和控制多种过程变量&#xff0c;确保系统的正常运行&#xff0c;并且满足生产的要求。以下是关于FCP270 P0917YZ的一些可能用途和特点&#xff1a…

【Java 多线程】从源码出发,剖析Threadlocal的数据结构

文章目录 exampleset(T value)createMap(t, value);set(ThreadLocal<?> key, Object value)ThreadLocalMap和Thread的关系 全貌 ThreadLocal是个很重要的多线程类&#xff0c;里面数据结构的设计很有意思&#xff0c;很巧妙。但是我们平时使用它的时候常常容易对它的使用…

SwiftUI Release 引入的辅助焦点管理

文章目录 前言使用 FocusState 属性包装器高级技巧&#xff1a;专用辅助技术可聚焦字段的高级用法优化体验运行截图总结 前言 SwiftUI Release 引入了强大的新功能&#xff0c;其中之一是辅助焦点管理。 这个新功能使得在SwiftUI中处理辅助技术&#xff08;如 VoiceOver 和 S…

Python程序设计 循环结构(二)

1.斐波那契数列 编写一个能计算斐波那契数列中第x个数的小程序。斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列、 因数学家莱昂纳多斐波那契&#xff08;Leonardoda Fibonacci&#xff09;以兔子繁殖为例子而引入&#xff0c;故又称为…

protobuf 从版本 4.24.4 降级到版本 3.19.0

1.查看protobuf版本号&#xff1a; pip show protobuf2.卸载 4.24.4 的版本 pip uninstall protobuf3.安装 3.19.0 的版本 pip install protobuf3.19.04.查看版本是否安装成功 pip show protobuf

STM32通用输入输出

一、GPIO介绍 功能&#xff1a; 输入&#xff08;Input&#xff09;&#xff1a; 浮空:输入没有接上拉和下拉 模拟&#xff1a;输入没有走上拉和下拉走的是模拟输入 上拉&#xff1a;上拉电阻是合上的&#xff0c;接入点为上拉电阻 下拉&#xff1a;下拉电阻是合上的 输…

Cocos2dx-lua ScrollView[三]高级篇

一.概述 本文缩写说明:sv = ScrollView, cell代表ScrollView的一个子节点 本文介绍sv的一种封装类库,来实现快速创建sv,有如下几个优点: 1.item的位置通过参数控制,提高开发效率 2.免去了调用sv的API,提高开发效率 3.分帧创建,提高性能 4.可通过参数控制,复用ite…

uniapp h5 引入阿里云一键登录

参考官方文档: 如何将H5页面接入网页端SDK并一键登录_号码认证服务(PNVS)-阿里云帮助中心 本文主要分享uniapp 对SDK依赖文件的引入 采用npm包引入的方法: 1.下载 // 下载npm资源并添加依赖到package.json npm i aliyun_numberauthsdk_web -S tips: 查看package.json文件,确…

Java毕业设计-基于springboot开发的疫情防控期间外出务工人员信息管理系统-毕业论文+答辩PPT(附源代码+演示视频)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1、开发说明2、需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、后台登录2.1管理员功能2.2用户功能2.3采集员功能2.4分析员功能 四、毕设内容和源代码获取总结 Java毕业设计-基…

MySql实战--事务到底是隔离的还是不隔离的

第3篇文章和你讲事务隔离级别的时候提到过&#xff0c;如果是可重复读隔离级别&#xff0c;事务T启动的时候会创建一个视图read-view&#xff0c;之后事务T执行期间&#xff0c;即使有其他事务修改了数据&#xff0c;事务T看到的仍然跟在启动时看到的一样。也就是说&#xff0c…

MySQL安装和配置(超详细)

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;&#x1f468;&#x1f3fb;‍&#x1f393;告别&#xff0c;今天 &#x1f4d4;高质量专栏 &#xff1a;☕java趣味之旅 欢迎&#x1f64f;点赞&#x1f5e3;️评论&#x1f4e5;收藏&#x1f493;关注 &#x1f496;衷心的希…