Redis 的 Red Lock 是什么?你了解吗?回答重点Red Lock,又称为红锁,是一种分布式锁的实现方案,旨在解决在分布式环境中使用 Redis 实现分布式锁时的安全性问题。
一般情况下,我们在生产环境会使用主从+哨兵方式来部署 Redis。
如果我们正在使用 redis 分布式锁,此时发生了主从切换,但从节点上不一定已经同步了主节点的锁信息。
所以新的主节点上可能没有锁的信息。此...
Redis 中如何保证缓存与数据库的数据一致性?回答重点缓存和数据库的同步可以通过以下几种方式:
1)先更新缓存,再更新数据库
2)先更新数据库存,再更新缓存
3)先删除缓存,再更新数据库,后续等查询把数据库的数据回种到缓存中
4)先更新数据库,再删除缓存,后续等查询把数据库的数据回种到缓存中
5)缓存双删策略。更新数据库之前,删除一次缓存;更新完数据库后,再进行一次延迟删除
6)使用 Bi...
Redis 中的缓存击穿、缓存穿透和缓存雪崩是什么?回答重点缓存击穿:指某个热点数据在缓存中失效,导致大量请求直接访问数据库。此时,由于瞬间的高并发,可能导致数据库崩溃。
缓存穿透:指查询一个不存在的数据,缓存中没有相应的记录,每次请求都会去数据库查询,造成数据库负担加重。
缓存雪崩:指多个缓存数据在同一时间过期,导致大量请求同时访问数据库,从而造成数据库瞬间负载激增。
解决方案缓存击穿:
...
如何使用 Redis 快速实现排行榜?回答重点使用 Redis 实现排行榜的方式主要利用 Sorted Set(有序集合),它可以高效地存储、更新、以及获取排名数据。
实现排行榜的主要步骤:
1)使用 Sorted Set 存储分数和成员
使用 Redis 的 ZADD 命令,将用户和对应的分数添加到有序集合中。例如:ZADD leaderboard 1000 user1,将用户 user...
Redis String 类型的底层实现是什么?(SDS)回答重点Redis 中的 String 类型底层实现主要基于 SDS(Simple Dynamic String 简单动态字符串)结构,并结合 int、embstr、raw 等不同的编码方式进行优化存储。
扩展知识C 语言字符串的缺陷Redis 为什么没有使用 C 标准库提供的字符串,而是实现了一种动态字符串?因为 C 语言的字符串本...
如何使用 Redis 统计大量用户唯一访问量(UV)?回答重点Redis 中 HyperLogLog 结构,可以快速实现网页 UV 、PV 等统计场景。它是一种基数估算算法的概率性数据结构,可以用极少的内存统计海量用户唯一访问量的近似值。
Set 也可以实现,用于精确统计唯一用户访问量,但是但当用户数非常大时,内存开销较高。
扩展知识HyperLogLog 使用介绍HyperLogLog...
如何使用 Redis 快速实现布隆过滤器?回答重点
布隆过滤器是一种高效的概率数据结构,常用于检测一个元素是否在一个集合中,可以有效减少数据库的查询次数,解决缓存穿透等问题。
可以通过使用 位图(Bitmap) 或使用 Redis 模块 RedisBloom。
1)使用位图实现布隆过滤器:
使用 Redis 的位图结构 SETBIT 和 GETBIT 操作来实现布隆过滤器。位图本质上是一...
你在项目中使用的 Redis 客户端是什么?回答重点常见在项目中使用的客户端有以下三种:
Jedis 适用于简单的同步操作和单线程环境。
Lettuce 适用于高并发、高性能和多线程环境,尤其是需要异步和响应式编程的场景。
Redisson 适用于复杂的分布式系统,提供丰富的分布式对象和服务,简化开发。
JedisJedis 是一款比较经典的 Java 客户端了,里面提供了比较全面的 R...
Redis 中的 Geo 数据结构是什么?回答重点Redis 中的 Geo(Geolocation 的简写形式,代表地理坐标) 数据结构主要用于地理位置信息的存储。通过这个结构,可以方便地进行地理位置的存储、检索、以及计算地理距离等操作。Geo 数据结构底层使用了 Sorted Set,并且结合了 Geohash 编码算法来对地理位置进行处理。
它是 Redis 2.2 版本后新增的数据类...
Redis 字符串类型的最大值大小是多少?回答重点Redis 字符串能存储的最大容量是 512 MB 的数据,可以查看官方文档:
无论是网络传输、内存分配还是字符串操作,大字符串都会增加 Redis 服务器的负载。
且过大的字符串在 GET、SET、APPEND、STRLEN 等操作都会导致性能瓶颈。
所以官方给字符串的大小做了限制,防止单个键值对占用过多的内存,影响整体性能和稳定性。
...
Redis 中 EMBSTR 对象的阈值设置为何为 44?其调整历史是什么?为什么 EMBSTR 的阈值大小是 44 个字节?这个问题有几个关键点:
1)Redis 使用的是 jemalloc 作为内存分配器。
2)jemalloc 是以 64 字节作为内存单位进行内存分配的,如果超过了 64 字节,即超过了一个内存单元,使用的就是 raw 编码,反之使用的就是 EMBSTR 编码。
3)核...
Redis 性能瓶颈时如何处理?回答重点如果 Redis 无法承受当前的负载的话,可以考虑从以下几个解决方法去解决:
首先想到的是扩容,比如增加 Redis 的配置,容纳更多的内存等。
如果超过单机配置了,那么可以上 redis 主从,通过从服务分担读取数据的压力,利用哨兵自动进行故障转移。
还可以利用 redis 集群进行数据分片,比如 Redis Cluster。
也可以增加本地内存,通...
Redis 主从复制的常见拓扑结构有哪些?回答重点Redis 主从的几种常见拓扑结构如下(忽略哨兵):
1)一主多从:
这是最基本的拓扑结构,包含一个主节点和多个从节点。所有写操作都在主节点上执行,而读操作可以在从节点上进行,以提高读取速度和负载均衡。
2)树状主从结构(级联):
从节点也可以作为其他从节点的主节点。这样形成了一个层次结构,主节点负责写操作,而从节点负责读操作,并将...
Redis 中原生批处理命令(MSET、MGET)与 Pipeline 的区别是什么?回答重点原生批处理命令(MSET、MGET) 和 Pipeline 都可以用于一次性处理多个命令,但它们在实现方式和应用场景上有所不同:
1)MSET / MGET(原生批处理命令):
MSET 和 MGET 是 Redis 提供的原生批处理命令,用于批量设置和获取多个键值。
它们是 单个命令,...
如何在 Redis 中实现队列和栈数据结构?回答重点可以通过 List 类型 来实现 队列 和 栈 :
实现队列(FIFO):
队列是一种 先进先出(FIFO) 的数据结构。在 Redis 中,可以使用 LPUSH 和 RPOP 命令组合来实现队列。
LPUSH 向列表的左侧推入元素,而 RPOP 从列表的右侧弹出元素,这样可以保证最先进入的元素最先被弹出。
实现栈(LIFO):
栈是...
Redis 事务与关系型数据库事务的主要区别是什么?回答重点Redis 的事务跟严格意义上的关系型数据库事务不一样,先复习下数据库事务 ACID 的定义:
原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败,且可以回滚到事务开始前的状态。
一致性(Consistency):事务执行前后,数据库必须保持一致的状态。
隔离性(Isolation):事务的执行是隔离的,事务...
Redis 中的 Ziplist 和 Quicklist 数据结构的特点是什么?回答重点Ziplist:
简单、紧凑、连续存储,适用于小数据量场景,但对大量数据或频繁的修改操作不太友好。
适合小数据量场景,例如短列表、小哈希表等,因为它的内存紧凑,可以大幅减少内存使用
Quicklist:
通过将链表和 Ziplist 结合,既实现了链表的灵活操作,又能节省内存,在 Redis 3.2...
Redis 复制延迟的常见原因有哪些?回答重点
Redis 的复制延迟是指从节点同步主节点数据时可能出现时间延迟。在读写分离场景,这个延迟会导致明明写入了数据,但是去从节点查的时候没查到。
可能原因如下:
1)网络原因
可能是带宽不足,或者网络抖动导致同步的延迟。
不过一般内网情况下不会产生这个问题。
2)主节点负载过高
主节点接收到大量的写操作,在处理客户端请求的同时,还需向从节点发送复...
Redis Cluster 模式与 Sentinel 模式的区别是什么?回答重点1)Redis Cluster 是 Redis 集群,提供自动分片功能,将数据自动分布在多个节点上,支持自动故障转移。如果一个节点失败,集群会自动重新配置和平衡,不需要外部介入,因为它内置了哨兵逻辑。
2)Sentinel 是哨兵,主要用于管理多个 Redis 服务器实例来提高数据的高可用性。当主节点宕机,哨兵会...
Redis 的 ListPack 数据结构是什么?回答重点ListPack 是 Redis 内部的一种数据结构,用于高效存储短小的字符串或整数集合。它是一种紧凑型的序列化数据结构,旨在减少内存占用和提升性能。为了尽可能紧凑地存储数据,因此它没有使用 Redis 常见的对象模型,而是直接以字节序列的形式存储数据。
ListPack 是 Redis 6.0 引入的新数据类型,在 List、Has...
Redis 中的内存碎片化是什么?如何进行优化?回答重点Redis 的内存碎片化是指内存使用中出现小块空间被闲置,无法被有效利用的现象。
Redis 默认使用 jemalloc 作为内存分配器,它是按照固定大小来分配内存的,比如实际需要 8kb 的内存,分配器给了 12kb。
那么多余的 4kb 其实就无法被利用上了,它就叫内存碎片。
且频繁创建和删除大量数据的时候,会导致内存块大小和位置...
在 Redis 集群中,如何根据键定位到对应的节点?回答重点Redis 集群将数据分布到 16384 个哈希槽(slots) 中,每个键通过哈希函数计算出一个槽位编号,然后根据槽位编号定位到具体的节点,具体是使用 CRC16 哈希函数计算键的哈希值,然后对 16384 取模,得到哈希槽编号(范围是 0 到 16383)。
扩展知识Redis 集群节点的通信Redis 集群节点在一开始的时候,...
Redis 的虚拟内存(VM)机制是什么?回答重点Redis 的 VM 机制(Virtual Memory)曾经是 Redis 早期版本(2.0 之前)的一部分,用于将部分数据存储在磁盘上,以扩展内存数据库的容量。当内存不足时,Redis 会将冷数据(不经常访问的数据)移到磁盘,并将热数据(经常访问的数据)保留在内存中。
通过这种方式,Redis 可以处理比实际物理内存更多的数据。
虽然能使...
两百万个生产者发送消息,仅一个消费者,如何高效设计锁?重点回答1)使用无锁数据结构:可以使用无锁的并发队列,如Java的ConcurrentLinkedQueue,它采用了非阻塞算法,避免了加锁的开销。这样,多个生产者可以并发地将消息添加到队列中,而消费者可以从队列中安全地读取消息。
2)批量操作:生产者可以批量发送消息,减少锁竞争的频率。例如,一个生产者可以先在本地缓存一批消息,然后一次性...
Java 写入文件到磁盘会经历哪些过程?重点回答这个问题虽然主要考察对操作系统缓存、文件系统和磁盘的理解,不过最好在开头再提一下 Java 中的操作,表现出从应用层到底层 DMA 的全方位理解。
第一步:写入文件缓冲区为了提高效率,写入文件都会利用缓冲区,即当写入数据时,数据先被存储到缓冲区,而不是直接写入磁盘。缓冲区的目的是减少磁盘 IO 操作的次数,提高性能。
一般用的是 Buffer...
如何在附近 100w 的商户中,快速找到离你最近的 5 家商户?回答重点可以使用 MySQL 或 MongoDB 的空间索引,或者使用 Redis 提供的 Geo 数据结构来存储商户位置的位置信息来实现根据距离的快速查找。
使用空间索引例如 R-tree,它适用于二维空间的树形数据结构,能够高效地进行范围查询和最近邻查询。将商户位置(经纬度)数据按照地理区域组织成树结构,可以快速找到位于用户...
项目上有个导出 excel 场景发现很慢,怎么优化?回答重点1)先定位慢在哪儿?需要定位导出 excel 慢在哪里:
业务逻辑慢?
数据库查询慢?
excel 生成慢?
2)针对性解决慢的问题如果是业务逻辑处理很慢,则需要优化调整逻辑,比如将一些在循环内的多次 RPC 调用,变成一次(或更少)的批量 RPC 调用。
如果是数据库查询慢,则查看 SQL 是都命中索引,是否有额外的排序逻辑等...
线上发现 Redis 机器爆了,如何优化?回答重点1)首先需要排查并确定根因通过监控工具(如Prometheus、Grafana等或云上自带的一些监控)查看 Redis 的 CPU、内存、命令执行时间或带宽等指标,确定瓶颈所在。
2)依据根因针对性解决问题如果是内存耗尽,可能需要增加机器的内存量(升配),即临时升配解决线上问题后。
后续再走查代码和了解相关业务,判断有些数据是否有必要都存...
项目上需要导入一个几百万数据 excel 文件到数据库中,有哪些注意点?回答重点对于百万数据的导入,一般需要关注三类问题:
1)内存,如果一次性在堆内加载过多的数据,可能会导致内存溢出。2)时间,百万数据插入数据库需要一定的时间,同步调用可能会使得方法超时。3)异常,百万数据中可能会有很多异常的情况,比如格式错误、重复数据等等。
内存是有限的,不能一次性将 excel 内的所有数据都加载到内...
如果一笔订单,用户在微信和支付宝同时支付,会怎么样?回答重点微信和支付宝都会支付成功,因为支付渠道是第三方系统,它们之间的数据是不相通的,因此无法阻止用户付款。
这样一来同一笔订单,用户就会多付了一笔钱,如何避免这个情况?
思路其实很清晰,不管是支付宝支付还是微信支付,用户支付后三方都会进行回调,这个回调处理逻辑在我们的系统中,因此我们可以在这里控制。
支付单都会有状态机,例如从支付中...