使用redis pipeline提升性能

这篇具有很好参考价值的文章主要介绍了使用redis pipeline提升性能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本篇来介绍一下redis pipeline,主要是由于最近一次在帮开发同学review代码的时候,发现对redis有个循环操作可以优化。场景大概是这样的,根据某个uid要从redis查询一批数据,每次大概1000个key左右,如果查得到就返回,否则查db,然后写回缓存。由于每次要查的key比较多,虽然redis单次查询很快,但如果key很多,每次查询redis都需要读写socket,与client间的网络数据传输,都需要消耗时间,累加起来也会变得非常慢。开发同学决定使用批量的方式,例如每次操作100个key,使用RedisTemplate批量查询代码如下:

redisTemplate.opsForValue().multiGet(keys);

如果查询到的是null,则表示缓存不存在或过期,则查询数据库,再批量写回redis,伪代码如下:

for (Long id : list) {
    operations.opsForValue().set("key", id, 30, TimeUnit.MINUTES);
}

他并没有使用批量的方式,如果有100个,这里就需要执行100次set命令,经过了解后原因是批量写入并不能设置过期时间,我们看它的api确实只能设置key-value,但没有过期时间也是不行的。

void multiSet(Map<? extends K, ? extends V> map);

单个循环设置肯定不行,除了自己执行方法会比较慢,影响用户体验,可能导致接口超时外,由于redis是单线程执行命令的,还会影响其它命令的执行,所以必须优化。
优化的方式就是本篇要介绍的:pipeline。

pipeline

pipeline是管道的意思,它最主要的作用就是降低RRT(client-server数据传输往返时间)。在请求-响应过程,除了传递我们的数据,还需要协议信息,例如http协议的请求头,响应头,这些信息也会增加传输时间。举个例子,假设一次RRT是10ms,那么执行10条命令,就需要100ms,如果我们将其打包到一起执行,RRT就还是10ms(虽然传输的数据变多了,但协议本身的信息没有变多,基本可以忽略不计),传输效率提升了10倍。除此之外,redis server每次处理命令都需要对Socket进行IO操作,这涉及到用户态、内核态的切换,如果批量进行处理,对性能的提升也很有帮助。
pineline将一批命令打包一起执行,但不保证他们的原子性,不像事务一样可以保证一起成功或失败,可能前面的命令执行成功了,后面的执行失败。
这和我们平时操作数据库的思想是一样的,单个查询转换为批量查询,单个插入转换为批量插入,同样需要注意是,批量虽好,但不能一次过多,否则处理起来比较久,反而得不偿失。
更多的知识可参考官方文档:https://redis.io/docs/manual/pipelining/

我们使用springboot 2.x版本,使用spring-boot-starter-data-redis,它给我们默认集成的redis client是lettuce。在使用一个不熟悉或比较新的东西的时候,本人有一个习惯,会先google一下,例如:“RedisTemplate pipeline 注意事项”,“RedisTemplate pipeline 坑”,看看有没有前人踩过坑,借鉴一下。这次也一样,google之后果然发现有点坑,例如这篇提到的Spring Data Redis与Lettuce使用pipeline时,实际命令并不是一起执行的,有时是单条执行,有时是合并几条执行。
使用redis pipeline提升性能

我们自己写下测试代码如下:

redisTemplate.executePipelined(new SessionCallback<Object>() {

	@Override
	public Object execute(RedisOperations operations) throws DataAccessException {
		for (int i = 0; i < 100; i++) {
			operations.opsForValue().set("testPipeline2" + i, i, 1, TimeUnit.MINUTES);
		}
		return null;
	}
});

在set位置打个断点,然后到redis server使用monitor命令观察,看命令到底是不是一条一条给过来的。monitor命令会将server执行的命令都打印出来,生产环境慎用。
按照上面的分析,正常情况下这些命令应该是一起发送到server端一起执行的,不会断断续续,但实际我们观察确实不是一起给过来,断断续续的,如下:
使用redis pipeline提升性能

我们把lettuce替换成jedis看看。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
	<exclusions>
		<exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
	</exclusions>
</dependency>
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
</dependency>

还是执行上面的代码,打断点,使用jedis可以观察到,每次循环monitor都不会观察到有命令执行,直到最后才一批给过来。
使用redis pipeline提升性能

但我们不想直接替换lettuce为jedis,一个是它是spring boot默认集成的,拥有更好的性能,二是替换后不知道其它功能有没有影响,那怎么办呢?
我们项目还使用redission分布式锁,其实redission也是一个redis client,理论上它应该实现所有client的功能,pipeline自然也有实现。
我们使用redission如下:

RBatch batch = redissonClient.createBatch();
for (int i = 0; i < 100; i++) {
	batch.getBucket("testBatch" + i).setAsync(i, 1, TimeUnit.MINUTES);
}
batch.execute();

这次我们把断点打在execute位置,看看是不是execute时才一起提交到server执行,答案显然是的。
使用redis pipeline提升性能

接下来我们简单测试一下性能差距,分别是单个请求,使用lettuce,使用jedis,使用redission,执行10000次,耗时如下:
单个请求:73029ms
lettuce: 712ms
jedis: 413ms
redission: 341ms

