简单聊一聊Redis的缓存是如何做到的

本文探讨了Redis作为缓存的工作原理,包括其基于内存的高速响应和两种缓存情况。Redis缓存分为只读和读写两种模式,分别适用于不同场景。在使用Redis做缓存时,应注意缓存命中和未命中的处理策略,以及数据一致性问题。

前言

基于Redis的高性能特性,我们将Redis用在缓存场景非常广泛。使用起来方便,响应也是远超关系型数据库。

但我们用Redis做缓存时,也要注意各种问题的应对和措施,比如缓存失效、数据一致性问题等。因此,用redis做缓存需要熟悉这一套逻辑的工作原理、异常处理等。

缓存的工作机制

缓存的特征

说到redis适合做缓存,我们第一时间能想到的原因就是Redis基于内存,响应快。这个是对的,我们结合计算机三个存储介质的速度来看:

  • CPU:响应速度20-40ns,存储空间1-32MB;

  • 内存:响应速度100ns,存储空间一般在16G-128GB之间;

  • 磁盘:响应速度3-5ms,存储空间可达到4TB。

这个对比显而易见,响应速度上cpu > 内存 > 磁盘,存储空间上cpu < 内存 < 磁盘。综合起来看,内存是最适合作为缓存的,因为速度快,而空间也相对来说较大。

在计算机中,缓存有这2种:

  • cpu中的缓存:这是用来缓存内存数据的;

  • 内存中的缓存:用来缓存磁盘中的数据。

最快的CPU,内存速度也不错,而磁盘是最慢的。如果我们要保证响应速度,就得避免即时从磁盘拉取数据了。

总结一下,缓存的特征就是响应快,避免每次从磁盘获取数据;缓存系统的空间容量比磁盘小,因此不能把所有数据都放缓存中。这也就是Redis作为缓存通常要配合存在磁盘的mysql工作的缘故。

Redis缓存的2种情况

我们用Redis做缓存时,业务数据通常在数据中(比如mysql)。当客户端要访问数据时,先从redis拉取缓存,这时就有2种情况了:

  • 数据在缓存上: 也就是缓存命中,此时直接将缓存结果返回。

  • 数据不在缓存上:也就是缓存未命中,这个时候就得从mysql来读取数据了,而响应速度自

### 关于 Redis 封装的编程讨论或教程 #### 使用 C# 和 StackExchange.Redis 实现 Redis 帮助类封装 为了提高开发效率并遵循面向对象设计原则,在实际项目中通常会对第三方库进行二次封装。对于 Redis 的操作也不例外,可以基于 `StackExchange.Redis` 库创建个通用的帮助类来简化常用命令的操作。 下面是简单的例子展示如何构建这样的帮助类: ```csharp public class RedisHelper { private readonly ConnectionMultiplexer _connection; public RedisHelper(string configuration) { _connection = ConnectionMultiplexer.Connect(configuration); } /// <summary> /// 设置缓存项 /// </summary> public void SetString(string key, string value, TimeSpan? expiry = null) { var db = _connection.GetDatabase(); db.StringSet(key, value, expiry); } } ``` 这段代码展示了基本的功能——连接到 Redis 服务器以及设置带有可选过期时间的数据[^1]。 #### Spring Boot 中集成 RedisTemplate 进行数据交互 在 Java 生态圈里,特别是采用 Spring Boot 框架的应用程序,可以通过注入 `RedisTemplate` 或者专门处理字符串类型的 `StringRedisTemplate` 来方便地访问 Redis 数据源。这种方式不仅限定了类型安全还提供了丰富的 API 支持各种复杂场景下的需求。 例如,要保存条记录至指定 Key 下面,则只需要调用如下方法即可完成相应工作: ```java @Resource private StringRedisTemplate stringRedisTemplate; // ... stringRedisTemplate.opsForValue().set("myKey", "HelloWorld"); ``` 这里利用了 Spring 提供的强依赖注入机制使得整个过程变得异常简洁明了[^2]。 #### 利用 Lua 脚本来增强 Redis 功能 除了直接使用原生指令外,还可以借助 Lua 编写的脚本进步提升性能和逻辑控制能力。由于 Lua 是种轻量级嵌入式的解释型语言,因此非常适合用来编写高效的业务规则处理器或者其他自定义功能模块。 考虑这样个案例:当需要确保某个商品库存数量减少的同时更新订单状态,并且这两个动作必须作为个整体不可分割地被执行时,就可以通过编写段 Lua Script 达成目的[^3]: ```lua if (tonumber(redis.call('GET', KEYS[1])) >= tonumber(ARGV[1])) then redis.call('DECRBY', KEYS[1], ARGV[1]) return true else return false end ``` 此段脚本实现了检查现有库存是否充足再决定是否允许购买行为的发生,从而保障了事务的致性。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值