redis使用pipeline通道大幅度提升redis的处理速度,节省成本-阿里云开发者社区

开发者社区> 优惠码优惠> 正文

redis使用pipeline通道大幅度提升redis的处理速度,节省成本

简介: redis使用pipeline通道大幅度提升redis的处理速度,节省成本 最近在做项目的时候,遇到大量的读写,最开始都是set,get一条条的循环去取数据,当数据量大的时候,数据处理相当慢慢,就想到批处理数据的方式,最开始set数据的时候,想到的是mset 也算是批量插入数据,这个在数据量几百.
+关注继续查看

redis使用pipeline通道大幅度提升redis的处理速度,节省成本

最近在做项目的时候,遇到大量的读写,最开始都是set,get一条条的循环去取数据,当数据量大的时候,数据处理相当慢慢,就想到批处理数据的方式,最开始set数据的时候,想到的是mset 也算是批量插入数据,这个在数据量几百的话甚至几千的插入量,也是OK的,取数据的时候用mget  这个100的数据量以下,性能还可以保证,再大的话就是严重有问题,数据量越大取出的成本本越高 ,另外一个,在用mset批量插入的时候,遇到一个难道,不过这是对redis不太了解的原因,后面无意中发现,set的时候,可以直接在后面参加参数,利用redisTemplate模板,

    redisTemplate.opsForValue().set("key_s2", maps2.toString(), 1000, TimeUnit.SECONDS); 轻松搞定 
  下面主要是针对 pipeline 管道方式批量插入,插入的数据量都 是在100000条数据,redis通过tcp来对外提供服务,client通过socket连接发起请求,每个请求在命令发出后会阻塞等待redis服务器进行处理,处理完毕后将结果返回给client。每一个命令都对应了发送、接收两个网络传输,假如一个流程需要0.1秒,那么一秒最多只能处理10个请求,将严重制约redis的性能。

当我们要处理上万以上数据的时候,就不得不另想办法,此时pipeline管道就是解决执行大量命令时、会产生大量数据来回次数而导致延迟的技术。其实原理比较简单,pipeline是把所有的命令一次发过去,避免频繁的发送、接收带来的网络开销,redis在打包接收到一堆命令后,依次执行,然后把结果再打包返回给客户端。

下面直接用代码试下,当然还作了其它的一些改动,比如RedisConnection 和SessionCallback 参数性能上不太一样,相差也不多,重点说一下, redisConnection.openPipeline();  这个方法在doInRedis内部其实已经有,但是在这里首先打开和关闭,对性能有一定的提高,10万次提升100毫秒左右

//加 redisConnection.openPipeline(); 打开资源  第一次耗时:470  第二次 耗时:468  毫秒

//不加redisConnection.openPipeline();打开和关闭 第一次 耗时:533  第二次 耗时:490,主要是第一次执行操作 其实是可以忽略了,并且这个的参数是 doInRedis重写方法是 RedisConnection 参数,后续对set的的操作必须是以redisConnection 参数开始,应该是新建一个接连去处理后续的所有操作,再到通道关闭,这样麻烦一些,所有的序列化都要自己去处理

public void pipelinedTest(){
        Long time = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            redisTemplate.opsForValue().increment("pipline", 1);
        }
        System.out.println("耗时:" + (System.currentTimeMillis() - time));
        time = System.currentTimeMillis();
        Map maps = new HashMap<>();
        maps.put("name", "lmc");
        maps.put("姓名", "李四");
        redisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override  
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {  
                redisConnection.openPipeline();  
                for (int i = 0;i < 100000;i++){
                    redisConnection.incrBy("a".getBytes(),1L);
                }
                redisConnection.set("keys".getBytes(), maps.toString().getBytes());
                redisConnection.closePipeline();  
                return null;  
            }
        });
        System.out.println("*****************"+redisTemplate.opsForValue().get("keys"));
        System.out.println("耗时:" + (System.currentTimeMillis() - time));
    }

 

