spring data redis防坑指南

来源:互联网 发布:盛势网络剧在线观看 编辑:程序博客网 时间:2024/05/16 10:00

标题有点大。

spring很优秀,但也会有缺点。下面写两点spring data redis中的“准”坑


坑1:

每个封装操作都新取connection

比如

HashOperations<String, String, String> hashOps;

hashOps.values();

类似这样的封装,方法(比如上述values())内部都是使用execute方法

List<byte[]> rawValues = execute(new RedisCallback<List<byte[]>>() {


public List<byte[]> doInRedis(RedisConnection connection) {
return connection.hVals(rawKey);
}
}, true);

这个方法的特点是(具体可见org.springframework.data.redis.core.RedisTemplate 177行)先获取连接,然后执行回调(比如上述doInRedis()),最后释放连接。

如果业务复杂点,用redis频繁点,很容易会出现下述场景:

fun(){

hashOps.values();

hashOps.values();

hashOps.values();

}

即同一个方法中(或者更宽泛一点,整个servlet执行周期,可能不止一个fun)会有大量连接获取、释放的操作。这在线程很多的情况下会造成严重的连接争用,让你不得不“配合”线程数增加连接数,虽然redis服务端用nio让连接数问题不那么敏感,但用redis的时候一般都是为高性能场景,所以能“省”还是最好省点


坑2:

execute方法使用redis数据库连接死锁

这个坑有点“危言耸听”,其实不能完全怪spring data redis,但它却是起到了“诱导犯罪”的作用,其实和坑1有关联。

为了摆脱坑1中需要建立大量redis连接的缺点,其实我们也可以自己去调用execute方法,这样就可以实现下述模型了:

connection = connectionFactory.get(); // 隐藏在execute中,业务代码看不到

connection.ops();

connection.ops();

connection.ops();

connetion.release(); // 隐藏在execute中,业务代码看不到

这样就把原来需要n次获取、归还连接,变成只需1次获取、归还连接。但是,这个隐藏的“坑”就在你想要摆脱坑1时出现了。。。


假设你在

connection.ops();

connection.ops();

connection.ops();

总掺杂了坑1中提到的类似hashOps.values();操作,这时候数据库连接获取、释放就变成了

connectionFactory.get();  // 步骤A

connectionFactory.get();

业务操作();

connetion.release();

connetion.release();

老司机应该懂这个模型有啥问题


其实spring data redis的最常用封装对象jedis已足够简单,因为redis毕竟不是有复杂sql操作的数据库,它提供的基本都是原子api,而且spring data redis对新版本redis的新特性实现往往很滞后。。。远远不如官方客户端jedis那样及时。

但总要找个用的理由,好吧。1、spring data redis在对象序列化和反序列化上比较方便。2、spring data redis属于spring、属于spring data系列

原创粉丝点击