Redis客户端Lettuce源码「一」Jedis vs Lettuce

@[toc]

基本实现对比


Jedis
Lettuce
支持JDK版本
JDK6+
JDK8+
IO模型
BIO
NIO(Netty)
连接复用
连接池
单一长连接
线程安全
Jedis线程不安全
StatefulRedisConnection线程安全


性能对比

Redis-Server测试环境:

  • 服务器配置:四核16G
  • Redis版本:5.0.5
  • Redis配置文件:默认配置

Redis-Client测试环境:

  • 服务器配置:四核16G
  • JDK版本:JDK8、基于Springboot 2.1.6.RELEASE版本的RedisTemplate测试
  • Jedis连接池配置:max:50,min:10
  • 测试工具:JMH(https://www.jianshu.com/p/2a83cc26d0e9)

如下图所示,对于各种大小value的get、set测试,二者无论是响应时间还是吞吐量,都相差不大,没有数量级的差异。(影响测试结果的因素有很多,存在一些偶然因素,所以这个结果不能说明Lettuce的响应性能就比Jedis好)同时也能看出来随着value大小的增加,无论是吞吐量还是响应性能都急剧的下降,所以我们在开发过程中存入Redis中的数据要尽可能的小。

Redis客户端Lettuce源码「一」Jedis vs Lettuce

Jedis的基本用法

pom添加依赖

<code>    <dependencies>        <dependency>            <groupid>redis.clients/<groupid>            <artifactid>jedis/<artifactid>            <version>3.1.0/<version>        /<dependency>    /<dependencies>/<code>

使用Jedis的示例代码

<code>public class JedisSimpleUse {    private String host = "localhost";    private int port = 6379;    private String password = "password";    /**     * 直接构建Jedis实例的方式使用Jedis     */    public void useJedis() {        //指定Redis服务Host和port, Jedis是非线程安全的,只能单个线程访问,每个线程都要单独构建Jedis对象        Jedis jedis = new Jedis(host, port);        try {            //如果Redis服务连接需要密码,指定密码            jedis.auth(password);            //访问Redis服务            String value = jedis.get("key");        } finally {            //使用完关闭连接            jedis.close();        }    }    private JedisPool jedisPool;    /**     * 初始化JedisPool     */    public void initJedisPool() {        GenericObjectPoolConfig genericObjectPool = new GenericObjectPoolConfig();        jedisPool = new JedisPool(genericObjectPool, host, port, Protocol.DEFAULT_TIMEOUT, password);    }    /**     * 基于连接池的方式使用Jedis     */    public void useJedisPool() {        Jedis jedis = jedisPool.getResource();        try {            //访问Redis服务            String value = jedis.get("key");        } finally {            //使用完关闭连接            jedis.close();        }    }    public static void main(String[] args) {        JedisSimpleUse jedisSimpleUse = new JedisSimpleUse();        //调用Jedis实例方法        jedisSimpleUse.useJedis();        // 初始化JedisPool,只需要初始化一次        jedisSimpleUse.initJedisPool();        // 多次基于JedisPool调用Redis        jedisSimpleUse.useJedisPool();        jedisSimpleUse.useJedisPool();    }}/<code>

Jedis配合Springboot RedisTemplate使用

pom添加依赖

<code><dependencymanagement>        <dependencies>            <dependency>                <groupid>org.springframework.boot/<groupid>                <artifactid>spring-boot-dependencies/<artifactid>                <version>2.1.6.RELEASE/<version>                <scope>import/<scope>                <type>pom/<type>            /<dependency>        /<dependencies>    /<dependencymanagement><dependencies>        <dependency>            <groupid>redis.clients/<groupid>            <artifactid>jedis/<artifactid>        /<dependency>        <dependency>            <groupid>org.springframework.boot/<groupid>            <artifactid>spring-boot-starter-data-redis/<artifactid>                        <exclusions>                <exclusion>                    <groupid>io.lettuce/<groupid>                    <artifactid>lettuce-core/<artifactid>                /<exclusion>            /<exclusions>        /<dependency>    /<dependencies>/<code>

application.properties配置文件

<code>spring.redis.host=localhostspring.redis.port=6379spring.redis.password=password/<code>

测试代码

<code>@Component@SpringBootApplicationpublic class JedisWithRedisTemplate {    /**     * SpringBoot autoconfigure在classpath中发现Jedis class会自动注入StringRedisTemplate     */    @Autowired    StringRedisTemplate redisTemplate;    public void testRedisTemplate() {        //redisTemplate封装了对Jedis的获取和释放、并使用JedisPool连接池        redisTemplate.opsForValue().set("key", "val123");        String value = redisTemplate.opsForValue().get("key");        System.out.println("get redis value with RedisTemplate, value is :" + value);        redisTemplate.delete("key");    }    public static void main(String[] args) {        // 创建SpringApplicationContext容器        ConfigurableApplicationContext applicationContext = SpringApplication.run(JedisWithRedisTemplate.class, args);        //从容器中获取测试Bean        JedisWithRedisTemplate jedisWithRedisTemplate = applicationContext.getBean(JedisWithRedisTemplate.class);        jedisWithRedisTemplate.testRedisTemplate();    }}/<code>

Lettuce的基本用法

pom添加依赖

<code><dependencies>        <dependency>            <groupid>io.lettuce/<groupid>            <artifactid>lettuce-core/<artifactid>        /<dependency>    /<dependencies>/<code>

测试代码

<code>public class LettuceSimpleUse {    private void testLettuce() throws ExecutionException, InterruptedException {        //构建RedisClient对象,RedisClient包含了Redis的基本配置信息,可以基于RedisClient创建RedisConnection        RedisClient client = RedisClient.create("redis://localhost");        //创建一个线程安全的StatefulRedisConnection,可以多线程并发对该connection操作,底层只有一个物理连接.        StatefulRedisConnection<string> connection = client.connect();        //获取SyncCommand。Lettuce支持SyncCommand、AsyncCommands、ActiveCommand三种command        RedisStringCommands<string> sync = connection.sync();        String value = sync.get("key");        System.out.println("get redis value with lettuce sync command, value is :" + value);        //获取SyncCommand。Lettuce支持SyncCommand、AsyncCommands、ActiveCommand三种command        RedisAsyncCommands<string> async = connection.async();        RedisFuture<string> getFuture = async.get("key");        value = getFuture.get();        System.out.println("get redis value with lettuce sync command, value is :" + value);    }public static void main(String[] args) throws ExecutionException, InterruptedException {        new LettuceSimpleUse().testLettuce();    }}/<string>/<string>/<string>/<string>/<code>

Lettuce配合Springboot RedisTemplate使用

pom配置文件

<code>    <dependencies>        <dependency>            <groupid>io.lettuce/<groupid>            <artifactid>lettuce-core/<artifactid>        /<dependency>        <dependency>            <groupid>org.springframework.boot/<groupid>            <artifactid>spring-boot-starter-data-redis/<artifactid>        /<dependency>    /<dependencies><dependencymanagement>        <dependencies>            <dependency>                <groupid>org.springframework.boot/<groupid>                <artifactid>spring-boot-dependencies/<artifactid>                <version>2.1.6.RELEASE/<version>                <scope>import/<scope>                <type>pom/<type>            /<dependency>        /<dependencies>    /<dependencymanagement>/<code>

application.properties

<code>spring.redis.host=localhostspring.redis.port=6379spring.redis.password=passwords/<code>

测试代码

<code>@SpringBootApplicationpublic class LettuceWithRedisTemplate {    /**     * SpringBoot autoconfigure在classpath中发现Lettuce class会自动注入StringRedisTemplate     */    @Autowired    StringRedisTemplate redisTemplate;    public void testRedisTemplate() {        //redisTemplate封装了对Lettuce StatefulRedisConnection的调用        redisTemplate.opsForValue().set("key", "val123");        String value = redisTemplate.opsForValue().get("key");        System.out.println("get redis value with RedisTemplate, value is :" + value);        redisTemplate.delete("key");    }    public static void main(String[] args) {        // 创建SpringApplicationContext容器        ConfigurableApplicationContext applicationContext = SpringApplication.run(LettuceWithRedisTemplate.class, args);        //从容器中获取测试Bean        LettuceWithRedisTemplate lettuceWithRedisTemplate = applicationContext.getBean(LettuceWithRedisTemplate.class);        lettuceWithRedisTemplate.testRedisTemplate();    }}/<code>


分享到:


相關文章: