十. redis java client
redis 主页上列出的 java 客户端有JDBC-Redis JRedis Jedis三种, 下面分别介绍三种客户端的优缺点及其他相关的工具.
| 支持 redis 版本 | 性能 | 维护 | 推荐 |
JDBC-Redis | not good | |||
JRedis | 1.2.n release 2.0.0 尚未 release 版本 | fast | ||
Jedis | 2.0.0 release | fast | actively developed | 推荐 |
JDBC-Redis
JDBC-Redis is just a JDBC wrapper for JRedis database.
If you plan on using your code with different back-ends then JDBC is a good way to go. NOTE: It is not a complete JDBC implementation and the NOSQL will bleed through.
If you are going to stay with Redis then I would suggest using the API, which will give you more flexibility. Use a DAO layer pattern to encapsulate your DB Access and down the road that is all you will need to change.
Redis syntax is completely different from standard SQL so using JDBC doesn't help encapsulating different back-ends as you suggest: I would have to write new queries anyway... – muriloq Jun 16 '10 at 14:00
@muriloq - but the mechanical acquiring and releasing resources is standard. – Romain Hippeau
spring wrapper
Spring provides a wrapper around both implementations(Jredis Jedis) and they're providing serialization/deserialization, amongst other things:
Person p = new Person("Joe", "Trader", 33);
template.convertAndSet("trader:1", p);
Person samePerson = template.getAndConvert("trader:1", Person.class);
Assert.assertEquals(p, samePerson);
放弃 spring wrapper
项目中本来打算使用 spring wrapper, 出于以下原因最终还是放弃, 直接使用 Jedis, 等有时间在把:
1.spring wrapper 的版本是 1.0.0.M2,里面有些 bug (*)
2. 对 shard 的支持没有 jedis 好
3. 依赖 spring3.0(主要是 spring3.0 core 中的 convert 及 serializer), 我们目前大多项目还是采用 spring2.5.6(主要)
4. 经过多层封装后性能还是会有损耗
spring nosql/cross-store
prototype implementation allowing entities to be stored in multiple types of data stores (i.e. JPA and Neo4j or JPA and Redis etc.)
JOhm
JOhm is a blazingly fast Object-Hash Mapping library for Java inspired by the awesome Ohm. The JOhm OHM is a modern-day avatar of the old ORM's like Hibernate with the difference being that we are not dealing with an RDBMS here but with a NoSQL rockstar.
homepage:https://github.com/xetorthio/johm
jedis pool 的问题
在使用 jedis pool 时遇到了这个问题:It seems like server has closed the connection
原因分析:
1.redis server 关闭了此客户端的连接:server 端设置了 maxidletime( 默认是 5 分钟),服务端会不断循环检测 clinet 的最后一次通信时间(lastinteraction),如果大于 maxidletime,则关闭连接,并回收相关资源。client 在向该连接中写数据后就会由于 server 端已经关闭而出现 broken pipe 的问题。
2.pool 的设置错误:
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="20" />
<property name="maxIdle" value="10" />
<property name="maxWait" value="1000" />
</bean><!-- jedis shard 信息配置 -->
<bean id="jedis.shardInfo"class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="*.*.*.*" />
<constructor-arg index="1" value="6379" />
</bean>
<!-- jedis shard pool 配置 -->
<bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
<constructor-arg index="0" ref="jedisPoolConfig" />
<constructor-arg index="1">
<list>
<ref bean="jedis.shardInfo" />
</list>
</constructor-arg>
</bean>
<bean id="jedisCommands" factory-bean="shardedJedisPool"
factory-method="getResource" />
上面的这种配法在 spring 初始化时获取一次实例化 jedisCommands,而后每次的 redis 的调用时并未从 pool 中获取
解决方案:
设置
<!-- POOL 配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="20" />
<property name="maxIdle" value="10" />
<property name="maxWait" value="1000" />
<property name="testOnBorrow" value="true"/>
</bean>
<!-- jedis shard 信息配置 -->
<bean id="jedis.shardInfo"class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="*.*.*.*" />
<constructor-arg index="1" value="6379" />
</bean>
<!-- jedis shard pool 配置 -->
<bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
<constructor-arg index="0" ref="jedisPoolConfig" />
<constructor-arg index="1">
<list>
<ref bean="jedis.shardInfo" />
</list>
</constructor-arg>
</bean>
参考:
http://stackoverflow.com/questions/3047010/best-redis-library-for-java
https://github.com/xetorthio/johm