Redis客戶(hù)端Lettuce源碼【一】Jedis vs Lettuce

@[toc]

基本實(shí)現(xiàn)對(duì)比

Jedis Lettuce
支持JDK版本 JDK6+ JDK8+
IO模型 BIO NIO(Netty)
連接復(fù)用 連接池 單一長(zhǎng)連接
線(xiàn)程安全 Jedis線(xiàn)程不安全 StatefulRedisConnection線(xiàn)程安全

性能對(duì)比

Redis-Server測(cè)試環(huán)境:

  • 服務(wù)器配置:四核16G
  • Redis版本:5.0.5
  • Redis配置文件:默認(rèn)配置

Redis-Client測(cè)試環(huán)境:

如下圖所示,對(duì)于各種大小value的get温算、set測(cè)試岗钩,二者無(wú)論是響應(yīng)時(shí)間還是吞吐量申眼,都相差不大谬晕,沒(méi)有數(shù)量級(jí)的差異宿亡。(影響測(cè)試結(jié)果的因素有很多,存在一些偶然因素彪腔,所以這個(gè)結(jié)果不能說(shuō)明Lettuce的響應(yīng)性能就比Jedis好)
同時(shí)也能看出來(lái)隨著value大小的增加侥锦,無(wú)論是吞吐量還是響應(yīng)性能都急劇的下降,所以我們?cè)陂_(kāi)發(fā)過(guò)程中存入Redis中的數(shù)據(jù)要盡可能的小德挣。


lettuce vs jedis性能對(duì)比

Jedis的基本用法

pom添加依賴(lài)

    <dependencies>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.1.0</version>
        </dependency>
    </dependencies>

使用Jedis的示例代碼

public class JedisSimpleUse {
    private String host = "localhost";
    private int port = 6379;
    private String password = "password";

    /**
     * 直接構(gòu)建Jedis實(shí)例的方式使用Jedis
     */
    public void useJedis() {
        //指定Redis服務(wù)Host和port恭垦, Jedis是非線(xiàn)程安全的,只能單個(gè)線(xiàn)程訪(fǎng)問(wèn)格嗅,每個(gè)線(xiàn)程都要單獨(dú)構(gòu)建Jedis對(duì)象
        Jedis jedis = new Jedis(host, port);
        try {
            //如果Redis服務(wù)連接需要密碼番挺,指定密碼
            jedis.auth(password);
            //訪(fǎng)問(wèn)Redis服務(wù)
            String value = jedis.get("key");
        } finally {
            //使用完關(guān)閉連接
            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 {
            //訪(fǎng)問(wèn)Redis服務(wù)
            String value = jedis.get("key");
        } finally {
            //使用完關(guān)閉連接
            jedis.close();
        }
    }

    public static void main(String[] args) {
        JedisSimpleUse jedisSimpleUse = new JedisSimpleUse();
        //調(diào)用Jedis實(shí)例方法
        jedisSimpleUse.useJedis();

        // 初始化JedisPool,只需要初始化一次
        jedisSimpleUse.initJedisPool();

        // 多次基于JedisPool調(diào)用Redis
        jedisSimpleUse.useJedisPool();
        jedisSimpleUse.useJedisPool();
    }
}

Jedis配合Springboot RedisTemplate使用

pom添加依賴(lài)

<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>
            <!--因?yàn)閟pring-boot-starter-data-redis默認(rèn)引用了lettuce吗浩,所以需要排除lettuce-->
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

application.properties配置文件

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=password

測(cè)試代碼

@Component
@SpringBootApplication
public class JedisWithRedisTemplate {
    /**
     * SpringBoot autoconfigure在classpath中發(fā)現(xiàn)Jedis class會(huì)自動(dòng)注入StringRedisTemplate
     */
    @Autowired
    StringRedisTemplate redisTemplate;

    public void testRedisTemplate() {
        //redisTemplate封裝了對(duì)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) {
        // 創(chuàng)建SpringApplicationContext容器
        ConfigurableApplicationContext applicationContext = SpringApplication.run(JedisWithRedisTemplate.class, args);
        //從容器中獲取測(cè)試Bean
        JedisWithRedisTemplate jedisWithRedisTemplate = applicationContext.getBean(JedisWithRedisTemplate.class);
        jedisWithRedisTemplate.testRedisTemplate();
    }
}