第二种方式 execute 重写方法,参数RedisOperations 这种方式比较省心,不需要参数来操作, 用redisTemplate模板操作直接省去了很多数据封装的问题,但是性能上稍微差一点
// 这是第一次执行耗时:596    第二次执行耗时:589  毫秒


        Long time = System.currentTimeMillis();
        Map maps2 = new HashMap<>();
        maps2.put("name", "lmc");
        maps2.put("姓名", "李四");
        time = System.currentTimeMillis();
        redisTemplate.executePipelined(new SessionCallback<Object>() {
            @Override
            public <K, V> Object execute(RedisOperations<K, V> redisOperations) throws DataAccessException {
                for (int i = 0; i < 100000; i++) {
                    redisTemplate.opsForValue().increment("piplineddd", 1L);
                }
                redisTemplate.opsForValue().set("key_s2", maps2.toString(), 1000, TimeUnit.SECONDS);
                return null;
            }
        });
        System.out.println("

: "+redisTemplate.opsForValue().get("key_s2"));
        System.out.println("耗时:" + (System.currentTimeMillis() - time));
    直接一次性提交,所以executePipelined源码提供了多种方式供我们选择,底层提交都 一样的,只是在对外提供的方式为了满足更多的需求,

还在慢慢研究当中,如有描述不恰当的,还请各位指教

原文地址https://blog.csdn.net/limingcai168/article/details/81170399

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
处理亿级数据的“定时任务”,如何缩短执行时间?
一次性集中处理大量数据的定时任务,优化思路是:同一份数据,减少重复计算次数;分摊CPU计算时间,尽量分散处理(甚至可以实时),而不是集中处理;减少单次计算数据量。
564 0
一个内存增长问题的分析和处理(二)——valgrind工具的用法
valgrind是linux下对C++和C程序进行内存泄露检测的工具,除了内存检测,valgrind还提供了很多其他的功能,这里主要介绍下valgrind的内存检测的功能。   首先是文件的下载,valgrind的官方网址是http://valgrind.org/,最新版本的valgrind是3.9,下载地址如下:http://valgrind.org/downloads/。
997 0
JavaScript正则使用点滴
写在前面:关于“railroad diagrams”,摘抄自网络:http://202.207.0.245:9001/jisuanjifazhanshi/tuling/19.htm     我们目前所看到的许多语言的BNF实际上是EBNF,不过人们往往忽略掉这个E字。
607 0
一个内存增长问题的分析和处理(二)——valgrind工具的用法
valgrind是linux下对C++和C程序进行内存泄露检测的工具,除了内存检测,valgrind还提供了很多其他的功能,这里主要介绍下valgrind的内存检测的功能。   首先是文件的下载,valgrind的官方网址是http://valgrind.org/,最新版本的valgrind是3.9,下载地址如下:http://valgrind.org/downloads/。
774 0
sql server 表索引碎片处理
DBCC SHOWCONTIG (Transact-SQL) SQL Server 2005 其他版本 更新日期: 2007 年 9 月 15 日 显示指定的表或视图的数据和索引的碎片信息。
1004 0
使用批处理根据项目工程文件生成Nuget包并发布(支持.NET Core)
最近在使用之前自己编写的批处理给.NET Core项目打包时出问题了,发现之前的脚本根本不适用了,折腾了半天,总算解决了。因此在这里分享下经验,并且奉上整理好的脚本。 Nuget包这里就不多介绍了,需要了解的请访问:https://docs.microsoft.com/zh-cn/nuget/ 下面开始本篇教程。
1122 0
抖音短视频系统开发,消息机制的原理细节处理
对于Android抖音短视频系统开发来说,Binder和Handler是两大利剑,分别实现了进程间和线程间的通讯。Android的消息机制
372 0
Redis: pipeline加速Redis请求,实现批处理
Redis: pipeline加速Redis请求,实现批处理
4351 0
你还在用迭代器处理集合吗?试试Stream,真香!
首先给大家看一段代码,让大家直观感受下 Java7 和 Java8 遍历处理集合的不同 Dish 是一个菜肴对象,calories 属性表示该菜品的卡路里值,name 则是菜品的名称。我们需要过滤出卡路里小于400、然后根据卡路里值升序、接着拿到他们的名称列表并返回
7 0
+关注
优惠码优惠
阿里云优惠码阿里云推荐券bieryun.com
203
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载