如何制作导航网站,wordpress图片缩略图,企业建站1年,wordpress单栏主题Redis是一个著名的key-value存储系统#xff0c;也是nosql中的最常见的一种#xff0c;这篇文章主要给大家总结了关于在java中jedis操作redis的几种常见方式#xff0c;文中给出了详细的示例代码供大家参考学习#xff0c;需要的朋友们下面来一起看看吧。前言Redis是一个著…Redis是一个著名的key-value存储系统也是nosql中的最常见的一种这篇文章主要给大家总结了关于在java中jedis操作redis的几种常见方式文中给出了详细的示例代码供大家参考学习需要的朋友们下面来一起看看吧。前言Redis是一个著名的key-value存储系统也是nosql中的最常见的一种。其实个人认为redis最强大的地方不在于其存储而在于其强大的缓存作用。我们可以把它想象成一个巨大的(多借点集群聚合多借点的内存)的Map也就是Key-Value。所以我们可以把它做成缓存组件。官方推荐的Java版客户端是jedis非常强大和稳定支持事务、管道及有jedis自身实现。我们对redis数据的操作都可以通过jedis来完成。那我们就来看一看jedis不同的调用方式(1)普通同步方式public voidjedisNormal() {Jedis jedis new Jedis(localhost);long start System.currentTimeMillis();for (int i 0; i 100000; i) {String result jedis.set(n i, n i);}long end System.currentTimeMillis();System.out.println(Simple SET: ((end - start)/1000.0) seconds);jedis.disconnect();}//每次set之后都可以返回结果标记是否成功。(2)事务方式(Transactions)所谓事务即一个连续操作是否执行是一个事务要么完成要么失败没有中间状态。而redis的事务很简单他主要目的是保障一个client发起的事务中的命令可以连续的执行而中间不会插入其他client的命令也就是事务的连贯性。public voidjedisTrans() {Jedis jedis new Jedis(localhost);long start System.currentTimeMillis();Transaction txjedis.multi();for (int i 0; i 100000; i) {tx.set(t i, t i);}List results tx.exec();long end System.currentTimeMillis();System.out.println(Transaction SET: ((end - start)/1000.0) seconds);jedis.disconnect();}//我们调用jedis.watch(…)方法来监控key如果调用后key值发生变化则整个事务会执行失败。另外事务中某个操作失败并不会回滚其他操作。这一点需要注意。还有我们可以使用discard()方法来取消事务。(3)管道(Pipelining)管道是一种两个进程之间单向通信的机制。那再redis中为何要使用管道呢有时候我们需要采用异步的方式一次发送多个指令并且不同步等待其返回结果。这样可以取得非常好的执行效率。public voidjedisPipelined() {Jedis jedis new Jedis(localhost);Pipeline pipelinejedis.pipelined();long start System.currentTimeMillis();for (int i 0; i 100000; i) {pipeline.set(p i, p i);}List results pipeline.syncAndReturnAll();long end System.currentTimeMillis();System.out.println(Pipelined SET: ((end - start)/1000.0) seconds);jedis.disconnect();}(4)管道中调用事务对于事务以及管道这两个概念我们都清楚了。在某种需求下我们需要异步执行命令但是又希望多个命令是有连续的所以我们就采用管道加事务的调用方式。jedis是支持在管道中调用事务的。public voidjedisCombPipelineTrans() {jedis new Jedis(localhost);long start System.currentTimeMillis();Pipeline pipelinejedis.pipelined();pipeline.multi();for (int i 0; i 100000; i) {pipeline.set( i, i);}pipeline.exec();List results pipeline.syncAndReturnAll();long end System.currentTimeMillis();System.out.println(Pipelined transaction: ((end - start)/1000.0) seconds);jedis.disconnect();}//效率上可能会有所欠缺(5)分布式直连同步调用这个是分布式直接连接并且是同步调用每步执行都返回执行结果。类似地还有异步管道调用。其实就是分片。public voidjedisShardNormal() {List shards Arrays.asList(new JedisShardInfo(localhost,6379),new JedisShardInfo(localhost,6380));ShardedJedis sharding newShardedJedis(shards);long start System.currentTimeMillis();for (int i 0; i 100000; i) {String result sharding.set(sn i, n i);}long end System.currentTimeMillis();System.out.println(SimpleSharing SET: ((end - start)/1000.0) seconds);sharding.disconnect();}(6)分布式直连异步调用public voidjedisShardpipelined() {List shards Arrays.asList(new JedisShardInfo(localhost,6379),new JedisShardInfo(localhost,6380));ShardedJedis sharding newShardedJedis(shards);ShardedJedisPipeline pipelinesharding.pipelined();long start System.currentTimeMillis();for (int i 0; i 100000; i) {pipeline.set(sp i, p i);}List results pipeline.syncAndReturnAll();long end System.currentTimeMillis();System.out.println(PipelinedSharing SET: ((end - start)/1000.0) seconds);sharding.disconnect();}(7)分布式连接池同步调用如果你的分布式调用代码是运行在线程中那么上面两个直连调用方式就不合适了因为直连方式是非线程安全的这个时候你就必须选择连接池调用。连接池的调用方式适合大规模的redis集群并且多客户端的操作。public voidjedisShardSimplePool() {List shards Arrays.asList(new JedisShardInfo(localhost,6379),new JedisShardInfo(localhost,6380));ShardedJedisPool pool new ShardedJedisPool(newJedisPoolConfig(), shards);ShardedJedis onepool.getResource();long start System.currentTimeMillis();for (int i 0; i 100000; i) {String result one.set(spn i, n i);}long end System.currentTimeMillis();pool.returnResource(one);System.out.println(SimplePool SET: ((end - start)/1000.0) seconds);pool.destroy();}(8)分布式连接池异步调用public voidjedisShardPipelinedPool() {List shards Arrays.asList(new JedisShardInfo(localhost,6379),new JedisShardInfo(localhost,6380));ShardedJedisPool pool new ShardedJedisPool(newJedisPoolConfig(), shards);ShardedJedis onepool.getResource();ShardedJedisPipeline pipelineone.pipelined();long start System.currentTimeMillis();for (int i 0; i 100000; i) {pipeline.set(sppn i, n i);}List results pipeline.syncAndReturnAll();long end System.currentTimeMillis();pool.returnResource(one);System.out.println(PipelinedPool SET: ((end - start)/1000.0) seconds);pool.destroy();}9)需要注意的地方事务和管道都是异步模式。在事务和管道中不能同步查询结果。比如下面两个调用都是不允许的Transaction tx jedis.multi();for (int i 0; i 100000; i) {tx.set(t i, t i);}System.out.println(tx.get(t1000).get()); //不允许List results tx.exec();……Pipeline pipelinejedis.pipelined();long start System.currentTimeMillis();for (int i 0; i 100000; i) {pipeline.set(p i, p i);}System.out.println(pipeline.get(p1000).get()); //不允许List results pipeline.syncAndReturnAll();事务和管道都是异步的个人感觉在管道中再进行事务调用没有必要不如直接进行事务模式。分布式中连接池的性能比直连的性能略好(见后续测试部分)。分布式调用中不支持事务。因为事务是在服务器端实现而在分布式中每批次的调用对象都可能访问不同的机器所以没法进行事务。(10)总结分布式中连接池方式调用不但线程安全外根据上面的测试数据也可以看出连接池比直连的效率更好。经测试分布式中用到的机器越多调用会越慢。