写点什么

Redis 4.0 鲜为人知的功能将加速您的应用程序

  • 2019-12-09
  • 本文字数:1685 字

    阅读完需:约 6 分钟

Redis 4.0 鲜为人知的功能将加速您的应用程序

Redis 4.0 给 Redis 生态带来了一个惊人的功能:Modules(模块)。Modules 是 Redis 的一大转变,它是 Redis 内部自定义数据类型和全速计算的开放环境。但是,尽管对该版本的大多数关注都集中在 Modules 上,但新版本还引入了一个非常重要的命令,它就是游戏规则的改变者:UNLINK。


您可以使用 redis-cli 连接 redis-server 执行 info 命令,去查看当前 redis 版本中是否可以使用 UNLINK 命令。info 响应将告诉您有关服务器的所有信息。在第一部分(#Server)中,返回结果有一行值为 redis_version。如果该值大于 4.0,则可以使用 UNLINK 命令。并非所有 Redis 提供商都保持最新版本,因此最好在更改代码之前检查 redis 版本。


让我们回顾一下 Redis 的关键架构功能之一:“单线程”。Redis 在大多数情况下是一个单线程应用程序。它一次只做一件事,这样可以把这些事做的更快。多线程有点复杂,并且引入了锁和其他可能降低应用程序速度的问题。尽管 Redis(最高 4.0 版)通过多线程方式执行了少量操作,但它通常在启动另一个命令之前先要完成一个命令。


相比于快速读写,您可能会觉得使用 DEL 命令去删除一个键值不需要考虑太多,但是在很多情况下,删除数据同样很重要。与 Redis 中的大多数命令一样,DEL 命令在单个线程中运行,如果您获取一个几千字节的键值,花费不到一毫秒的时间,这是您所感知不到的。然而,当您获取的键值大小是兆字节、100 兆字节或者 500 兆字节会发生什么呢?哈希、排序、列表等数据结构会随着时间的推移而添加更多的数据进去,这样会生成一个数 GB 大小的数据集。然后用 DEL 命令去删除大 Key 时会发生什么呢?由于 Redis 是单线程操作的,处理这种请求时整个服务都处于等待中,需要等待该命令执行完成才能执行其它操作。同时,我们考虑更复杂的一种场景,这些键中保存的数据可能已经包含数以千万个微小请求,因此应用程序或操作员可能无法真正了解删除这些数据需要花费多长时间。


理智会告诉我们不要在拥有 100 万元素的排序集上运行如下这样的命令:


> ZRANGE some-zset 0 -1
复制代码


但是,在上面的 some-zset 集合中执行 DEL 命令将花费和上面一样的时间-中间没有传输开销,但是它会一直去分配内存,而且您会一直卡死在 CPU 繁忙中。在使用 UNLINK 之前,您可能会结合 SCAN 命令采用非原子性的方法进行一些少量删除,去避免这种持续分配内存的噩梦。上面无论使用哪种方式,都是让人无法接受的。


您可能已经猜到了,就是使用 UNLINK 命令来替换 DEL!从语法上讲,UNLINK 与 DEL 相同,但 UNLINK 提供了更为理想的解决方案。首先,它将键值从整个键值空间中删除。然后,在另一个线程中,它开始回收内存。从多线程的角度来看,这是一种安全的操作,因为它(在主线程中)从键空间中删除了该项,从而使 Redis 其它命令无法访问。


如果你有一个快速增长的键值-不管键值的大小如何,UNLINK 都是 O(1)操作(每个键;在主线程中)。使用 DEL 删除一个大值可能需要几百毫秒或更长时间,而 UNLINK 将在不到一毫秒的时间内完成(包括网络往返)。当然,您的服务器仍将需要花一些时间在另一个线程中重新分配该值的内存(其中的工作是 O(N),其中 N 是已删除值的分配数),但是主线程的性能不会被另一个线程中正在进行的操作严重影响到。


因此,您是否应该用 UNLINK 命令替换代码中的所有 DEL 命令?当然,在少数情况下,DEL 正是您所需要的。这里我可以想到两点:


1、 在 MULTI / EXEC 或 pipeline 中,在添加和删除大值时 DEL 命令是一种理想选择。在这种情况下,UNLINK 不会立即释放空间,并且在处理繁忙的情况下(如果内存已满),您可能会遇到麻烦。


2、 在更紧急的情况下,在无快速响应驱逐数据下您可以写入数据。


在没有极端内存限制的理想环境中,很难想到不使用 UNLINK 的情况。UNLINK 将提供更一致的行为,总体上具有更好的性能,并且代码更改非常小(如果可以在客户端中重命名命令,则无需更改)。如果 UNLINK 适合您的应用程序,请就此将您的 DEL 更改为 UNLINK,然后查看它的性能提高。


本文转载自公众号中间件小哥(ID:huawei_kevin)。


原文链接:


https://mp.weixin.qq.com/s/4odHzLpzMK0F0eQ7nFATGw


2019-12-09 16:453002

评论

发布
暂无评论
发现更多内容

产品经理的商业能力

punkboy

程序人生 产品经理 商业 商业模式 商业价值

[Redis] 你了解 Redis 的三种集群模式吗?

猴哥一一 cium

redis redis高可用 redis哨兵模式 群集安装

MySQL实战笔记-事务隔离和MVCC

shiziwen

MySQL 学习 事务隔离级别

架构学习历程

这些Java8官方挖的坑,你踩过几个?

牧码哥

Java 踩坑 加密 「Java 25周年」

Linux 自动化运维工具 ansible

杨仪军

Linux 运维自动化

深度解读 Flink 1.11:流批一体 Hive 数仓

Apache Flink

大数据 flink 流计算 实时计算

不想被下载限速,教你自建属于自己的云盘!

小傅哥

小傅哥 云服务 云盘 在线网盘

除了直接看余额,谁更有钱还能怎么比(三)

石君

零知识证明 多方计算 同态加密

机器学习算法评估指标——2D目标检测

做技术BP的文案Gou

匆忙的一周 ARTS第二周

困到清醒

游戏夜读 | 2020周记(5.24-5.31)

game1night

【求锤得锤的故事】Redis锁从面试连环炮聊到神仙打架。

why技术

redis 分布式锁 分布式系统

是公司养活了你,还是你养活了公司?

四猿外

生涯规划 程序员 个人成长

深入理解ContextClassLoader

Skye

深入理解JVM ContextClassLoader

搞定 HTTP 协议(一):HTTP 与网络基础

零和幺

技术 大前端 HTTP

【大厂面试01期】高并发场景下,如何保证缓存与数据库一致性?

NotFound9

Java MySQL 数据库 redis 后端

深入理解JVM类加载机制

Skye

类加载 深入理解JVM

深入理解ClassLoader

Skye

类加载 深入理解JVM ClassLoader

ARTS打卡 第2周

引花眠

ARTS 打卡计划

万字长文,助你吃透Eureka服务发现机制!

攀岩飞鱼

分布式 微服务 Eureka

iOS 动画 - 窗景篇(一)

柯烂

ios objective-c swift 移动应用 动画

关于区块链的“去中心化”,90% 的人都搞错了

CECBC

CECBC 区块链技术 去中心化 专制

赢的境界 - 双赢思维

石云升

创业 创业心态 双赢思维

CPU的性能,编译器是这样压榨的!

GPU

算法 cpu 编译器 程序语言

我的 Windows 利器

玄兴梦影

工具 Win

从技术到管理,我在极客时间的成长历程

邓建春

信息的表示与存储-整数的表示

引花眠

java的时间利器:joda

毛佳伟🐳

Java

坏的开始是成功的一半

escray

啪啪,打脸了!领导说:try-catch必须放在循环体外!

王磊

Java 性能优化 性能 java编程

Redis 4.0 鲜为人知的功能将加速您的应用程序_文化 & 方法_中间件小哥_InfoQ精选文章