redis开发与运维-redis0401-补充-redis流水线与Jedis执行流水线

文章目录

  • 【README】
  • 【1】redis流水线Pipeline
    • 【1.1】redis流水线概念
    • 【1.2】redis流水线性能测试
      • 【1.2.1】使用流水线与未使用流水线的性能对比
      • 【1.2.2】使用流水线与redis原生批量命令的性能对比
      • 【1.2.3】流水线缺点
    • 【1.3】Jedis客户端执行流水线
      • 【1.3.1】Jedis客户端执行流水线实现批量删除代码实践
      • 【1.3.2】Jedis客户端执行流水线并获取执行结果代码实践

【README】

本文总结自《redis开发与运维》,作者付磊,张益军,墙裂推荐;

  • 本文使用的redis版本是 7.0.15 ;
  • 本文主要介绍redis流水线概念及jedis操作流水线代码实践;
  • 代码参见: https://github.com/TomJourney/redisDiscover/tree/master


【1】redis流水线Pipeline

1)redis客户端执行一条命令分为4个步骤:

  1. 发送命令;
  2. 命令排队;
  3. 命令执行;
  4. 返回结果;

2)RTT往返时间:发送命令与返回结果的执行耗时(RTT-Round Trip Time)

3)问题与解决方法:

  • 问题:redis的批量操作命令能够有效节约RTT,如mget,mset。但问题是大部分命令不支持批量操作,如hgetall,即批量业务场景只能执行单条命令,网络IO高,导致RTT高。

    • 【例】: redis客户端在北京,服务器在上海,两地直线距离为1300公里,1次RTT时间=1300*2/(300000 * 2/3) = 13ms(光在真空中的速度为每秒30w公里,假设光纤传播速度为光速的2/3,即每秒20w公里)
    • 若批量业务场景需要执行10次hgetall,则需要130ms,单单操作redis的网络io就有130ms,还不算正常的业务逻辑耗时,显然操作redis的耗时是不合理的(补充: 一般一次请求响应的网络耗时不超过200ms );
  • 解决方法:使用redis流水线技术;

4)其他补充: redis命令真正执行的耗时是微秒级别(1s=1000000 microsecond);所以才会有redis性能瓶颈在网络开销的说法



【1.1】redis流水线概念

1)redis流水线:能够将一组redis命令进行组装, 通过一次RTT传输给redis,再将这组执行结果一次性返回给客户端;即使用pipeline执行n次命令,耗时1个RTT;

在这里插入图片描述



【1.2】redis流水线性能测试

【1.2.1】使用流水线与未使用流水线的性能对比

1)在不同网络环境下, 10000条set未使用流水线命令 与 使用流水线命令执行耗时如下。

在这里插入图片描述

2)redis流水线性能对比结论:

  • 流水线执行速度一般比逐条执行要快;
  • 客户端与服务器的网络延时越大,,则流水线的效果越明显;


【1.2.2】使用流水线与redis原生批量命令的性能对比

1)流水线与原生批量命令区别:

  • 流水线执行命令不是原子的,而原生批量命令是原子的;
  • 流水线支持多个命令,而原生批量命令是一个命令操作多个key,如mset;
  • 流水线需要客户端与服务器同时提供支持,而原生批量命令是redis服务器提供支持;


【1.2.3】流水线缺点

1)每次流水线封装的命令不能太多,流水线组装的命令过多可能导致阻塞;

  • 一方面:一次流水线可能增加客户端的等待时间;
  • 另一方面:造成一定的网络阻塞;

2)解决方法: 可以将包含大量命令的流水线拆分为多个小流水线;



【1.3】Jedis客户端执行流水线

【1.3.1】Jedis客户端执行流水线实现批量删除代码实践

【PooledJedisBatchDelViaPipeline】池化jedis操作流水线

public class PooledJedisBatchDelViaPipeline {public static void main(String[] args) {BusiJedisFactoryUsingPool busiJedisFactoryUsingPool = BusiJedisFactoryUsingPool.build();// 从jedis连接池获取jedis对象Jedis jedis = busiJedisFactoryUsingPool.getJedis();try {System.out.println(jedis.get("user01"));System.out.println(jedis.get("user02"));batchDelete(jedis, Arrays.asList("user01", "user02"));} catch (Exception e) {throw new IllegalStateException(e.getMessage(), e);} finally {if (Objects.nonNull(jedis)) {jedis.close();}}// 删除键之后获取键// 从jedis连接池获取jedis对象System.out.println("========== 删除键之后获取键 ========== ");jedis = busiJedisFactoryUsingPool.getJedis();try {System.out.println(jedis.get("user01"));System.out.println(jedis.get("user02"));} catch (Exception e) {throw new IllegalStateException(e.getMessage(), e);} finally {if (Objects.nonNull(jedis)) {jedis.close();}}}private static void batchDelete(Jedis jedis, List<String> keys) {// 生成pipeline对象Pipeline pipeline = jedis.pipelined();for (String key : keys) {pipeline.del(key);}// 提交命令到redispipeline.sync();}
}

【日志】

zhagnsan01
zhagnsan02
========== 删除键之后获取键 ========== 
null
null

【代码解说】

