【java面试题-Redis篇-2024】

##java面试题大全

详细面试题-持续更新中-点击跳转

点赞、收藏、加关注
·
·

java基础面试题

  • ##java面试题大全
    • 1、什么是 Redis
    • 2、Redis 的数据结构类型
    • 3、Redis 为什么快
    • 4、什么是跳跃表
    • 5、什么是 I/O 多路复用
    • 6、什么是缓存击穿、缓存穿透、缓存雪崩
    • 7、什么是布隆过滤器
    • 8、热点 Key 问题
      • 1)热点 Key 怎么样会影响到 Redis 服务
      • 2)如何识别到热点 Key
      • 3)如何解决 热点 Key 问题
    • 9、Redis 过期策略和内存淘汰策略
    • 10、Redis 持久化
    • 11、实现 Redis 的高可用
      • 1)主从集群
      • 2)哨兵模式
      • 3)分片集群
    • 12、使用过 Redis 分布式锁嘛
    • 13、Redisson 原理
    • 14、什么是 Redlock 算法
    • 15、MySQL 与 Redis 如何保证双写一致性
    • 16、Redis 事务机制
    • 17、Redis 的 Hash 冲突怎么办
    • 18、Redis 底层,使用的什么协议

1、什么是 Redis

Redis,英文全称是 Remote Dictionary Server(远程字典服务),是一个开源的使用 C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。与 MySQL 数据库不同的是,Redis 的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过 10 万次读写操作。因此 Redis 被广泛应用于缓存,另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务、持久化、LUA 脚本、多种集群方案

2、Redis 的数据结构类型

** 1.String **

  • 简介:字符串。String 是 Redis 最基础的数据结构类型,它是二进制安全的,可以存储图片或者序列化的对象,值最大存储为 512M
  • 应用场景:共享 Session、分布式锁、计数器
  • 拓展:C 语言的字符串是 char[] 实现的,而 Redis 使用 SDS(simple dynamic string)封装。SDS 会保存空闲的长度、已使用的长度、实际保持的内容值。
    • 字符串长度处理:Redis 获取字符串长度,时间复杂度为 O(1),而 C 语言中,需要从头开始遍历,复杂度为 O(n)
    • 空间预分配:字符串修改越频繁的话,内存分配越频繁,就会消耗性能,而 SDS 修改和空间扩充,会额外分配未使用的空间,减少性能损耗
    • 惰性空间释放:SDS 缩短时,不是回收多余的内存空间,而是 free 记录下多余的空间,后续有变更,直接使用 free 中记录的空间,减少分配
    • 二进制安全:Redis 可以存储一些二进制数据,在C语言中字符串遇到 ‘\0’ 会结束,而 SDS 中标志字符串结束的是 len 属性

** 2.Hash **

  • 简介:哈希。哈希类型是指 v(值)本身又是一个键值对(k-v)结构
  • 应用场景:缓存用户对象信息

** 3.List **

  • 简介:列表。列表类型是用来存储多个有序的字符串
  • 应用场景:消息队列、文章列表
  • 拓展:lpush+lpop=Stack(栈);lpush+rpop=Queue(队列);lpsh+ltrim=Capped Collection(有限集合);lpush+brpop=Message Queue(消息队列)

** 4.Set **

  • 简介:集合。集合类型也是用来保存多个的字符串元素,但是不允许重复元素
  • 应用场景:用户标签、生成随机数抽奖、用户点赞
  • 拓展:smembers 和 lrange、hgetall 都属于比较重的命令,如果元素过多存在阻塞 Redis 的可能性,可以使用 sscan 来完成

** 5.ZSet **

  • 简介:有序集合。已排序的字符串集合,同时元素不能重复
  • 应用场景:排行榜

** 6.Geo **

  • 简介:地图位置。Redis3.2 推出的,地理位置定位,用于存储地理位置信息,并对存储的信息进行操作
  • 应用场景:用户定位,附近商家

