Redis数据库管道技术运用

2017-08-22  本文已影响0人  yasin_739c

什么是REDIS管道技术

因为REDIS是一种基于客户端-服务端模型以及请求/响应协议的TCP服务,所以客户端会阻塞等待服务端的返回结果。

然而REDIS管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。

这样的结果是什么呢?就是,快!

如何使用

这里介绍的是spring-redis中的API

```

T execute(RedisCallback action);

T execute(SessionCallback session);

List executePipelined(RedisCallback action);

List executePipelined(final RedisCallback action, final RedisSerializer resultSerializer);

List executePipelined(final SessionCallback session);

List executePipelined(final SessionCallback session, final RedisSerializer resultSerializer);

T execute(RedisScript script, List keys, Object... args);

T execute(RedisScript script, RedisSerializer argsSerializer, RedisSerializer resultSerializer,

List keys, Object... args);

```

可以发现spring-redis提供了很多相关方法,以execute命名的方法不罕见,在JDK中线程池相关操作也是execute,所以这类方法的共性都是执行一段逻辑罢了。

使用execute方法的好处是**不用频繁去找连接池要链接**,可以使用**一个链接处理一段逻辑**,所以如果有一段逻辑中**多次操作**REDIS的,就最好采用这类方法。

接下来分别介绍下它们的用法

在介绍方法用途之前,有这么几个参数类型是它们共有的,有必要先了解下这几个参数是什么意思

1.RedisCallback

这个接口需要实现doInRedis方法,参数是RedisConnection

可以利用RedisConnection调用一些REDIS最底层的方法,基本和REDIS命令一个等级了

这个方法不需要关心连接关闭和异常处理问题

2.SessionCallback

这个接口需要实现execute方法,参数是RedisOperations

可以利用RedisOperations执行一系列操作

可以用事务相关命令控制事务

3.RedisSerializer

序列化和反序列化实现

REDIS不接收空值参数,但是可以返回空结果(比如不存在的KEY)

4.RedisScript

REDIS2.6版本后可以支持脚本

方法介绍

-` T execute(RedisCallback action);`

返回值可由自己定义,自动适配DAO实现,自动选择序列化实现,**不支持事务**,不用关心连接声明周期,**可以开启管道**

调用栗子:

```

String str = redisTemplate.execute((RedisCallback) connection -> {

connection.openPipeline();    //开启管道

connection.closePipeline();      //关闭管道

byte[] bytes = connection.get("".getBytes());    //可以操作数据

return Arrays.toString(bytes);

});

```

-` T execute(SessionCallback session);`

在同一个会话中执行多种REIDS操作,**支持事务**,**不能使用管道**

调用栗子:

```java

redisTemplate.execute(new SessionCallback() {

@Override

public String execute(RedisOperations operations) throws DataAccessException {

operations.watch();      //可以事务管理

// Read

operations.multi();

// Write operations

operations.exec();

return null;

}

});

```

-`List executePipelined(RedisCallback action);`

使用方法同上,只不过这类方法会**自动开启管道**,REDIS的管道技术是**不支持事务**的,并且该方法不能指定返回值,如果定义了返回值会抛异常:

```

Object result = action.doInRedis(connection);

if (result != null) {

throw new InvalidDataAccessApiUsageException(

"Callback cannot return a non-null value as it gets overwritten by the pipeline");

}

```

所以返回值不能自定义,而是根据管道执行完毕后所查询出来的结果,每条以Object对象形式装进List返回。

调用栗子:

```java

List objects = redisTemplate.executePipelined(new SessionCallback() {

@Override

public Object execute(RedisOperations operations) throws DataAccessException {

operations.opsForValue().get("TEST_KEY");

operations.opsForValue().get("ORG_SERVICE:472");

return null;

}

});

```

总结:使用管道可以将多次REDIS操作在同一管道中执行,不仅提高效率而且节省了连接的占用,

但是否使用管道还得根据具体情况而定,毕竟创建管道是需要消耗资源的。

上一篇下一篇

猜你喜欢

热点阅读