Redis进阶使用

一、在日常工作中,使用Redis有什么需要注意的?

  • 设置合适的过期时间。
  • 尽量避免大key问题,避免用字符串存储过大的数据;避免集合的数据量太大,要定期清除。

二、常用的数据结构有哪些?用在什么地方?

按照使用的频率排序。

  • 字符串类型,用作常规的缓存,比如缓存token;存储点赞数、库存等需要增减的数字类型,自带自增自减API。
  • zset类型,支持去重和排序,可以用来实现排行榜,使用热度作为分数值,每次插入数据的时候记得删除排行榜之外的数据,还可以随机获取数据。
  • 哈希类型,对于符合对象结构类型的数据,可以考虑使用哈希类型存储。例如一个班有多个学生。可以用班级id作为哈希的key,使用学员id作为键,存储学生信息JSON数据。
  • set类型,需要去重又不需要排序的时候可以使用set结构,并且set还支持查询集合的交集、并集、差集;可以用来做用户推荐。
  • list类型,存储集合数据,支持随机取值。

三、如何保证数据库和缓存的一致性?

首先明确一点,使用了缓存了,就基本会存在延迟,因此在能接受一点延迟的情况下才使用缓存。
需要保持数据库和缓存一致性的数据都会设置合适的过期时间,这个过期时间是保持一致性兜底。

更新缓存方案

该方案就是在数据更新完成之后就去更新缓存。如果事务尚未提交就更新,可能事务回滚了导致缓存和数据库不一致。事务提交之后更新缓存失败,也会导致缓存和数据库不一致。
有一个比较严重的问题,如果两个线程并发更新,实际数据库更新是先更新A再更新B,结果缓存却先执行了B再执行A,这样就会导致缓存和数据库不一致。
但也有优势,特别是现在很多项目的数据库都采用主从架构,主动更新可以直接拿到最新的数据。

删除缓存方案

该方案就是在数据更新完成之后就去删除缓存。下次查询的时候检测到没有缓存就会去数据库查缓存。
存在缓存删除失败问题。还有一个更致命的问题,因为更新缓存的时候一般查的是从库,有可能主从同步尚未完成就将旧值更新到了缓存导致缓存和数据库不一致。

延时双删方案

该方案是基于上述的方案的改进版,先删除缓存,延时之后再删除一次。这样可以防止第一次删除失败,也可以防止主从同步完成之前将旧值更新到缓存。
但也会引入新的问题,延时时间难以精准控制。不同数据库的主从复制时间差不同。
并且延时需要引入新的中间件,增加了不确定性,可能中间件故障导致消息丢失而第二次删除失败。
容易引发缓存击穿,两次删除缓存会导致大量请求进入数据库。

实际企业开发中使用较少。

订阅binlog方案

通过订阅binlog来更新缓存,该方案可以确保更新的是最新变更的数据。大厂一般用该方案。
通过监听binlog的变化来异步更新缓存,该方案防止了读取到旧数据的问题。

分布式锁+版本号方案

该方式通过对比版本号来防止更新到旧数据。在数据库存储数据的版本号,并且在缓存缓存数据的版本号。在更新的时候加分布式锁防止并发更新,查询缓存中的版本号和查到的数据的版本号进行对比,如果缓存的版本号小于数据库的版本号则更新吗,这样也可以防止更新旧数据到缓存。

四、Pipeline技术

Redis支持管道技术,可以将批量的命令通过管道执行。实际上就是类似于命令的批量操作,只需要建立一次连接一次性将命令都发送到服务端执行,通过减少网络通信次数来提升速度。
在需要批量执行Redis命令的场景下性能提升显著。
但需要注意,该操作只是批量处理,只能保证在redis按照顺序执行,但中间可能穿插其他的命令,整个批量操作也不具备原子性。如果一批redis命令中间不允许穿插其他redis命令,还是要使用lua脚本或者redis事务。