Lettuce的基本用法

pom添加依賴(lài)

<dependencies>
        <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </dependency>
    </dependencies>

測(cè)試代碼

public class LettuceSimpleUse {
    private void testLettuce() throws ExecutionException, InterruptedException {
        //構(gòu)建RedisClient對(duì)象,RedisClient包含了Redis的基本配置信息懂扼,可以基于RedisClient創(chuàng)建RedisConnection
        RedisClient client = RedisClient.create("redis://localhost");

        //創(chuàng)建一個(gè)線(xiàn)程安全的StatefulRedisConnection禁荸,可以多線(xiàn)程并發(fā)對(duì)該connection操作,底層只有一個(gè)物理連接.
        StatefulRedisConnection<String, String> connection = client.connect();

        //獲取SyncCommand。Lettuce支持SyncCommand阀湿、AsyncCommands赶熟、ActiveCommand三種command
        RedisStringCommands<String, 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, 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();
    }
}

Lettuce配合Springboot RedisTemplate使用

pom配置文件

    <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>

application.properties

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=passwords

測(cè)試代碼

@SpringBootApplication
public class LettuceWithRedisTemplate {
    /**
     * SpringBoot autoconfigure在classpath中發(fā)現(xiàn)Lettuce class會(huì)自動(dòng)注入StringRedisTemplate
     */
    @Autowired
    StringRedisTemplate redisTemplate;

    public void testRedisTemplate() {
        //redisTemplate封裝了對(duì)Lettuce StatefulRedisConnection的調(diào)用
        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) {
        // 創(chuàng)建SpringApplicationContext容器
        ConfigurableApplicationContext applicationContext = SpringApplication.run(LettuceWithRedisTemplate.class, args);
        //從容器中獲取測(cè)試Bean
        LettuceWithRedisTemplate lettuceWithRedisTemplate = applicationContext.getBean(LettuceWithRedisTemplate.class);
        lettuceWithRedisTemplate.testRedisTemplate();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市灾挨,隨后出現(xiàn)的幾起案子邑退,更是在濱河造成了極大的恐慌,老刑警劉巖劳澄,帶你破解...
    沈念sama閱讀 212,185評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件地技,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡秒拔,警方通過(guò)查閱死者的電腦和手機(jī)莫矗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,445評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)砂缩,“玉大人作谚,你說(shuō)我怎么就攤上這事♀职牛” “怎么了妹懒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,684評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)双吆。 經(jīng)常有香客問(wèn)我眨唬,道長(zhǎng)滔悉,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,564評(píng)論 1 284
  • 正文 為了忘掉前任单绑,我火速辦了婚禮,結(jié)果婚禮上曹宴,老公的妹妹穿的比我還像新娘搂橙。我一直安慰自己,他們只是感情好笛坦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,681評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布区转。 她就那樣靜靜地躺著,像睡著了一般版扩。 火紅的嫁衣襯著肌膚如雪废离。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,874評(píng)論 1 290
  • 那天礁芦,我揣著相機(jī)與錄音蜻韭,去河邊找鬼。 笑死柿扣,一個(gè)胖子當(dāng)著我的面吹牛肖方,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播未状,決...
    沈念sama閱讀 39,025評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼俯画,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了司草?” 一聲冷哼從身側(cè)響起艰垂,我...
    開(kāi)封第一講書(shū)人閱讀 37,761評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎埋虹,沒(méi)想到半個(gè)月后猜憎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,217評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吨岭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,545評(píng)論 2 327
  • 正文 我和宋清朗相戀三年拉宗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辣辫。...
    茶點(diǎn)故事閱讀 38,694評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旦事,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出急灭,到底是詐尸還是另有隱情姐浮,我是刑警寧澤,帶...
    沈念sama閱讀 34,351評(píng)論 4 332
  • 正文 年R本政府宣布葬馋,位于F島的核電站卖鲤,受9級(jí)特大地震影響肾扰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蛋逾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,988評(píng)論 3 315
  • 文/蒙蒙 一集晚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧区匣,春花似錦偷拔、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,778評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至姑丑,卻和暖如春蛤签,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背栅哀。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,007評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工震肮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人留拾。 一個(gè)月前我還...
    沈念sama閱讀 46,427評(píng)論 2 360
  • 正文 我出身青樓钙蒙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親间驮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子躬厌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,580評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容