** 7.Bitmaps **

  • 简介:位图。用一个比特位来映射某个元素的状态,在 Redis 中,它的底层是基于字符串类型实现的,可以把 Bitmaps 成作一个以比特位为单位的数组
  • 应用场景:签到、用户是否在线状态

** 8.HyperLogLog **

  • 简介:用来做基数统计算法的数据结构
  • 应用场景:统计网站的UV

3、Redis 为什么快

  • 基于内存存储实现:Redis 基于内存存储实现的数据库,相对于数据存在磁盘的 MySQL 数据库,省去磁盘 I/O 的消耗
  • 高效的数据结构:Redis 自己也封装了一些数据结构,可以有效的提高效率。如:String 的动态字符串结构、ZSet 的跳跃表
  • 合理的数据编码:Redis 每种基本类型,对应多种数据结构,使用什么样编码,是 Redis 设计者总结优化的结果,Redis 会自动的根据元素个数、元素内容大小选择合适的数据编码。如:
    • String:如果存储数字的话,是用 int 类型的编码;如果存储非数字,小于等于 39 字节的字符串,是 embstr 编码;大于 39 个字节,则是 raw 编码。
    • List:如果列表的元素个数小于 512 个,列表每个元素的值都小于 64 字节(默认),使用 ziplist 编码,否则使用 linkedlist 编码
    • Zset:当有序集合的元素个数小于 128 个,每个元素的值小于 64 字节时,使用 ziplist 编码,否则使用 skiplist(跳跃表)编码
  • 合理的线程模型:采用 I/O 多路复用。I/O 多路复用技术可以让单个线程高效的处理多个连接请求,而 Redis 使用用 epoll 作为 I/O 多路复用技术的实现。并且,Redis 自身的事件处理模型将 epoll 中的连接、读写、关闭都转换为事件,不在网络 I/O 上浪费过多的时间
  • 虚拟内存机制:Redis 直接自己构建了 VM 机制 ,不会像一般的系统会调用系统函数处理,会浪费一定的时间去移动和请求。虚拟内存机制就是暂时把不经常访问的数据(冷数据)从内存交换到磁盘中,从而腾出宝贵的内存空间用于其它需要访问的数据(热数据)。通过 VM 功能可以实现冷热数据分离,使热数据仍在内存中、冷数据保存到磁盘。这样就可以避免因为内存不足而造成访问速度下降的问题

4、什么是跳跃表

  • 跳跃表是有序集合 zset 的底层实现之一
  • 跳跃表支持平均 O(logN) 复杂度的节点查找,还可以通过顺序性操作批量处理节点
  • 跳跃表就是在链表的基础上,增加多级索引提升查找效率

5、什么是 I/O 多路复用

  • redis的网络模型是 io 多路复用+事件派发,有多个事件处理器,如连接应答处理器、[命令回复处理器]、命令请求处理器([接受请求参数、把数据转换成redis命令]、执行命令写入到缓冲队列、[由命令回复处理器进行响应给客户端结果])。[多线程的处理]
  • Redis 是基于内存的,所以它的性能瓶颈是网络 IO,IO 多路复用技术就是为了实现高效的网络请求,6 版本之后引入多线程也是为了解决这个问题
    • 阻塞 io:需要内核缓冲区等待数据,然后从内核缓冲区拷贝到用户缓冲区
    • 非阻塞 io:请求内核缓冲区的数据,没有就返回异常信息,然后再去请求,直到有数据,然后从内核缓冲区拷贝到用户缓冲区
    • io 多路复用:使用单个线程如使用 select 函数可以监听多个 socket(客户端的连接),并在某个 socket 可读可写时得到通知,避免无效的等待。使用 select 或者 poll 实现不会知道是哪个 socket 就绪的,使用 epoll 用户进程会知道就绪的 socket

6、什么是缓存击穿、缓存穿透、缓存雪崩

