标签: Redis

花小染 | 2024-06-11 | Redis后端相关

百度面试:如何用Redis实现限流?

高并发系统有三大特征:限流、缓存和熔断,所以限流已经成为当下系统开发中必备的功能了。那么,什么是限流?如何实现限流?使用 Redis 能不能实现限流?接下来我们一起来看。 1.什么是限流? 限流是指在各种应用场景中,通过技术和策略手段对数据流量、请求频率或资源消耗进行有计划的限制,以避免系统负载过高、性能下降甚至崩溃的情况发生。限流的目标在于维护系统的稳定性和可用性,并确保服务质量。 使用限流有以下几个好处: 1. 保护系统稳定性 :过多的并发请求可能导致服务器内存耗尽、CPU 使用率饱和,从而引发系统响应慢、无法正常服务的问题。 2. 防止资源滥用 :确保有限的服务资源被合理公平地分配给所有用户,防止个别用户或恶意程序过度消耗资源。 3. 优化用户体验 :对于网站和应用程序而言,如果任由高并发导致响应速度变慢,会影响所有用户的正常使用体验。 4. 保障安全 :在网络层面,限流有助于防范 DoS/DDoS 攻击,降低系统遭受恶意攻击的风险。 5. 运维成本控制 :合理的限流措施可以帮助企业减少不必要的硬件投入,节省运营成本。 ...

 271 |  0 |  0 Redis后端相关

晴天 | 2024-06-04 | Redis后端相关

Redis Pipelining 底层原理分析及实践

Redis是一种基于客户端-服务端模型以及请求/响应的TCP服务。在遇到批处理命令执行时,Redis提供了Pipelining(管道)来提升批处理性能。本文结合实践分析了Spring Boot框架下Redis的Lettuce客户端和Redisson客户端对Pipeline特性的支持原理,并针对实践过程中遇到的问题进行了分析,可以帮助开发者了解不同客户端对Pipeline支持原理及避免实际使用中出现问题。 一、前言 Redis 已经提供了像 mget 、mset 这种批量的命令,但是某些操作根本就不支持或没有批量的操作,从而与 Redis 高性能背道而驰。为此, Redis基于管道机制,提供Redis Pipeline新特性。Redis Pipeline是一种通过一次性发送多条命令并在执行完后一次性将结果返回,从而减少客户端与redis的通信次数来实现降低往返延时时间提升操作性能的技术。目前,Redis Pipeline是被很多个版本的Redis 客户端所支持的。 二、Pipeline 底层原理分析 2.1 Redis单个命令执行基本步骤 Redis是一种...

 197 |  0 |  0 Redis后端相关

蔡文姬 | 2024-05-27 | Redis后端相关

经典面试题:Redis 持久化有哪几种方式,怎么选?

前言 今天给大家分享一道经典面试题:Redis 持久化有哪几种方式,怎么选? AOF持久化 RDB持久化 AOF和RDB如何选择 1 AOF 持久化 Redis是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了两种持久化方式, RDB和AOF 。我们先来介绍 AOF 。 AOF(append only file) 持久化,采用日志的形式来记录每个写操作,追加到AOF文件的末尾。 Redis默认情况是不开启AOF的 。重启时再重新执行AOF文件中的命令来恢复数据。它主要解决数据持久化的实时性问题。 AOF是 执行完命令后才记录日志的 。为什么不先记录日志再执行命令呢?这是因为Redis在向AOF记录日志时,不会先对这些命令进行语法检查,如果先记录日志再执行命令,日志中可能记录了错误的命令,Redis使用日志回复数据时,可能会出错。 正是因为执行完命令后才记录日志,所以不会阻塞当前的写操作。但是会存在 两个风险 : 1. 更执行完命令还没记录日志时,宕机了会导致数据丢...

 175 |  0 |  0 Redis后端相关

石昊 | 2024-05-21 | Redis后端相关

把Redis当作队列来用,真的合适吗?

我经常听到很多人讨论,关于「把 Redis 当作队列来用是否合适」的问题。 有些人表示赞成,他们认为 Redis 很轻量,用作队列很方便。 也些人则反对,认为 Redis 会「丢」数据,最好还是用「专业」的队列中间件更稳妥。 究竟哪种方案更好呢? 这篇文章,我就和你聊一聊把 Redis 当作队列,究竟是否合适这个问题。 我会从简单到复杂,一步步带你梳理其中的细节,把这个问题真正的讲清楚。 看完这篇文章后,我希望你对这个问题你会有全新的认识。 在文章的最后,我还会告诉你关于「技术选型」的思路,文章有点长,希望你可以耐心读完。 从最简单的开始:List 队列 首先,我们先从最简单的场景开始讲起。 如果你的业务需求足够简单,想把 Redis 当作队列来使用,肯定最先想到的就是使用 List 这个数据类型。 因为 List 底层的实现就是一个「链表」,在头部和尾部操作元素,时间复杂度都是 O(1),这意味着它非常符合消息队列的...

 191 |  0 |  0 Redis后端相关

流苏 | 2024-05-17 | Redis后端相关

Redis的RESP协议真的这么简单?抓包分析

听说 Redis 协议很简单,那今天就抓个包来一起看看吧。 RESP 是什么 官网 Redis 的序列化协议, 是一种二进制协议,支持多种数据类型,其中,数据的第一个字节(First byte)决定其类型,使用( CRLF \r\n )作为协议的终止符。 特点:易于实现,快速解析,可直接阅读 目前有 RESP2 和 RESP3(Redis6开始) 两个版本。 支持这么多种类型 👇 | RESP data type | Minimal protocol version | Category | First byte | | --------------- | ----------------------- | -------- | --------- | | Simple strings | RESP2 | Simple | + |

 186 |  0 |  0 Redis后端相关

大牛猫 | 2024-05-14 | Redis后端相关

这些年背过的面试题:Redis 高可用篇

一、Redis 如何实现持久化? Chaya 转行做程序员,去大厂面试被面试官问到:“Redis 如何实现持久化?” Chaya 心想:“好家伙,我学了码哥的 Redis 高手心法,这不要起飞么,是时候展示真正的技术了。” Redis 有两个方式实现了数据持久化,他们分别是 RDB 快照和 AOF(Append Only File)。 RDB 内存快照是全量持久化,AOF 做增量持久化。 bgsave 指令会调用 glibc 的函数 fork 产生一个子进程用于写入临时 RDB 文件,快照持久化完全交给子进程来处理,完成后自动结束, 父进程可以继续处理客户端请求 ,阻塞只发生在 fork 阶段,时间很短,当子进程写完新的 RDB 文件后,它会替换旧的 RDB 文件。 RDB 文件实时性不够,宕机的时候可能会导致大量数据丢失。此外,fork 子进程属于重量级操作,执行成本比较高,频繁生成 RDB 文件,磁盘压力也...

 260 |  0 |  0 Redis后端相关

渣渣辉 | 2024-05-11 | Redis后端相关

Redis综述篇:与面试官彻夜长谈Redis缓存、持久化、淘汰机制、哨兵、集群底层原理!

一、Redis基本概念 • 面试官心理: 靠!手上活都没干完又叫我过来面试,这不耽误我事么,今儿又得加班补活了........咦,这小伙子简历不错啊,先考考它 Redis .......... • 面试官: 谈谈你对 Redis 的理解? • 我: Redis 是 ANSI C 语言编写的一个基于内存的高性能键值对( key-value )的 NoSQL 数据库,一般用于架设在Java程序与数据库之间用作缓存层,为了防止DB磁盘IO效率过低造成的请求阻塞、响应缓慢等问题,用来弥补DB与Java程序之间的性能差距,同时,也可以在DB吞吐跟不上系统并发量时,避免请求直接落入DB从而起到保护DB的作用。 • 而 Redis 一般除了缓存DB数据之外还可以利用它丰富的数据类型及指令来实现一些其他功能,比如:计数器、用户在线状态、排行榜、 session 存储等,同时 Redis 的性能也非常可观,通过官方给出的数据显示能够达到10w/s的QPS处理,但是在生产环境的实测结果大概读取QPS在7-9w/s,写入QPS在6-8w/s左右...

 178 |  0 |  0 Redis后端相关

