Redis客户端

前言

通过《redis功能实现》的了解,并且redis官方提供了《JAVA Redis客户端》。其中Jedis,lettuce提供对redis基本封装, redisson为高级封装。

三架构对比

针对redis java client,从多角度进行选型对比

JedisLettuceRedisson
地址https://github.com/xetorthio/jedishttps://lettuce.io/https://github.com/redisson/redisson
what且健全的redis java客户端,支持redis的所有特性和命令,如事务、管道、发布订阅。线程安全的redis客户端,封装同步、异步、交互API。不执行阻塞和事务操作时,多线程可共享连接。线程安全的redis客户端,支持多场景,提供基于redis的某些分布式服务解决方案
实现与使用实现简单,使用简单实现较复杂,使用简单实现复杂,使用简单
网络阻塞IONettyNetty
redis命令特性支持redis命令与特性提供健全的支持redis命令与特性支持redis命令和特性支持
抽象封装程度没有做特别的抽象,特性使用是否正确依赖使用者。同步、异步、交互场景封装丰富的数据模型、分布式服务、特性的封装,第三方框架的扩展实现
操作的维度指令维度的操作指令维度的操作使用对象、服务将redis指令和业务分离,对象维度的操作,使用更方便,没有使用指令灵活,支持redisClient执行指令;分布式服务特性缺乏管理平台。
redis连接每次操作均需要从连接池中获取连接,线程间不可以共享连接,高并发时需要考虑连接过多对client和server的影响。共享连接,连接是long-lived和线程安全的,而且自动重连共享连接
client分片支持,提供实现不支持,未提供实现不支持,针对特殊数据模型提数据分片
read slave未找到使用slave执行read指令的API,但可以自行实现支持slave执行read指令支持slave执行read指令
排他+超时支持支持需要使用封装的数据模型
社区维护社区维护好,版本更新快社区维护一般,版本更新较慢分为企业版和开源版,维护好,版本更新快

Jedis

jedis主要采用连接池+bio的方式完成jedis的通试。

  1. Jedis.keys方法
// redis.clients.jedis.Jedis最终会调用以下方法
// redis.clients.jedis.Connection
public void sendCommand(final ProtocolCommand cmd, final byte[]... args) {
    try {    
          // 以bio的方式连接
          connect();
          // 组装命令向outputStream写入协议
          Protocol.sendCommand(outputStream, cmd, args);
    } catch (JedisConnectionException ex) {
      // ...
    }
}
  1. JedisPool连接池接入
// JedisPool最终会通过些访求进行初始化
// poolConfig 实现类 JedisPoolConfig 主要提供连接commons.pool2连接池的配置参数
// factory 实现类 RedisPooledObjectFactory 主要实现commons.pool2资源创建接口PooledObjectFactory
public void initPool(final GenericObjectPoolConfig poolConfig, PooledObjectFactory<T> factory) {

    this.internalPool = new GenericObjectPool<>(factory, poolConfig);
}
  1. JedisPool例子
public static void main(String[] args) throws Exception {
        JedisPool jedisPool = new JedisPool("localhost", 6379);
        // 不可以多线程使用
        Jedis jedis = jedisPool.getResource();
        System.out.println(jedis.get("foo"));
        jedis.close();
}

lettuce

lettuce使用netty + nio,复用同一个连接。《netty连接redis例子

  1. 通过PlainChannelInitializer实现ChannelInitializer接入netty
  2. CommandHandler 为核心的命令入口
  3. 通过ArrayDeque<RedisCommand<?, ?, ?>> stack 并结合CompletableFuture实现命令的发送和接收的关系
 public static void main(String[] args) throws Exception {
        RedisURI redisUri = RedisURI.Builder.redis("localhost")
                .withDatabase(1)
                .build();
        RedisClient client = RedisClient.create(redisUri);
        // connection普通命令多线程复用,但是使用事务不可以
        StatefulRedisConnection<String, String> connection = client.connect();
        RedisCommands<String, String> sync = connection.sync();
        System.out.println(sync.get("foo"));
        connection.close();
}

Redisson

redisson也是使用netty + nio,复用同一个连接。《netty连接redis例子

  1. 通过RedisChannelInitializer实现ChannelInitializer接入netty
  2. CommandDecoder,CommandEncoder 为核心的命令入口
  3. 通过CommandsQueue 并结合CompletableFuture 子类 RPromise 实现命令的发送和接收的关系
 public static void main(String[] args) {
        RedisClientConfig redisClientConfig = new RedisClientConfig();
        redisClientConfig.setAddress("redis://127.0.0.1:6379");
        RedisClient client = RedisClient.create(redisClientConfig);

        //  connection普通命令多线程复用,但是使用事务不可以
        RedisConnection redisConnection = client.connect();
        // 封装了个命令对象
        // @see RedisCommands.SET
        RedisCommand<String> SET = new RedisCommand<>("SET");
        String setValue = redisConnection.sync(SET, "foo", "yoyo1");
        System.out.println(setValue);
        RedisCommand<String> GET = new RedisCommand<>("GET");
        String value = redisConnection.sync(GET, "foo");
        System.out.println(value);
}

以下是Redisson比较热门的高级封装

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值