Redis Java Lettuce驅(qū)動框架原理解析
Lettuce是一個高性能基于Java編寫的Redis驅(qū)動框架,底層集成了Project Reactor提供天然的反應(yīng)式編程,通信框架集成了Netty使用了非阻塞IO,5.x版本之后融合了JDK1.8的異步編程特性,在保證高性能的同時提供了十分豐富易用的API,5.1版本的新特性如下:
支持Redis的新增命令ZPOPMIN, ZPOPMAX, BZPOPMIN, BZPOPMAX。 支持通過Brave模塊跟蹤Redis命令執(zhí)行。 支持Redis Streams。 支持異步的主從連接。 支持異步連接池。 新增命令最多執(zhí)行一次模式(禁止自動重連)。 全局命令超時設(shè)置(對異步和反應(yīng)式命令也有效)。 ......等等注意一點:Redis的版本至少需要2.6,當然越高越好,API的兼容性比較強大。
引入依賴項:
<dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>5.3.4.RELEASE</version></dependency>
一、連接Redis
單機、哨兵、集群模式下連接Redis需要一個統(tǒng)一的標準去表示連接的細節(jié)信息,在Lettuce中這個統(tǒng)一的標準是RedisURI。可以通過三種方式構(gòu)造一個RedisURI實例:
定制的字符串URI語法:
RedisURI uri = RedisURI.create('redis://localhost/');
使用建造器(RedisURI.Builder):
RedisURI uri = RedisURI.builder().withHost('localhost').withPort(6379).build();
直接通過構(gòu)造函數(shù)實例化:
RedisURI uri = new RedisURI('localhost', 6379, 60, TimeUnit.SECONDS);
二、基本使用
Lettuce使用的時候依賴于四個主要組件:
RedisURI:連接信息。 RedisClient:Redis客戶端,特殊地,集群連接有一個定制的RedisClusterClient。 Connection:Redis連接,主要是StatefulConnection或者StatefulRedisConnection的子類,連接的類型主要由連接的具體方式(單機、哨兵、集群、訂閱發(fā)布等等)選定,比較重要。 RedisCommands:Redis命令A(yù)PI接口,基本上覆蓋了Redis發(fā)行版本的所有命令,提供了同步(sync)、異步(async)、反應(yīng)式(reative)的調(diào)用方式,對于使用者而言,會經(jīng)常跟RedisCommands系列接口打交道。一個基本使用例子如下:
RedisURI redisUri = RedisURI.builder() // <1> 創(chuàng)建單機連接的連接信息 .withHost('localhost') .withPort(6379) .withTimeout(Duration.of(10, ChronoUnit.SECONDS)) .build();RedisClient redisClient = RedisClient.create(redisUri); // <2> 創(chuàng)建客戶端StatefulRedisConnection<String, String> connection = redisClient.connect(); // <3> 創(chuàng)建線程安全的連接RedisCommands<String, String> redisCommands = connection.sync();// <4> 創(chuàng)建同步命令SetArgs setArgs = SetArgs.Builder.nx().ex(5);String result = redisCommands.set('name', 'throwable', setArgs);result = redisCommands.get('name');System.out.println(result);// ... 其他操作connection.close(); // <5> 關(guān)閉連接redisClient.shutdown(); // <6> 關(guān)閉客戶端
關(guān)閉連接一般在應(yīng)用程序停止之前操作,一個應(yīng)用程序中的一個Redis驅(qū)動實例不需要太多的連接(一般情況下只需要一個連接實例就可以,如果有多個連接的需要可以考慮使用連接池,其實Redis目前處理命令的模塊是單線程,在客戶端多個連接多線程調(diào)用理論上沒有效果)。
關(guān)閉客戶端一般應(yīng)用程序停止之前操作,如果條件允許的話,基于后開先閉原則,客戶端關(guān)閉應(yīng)該在連接關(guān)閉之后操作。
三、Lettuce API
同步(sync):RedisCommands。 異步(async):RedisAsyncCommands。 反應(yīng)式(reactive):RedisReactiveCommands。RedisURI redisUri = RedisURI.builder() .withHost('localhost') .withPort(6379) .withTimeout(Duration.of(10, ChronoUnit.SECONDS)) .build();RedisClient client = RedisClient.create(redisUri);StatefulRedisConnection<String, String> connection = client.connect();
Redis命令A(yù)PI的具體實現(xiàn)可以直接從StatefulRedisConnection實例獲取,見其接口定義:
public interface StatefulRedisConnection<K, V> extends StatefulConnection<K, V> { boolean isMulti(); RedisCommands<K, V> sync(); RedisAsyncCommands<K, V> async(); RedisReactiveCommands<K, V> reactive();}
值得注意的是,在不指定編碼解碼器RedisCodec的前提下,RedisClient創(chuàng)建的StatefulRedisConnection實例一般是泛型實例StatefulRedisConnection<String,String>,也就是所有命令A(yù)PI的KEY和VALUE都是String類型,這種使用方式能滿足大部分的使用場景。當然,必要的時候可以定制編碼解碼器RedisCodec<K,V>。
同步API
先構(gòu)建RedisCommands實例
RedisCommands<String, String> redisCommands= connection.sync();String pong = redisCommands.ping();// 返回PONGSystem.out.println('pong:' + pong);
SetArgs setArgs = SetArgs.Builder.nx().ex(5);redisCommands.set('name', 'throwable', setArgs);String value = redisCommands.get('name');System.out.println('name:' + value);
同步API在所有命令調(diào)用之后會立即返回結(jié)果。如果熟悉Jedis的話,RedisCommands的用法其實和它相差不大。
異步API
先構(gòu)建RedisAsyncCommands實例:
RedisAsyncCommands<String, String> redisCommands = connection.async();
基本使用:
RedisAsyncCommands<String, String> redisCommands = connection.async();RedisFuture<String> redisFuture = redisCommands.ping();// 返回PONGSystem.out.println('pong:' + redisFuture.get());
SetArgs setArgs = SetArgs.Builder.nx().ex(5);RedisFuture<String> future = redisCommands.set('name', 'throwable', setArgs);System.out.println('name:' + future.get());
RedisAsyncCommands所有方法執(zhí)行返回結(jié)果都是RedisFuture實例,而RedisFuture接口的定義如下:
public interface RedisFuture<V> extends CompletionStage<V>, Future<V> { String getError(); boolean await(long timeout, TimeUnit unit) throws InterruptedException;}
也就是,RedisFuture可以無縫使用Future或者JDK1.8中引入的CompletableFuture提供的方法。
反應(yīng)式API
Lettuce引入的反應(yīng)式編程框架是Project Reactor,如果沒有反應(yīng)式編程經(jīng)驗可以先自行了解一下Project Reactor。
構(gòu)建RedisReactiveCommands實例:
RedisReactiveCommands<String, String> redisCommands = connection.reactive();
根據(jù)Project Reactor,RedisReactiveCommands的方法如果返回的結(jié)果只包含0或1個元素,那么返回值類型是Mono,如果返回的結(jié)果包含0到N(N大于0)個元素,那么返回值是Flux。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. Xml簡介_動力節(jié)點Java學(xué)院整理2. UDDI FAQs3. 低版本IE正常運行HTML5+CSS3網(wǎng)站的3種解決方案4. ASP常用日期格式化函數(shù) FormatDate()5. 將properties文件的配置設(shè)置為整個Web應(yīng)用的全局變量實現(xiàn)方法6. CSS可以做的幾個令你嘆為觀止的實例分享7. JSP+Servlet實現(xiàn)文件上傳到服務(wù)器功能8. jsp+servlet實現(xiàn)猜數(shù)字游戲9. jsp文件下載功能實現(xiàn)代碼10. JSP之表單提交get和post的區(qū)別詳解及實例