OOM | 2024-05-06 | Spring 全家桶Redis后端相关

SpringBoot+Redis+定时任务模拟手机短信验证

说明 只是模拟给手机发送短信验证码,并且进行校验 真正能够给手机发送验证码短信还需要结合第三方,如阿里云、讯飞等 需求 发送手机号,返回验证码(6位随机数字) 每个手机号一天只能发送10次(为了测试方便,可以改成3次),每天0点重置次数 当天获取次数达到上限,提示“当天验证码获取次数已达上限,请明天再次使用” 每个验证码有效期为5分钟,获取验证码提示“【XX系统】您的手机验证码为:XXXXXX,有效期5分钟,此功能每天最多获取XX条,请勿向任何人出示,以免账号被盗” 5分钟内再次获取验证码提示“已有可用验证码,XX分XX秒内依然有效” 发送手机号和验证码,对手机号和验证码进行校验,返回验证结果 提示:“验证通过”或“验证失败,请确认手机号或验证码” 代码实现 1.依赖 <dependency     <groupId org.springframework.boot</groupId     <artifactId spring-boot-starter-data-redis</art

 273 |  0 |  0 Spring 全家桶Redis

晴天 | 2024-04-22 | Redis后端相关

Redis Stream 用做消息队列完美吗

Redis Stream 是 Redis 5.0 版本中引入的一种新的数据结构,用于实现消息传递的功能。 这篇文章,分享笔者学习 Redis Stream 的心得,希望对大家有所启发。 1 基础知识 Redis Stream 的结构如下图所示,它是一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容。 每个 Redis Stream 都有唯一的名称 ,对应唯一的 Redis Key 。 同一个 Stream 可以挂载多个 消费者组 ConsumerGroup , 消费组不能自动创建,需要 使用 XGROUP CREATE 命令创建 。 每个消费组会有个 游标 last_delivered_id ,任意一个消费者读取了消息...

 255 |  0 |  0 Redis后端相关

OOM | 2024-04-19 | Redis后端相关

Redis Stream 用做消息队列完美吗

Redis Stream 是 Redis 5.0 版本中引入的一种新的数据结构,用于实现消息传递的功能。 这篇文章,分享笔者学习 Redis Stream 的心得,希望对大家有所启发。 1 基础知识 Redis Stream 的结构如下图所示,它是一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容。 每个 Redis Stream 都有唯一的名称 ,对应唯一的 Redis Key 。 同一个 Stream 可以挂载多个 消费者组 ConsumerGroup , 消费组不能自动创建,需要 使用 XGROUP CREATE 命令创建 。 每个消费组会有个 游标 last_delivered_id ,任意一个消费者读取了消息...

 436 |  0 |  0 Redis后端相关

花小染 | 2024-03-25 | Redis后端相关

Redis缓存预热,该如何实现?

