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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 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

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
28天前
|
NoSQL 网络协议 Java
【赵渝强老师】Redis的管道Pipeline
Redis采用客户端-服务器模型和请求/响应协议,通常一个请求包括客户端发送查询请求并等待服务端响应。为了提高性能,Redis引入了管道PipeLine技术,可以一次性发送多条命令并一次性返回结果,减少客户端与服务器间的通信次数,从而降低往返延迟。示例代码展示了普通命令和管道命令在插入1万条数据时的性能差异,后者执行时间显著缩短。视频讲解提供了更详细的解释。
|
4月前
|
监控 NoSQL Go
Go语言中高效使用Redis的Pipeline
Redis 是构建高性能应用时常用的内存数据库,通过其 Pipeline 和 Watch 机制可批量执行命令并确保数据安全性。Pipeline 类似于超市购物一次性结账,减少网络交互时间,提升效率。Go 语言示例展示了如何使用 Pipeline 和 Pipelined 方法简化代码,并通过 TxPipeline 保证操作原子性。Watch 机制则通过监控键变化实现乐观锁,防止并发问题导致的数据不一致。这些机制简化了开发流程,提高了应用程序的性能和可靠性。
72 0
|
存储 NoSQL Java
Redis性能优化:理解与使用Redis Pipeline
当我们谈论Redis数据处理和存储的优化方法时, Redis Pipeline 无疑是一个不能忽视的重要技术。
834 0
Redis性能优化:理解与使用Redis Pipeline
|
NoSQL Redis Anolis
性能优化特性之:Redis批处理pipeline模式
本文介绍了一种更贴近实际使用的redis验测方法:多pipline模式,并从原理、使用方法进行详细阐述。
|
7月前
|
存储 NoSQL 关系型数据库
Redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
Redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
206 0
|
NoSQL Java Redis
Redis 从入门到精通之Redis Pipeline
使用Redis Pipeline可以大大提高Redis的性能和吞吐量,但需要注意命令的顺序和语义,以保证数据的正确性和一致性。同时,使用Jedis和RedisTemplate实现Redis Pipeline时,需要遵循最佳实践,避免出现错误和异常。 2. 在使用Jedis实现Redis Pipeline时,需要使用Pipeline对象添加多个命令并执行,然后通过`syncAndReturnAll`方法获取所有命令的执行结果。 3. 在使用RedisTemplate实现Redis Pipeline时,需要使用`executePipelined`方法添加多个命令并执行,然后通过返回的结果列表获取
681 11
Redis 从入门到精通之Redis Pipeline
|
存储 NoSQL 关系型数据库
redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
207 0
|
人工智能 NoSQL Java
SpringBoot实战(十七):Redis Pipeline 轻松实现百倍性能提升(续)
SpringBoot实战(十七):Redis Pipeline 轻松实现百倍性能提升(续)
336 0
|
NoSQL Java Redis
Redis-12Redis 流水线( pipeline )
Redis-12Redis 流水线( pipeline )
110 0
|
NoSQL Redis
Redis 的 pipeline对象是事务吗?
Redis 的 pipeline对象是事务吗?
261 0