五、什么是Redis的大key问题?

Redis的大key问题本质上是Redis的key对应的值太大了,比如字符串类型的值到了5M或者集合类型数量集合内元素量达到了5000.

大key问题有什么影响?

  • 内存占用高,容易引发OOM;
  • 大key数据操作延迟高,像持久化、迁移等;
  • 读取的大key时候会阻塞其他操作。

出现Redis大key问题该如何处理?

处理Redis大key问题可以分成两部分,一部分是处理已经产生的大key,一部分是预防。
对于已经产生的大key,首先可以通过一些工具来找出这些大key,比如使用redis-cli --bigkeys结合MEMORY USAGE key可以查看某个key对应的值的大小。

  • 拆分大key,将大key的值拆分来降低单个值的大小。字符串类型可以通过固定_后缀拆分成子key存储,哈希类型可以按照字段哈希进行分片,集合类型可以按照数量进行分片。
  • 拆分之后的值可能还是大,可以存储值之前使用压缩算法压缩值,进一步降低值的大小。
  • 采用异步删除来删除key,这样可以防止阻塞,采用unlink,不要采用del。
  • 设置合适的过期时间,特别是临时性大key
  • 针对集合类型的数据结构,记得要清除无用数据,避免集合越来越大。

预防方面,在设计初期就预测key的大小,如果可能发展成大key的键,在设计上可以直接采用上述设计。

### Redis 的高级用法和特性 #### 1. 使用带有自动补全和语法高亮的交互式 CLI 为了更高效地管理和操作 Redis 数据库,可以采用具备自动完成命令以及提供语法高亮特性的客户端工具。这种增强型CLI能够显著提升用户体验,在执行复杂查询时尤为有用[^1]。 ```bash # 安装并运行支持自动完成与语法高亮特性的Redis CLI pip install interactive-redis-cli interactive_redis_cli ``` #### 2. 启用多种持久化机制保障数据安全 通过配置 `redis.conf` 文件中的设置项来激活 RDB (快照) 和 AOF (追加仅文件) 这两种不同的持久化策略。这有助于防止意外断电或其他异常情况造成的数据丢失风险。当容器启动时指定挂载外部卷用于存储这些持久化的数据库副本,从而实现跨重启后的状态保持[^2]。 ```dockerfile # Docker Compose 或者直接使用Docker指令启动带持久化的Redis实例 docker run --name redis \ -v /local/path/to/data:/data \ -v /local/path/to/conf/redis.conf:/usr/local/etc/redis/redis.conf \ -p 6379:6379 -d redis \ redis-server /usr/local/etc/redis/redis.conf ``` #### 3. 创建受限账户提高安全性 对于生产环境下的 Redis 实例来说,创建一个专门的服务账号是非常重要的一步。该账号不具备 shell 访问权限,并且其家目录也被移除以减少潜在的安全威胁。此外还将 Redis 可执行程序及其工作路径赋予此特定用户组所有权,确保只有授权人员才能对其进行修改或访问[^3]。 ```bash # 添加不具Shell登录能力也不拥有Home Directory的新用户 sudo useradd -M -s /sbin/nologin redis # 更改Redis安装目录所属权给新建立的用户 chown -R redis:redis /path/to/installation/ ``` #### 4. 构建分布式集群架构扩展性能 随着业务增长带来的负载压力增大,单机版 Redis 很难满足需求。此时可以通过构建多节点组成的集群模式来进行横向扩容。每个节点负责处理一部分键空间内的读写请求,而整个系统的吞吐量则取决于所有成员共同协作的结果。在实际部署过程中需注意各服务器间网络连接质量及延迟等因素的影响[^4]。 ```bash # 分别于不同主机上依次启动多个Redis服务端进程作为集群组成部分之一 /usr/local/redis/src/redis-server /etc/redis/node-01.conf /usr/local/redis/src/redis-server /etc/redis/node-02.conf ... ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值