** 缓存击穿: **

  • 产生原因:指热点 Key 在某个时间点过期的时候,而恰好这个时间点有大量的并发请求这个热点 Key,从而大量的请求请求到数据库,导致数据库压力过大甚至宕机
  • 解决方法:
    • 使用互斥锁:缓存失效时,不是立即去加载数据库数据,而是先使用某些带成功返回的原子操作命令,如 Redis 的 setnx 去操作,成功的时候,再去加载数据库数据和设置缓存。否则就去重试获取缓存,这样就可以保证只有一个请求请求数据库
    • 设置永不过期:是指不设置过期时间

** 缓存穿透: **

  • 产生原因:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而导致数据库压力过大甚至宕机
  • 解决方法:
    • 校验非法请求:在 API 入口,对参数进行校验,过滤非法值
    • 缓存空值:如果查询数据库为空,可以给缓存设置个空值,或者默认值
    • 使用布隆过滤器:使用布隆过滤器快速判断数据是否存在。即一个查询请求过来时,先通过布隆过滤器判断值是否存在,存在才继续往下查,可能存在误判,key 如果不存在那一定不存在,如果判断 key 存在,也有可能是不存在的

** 缓存雪崩: **

  • 产生原因:指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,导致数据库压力过大甚至宕机
  • 解决方法:
    • 过期时间分散:缓存雪奔一般是由于大量数据同时过期造成的,对于这个原因,可通过均匀设置过期时间解决,比如添加随机数
    • 构建高可用集群:Redis 故障宕机也可能引起缓存雪奔,这就需要构造Redis高可用集群了

7、什么是布隆过滤器

  • 布隆过滤器是一种占用空间很小的数据结构,它由一个很长的二进制向量和一组Hash映射函数组成,它用于检索一个元素是否在一个集合中,空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难
  • 布隆过滤器原理:假设我们有个集合 A,A 中有 n 个元素。利用 k 个哈希散列函数,将 A 中的每个元素映射到一个长度为 a 位的数组 B 中的不同位置上,这些位置上的二进制数均设置为 1。如果待检查的元素,经过这 k 个哈希散列函数的映射后,发现其 k 个位置上的二进制数全部为 1,这个元素很可能属于集合 A,反之,一定不属于集合 A
  • 如何降低误判率:搞多几个哈希函数映射,降低哈希碰撞的概率;增加 B 数组的 bit 长度

8、热点 Key 问题

在 Redis 中,把访问频率高的 Key,称为热点 Key。如果某一热点 Key 的请求到服务器主机时,由于请求量特别大,可能会导致主机资源不足,甚至宕机,从而影响正常的服务

1)热点 Key 怎么样会影响到 Redis 服务

  • 用户消费的数据远大于生产的数据,如秒杀、热点新闻等读多写少的场景
  • 请求分片集中,超过单 Redis 服务器的性能,比如固定名称 Key,Hash 值落入同一台服务器,瞬间访问量极大,超过机器瓶颈,产生热点 Key 问题

2)如何识别到热点 Key

  • 凭经验判断哪些是热Key;
  • 客户端统计上报;
  • 服务代理层上报

3)如何解决 热点 Key 问题

  • Redis 集群扩容,增加分片副本,均衡读流量
  • 将热点 Key 分散到不同的服务器中
  • 使用二级缓存,即 JVM 本地缓存,减少 Redis 的读请求

9、Redis 过期策略和内存淘汰策略

** 过期策略:**

  • 定时过期:每个设置过期时间的 Key 都需要创建一个定时器,到过期时间就会立即对 Key 进行清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的 CPU 资源去处理过期的数据,从而影响缓存的响应时间和吞吐量
  • 惰性过期:只有当访问一个 Key 时,才会判断该 Key 是否已过期,过期则清除。该策略可以最大化地节省 CPU 资源,却对内存非常不友好。极端情况可能出现大量的过期 Key 没有再次被访问,从而不会被清除,占用大量内存
  • 定期过期:每隔一定的时间,会扫描一定数量的数据库的字典中一定数量的 Key,并清除其中已过期的 Key。该策略是前两者的一个折中方案。一般同时使用了惰性过期和定期过期两种策略