什么是缓存预热? 缓存预热是一种在程序启动或缓存失效之后,主动将热点数据加载到缓存中的策略。 这样,在实际请求到达程序时,热点数据已经存在于缓存中,从而减少了缓存穿透和缓存击穿的情况,也缓解了 SQL服务器 的压力。 实现 缓存抽象类 首先我们先来实现一个缓存抽象类,这个抽象类的作用就是在将来我们需要将某个模块的数据需要提前加载到缓存中的时候,我们可以创建一个它的实现类,来进行数据的缓存与加载,具体使用方式请看后边我写的例子。 public abstract class AbstractCache {     /        缓存       /     protected abstract void init();     /        获取缓存              @param <T        @return       /     public abstract <T  T get();     /        清理缓存       /     public abstract void clear

 305 |  0 |  0 Redis后端相关

布朗熊 | 2024-03-21 | Spring 全家桶Redis后端相关

SpringBoot+Redis自定义注解实现发布订阅

前言 最近开发了一个内部消息组件,逻辑大体是通过定义注解 @MessageHub ,在启动时扫描全部bean中有使用了该注解的方法后台创建一个常驻线程代理消费数据,当线程消费到数据就回写到对应加了注解的方法里。 @Slf4j @Service public class RedisConsumerDemo {     @MessageHub(topic = "${uptown.topic}", type = "REDIS_PUBSUB")     public void consumer(Object message) {         log.info("pubsub info {} ", message);     }    } 实现redis的队列、stream方式实现都很简单,唯独发布订阅方式,网上的demo全都是一个固定套路,通过redis容器注入监听器,而且回写非常死板。那么如何将这块的逻辑统一呢。 之前总结过消息组件的代码设计,这里贴一下链接: “https://juejin.cn/post/7204113113699729463

 311 |  0 |  0 Spring 全家桶Redis

花小染 | 2024-01-31 | Redis后端相关

说说Redis Hash实现原理?

1. 是什么 [Redis Hash]()(散列表)是一种 field-value pairs(键值对)集合类型,类似于 Python 中的字典、Java 中的 HashMap。一个 field 对应一个 value,你可以通过 field 在 O(1) 时间复杂度查 field 找关联的 field,也可以通过 field 来更新或者删除这个键值对。 Redis 的散列表 dict 由 数组 + 链表 构成,数组的每个元素占用的槽位叫做 哈希桶 ,当出现散列冲突的时候就会在这个桶下挂一个链表,用“ 拉链法”解决散列冲突的问题 。 简单地说就是将一个 key 经过散列计算均匀的映射到散列表上。 图 2-18 2. 修炼心法 Hash 数据类型底层存储数据结构实际上有两种。 1. dict 结构。 2. 在 7.0 版本之前使用 ziplist,之后被 listpack 代替。 通常情况下使用 di...

 462 |  0 |  0 Redis后端相关

大牛猫 | 2024-01-30 | Spring 全家桶Redis后端相关

字节二面:Spring Boot Redis 可重入分布式锁实现原理?

书接上回,码哥上一篇[《纠正误区:这才是 SpringBoot Redis 分布式锁的正确实现方式》](https://www.developers.pub/article/1280668)分享了分布式锁如何从错误到残缺,再到青铜版本的高性能 Redis 分布式锁代码实战,让你一飞冲天。 这是我们最常用的分布式锁方案,今天码哥给你来一个进阶。 [Chaya]():「码哥,上次的分布式锁版本虽然好,但是不支持可重入获取锁,还差一点点意思。」 Chaya 别急,今日码哥给你带来一个高性能可重入 Redis 分布式锁解决方案,直捣黄龙,一笑破苍穹。 什么是可重入锁 当一个线程执行一段代码成功获取锁之后,继续执行时,又遇到加锁的代码,可重入性就就保证线程能继续执行,而不可重入就是需要等待锁释放之后,再次获取锁成功,才能继续往下执行。 public synchronized void a() {     b(); } public synchronized void b() {     // doWork } 假设 X 线程在 a 方法获取锁之后,继续执行

 544 |  0 |  0 Spring 全家桶Redis

大牛猫 | 2024-01-30 | Spring 全家桶Redis后端相关

纠正误区:这才是 SpringBoot Redis 分布式锁的正确实现方式

在说分布式锁之前,我们先说下为什么需要分布式锁。 在单机部署的时候,我们可以使用 Java 中提供的 JUC 锁机制避免多线程同时操作一个共享变量产生的安全问题。JUC 锁机制只能保证同一个 JVM 进程中的同一时刻只有一个线程操作共享资源。 一个应用部署多个节点,多个进程如果要修改同一个共享资源,为了避免操作乱序导致的并发安全问题,这个时候就需要引入分布式锁, 分布式锁就是用来控制同一时刻,只有一个 JVM 进程中的一个线程可以访问被保护的资源。 分布式锁很重要,然而很多公司的系统可能还在跑着有缺陷的分布式锁方案,其中不乏一些大型公司。 所以,码哥今天分享一个正确 Redis 分布式锁代码实战,让你一飞冲天,该代码可直接用于生产,不是简单的 demo。 温馨提示:如果你只想看代码实战部分,可直接翻到 SpringBoot 实战章节。 错误的分布式锁 说正确方案之前,先来一个错误的,知道错在哪,才能意识到如何写正确。 在银行工作的小白老师,使用 Redis SET 指令实现加锁, 指令满足了当 key 不存在则设置 value,同时设置超...

 348 |  0 |  0 Spring 全家桶Redis