  • jedis.pipelined() :创建流水线对象;
  • pipeline.del(String key) 与 jedis.del(String key) 的写法是一致的,只不过pipeline.del(String key) 不会立即执行命令;
  • pipeline.sync() 执行流水线组装的多个命令(发送组装多个命令的流水线到redis服务器)


【1.3.2】Jedis客户端执行流水线并获取执行结果代码实践

1)syncAndReturnAll(): 执行流水线命令并获取执行结果

【PooledJedisSetAndGetResultViaPipeline】

public class PooledJedisSetAndGetResultViaPipeline {public static void main(String[] args) {BusiJedisFactoryUsingPool busiJedisFactoryUsingPool = BusiJedisFactoryUsingPool.build();// 从jedis连接池获取jedis对象Jedis jedis = busiJedisFactoryUsingPool.getJedis();try {setAndGetReulst(jedis);} catch (Exception e) {throw new IllegalStateException(e.getMessage(), e);} finally {if (Objects.nonNull(jedis)) {jedis.close();}}}private static void setAndGetReulst(Jedis jedis) {// 生成pipeline对象Pipeline pipeline = jedis.pipelined();pipeline.set("user03", "zhangsan03");pipeline.incr("age");// syncAndReturnAll 执行流水线命令并返回结果List<Object> resultList = pipeline.syncAndReturnAll();for (Object result : resultList) {System.out.println(result);}}
}

【日志】

OK
2


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65810.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode hot 100 杨辉三角

118. 杨辉三角 已解答 简单 相关标签 相关企业 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 class Solution(object):def generate(self, numRows):""":ty…

Uncaught ReferenceError: __VUE_HMR_RUNTIME__ is not defined

Syntax Error: Error: vitejs/plugin-vue requires vue (>3.2.13) or vue/compiler-sfc to be present in the dependency tree. 第一步 npm install vue/compiler-sfc npm run dev 运行成功&#xff0c;本地打开页面是空白&#xff0c;控制台报错 重新下载了vue-loa…

【微服务】【Sentinel】认识Sentinel

文章目录 1. 雪崩问题2. 解决方案3. 服务保护技术对比4. 安装 Sentinel4.1 启动控制台4.2 客户端接入控制台 参考资料: 1. 雪崩问题 微服务调用链路中的某个服务故障&#xff0c;引起整个链路中的所有微服务都不可用&#xff0c;这就是雪崩。动图演示&#xff1a; 在微服务系统…

【Python运维】构建基于Python的自动化运维平台:用Flask和Celery

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在现代IT运维中,自动化运维平台扮演着至关重要的角色,它能够显著提高运维效率,减少人为错误,并且增强系统的可维护性。本文将引导读者如…

STM32完全学习——使用定时器1精确延时

一、定时器的相关配置 首先一定要是递减定时器&#xff0c;递增的不太行&#xff0c;控制的不够准确&#xff0c;其次在大于10微秒的延时是非常准确的&#xff0c;小于的话&#xff0c;就没有那没准&#xff0c;但是凑合能用。误差都在一个微秒以内。使用高级定时器也就是时钟…

connect to host github.com port 22: Connection timed out 的解决方法

原因是 Github 被 GFW 屏蔽了。 Windows 系统&#xff0c;打开 C:\Windows\System32\drivers\etc&#xff0c;复制其中的 hosts 文件至桌面&#xff0c;用文本编辑器或者其他工具打开。 复制以下内容进去&#xff1a; 140.82.114.4 github.com 151.101.1.6 github.global.ss…

PyTorch中的autocast:混合精度训练的实现原理

PyTorch中的autocast&#xff1a;混合精度训练的实现原理 在深度学习中&#xff0c;尤其是在训练大型模型时&#xff0c;计算资源和显存消耗往往是非常关键的因素。为了优化这些问题&#xff0c;混合精度训练&#xff08;Mixed Precision Training&#xff09;应运而生。autoc…

Word格式修改

经常修改格式&#xff0c;留下这篇汇总 Word的累加符号上下标变右标指定目录&#xff1a;word如何取消封面或者目录下方的页码&#xff0c;页码从正文开始加参考文献&#xff1a;【Word】怎样给论文添加引用参考文献删空白页&#xff1a; word中无法删除空白页怎么办&#xff…

常见的排序算法过程和比较分析

比较分析 排序类别排序算法时间复杂度&#xff08;最好&#xff09;时间复杂度&#xff08;最坏&#xff09;时间复杂度&#xff08;平均&#xff09;辅助空间复杂度稳定性插入排序直接插入排序O(n)O(n)O(n)O(1)稳定插入排序折半插入排序O(n)O(n)O(n)O(1)稳定插入排序希尔排序…

随笔 | 写在2024的最后一天

. 前言 转眼又到了一年的末端。过去这一年&#xff0c;和前些年有些不同&#xff0c;变化巨大&#xff0c;感触良多。多到一时竟不知从何开始写。今天这篇随笔&#xff0c;因为时间有限&#xff0c;可能文法也会有些凌乱&#xff0c;就是想到哪里写到哪里&#xff0c;如果未来…

【QGIS入门实战精品教程】7.3:QGIS制作千层饼(DEM+等高线+影像+TIN)

文章目录 一、效果展示二、数据准备三、制作过程1. 打开软件2. 添加图层3. 制作千层饼一、效果展示 二、数据准备 订阅专栏后,从专栏配套案例数据包中的7.3.rar中获取。 1. dem 2. 影像 3. 等高线 4. tin 三、制作过程 1. 打开软件 打开QGIS软件。 QGIS软件主界面。

如何将CSDN文章 导出为 PDF文件

一、首先&#xff0c;打开我们想要导出为 PDF格式的 CSDN文章&#xff0c;以下图为例。 二、按 F12 调出浏览器调式模式后&#xff0c;选择 控制台 三、在控制台处粘贴代码 代码&#xff1a; (function(){ use strict;var articleBox $("div.article_content"…

Apache Hive常见问题

入门问题 什么是Apache Hive&#xff1f; 解释Hive的用途。Hive作为基于Hadoop的数据仓库工具是如何工作的&#xff1f;与传统关系型数据库相比&#xff0c;使用Hive有什么优势&#xff1f; Hive和关系型数据库管理系统&#xff08;RDBMS&#xff09;之间的区别是什么&#…

HTML——54. form元素属性

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>form元素属性</title></head><body><!--form标签用于创建一个表单&#xff0c;会将里面的内容一起发送服务器&#xff0c;结构类似于表格--><!-…

告别 $arr[0]: PHP 和 Laravel 中更优雅的数组处理方式

你是否曾经历过这样的惊魂时刻&#xff1a;线上代码突然崩溃&#xff0c;只因访问了一个不存在的数组元素&#xff1f;或者更糟的是&#xff0c;应用开始疯狂抛出错误&#xff0c;而你却毫无头绪&#xff1f;这一切的罪魁祸首可能就是看似人畜无害的硬编码数组索引&#xff0c;…

二十三种设计模式-单例模式

单例模式&#xff08;Singleton&#xff09;&#xff1a;确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 单例模式两种实现方法&#xff1a;懒汉式和饿汉式。 懒汉式&#xff08;Lazy Initialization&#xff09; 懒汉式单例模式在第一次被使用时才创建实例&…

聊聊长连接和短连接

大家好&#xff0c;我是G探险者。 现在的软件架构无非就是两种架构模式&#xff0c;C/S架构&#xff0c;B/S架构。 C/S架构&#xff1a;C就是客户端client&#xff0c;S就是服务端server。 B/S架构&#xff1a;B就是浏览器browser,S就是服务端server。 当别人问你的项目是什么架…

【Linux报告】实训六 重置超级用户密码

实训六 重置超级用户密码 2018编写-今日公布 【练习一】忘记root密码 步骤一&#xff1a;开启或重启系统&#xff0c;并且要在五秒之内按任何键&#xff1b; 步骤二&#xff1a;按任意键&#xff0c;停止进入系统&#xff0c;按【e】键&#xff0c;跳转新页面&#xff0c;再…

一种pod容器动态挂卷方案

一、背景 1.1 个人调试kvm 我们这边基于云平台的k8skubevirt&#xff0c;给安卓手机领域的开发工程师们提供了独占式虚拟机资源。这些资源主要用于工程师的个人级开发与调试&#xff0c;因此有如下特点&#xff1a; 使用时间与工作时间强相关&#xff0c;即工程师工作时间使…

Docker Compose 构建 EMQX 集群 实现mqqt 和websocket

EMQX 集群化管理mqqt真香 目录 #目录 /usr/emqx 容器构建 vim docker-compose.yml version: 3services:emqx1:image: emqx:5.8.3container_name: emqx1environment:- "EMQX_NODE_NAMEemqxnode1.emqx.io"- "EMQX_CLUSTER__DISCOVERY_STRATEGYstatic"- …