** 淘汰策略:**

  • volatile-lru:当内存不足以容纳新写入数据时,从设置了过期时间的 Key 中使用 LRU(最近最少使用) 算法进行淘汰
  • allkeys-lru:当内存不足以容纳新写入数据时,从所有 Key 中使用 LRU 算法进行淘汰
  • volatile-lfu:4.0 版本新增,当内存不足以容纳新写入数据时,在过期的 Key 中,使用 LFU(使用频率最少) 算法进行删除 Key
  • allkeys-lfu:4.0 版本新增,当内存不足以容纳新写入数据时,从所有 Key 中使用 LFU 算法进行淘汰
  • volatile-random:当内存不足以容纳新写入数据时,从设置了过期时间的 Key 中,随机淘汰数据
  • allkeys-random:当内存不足以容纳新写入数据时,从所有 Key 中随机淘汰数据
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的 Key 中,根据过期时间进行淘汰,越早过期的优先被淘汰
  • noeviction:默认策略,当内存不足以容纳新写入数据时,新写入操作会报错

10、Redis 持久化

RDB 持久化:

  • Redis Database Backup file(Redis数据备份文件)
  • 每隔一段时间会将数据保存到磁盘中的备份文件中,在 redis.conf 配置文件中配置
  • 执行条件:执行 save 命令,会阻塞;执行 bgsave 命令,异步执行;Redis 停机时;触发 RDB 条件时,在 redis.conf 配置文件中配置,如:save 90 1:90秒内,如果至少有1个 key 被修改,则执行 bgsave
  • 优缺点: 适合大规模的数据恢复场景,如备份,全量复制等。没办法做到实时持久化/秒级持久化;新老版本存在 RDB 格式兼容问题

AOF 持久化:

  • Append Only File(追加文件)
  • 每一个写命令都会记录在 AOF 文件,默认关闭,修改 redis.conf 配置文件来开启。AOF 每次写命令都会记录(频率一般设置为每秒),所以文件会记录一些没用的数据,而且占用会很大,所以需要文件重写来压缩持久化文件,auto-aof-rewrite-percentage 100 AOF 文件比上次文件增长超过 100% 则触发重写,auto-aof-rewrite-min-size 64mb AOF 文件体积 64M 以上触发重写
  • 优缺点: 数据的一致性和完整性更高。AOF 记录的内容越多,文件越大,数据恢复变慢

11、实现 Redis 的高可用

1)主从集群

搭建:
在多个服务器上启动多个 Redis 实例,要想让 B、C 实例成为 A 实例的从节点,需要在 B、C 实例的配置文件或者命令行中使用命令 slaveof <masterip> <masterport> ,A 就成为了主节点,可读可写,B、C 就成为了从节点,只可读;它们的数据会自动同步

全量同步:

  1. slave 节点请求增量同步,将自己的 Replication Id(是数据集的标记,id一致则说明是同一数据集。每一个 master 都有唯一的 replid,slave 则会继承 master 节点的 replid) 和 offset(偏移量,随着记录在 repl_baklog 中的数据增多而逐渐增大。slave 完成同步时也会记录当前同步的 offset。如果 slave 的 offset 小于 master 的 offset,说明 slave 数据落后于 master,需要更新) 发送过去
  2. master 节点判断 replid,发现不一致,拒绝增量同步,确定了是第一次请求
  3. master 将完整内存数据生成 RDB,发送 RDB 到 slave
  4. slave 清空本地数据,加载 master 的 RDB,并将继承 master 节点的 replid
  5. master 将 RDB 期间的命令记录在 repl_baklog,并持续将 log 中的命令发送给 slave
  6. slave 执行接收到的命令,保持与 master 之间的同步

增量同步:

  1. master 判断 slave 发送过来的 replid 与自己一致,然后就发送 repl_baklog 中两者的 offset 相差值的内容来进行增量同步
  2. repl_baklog 相当于是一个环形数组,当 slave 出现问题,导致两者的 offset 相差值大于了整个数组的长度,就必须进行全量同步了