lettuce出乎意料执行还是很快,就想上面提到的,它有时还是会部分打包一起执行,但终究不是一次执行,有兴趣的可以深入了解一下。

更多分享,欢迎关注我的github:https://github.com/jmilktea/jtea文章来源地址https://www.toymoban.com/news/detail-661520.html

到了这里,关于使用redis pipeline提升性能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 扩散模型Diffusers Pipeline API使用介绍

    大部分扩散模型包含多个独立训练的子模型和组件模块组合而成,例如StableDiffusion 有: 3个独立训练的子模型:Autoencoder、 Conditional Unet、CLIP text encoder 调度器组件scheduler, CLIPImageProcessor, safety checker. 为了让开发者以最简单的方式使用最新最先进的扩散模型, diffusers 开发了

    2024年02月08日
    浏览(68)
  • springboot+redis+mysql+quartz-使用pipeline+lua技术将缓存数据定时更新到数据库

    代码讲解:7.3点赞功能-定时持久化到数据库-Java程序整合pipeline+lua_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1Lg4y1w7U9 代码: blogLike_schedule/like08 · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com) https://gitee.com/flowers-bloom-is-the-sea/XinQiUtilsOrDemo/tree/master/blogLike_schedule/like08 数据库表:

    2024年02月13日
    浏览(40)
  • springboot+redis+mysql+quartz-通过Java操作jedis使用pipeline获取缓存数据定时更新数据库

    代码讲解:6-点赞功能-定时持久化到数据库-pipeline+lua-优化pipeline_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1yP411C7dr 代码: blogLike_schedule/like06 · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com) https://gitee.com/flowers-bloom-is-the-sea/XinQiUtilsOrDemo/tree/master/blogLike_schedule/like06 数据库表的

    2024年02月16日
    浏览(43)
  • 如何提升SOLIDWORKS内存使用性能

    在使用SolidWorks处理大型装配体或是进行复杂模型的设计验证分析时,如果电脑配置比较低就会出现内存不足的提示。在碰到这样的情况时,假如由于具体条件的限制无法快速实现更换电脑配置的操作,如何在电脑硬件不变的提升SolidWorks 内存使用性能,就是大家比较关心的问

    2024年02月05日
    浏览(52)
  • 【WPF】使用 WriteableBitmap 提升 Image 性能

    由于中所周不知的原因,WPF 中想要快速的更新图像的显示速率一直以来都是一大难题。在本文中,我将分享一些我对于 WPF 领域的经验和见解。虽然我并不是这方面的专家,但是希望通过我的分享,能够为大家提供一些有用的信息和思考角度。 WriteableBitmap 继承至 System.Windo

    2024年01月24日
    浏览(56)
  • GitHub Copilot 使用攻略,本篇文章作者是GPT-3.5

    引言: 在软件开发领域,编写高质量的代码是开发者们的永恒追求。然而,传统的编码过程常常耗费大量时间和精力,而且在遇到复杂的问题时,开发者可能会面临困惑和不确定性。为了解决这些挑战,GitHub推出了一款强大的工具——GitHub Copilot,它利用人工智能技术提供智

    2024年02月16日
    浏览(58)
  • WPF线程使用详解:提升应用性能和响应能力

    在WPF应用程序开发中,线程的合理使用是保证应用性能和响应能力的关键。WPF提供了多种线程处理方式,包括UI线程、后台线程、Task/Async Await和BackgroundWorker。这些方式与传统的Thread类相比,更加适用于WPF框架,并能够简化线程操作。下面将详细介绍这些线程方式的特点以及与

    2024年02月15日
    浏览(57)
  • WPF性能优化示例:使用VirtualizingStackPanel提升界面加载速度

      概述: WPF界面绑定和渲染大量数据可能导致性能问题。通过启用UI虚拟化、异步加载和数据分页,可以有效提高界面响应性能。以下是简单示例演示这些优化方法。 在WPF中,当你尝试绑定和渲染大量的数据项时,性能问题可能出现。以下是一些可能导致性能慢的原因以及优

    2024年04月12日
    浏览(40)
  • 如何维护你的电脑:提升性能和延长使用寿命

    如何维护你的电脑:提升性能和延长使用寿命 😇博主简介:我是一名正在攻读研究生学位的人工智能专业学生,我可以为计算机、人工智能相关本科生和研究生提供排忧解惑的服务。如果您有任何问题或困惑,欢迎随时来交流哦!😄 ✨座右铭:宝剑锋从磨砺出,梅花香自苦

    2024年02月15日
    浏览(52)
  • 2023-06-03:redis中pipeline有什么好处,为什么要用 pipeline?

    2023-06-03:redis中pipeline有什么好处,为什么要用 pipeline? 答案2023-06-03: Redis客户端执行一条命令通常包括以下四个阶段: 1.发送命令:客户端将要执行的命令发送到Redis服务器。 2.命令排队:Redis服务器将收到的命令放入队列中,按照先进先出(FIFO)的原则等待执行。 3.命令

    2024年02月07日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包