Redis Client Lettuce 5 GA发布
經過13個月的開發階段和208張已解決的故障單,我很高興宣布Lettuce 5.0全面上市。 這是一個主要發行版,帶有一些重大更改,新的有趣功能以及Java 9兼容性。
從Maven Central獲取發布
<dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>5.0.0.RELEASE</version> </dependency>或從GitHub下載發行包 。
生菜5引入了動態的Redis命令API。 此編程模型使您可以聲明命令方法并根據需要調用命令并支持Redis模塊,而無需等待Lettuce支持新命令。
如果本地依賴項可用,則萵苣在Linux各自的macOS系統上默認為本地傳輸(epoll,kqueue)。
生菜5帶來了重大變化。 它刪除了過時的接口RedisConnection和RedisAsyncConnection以及它們分離的接口,從而支持StatefulRedisConnection和RedisCommands等。
重大更改:
生菜只需要netty 4.1 (不再支持netty 4.0)和Project Reactor 3.1 ,這使我們有了下一個變化:
通過使用Project Reactor類型Mono和Flux而不是RxJava 1和Observable ,反應式API基于反應式流。
如果您的代碼中需要RxJava的Single和Observable ,則在rxjava-reactive-streams使用發布者適配器來適應Mono和Flux 。
此版本引入了隨常規工件一起提供的新參考指南。
該參考指南綁定到特定版本,并且不會隨著時間的推移而更改,例如Wiki。
- 參考文檔: https : //lettuce.io/core/release/reference/ 。
- JavaDoc文檔: https : //lettuce.io/core/release/api/ 。
您可以找到完整的更改日志,其中包含自第一個5.0里程碑版本以來的所有更改,
在GitHub上 。 當心BREAKING更改。
感謝所有使生菜5成為可能的貢獻者。 感謝任何反饋或在GitHub上提出問題 。
動態Redis命令API
Redis命令接口抽象為類型安全的Redis命令調用提供了一種動態方式。 它允許您使用命令方法聲明接口,以顯著減少調用Redis命令所需的樣板代碼。
Redis是一個數據存儲,支持190多個已記錄命令和450多個命令排列。 對于客戶端開發人員和Redis用戶而言,命令的增長和對即將發布的模塊的跟蹤是一項挑戰,因為單個Redis客戶端中的每個模塊都沒有完整的命令覆蓋范圍。
用Lettuce調用自定義命令需要幾行代碼來定義傳遞參數的命令結構并指定返回類型。
RedisCodec<String, String> codec = StringCodec.UTF8; RedisCommands<String, String> commands = ...String response = redis.dispatch(CommandType.SET, new StatusOutput<>(codec),new CommandArgs<>(codec).addKey(key).addValue(value));Lettuce Command Interface抽象中的中心接口是Commands 。
該界面主要用作標記界面,可幫助您發現擴展該界面的界面。 您可以聲明自己的命令接口和參數序列,其中命令名稱是從方法名稱派生的,或由@Command提供。 引入新命令不需要您等待新的Lettuce版本,但是它們可以通過自己的聲明來調用命令。
該接口還可以根據用例支持不同的鍵和值類型。
根據方法聲明,命令是同步執行,異步執行還是使用反應執行模型執行。
public interface MyRedisCommands extends Commands {String get(String key); // Synchronous Execution of GET@Command("GET")byte[] getAsBytes(String key); // Synchronous Execution of GET returning data as byte array@Command("SET") // synchronous execution applying a TimeoutString setSync(String key, String value, Timeout timeout);Future<String> set(String key, String value); // asynchronous SET execution@Command("SET")Mono<String> setReactive(String key, String value); // reactive SET execution using SetArgs@CommandNaming(split = DOT) // support for Redis Module command notation -> NR.RUNdouble nrRun(String key, int... indexes); }RedisCommandFactory factory = new RedisCommandFactory(connection);MyRedisCommands commands = factory.getCommands(MyRedisCommands.class);String value = commands.get("key"); Redis命令界面給您帶來了很多新的可能性。 其中之一是透明的反應式采用。 Lettuce的反應式API基于Reactive Streams,但是通過命令接口,您可以聲明RxJava 1或RxJava 2返回類型,Lettuce將為您處理采用。 RxJava 1用戶的遷移路徑允許使用本機類型而無需
進一步轉換。
另請參閱: https : //lettuce.io/core/5.0.0.RELEASE/reference/#redis-command-interfaces
命令界面批處理
命令接口支持命令批處理,以在批處理隊列中收集多個命令,并通過一次寫入傳輸將批處理刷新。 命令批處理以延遲的方式執行命令。 這意味著在調用時沒有可用的結果。 批處理只能用于沒有返回值(void)的同步方法或返回RedisFuture的異步方法。
可以在兩個級別上啟用命令批處理:
- 在類級別,通過使用@BatchSize注釋命令界面。 所有方法都參與命令批處理。
- 在方法級別,通過將CommandBatching添加到參數中。 方法有選擇地參與命令批處理。
了解更多: https : //lettuce.io/core/5.0.0.RELEASE/reference/#command-interfaces.batch
遷移到反應流
Lettuce 4.0引入了基于RxJava 1和Observable的反應式API。 這是響應式Redis支持的開始。 生菜在各處都使用Observable ,因為其他反應式(如Single和Completable )仍處于測試階段或正在開發中。
從那時起,反應空間發生了很多變化。 RxJava 2是RxJava 1的后繼產品,現已到期。 RxJava 2并不完全基于Java 6的響應流和基線,而其他合成庫也可以從Java 8中受益。
這也意味著,沒有null值,并且使用專用值類型來表示API上的值多重性( 0|1和0|1|N )。
在Lettuce 5.0中,反應式API使用Project Reactor及其Mono和Flux類型。
生菜4
Observable<Long> del(K... keys);Observable<K> keys(K pattern);Observable<V> mget(K... keys);生菜5
Mono<Long> del(K... keys);Flux<K> keys(K pattern);Flux<KeyValue<K, V>> mget(K... keys);從RxJava 1切換到Project Reactor的使用需要切換庫。 大多數運營商使用相似甚至相同的名稱。 如果需要堅持使用RxJava 1,請使用rxjava-reactive-streams采用反應類型(RxJava 1 <-> Reactive Streams)。
遷移到反應流需要值包裝以指示不存在值。 在命令可以返回null值的情況下,您會發現與以前的API和同步/異步API相比有所不同。 Lettuce 5.0附帶了新的Value類型,這些類型是封裝值(或不存在)的單子。
另請參閱: https : //lettuce.io/core/5.0.0.RELEASE/reference/#reactive-api
值,鍵值和其他值類型
反應式故事促進了不可變類型的實現,因此此發行版增強了現有的值類型并引入了新的類型以減少null使用并促進函數式編程。
值類型是基于Value和KeyValue / ScoredValue延伸從那里。 值是封裝值或不存在的包裝器類型。 Value可以通過不同的方式創建:
Value<String> value = Value.from(Optional.of("hello"));Value<String> value = Value.fromNullable(null);Value<String> value = Value.just("hello");KeyValue<Long, String> value = KeyValue.from(1L, Optional.of("hello"));KeyValue<String, String> value = KeyValue.just("key", "hello");它轉換為Optional和Stream以與其他功能用途集成,并允許值映射。
Value.just("hello").stream().filter(…).count();KeyValue.just("hello").optional().isPresent();Value.from(Optional.of("hello")).map(s -> s + "-world").getValue();ScoredValue.just(42, "hello").mapScore(number -> number.doubleValue() * 3.14d).getScore();您還將發現,所有值類型的公共字段都用getter封裝,并且這些字段不再可訪問。
退避/延遲策略
感謝@jongyeol
當運行具有大量使用Redis的服務的基于云的服務時,一旦分區結束,網絡分區將嚴重影響Redis服務器的連接。 網絡分區會同時影響所有斷開連接的應用程序,并且所有節點或多或少會同時開始重新連接。
分區結束后,大多數應用程序將同時重新連接。 隨著重新連接時間的隨機化,抖動回退策略可以充分利用這種影響。
生菜具有各種退避實現:
- 均等抖動
- 全抖動
- 與裝飾相關的抖動
這些在ClientResources中配置:
DefaultClientResources.builder().reconnectDelay(Delay.decorrelatedJitter()).build();DefaultClientResources.builder().reconnectDelay(Delay.equalJitter()).build(); 另請參閱: https : //www.awsarchitectureblog.com/2015/03/backoff.html和
https://lettuce.io/core/5.0.0.RELEASE/reference/#clientresources.advanced-settings
Z…RANGE命令的新API
排序集范圍命令附帶有關方法重載的簡化API。 ZRANGEBYSCORE ,諸如ZRANGEBYSCORE , ZRANGEBYLEX , ZREMRANGEBYLEX等命令聲明了接受Range和Limit對象而不是不斷增長的參數列表的方法。 新的Range允許分數和值類型應用適當的二進制編碼。
4.2及更早版本
commands.zcount(key, 1.0, 3.0)commands.zrangebyscore(key, "-inf", "+inf")commands.zrangebyscoreWithScores(key, "[1.0", "(4.0")commands.zrangebyscoreWithScores(key, "-inf", "+inf", 2, 2)從5.0開始
commands.zcount(key, Range.create(1.0, 3.0));commands.zrangebyscore(key, Range.unbounded());commands.zrangebyscoreWithScores(key, Range.from(Boundary.including(1.0), Boundary.excluding(4.0));commands.zrangebyscoreWithScores(key, Range.unbounded(), Limit.create(2, 2));再見了番石榴
Lettuce 5.0不再使用Google的Guava庫。 Guava是Java 6兼容時代的好朋友, Future同步和回調很無聊。 隨Java 8和CompletableFuture改變了。
HostAndPort或LoadingCache等其他用途可以被內聯或替換為Java 8的Collection框架。
刪除不推薦使用的接口和方法
此發行版刪除了不推薦使用的接口RedisConnection和RedisAsyncConnection及其分離的接口,而支持StatefulRedisConnection和RedisCommands 。
使用該API時,您會發現細微的差別。 事務命令和數據庫選擇不再通過Redis Cluster API可用,因為舊API是從獨立API派生的。 RedisCommands和RedisAsyncCommands不再是Closeable 。 請使用commands.getStatefulConnection().close()關閉連接。 此更改消除了關閉命令界面和關閉連接的歧義。
連接池更換
花了相當長的時間,但4.3不贊成使用Lettuce的現有連接池支持。 特別是RedisClient.pool(…)和RedisClient.asyncPool(…) 。 這些方法在Lettuce 5.0中已刪除。
連接池的支持非常有限,并且將需要額外的重載,從而使API混亂以暴露所有支持的連接的池。 此版本帶來了一個可定制且不會污染API的替代品。 ConnectionPoolSupport提供了一些方法來創建接受工廠方法和池配置的連接池。
返回的連接對象是在調用close()時將連接返回到其池的代理。 StatefulConnection實施Closeable允許使用try-with-resources。
GenericObjectPool<StatefulRedisConnection<String, String>> pool = ConnectionPoolSupport.createGenericObjectPool(() -> client.connect(), new GenericObjectPoolConfig());try(StatefulRedisConnection<String, String> connection = pool.borrowObject()) {// Work }pool.close();Redis集群拓撲刷新共識
群集拓撲刷新在某些情況下(動態拓撲源)可能導致孤立。 如果從群集中刪除了群集節點,而生菜決定接受該已刪除節點的拓撲視圖,則可能會發生這種情況。 生菜卡在該節點上,無法使用剩余的群集。
此版本引入了PartitionsConsensus策略,以便在獲取多個視圖時確定最合適的拓撲視圖。 可以通過重寫RedisClusterClient.determinePartitions(Partitions, Map<RedisURI, Partitions>)定義策略。
生菜默認選擇具有大多數先前已知群集節點的拓撲視圖。 這有助于生菜堅持由最多節點組成的群集。
另請參閱: https : //github.com/lettuce-io/lettuce-core/issues/355
Redis集群中的異步連接
RedisClusterClient現在異步連接,而沒有中間阻塞到集群節點。 連接進度在之間共享
多個線程首次請求群集節點連接。 以前,連接是順序同步的。 每次連接嘗試都會阻止其他線程的后續嘗試。 如果群集節點連接超時,則線程將受到等待時間增加的懲罰。 如果說有10個線程等待連接,則最后一個線程必須等待多達10倍的連接超時。
異步連接一旦在內部使用Future即可啟動連接,因此多個并發連接嘗試會共享結果Future 。 錯誤現在可以更快地失敗,并且群集節點的使用完全異步,無需同步,也沒有陷入線程死鎖的危險。
Redis Cluster Pub / Sub關于節點選擇
RedisClusterClient.connectPubSub()現在返回一個StatefulRedisClusterPubSubConnection ,該StatefulRedisClusterPubSubConnection允許RedisClusterPubSubListener的注冊以及在特定集群節點上的預訂。
特定于群集節點的訂閱允許使用鍵空間通知。 密鑰空間通知不同于用戶空間Pub / Sub,因為密鑰空間通知不會廣播到整個集群,而是僅在發生通知的節點上發布。 一個常見的用例是密鑰在集群中過期。
StatefulRedisClusterPubSubConnection connection = client.connectPubSub();connection.addListener(…);connection.setNodeMessagePropagation(true);RedisClusterPubSubCommands<String, String> sync = connection.sync(); sync.slaves().commands().psubscribe("__key*__:expire");本地運輸
如果操作系統是合格的并且依賴項可用,則Lettuce現在默認情況下使用本機傳輸。 Lettuce從4.0版本開始支持epoll(在基于Linux的系統上),從此版本開始支持kqueue(基于BSD的系統,如macOS)。
可以通過設置io.lettuce.core.epoll=false來禁用Epoll的使用和系統屬性。 以類似的方式,可以禁用kqueue
與io.lettuce.core.kqueue=false 。
Epoll依賴性:
<dependency><groupId>io.netty</groupId><artifactId>netty-transport-native-epoll</artifactId><version>${netty-version}</version><classifier>linux-x86_64</classifier> </dependency>Kqueue依賴項:
<dependency><groupId>io.netty</groupId><artifactId>netty-transport-native-kqueue</artifactId><version>${netty-version}</version><classifier>osx-x86_64</classifier> </dependency>翻譯自: https://www.javacodegeeks.com/2017/09/redis-client-lettuce-5-ga-released.html
總結
以上是生活随笔為你收集整理的Redis Client Lettuce 5 GA发布的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小米note配置(小米Note10配置)
- 下一篇: jax-ws cxf_走向REST:在S