优化主从集群:

  • 在 master 中配置 repl-diskless-sync yes 启用无磁盘复制,避免全量同步时的磁盘 IO,但要求是网络带宽大,否则可能出现阻塞
  • Redis 单节点上的内存占用不要太大,减少 RDB 导致的过多磁盘 IO
  • 适当提高 repl_baklog 的大小,发现 slave 宕机时尽快实现故障恢复,尽可能避免全量同步
  • 限制一个 master 上的 slave 节点数量,如果实在是太多 slave,则可以采用主-从-从链式结构,减少 master 压力

2)哨兵模式

作用:

  • 监控:Sentinel 会不断检查您的 master 和 slave 是否按预期工作,每秒 ping 一下,未在规定时间内响应,则认为该实例主观下线,若超过指定数量(quorum)的 Sentinel 都认为该实例主观下线,则该实例客观下线
  • 自动故障恢复:如果 master 故障(客观下线),Sentinel 会将一个 slave 选举为 master。当故障实例恢复后也以新的 master 为主。选举前先排除与 master 节点断开超过指定时间的 slave 节点,主要根据 offset 值,越大说明数据越新,优先级越高
  • 通知:Sentinel 充当 Redis 客户端,当集群发生故障转移时,会将最新信息推送给 Redis 的客户端。Sentinel 给选中的 slave 节点发送 slaveof no one 命令,让该节点成为 master,然后给所有其它slave发送slaveof <新 master ip> <新 master port> 命令,让这些 slave 成为新 master 的从节点,最后,Sentinel 将故障节点标记为 slave,当故障节点恢复后会自动成为新的 master 的 slave 节点

搭建哨兵集群:

  1. 创建多个哨兵实例
  2. 为每个实例编写配置文件,指定监控的 master 节点的 ip、port、quorum
  3. 启动每一个实例,redis-sentinel 配置文件路径

RedisTemplate 使用哨兵集群:
1.引入 spring-boot-starter-data-redis 依赖
2.配置 Redis 地址:spring:redis:sentinel:nodes: List<每个哨兵的ip地址:端口号>
3.配置读写分离:

@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){//REPLICA _PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用才读取masterreturn clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}

3)分片集群

主从和哨兵可以解决高可用、高并发读的问题,分片集群进一步解决海量数据存储问题和高并发写的问题

搭建:
1.创建多个 Redis 实例
2.为每一个实例创建配置文件
3.启动每一个实例
4.使用命令创建集群:redis-cli --cluster create --cluster-replicas 1(每一个主节点的从节点数量) 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003(根据计算,前三个会成为主节点,后三个会成为从节点)

散列插槽:
Redis 会把每一个 master 节点映射到 0~16383 共 16384 个插槽(hash slot)上。数据 key 是与插槽绑定的。Redis 会根据 key 的有效部分进行 Hash 取余计算插槽值来决定数据存放在哪个 master 上,有效部分是:key 中包含 “{}”,且 “{}” 中至少包含 1 个字符,“{}” 中的部分是有效部分;key 中不包含 “{}”,整个 key 都是有效部分。可以设置 {} 前缀来将一类数据保存到同一 master 上

集群伸缩:
1.启动一个 Redis 实例
2.添加实例到集群:redis-cli --cluster add-node 192.168.150.101:7004(自己的实例) 192.168.150.101:7001(通知给集群中的一个实例)
3.转移插槽,刚添加的实例是没有插槽的,redis-cli --cluster reshard 192.168.150.101:7004(自己的实例),然后根据选项输入指定实例 id 来转移指定数量的插槽

故障转移:

  • 自动故障转移:当 一个master 宕机后,集群会自动选一个它的子节点来成为 master 节点
  • 手动故障转移:利用 cluster failover 命令可以手动让集群中这个 slave 节点成为 master 节点,实现无感知的数据迁移

RedisTemplate 使用分片集群:

  1. 引入 spring-boot-starter-data-redis 依赖
  2. 配置 Redis 地址:spring:redis:cluster:nodes: List<每个哨兵的ip地址:端口号>
  3. 配置读写分离:
@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){//REPLICA _PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用才读取masterreturn clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}

12、使用过 Redis 分布式锁嘛

数据库实现:
乐观锁,多个线程去插入数据,谁插入成功谁就获取到锁

zookeeper 实现:

zookeeper 的结构类似的文件目录,多线程向 zookeeper 创建一个子目录(节点)只会有一个创建成功,利用此特点可以实现分布式锁,谁创建该结点成功谁就获得锁

Redis 实现:

  • set key value NX EX 失效时间 命令实现,setIfAbsent(key,value) 方法,只有当键不存在的时候才能设置成功。需要结合 Lua 脚本解决原子性问题。而且过期时间设置不好确定
  • Redisson 实现,使用看门狗线程给使用中的锁续期,保证原子性,实现了 Lock 接口,List 接口

13、Redisson 原理

Redisson 使用:

  1. 引入 redisson-spring-boot-starter 依赖
  2. 在 yml 配置文件中配置 redisson 配置文件位置,然后引入配置文件
  3. 使用 RedissonClient 对象,getLock 方法设置锁获得 Lock 锁对象,然后锁对象进行上锁 lock(),释放锁 unlock

Redisson 原理:
只要线程加锁成功,就会启动一个 watch dog 看门狗,它是一个后台线程,会每隔 10 秒检查一下,如果线程还持有锁,那么就会不断的延长锁 key 的生存时间。因此,Redisson 就是解决了锁过期释放,业务没执行完问题

14、什么是 Redlock 算法

Redlock 算法解决的问题:
Redis 一般都是集群部署的,假设数据在主从同步过程,主节点挂了,如果线程一在 Redis 的 master 节点上拿到了锁,但是加锁的 key 还没同步到 slave 节点。恰好这时,master 节点发生故障,一个 slave 节点就会升级为 master 节点。线程二就可以获取同个 key 的锁,但线程一也已经拿到锁了,锁的安全性就得不到保障了,Redlock 算法就是解决这个问题的

Redlock 算法核心思想:
搞多个 Redis master 部署,以保证它们不会同时宕掉。并且这些 master 节点是完全相互独立的,相互之间不存在数据同步。同时,需要确保在这多个 master 实例上,是与在 Redis 单实例,使用相同方法来获取和释放锁

Redlock 算法核心步骤:

  • 按顺序向多个 master 节点请求加锁
  • 根据设置的超时时间来判断,是不是要跳过该 master 节点
  • 如果大于一半的节点加锁成功,并且使用的时间小于锁的有效期,即可认定加锁成功
  • 如果获取锁失败,解锁

15、MySQL 与 Redis 如何保证双写一致性

  • 延时双删:强一致性。先删缓存,再修改数据库,因为有数据库的主从复制,所以延时一会在删除缓存。但是延时的时间不好控制,还是有脏数据风险
  • 分布式锁:强一致性。使用加锁来防止意外情况,然后就可以正常同步数据。使用读写锁提高性能,代码中使用 redissonClient.getReadWriteLock 方法实现
  • MQ 异步通知:最终一致性。依赖 MQ 的可靠性
  • Canal 异步通知:最终一致性。伪装成从节点监听 binlog 日志

16、Redis 事务机制

Redis 通过 multi、exec、watch 等一组命令集合,来实现事务机制。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。简言之,Redis事务就是顺序性、一次性、排他性的执行一个队列中的一系列命令。执行事务的流程:开始事务(MULTI)、命令入队、执行事务(EXEC)、撤销事务(DISCARD )

17、Redis 的 Hash 冲突怎么办

  • Redis 作为一个 K-V 的内存数据库,它使用用一张全局的哈希来保存所有的键值对。这张哈希表,有多个哈希桶组成,哈希桶中有 entry 元素,每一个 entry 元素保存了 key 和 value 指针,其中 *key 指向了实际的键,*value 指向了实际的值
  • Redis 为了解决哈希冲突,采用了链式哈希。链式哈希是指同一个哈希桶中,多个元素用一个链表来保存,它们之间依次用指针连接。哈希冲突链上的元素只能通过指针逐一查找再操作
  • 当往哈希表插入数据很多,冲突也会越多,冲突链表就会越长,那查询效率就会降低了。为了保持高效,Redis 会对哈希表做 rehash 操作,也就是增加哈希桶,减少冲突。为了 rehash 更高效,Redis 还默认使用了两个全局哈希表,一个用于当前使用,称为主哈希表,一个用于扩容,称为备用哈希表
    在这里插入图片描述

18、Redis 底层,使用的什么协议

  • RESP,英文全称是 Redis Serialization Protocol,它是专门为 Redis 设计的一套序列化协议。这个协议其实在 Redis 1.2 版本时就已经出现了,但是到了 Redis 2.0 才最终成为 Redis 通讯协议的标准
  • RESP 主要有实现简单、解析速度快、可读性好等优点

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电商技术揭秘十五:数据挖掘与用户行为分析

相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xff1a;电商平台…

【接口自动化】参数化替换

在做接口测试时&#xff0c;除了测单个接口&#xff0c;还需要进行业务链路间的接口测试 比如[注册-登陆]需要token鉴权的业务流 当我们用使用postman/jmeter等工具时&#xff0c;将注册接口的一些响应信息提取出来&#xff0c;放到登陆接口的请求中&#xff0c;来完成某个业务…

Hadoop学习笔记

视频地址 简介 Hadoop是一个由Apache基金会所开发的分布式系统基础架构主要解决海量数据的存储和海量数据的分析计算问题 Hadoop组成 1. 架构 2. HDFS&#xff08;Hadoop Distributed FileSystem&#xff09; 简称HDFS&#xff0c;是一个分布式文件系统 2.1. 架构 2.1.1…

设计模式之创建型模式

创建型模式&#xff1a;创建对象的机制&#xff0c;从所需要实例化的对象中解耦。主要分成了五种设计模式&#xff0c;即工厂方法、抽象工厂、生成器、原型、单例。 文章目录 工厂方法抽象工厂生成器原型单例 工厂方法 问题&#xff1a;一个物流公司最初只使用卡车运输&#x…

刷题之Leetcode54题(超级详细)

54. 螺旋矩阵54. 螺旋矩阵 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/spiral-matrix/submissions/521329682/ 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入…

SEO优化艺术:精细化技巧揭示与搜索引擎推广全面战略解读

SEO&#xff08;搜索引擎优化&#xff0c;Search Engine Optimization&#xff09;是一种网络营销策略&#xff0c;旨在通过改进网站内外的各项元素&#xff0c;提升网站在搜索引擎自然搜索结果中的排名&#xff0c;从而吸引更多目标用户访问网站&#xff0c;增加流量&#xff…

《springcloud alibaba》 四 seata安装以及使用

目录 准备调整db配置准备创建数据库 seata配置nacos配置confi.txt下载向nacos推送配置的脚本 启动seata新建项目order-seata项目 订单项目数据库脚本pom.xmlapplication.yml启动类实体类dao类service类controller类feign类mapper类 stock-seata 库存项目数据库脚本pom.xmlappli…

第⑫讲:Ceph集群OSD扩缩容中Reblanceing数据的重分布

文章目录 1.Reblanceing数据重分布的概念2.验证Reblanceing触发的过程3.Reblanceing细节4.临时关闭Reblanceing机制 1.Reblanceing数据重分布的概念 当集群中OSD进行扩缩容操作后&#xff0c;会触发一个Reblanceing数据重分布的机制&#xff0c;简单的理解就是将扩缩容前后OSD…

AAC相关知识

一、AAC音频格式种类有哪些 AAC音频格式是一种由MPEG-4标准定义的有损音频压缩格式。AAC包含两种封装格式 ADIF&#xff08;Audio Data Interchange Format音频数据交换格式&#xff09;和ADTS&#xff08;Audio Data transport Stream音频数据传输流&#xff09;。 ADIF 特点…

RFID工业读写器步骤:只需4步,即可安装使用!

高频读写器在安装的时候需要先考察清楚安装环境&#xff0c;然后根据环境要求选定读写器&#xff0c;确定好对应的安装方式&#xff0c;以及安装位置。具体操作通常包括以下几个步骤&#xff1a; 1、了解安装环境 在安装之前&#xff0c;需要了解实际应用环境&#xff0c;根据环…

鸿蒙南向开发:制作【智能儿童手表】

样例简介 本项目是基于BearPi套件开发的智能儿童手表系统&#xff0c;该系统通过与GSM模块&#xff08;型号&#xff1a;SIM808&#xff09;的通信来实现通话和定位功能。 智能儿童手表系统可以通过云和手机建立连接&#xff0c;同步时间和获取天气信息&#xff0c;通过手机下…

智慧农场物联网系统:重塑农业的未来

随着科技的进步&#xff0c;物联网技术正在逐渐改变我们的生活。在农业领域&#xff0c;物联网系统也正在发挥着越来越重要的作用&#xff0c;为智慧农场的发展提供了新的可能。本文将深入探讨智慧农场物联网系统的优势、应用场景、技术实现以及未来发展趋势。 一、智慧农场物…

npm包安装与管理:深入解析命令行工具的全方位操作指南,涵盖脚本执行与包发布流程

npm&#xff0c;全称为Node Package Manager&#xff0c;是专为JavaScript生态系统设计的软件包管理系统&#xff0c;尤其与Node.js平台紧密关联。作为Node.js的默认包管理工具&#xff0c;npm为开发者提供了便捷的方式来安装、共享、分发和管理代码模块。 npm作为JavaScript世…

CKA 基础操作教程(五)

Kubernetes Ingress 理论学习 Ingress 提供从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源所定义的规则来控制。 Ingress 资源示例&#xff1a; apiVersion: networking.k8s.io/v1 # 指定 Kubernetes 中使用的 API 版本 kind: Ingress # 指定对象…

[dvwa] CSRF

CSRF 0x01 low 跨站&#xff0c;输入密码和确认密码直接写在url中&#xff0c;将连接分享给目标&#xff0c;点击后修改密码 社工方式让目标点击短链接 伪造404页&#xff0c;在图片中写路径为payload&#xff0c;目标载入网页自动请求构造链接&#xff0c;目标被攻击 http…

吴恩达深度学习笔记:深层神经网络(Deep Neural Networks)4.5-4.8

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第四周&#xff1a;深层神经网络(Deep Neural Networks)4.5 为什么使用深层表示&#xff1f;&#xff08;Why deep representations?&#xff09; 第一门课&#xff1a;神经网络和深度学习 (…

设计模式之观察者模式讲解

概念&#xff1a;定义对象间一种一对多的依赖关系&#xff0c;使得当每一个对象改变状态&#xff0c;则所有依赖于它的对象都会得到通知并被自动更新。 抽象主题&#xff1a;或者叫被观察者&#xff0c;可以持有、增加、删除观察者对象。具体主题&#xff1a;实现抽象主题定义的…

一部手机游全国|打造文旅云平台,开启智慧旅游新篇章

随着移动互联网的迅猛发展&#xff0c;旅游业在不断寻求创新与变革&#xff0c;旅游小程序作为智慧文旅的一个终端&#xff0c;在智慧推荐、智慧票务、智慧导览、智慧服务、虚拟体验等方面上&#xff0c;都具备发展潜力。小程序的出现&#xff0c;则从根本上大大提升了景区智慧…

如何快速开启一个项目-ApiHug - API design Copilot

ApiHug101-001开启篇 &#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin |…

数据库——实验6 视图的创建与使用

1. 视图的定义 视图是根据需要以一个表或多个表为基础&#xff0c;选择满足一定条件的行或列数据的静态定义。它是一种逻辑对象&#xff0c;是一种虚拟表。视图并不生成行或列的永久副本&#xff0c;并不占用存储空 间&#xff0c;也就是说&#xff0c;视图就是保存在数据库中…