Redis客户端Jedis的几种调用方式---事务、管道、分布式

本文介绍了Redis客户端Jedis的三种调用方式:事务、管道和分布式。强调了事务和管道的异步特性,指出在这些模式下无法同步查询结果。分布式调用不支持事务,且连接池在性能上优于直接连接。测试结果显示,分布式调用的机器数量越多,速度越慢,而使用连接池的方式更优。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis是key-value存储系统,而作为其官方推荐的java版客户端jedis也非常强大和稳定,支持事务、管道及有jedis自身实现的分布式。
在这里对jedis关于事务、管道和分布式的调用方式做一个简单的介绍和对比:

package com.ws.Redis;

import java.util.Arrays;
import java.util.List;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.Transaction;

public class RedisConnection {

    public static void main(String[] args) {
        normalFunction();
//      transactionsFunction();
//      pipeline();
//      combPipelineTranscationFunction();
//      shardNormalFunction();
//      shardpipelinedFunction();
//      shardPipelinedPoolFunction();
//      shardSimplePoolFunction();
    }

    //简单调用方式,每次set值之后都会返回结果,标记该次set是否成功。
    public static void normalFunction() {
        Jedis jedis = new Jedis("localhost", 6379);
        jedis.auth("123456");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            String result = jedis.set("normal" + i, "normal" + i);
        }
        long end = System.currentTimeMillis();
        System.out.println("Normal SET: " + ((end - start)/1000.0) + " seconds");
        jedis.disconnect();
    }

    //redis事务,一个client发起的事务中的命令可以连续执行,中间不会插入其他指令。
    //可以调用jedis.watch()方法来监控key,如果调用后的key值发生变化,则事务执行失败。使用tx.discard()方法取消事务。
    //注:事务中某个操作执行失败,并不会回滚其他操作。
    public static void transactionsFunction() {
        Jedis jedis = new Jedis("localhost", 6379);
        jedis.auth("123456");
        long start = System.currentTimeMillis();
        Transaction tx = jedis.multi();
        for (int i = 0; i < 10000; i++) {
            tx.set("transaction" + i, "transaction" + i);
        }
        List<Object> results = tx.exec();
        long end = System.currentTimeMillis();
        System.out.println("Transaction SET: " + ((end - start)/1000.0) + " seconds");
        jedis.disconnect();

    }

    //采用异步方式,一次发送多个set,不同步等待其返回的结果,可以极大的提升执行效率。
    public static void pipeline() {
        Jedis jedis = new Jedis("localhost", 6379);
        jedis.auth("123456");
        Pipeline pipeline = jedis.pipelined();
        long start = System.currentTimeMillis();
        for(int i=0; i<10000; i++){
            pipeline.set("pipeline" + i, "pipeline" + i);
        }
        List<Object> results = pipeline.syncAndReturnAll();
        long end = System.currentTimeMillis();
        System.out.println("Pipeline SET : " +((end-start)/1000.0) + " seconds");
        jedis.disconnect();
    }

    //在管道中使用事务,但是效率并不比但多使用事务效率高很多。
    public static void combPipelineTranscationFunction() {
        Jedis jedis = new Jedis("localhost", 6379);
        jedis.auth("123456");
        long start = System.currentTimeMillis();
        Pipeline pipeline = jedis.pipelined();
        pipeline.multi();
        for (int i = 0; i < 100000; i++) {
            pipeline.set("" + i, "" + i);
        }
        pipeline.exec();
        List<Object> results = pipeline.syncAndReturnAll();
        long end = System.currentTimeMillis();
        System.out.println("Pipelined transaction: " + ((end - start)/1000.0) + " seconds");
        jedis.disconnect();
    }

    //分布式直接连接,并且是同步调用,每步执行都返回执行结果。
    public static void shardNormalFunction() {
        List<JedisShardInfo> shards = Arrays.asList(
                new JedisShardInfo("localhost",6379),
                new JedisShardInfo("localhost",6380));
        ShardedJedis sharding = new ShardedJedis(shards);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            String result = sharding.set("shardNormal" + i, "shardNormal" + i);
        }
        long end = System.currentTimeMillis();
        System.out.println("Simple@Sharing SET: " + ((end - start)/1000.0) + " seconds");
        sharding.disconnect();
    }

    //分布式直接连接,并且是异步调用,不是每步执行都返回执行结果
    public static void shardpipelinedFunction() {
        List<JedisShardInfo> shards = Arrays.asList(
                new JedisShardInfo("localhost",6379),
                new JedisShardInfo("localhost",6380));
        ShardedJedis sharding = new ShardedJedis(shards);
        ShardedJedisPipeline pipeline = sharding.pipelined();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            pipeline.set("shardpipelined" + i, "shardpipelined" + i);
        }
        List<Object> results = pipeline.syncAndReturnAll();
        long end = System.currentTimeMillis();
        System.out.println("Pipelined@Sharing SET: " + ((end - start)/1000.0) + " seconds");
        sharding.disconnect();
    }

    //多线程方式,直接连接不安全,需要使用连接池方式,分布式连接池同步调用。
    public static void shardSimplePoolFunction() {
        List<JedisShardInfo> shards = Arrays.asList(
                new JedisShardInfo("localhost",6379),
                new JedisShardInfo("localhost",6380));
        ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);
        ShardedJedis one = pool.getResource();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            String result = one.set("shardSimplePool" + i, "shardSimplePool" + i);
        }
        long end = System.currentTimeMillis();
        pool.returnResource(one);
        System.out.println("Simple@Pool SET: " + ((end - start)/1000.0) + " seconds");
        pool.destroy();
    }

    //分布式连接池异步调用
    public static void shardPipelinedPoolFunction() {
        List<JedisShardInfo> shards = Arrays.asList(
                new JedisShardInfo("localhost",6379),
                new JedisShardInfo("localhost",6380));
        ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);
        ShardedJedis one = pool.getResource();
        ShardedJedisPipeline pipeline = one.pipelined();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            pipeline.set("shardPipelinedPool" + i, "shardPipelinedPool" + i);
        }
        List<Object> results = pipeline.syncAndReturnAll();
        long end = System.currentTimeMillis();
        pool.returnResource(one);
        System.out.println("Pipelined@Pool SET: " + ((end - start)/1000.0) + " seconds");
        pool.destroy();
    }
}

一些注意点:

  • 事务和管道都是异步模式。在事务和管道中不能同步查询结果。比如下面两个调用,都是不允许的;
  • 事务和管道都是异步的,在管道中再进行事务调用,没有必要,不如直接进行事务模式;
  • 分布式中,连接池的性能比直连的性能略好;
  • 分布式调用中不支持事务,因为事务是在服务器端实现,而在分布式中,每批次的调用对象都可能访问不同的机器,故没法使用事务;

测试:

Simple SET: 5.227 seconds

Transaction SET: 0.5 seconds

Pipelined SET: 0.353 seconds

Pipelined transaction: 0.509 seconds

Simple@Sharing SET: 5.289 seconds

Pipelined@Sharing SET: 0.348 seconds

Simple@Pool SET: 5.039 seconds

Pipelined@Pool SET: 0.401 seconds

另外,经测试分布式中用到的机器越多,调用会越慢。分布式中,连接池方式调用不但线程安全外,根据上面的测试数据,也可以看出连接池比直连的效率更好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值