Releases: redis/lettuce
5.0.2.RELEASE
This is the second bugfix release for Lettuce 5 shipping with 21 tickets resolved. It contains fixes for improved resilience behavior.
Upgrading is recommended.
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
Enhancements
- Do not fail if COMMAND command fails on startup #685 (Thanks to @pujian1984)
Fixes
- CommandHandler.rebuildQueue() causes long locks #615 (Thanks to @NikolaySPb)
- Cannot close connection when refreshing topology #656 (Thanks to @dangtranhoang)
- Weights param should be ignored if it is empty #657 (Thanks to @garfeildma)
- MasterSlave getNodeSpecificViews NPE with sync API #659 (Thanks to @boughtonp)
- RandomServerHandler can respond zero bytes #660
- ConcurrentModificationException when connecting a RedisClusterClient #663 (Thanks to @blahblahasdf)
- Switch RedisSubscription.subscriber to volatile #664
- Recovered Sentinels in Master/Slave not reconnected #668
- Handling dead Sentinel slaves #669 (Thanks to @vleushin)
- Support SLAVE_PREFERRED at valueOf method #671 (Thanks to @be-hase)
- RedisCommandTimeoutException after two subsequent MULTI calls without executing the transaction #673 (Thanks to @destitutus)
- Fix ConnectionWatchDog won't reconnect problem in edge case #679 (Thanks to @kojilin)
- At least once mode keeps requeueing commands on non-recoverable errors #680 (Thanks to @mrvisser)
- Retain ssl/tls config from seed uris in Master/Slave context #684 (Thanks to @acmcelwee)
- NOAUTH after full queue and reconnect #691
- RedisURI.create("localhost") causes NPE #694
Other
- Upgrade to Reactor Bismuth SR5 #698
- Upgrade to netty 4.1.21.Final #699
- Upgrade to RxJava 1.3.6 #700
- Upgrade to RxJava 2.1.9 #701
- Upgrade to Reactor Bismuth SR5 #704
Documentation
- Reference documentation: https://lettuce.io/core/5.0.2.RELEASE/reference/.
- JavaDoc documentation: https://lettuce.io/core/5.0.2.RELEASE/api/.
4.4.3.Final
This is the third bugfix release for Lettuce 4.4 shipping with 16 tickets fixed along with a few dependency upgrades.
It contains fixes for improved resilience behavior.
Upgrading is recommended.
<dependency>
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>4.4.3.Final</version>
</dependency>
Enhancements
- Do not fail if COMMAND command fails on startup #685 (Thanks to @pujian1984)
Fixes
- Weights param should be ignored if it is empty #657 (Thanks to @garfeildma)
- MasterSlave getNodeSpecificViews NPE with sync API #659 (Thanks to @boughtonp)
- RandomServerHandler can respond zero bytes #660
- ConcurrentModificationException when connecting a RedisClusterClient #663 (Thanks to @blahblahasdf)
- Recovered Sentinels in Master/Slave not reconnected #668
- Handling dead Sentinel slaves #669 (Thanks to @vleushin)
- Support SLAVE_PREFERRED at valueOf method #671 (Thanks to @be-hase)
- RedisCommandTimeoutException after two subsequent MULTI calls without executing the transaction #673 (Thanks to @destitutus)
- Fix ConnectionWatchDog won't reconnect problem in edge case #679 (Thanks to @kojilin)
- At least once mode keeps requeueing commands on non-recoverable errors #680 (Thanks to @mrvisser)
- Retain ssl/tls config from seed uris in Master/Slave context #684 (Thanks to @acmcelwee)
- NOAUTH after full queue and reconnect #691
- RedisURI.create("localhost") causes NPE #694
Other
Documentation
- JavaDoc documentation: https://lettuce.io/lettuce-4/4.4.3.Final/api/.
5.0.1.RELEASE
This is the first bugfix release for Lettuce 5 shipping with 20 tickets fixed and dependency upgrades. It contains fixes for resilience and error scenario handling and the dynamic command interfaces support. It also fixes an issue in the reactive API when using two or more threads to consume a RedisPublisher where it's possible the publisher never completes.
Upgrading is strongly recommended upgrade when using the reactive API.
Enhancements
- Add SocketAddressOutput to directly parse SENTINEL get-master-addr-by-name output #644
Fixes
- Lettuce doesn't fail early & cleanly with a host in protected mode #608 (Thanks to @exercitussolus)
- CommandHandler.rebuildQueue() causes long locks #615 (Thanks to @NikolaySPb)
- Request queue size is not cleared on reconnect #616 (Thanks to @NikolaySPb)
- BITPOS should allow to just specify start #623 (Thanks to @christophstrobl)
- HMGET proxy not working as expected #627 (Thanks to @moores-expedia)
- Consider binary arguments using command interfaces as keys using binary codecs #628
- Command.isDone() not consistent with CompletableFuture.isDone() #629
- Race condition in RedisPublisher DEMAND.request() and DEMAND.onDataAvailable() #634 (Thanks to @mayamoon)
- RedisPublisher.request(-1) does not fail #635
- Capture subscription state before logging in RedisPublisher #636
- Provide Javadoc path for Project Reactor #641
- Debug logging of ConnectionWatchdog has wrong prefix after reconnect #645 (Thanks to @mlex)
Other
- Upgrade to netty 4.1.17.Final #646
- Upgrade to Spring Framework 4.3.12 #648
- Upgrade to Commons Pool 2.4.3
- Upgrade to RxJava 1.3.3 #651
- Upgrade to RxJava2 2.1.6 #652
- Upgrade to HdrHistogram 2.1.10 #653
- Upgrade to Reactor Bismuth SR4 #647
Documentation
Reference documentation: https://lettuce.io/core/5.0.1.RELEASE/reference/.
JavaDoc documentation: https://lettuce.io/core/5.0.1.RELEASE/api/.
4.4.2.Final
This release ships with 15 tickets fixed along with a few dependency upgrades. The most significant change improves retry behavior with more than 1000 queued commands and an issue when using default methods on Java 9.
Enhancements
- Add SocketAddressOutput to directly parse SENTINEL get-master-addr-by-name output #644
Fixes
- Lettuce doesn't fail early & cleanly with a host in protected mode #608 (Thanks to @exercitussolus)
- Fix encapsulated default method lookup on interfaces #614
- CommandHandler.rebuildQueue() causes long locks #615 (Thanks to @NikolaySPb)
- Request queue size is not cleared on reconnect #616 (Thanks to @NikolaySPb)
- BITPOS should allow to just specify start #623 (Thanks to @christophstrobl)
- Command.isDone() not consistent with CompletableFuture.isDone() #629
- Provide Javadoc path for Project Reactor #641
- Debug logging of ConnectionWatchdog has wrong prefix after reconnect #645 (Thanks to @mlex)
Other
- Upgrade to netty 4.0.53.Final/4.1.17.Final #646
- Upgrade to Spring Framework 4.3.12 #648
- Upgrade to Commons Pool 2.4.3 #650
- Upgrade to RxJava 1.3.3 #651
- Upgrade to HdrHistogram 2.1.10 #653
- Upgrade Redis versions on TravisCI #655
Documentation
Browse the docs at https://github.com/lettuce-io/lettuce-core/wiki.
JavaDoc: https://lettuce.io/lettuce-4/4.4.2.Final/api/
5.0.0.RELEASE
After a 13 months development phase and 208 solved tickets, it is my pleasure to announce general availability of Lettuce 5.0.
This is a major release coming with several breaking changes and new interesting features and Java 9 compatibility.
Lettuce 5 introduces the dynamic Redis Commands API. This programming model enables you to declare command methods and invoke commands to your needs and support Redis Modules without waiting for Lettuce to support new commands.
Lettuce defaults to native transport (epoll, kqueue) on Linux respective macOS systems if the native dependency is available. You can disable this behavior by setting the system property io.lettuce.core.epoll
and io.lettuce.core.kqueue
to false
.
Lettuce 5 comes with breaking changes; it removes deprecated interfaces RedisConnection and RedisAsyncConnection and their segregated interfaces in favor of StatefulRedisConnection and RedisCommands et al.
Major breaking changes:
- We moved the artifact coordinates from biz.paluch.redis:lettuce to io.lettuce:lettuce-core
- We relocated packages from biz.paluch.redis to io.lettuce.core. The migration path is straight-forward by replacing the old package name in your imports with the new package name.
- The documentation has moved from http://redis.paluch.biz to https://lettuce.io.
- Removed Guava.
- We removed some deprecated methods, see below for full details.
Lettuce requires only netty and Project Reactor which brings us to the next change:
The reactive API is based on Reactive Streams by using Project Reactor types Mono
and Flux
instead of RxJava 1 and Observable
.
If you require RxJava's Single
and Observable
in your code, then use publisher adapters in rxjava-reactive-streams
to adapt Mono
and Flux
.
This release introduces a new reference guide that is shipped along the regular artifacts.
The reference guide is bound to a particular version and does not change over time, such as the Wiki.
Reference documentation: https://lettuce.io/core/release/reference/.
JavaDoc documentation: https://lettuce.io/core/release/api/.
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
You can find the full change log, containing all changes since the first 5.0 milestone release,
at the end of this document. Watch out for BREAKING changes.
Thanks to all contributors that made Lettuce 5 possible.
Dynamic Redis Commands API
The Redis Command Interface abstraction provides a dynamic way for typesafe Redis command invocation. It allows you to declare an interface with command methods to significantly reduce boilerplate code required to invoke a Redis command.
Redis is a data store supporting over 190 documented commands and over 450 command permutations. Command growth and keeping track with upcoming modules are challenging for client developers and Redis user as there is no full command coverage for each module in a single Redis client.
Invoking a custom command with Lettuce requires several lines of code to define command structures pass in arguments and specify the return type.
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));
The central interface in Lettuce Command Interface abstraction is Commands
.
This interface acts primarily as a marker interface to help you to discover interfaces that extend this one. You can declare your own command interfaces and argument sequences where the command name is derived from the method name or provided with @Command
. Introduction of new commands does not require you to wait for a new Lettuce release but they can invoke commands through own declaration.
That interface could be also supporting different key and value types, depending on the use-case.
Commands are executed synchronously, asynchronous or with a reactive execution model, depending on the method declaration.
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 Timeout
String 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.RUN
double nrRun(String key, int... indexes);
}
RedisCommandFactory factory = new RedisCommandFactory(connection);
MyRedisCommands commands = factory.getCommands(MyRedisCommands.class);
String value = commands.get("key");
You get a whole lot new possibilities with Redis Command Interfaces. One of them is transparent reactive type adoption. Lettuce's reactive API is based on Reactive Streams, however with command interfaces you can declare a RxJava 1 or RxJava 2 return type and Lettuce will handle the adoption for you. RxJava 1 users have a migration path that allows using native types without
further conversion.
See also: https://lettuce.io/core/5.0.0.RELEASE/reference/#redis-command-interfaces
Command Interface Batching
Command interfaces support command batching to collect multiple commands in a batch queue and flush the batch in a single write to the transport. Command batching executes commands in a deferred nature. This means that at the time of invocation no result is available. Batching can be only used with synchronous methods without a return value (void) or asynchronous methods returning a RedisFuture.
Command batching can be enabled on two levels:
- On class level by annotating the command interface with
@BatchSize
. All methods participate in command batching. - On method level by adding
CommandBatching
to the arguments. Method participates selectively in command batching.
@BatchSize(50)
interface StringCommands extends Commands {
void set(String key, String value);
RedisFuture<String> get(String key);
RedisFuture<String> get(String key, CommandBatching batching);
}
StringCommands commands = …
commands.set("key", "value"); // queued until 50 command invocations reached.
// The 50th invocation flushes the queue.
commands.get("key", CommandBatching.queue()); // invocation-level queueing control
commands.get("key", CommandBatching.flush()); // invocation-level queueing control,
// flushes all queued commands
Read more: https://lettuce.io/core/5.0.0.RELEASE/reference/#command-interfaces.batch
Migration to Reactive Streams
Lettuce 4.0 introduced a reactive API based on RxJava 1 and Observable
. This was the beginning of reactive Redis support. Lettuce used Observable
all over the place as other reactive types like Single
and Completable
were still beta or in development.
Since that time, a lot changed in the reactive space. RxJava 2 is the successor of RxJava 1 which has now reached end of life. RxJava 2 is not entirely based on Reactive Streams and baselines to Java 6 while other composition libraries can benefit from a Java 8.
This also means, no null
values and usage of dedicated value types to express value multiplicity (0|1
and 0|1|N
) on the API.
With Lettuce 5.0, the reactive API uses Project Reactor with its Mono
and Flux
types.
Lettuce 4
Observable<Long> del(K... keys);
Observable<K> keys(K pattern);
Observable<V> mget(K... keys);
Lettuce 5
Mono<Long> del(K... keys);
Flux<K> keys(K pattern);
Flux<KeyValue<K, V>> mget(K... keys);
Switching from RxJava 1 to Project Reactor use requires switching the library. Most operators use similar or even same names. If you're required to stick to RxJava 1, the use rxjava-reactive-streams
to adopt reactive types (RxJava 1 <-> Reactive Streams).
Migrating to Reactive Streams requires value wrapping to indicate absence of values. You will find differences in comparison to the previous API and to the sync/async API in cases where commands can return null
values. Lettuce 5.0 comes with new Value
types that are monads encapsulating a value (or their absence).
See also: https://lettuce.io/core/5.0.0.RELEASE/reference/#reactive-api
Value, KeyValue, and other value types
The reactive story facilitates immutable types so this release enhances existing value types and introduces new types to reduce null
usage and facilitate functional programming.
Value types are based on Value
and KeyValue
/ScoredValue
extend from there. Value is a wrapper type encapsulating a value or its absence. A Value
can be created in different ways:
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");
It transforms to Optional
and Stream
to integrate with other functional uses and allows value mapping.
Value.just("hello").stream().fil...
5.0.0.RC2
This release ships with 12 issues resolved and upgraded dependencies that contain breaking changes for Lettuce.
Enhancements
- Optimization for ValueListOutput #573 (Thanks to @CodingFabian)
- Enhance argument caching #575
- Introduce MethodTranslator caching #580
- Execute RedisAdvancedClusterCommands.scriptLoad(…) on all nodes #590
Fixes
- NPE in RedisStateMachine #576 (Thanks to @NikolaySPb)
- Prevent dead listener callbacks in shutdown sequence #581
- Javadoc in BitFieldArgs contains invalid links #583
- Fix IllegalArgumentException in RedisClient.connectSentinel #588 (Thanks to @andrewsensus)
- UnsupportedOperationException (List#add) in NestedMultiOutput #589 (Thanks to @zapl)
- GEOPOS fails with a single member in the var args #591 (Thanks to @FerhatSavci)
Other
Documentation
Browse the docs at https://lettuce.io/core/5.0.0.RC2/reference/
JavaDoc: https://lettuce.io/core/5.0.0.RC2/api/
4.4.1.Final
This release ships with 5 tickets resolved of which the majority fixes bugs.
Fixes
- Fix IllegalArgumentException in RedisClient.connectSentinel #588
- UnsupportedOperationException (List#add) in NestedMultiOutput #589
- GEOPOS fails with a single member in the var args #591
- Reduce logging of native transport state to INFO bug #596
Other
- Upgrade to netty 4.0.51/4.1.15 #600
Documentation
Browse the docs at https://github.com/lettuce-io/lettuce-core/wiki.
JavaDoc: https://lettuce.io/lettuce-4/4.4.1.Final/api/
4.4.0.Final
This release ships with 96 tickets fixed and is fully compatible with Redis 4.0.
It contains a range of performance improvements to lower GC pressure, introducing kqueue native transport on BSD-like systems and asynchronous, connection initialization for Redis Cluster and Cluster Pub/Sub subscriptions.
This release is compatible with Java 9 (class-path mode) requiring at least netty 4.1.11.Final.
Thanks to all contributors who made Lettuce 4.4.0 possible.
Redis Cluster Pub/Sub on Node-Selections
RedisClusterClient.connectPubSub()
now returns a StatefulRedisClusterPubSubConnection
that allows registration of RedisClusterPubSubListener
s and subscription on particular cluster nodes.
Cluster node-specific subscriptions allow usage of keyspace notifications. Keyspace notifications are different from userspace Pub/Sub since keyspace notifications don't broadcast to the entire cluster but are published only on the node the notification happens. A common usecase is when a key expires in the cluster.
StatefulRedisClusterPubSubConnection connection = client.connectPubSub();
connection.addListener(…);
connection.setNodeMessagePropagation(true);
RedisClusterPubSubCommands<String, String> sync = connection.sync();
sync.slaves().commands().psubscribe("__key*__:expire");
Native Transports
Lettuce now uses native transports by default, if the operating system is qualified and dependencies are available. Lettuce supports epoll (on Linux-based systems) since 4.0 and since this version kqueue (BSD-based systems, like macOS).
Epoll usage can be disabled with system properties by setting io.lettuce.core.epoll=false
. In a similar way, kqueue can be disabled with io.lettuce.core.kqueue=false
.
Epoll dependency:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty-version}</version>
<classifier>linux-x86_64</classifier>
</dependency>
Kqueue dependency:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-kqueue</artifactId>
<version>${netty-version}</version>
<classifier>osx-x86_64</classifier>
</dependency>
Asynchronous Connections in Redis Cluster
RedisClusterClient now connects asynchronously without intermediate synchronization to cluster nodes. The connection progress is shared between multiple threads that request a cluster node connection for the first time. Previously, connection was sequential-synchronous. Each connection attempt blocked subsequent attempts from other threads. If a cluster node connection ran into a timeout, threads were penalized with a growing wait time. If, say, 10 threads waited for a connection, the last thread had to wait up to 10 times the connection timeout.
Asynchronous connection initiates the connection once using internally a Future
so multiple concurrent connection attempts share the resulting Future
. Errors fail now faster and cluster node usage is fully asynchronous without synchronization and without the danger to run into a threading deadlock.
Scan Iterators
Scan operations (SCAN
, HSCAN
, SSCAN
, ZSCAN
) can be used through an enhanced ScanIterator
API. Scan iterators implement Iterator
allowing Java 8 stream usage and work with synchronous Redis Standalone and Redis Cluster connections. Scan iterators remove the complexity of cursor handling for initial/subsequent SCAN
commands and do not require a different approach
whether you use Redis Standalone or Redis Cluster.
RedisCommands<String, String> commands = …
ScanIterator<String> scan = ScanIterator.scan(commands, ScanArgs.Builder.limit(50).match("foo"));
// Iterator use
while(scan.hasNext()) {
// …
}
// Java 8 Stream
scan.stream().filter(…).map(…).forEach(…)
Commands
- Adopt to read-only variant GEORADIUS(BYMEMBER)_RO #564
- Support CLIENT and INFO commands for Redis Sentinel #415
Enhancements
- Allow Pub/Sub subscriptions on a node selection within Redis Cluster #385
- Document RedisClient and RedisClusterClient implementation hooks #392 (Thanks to @HaloFour)
- Provide scan iterators for SCAN/HSCAN/SSCAN and ZSCAN commands #397
- Extend RedisClusterClient and RedisClusterFactoryBean to take multiple hosts #401
- Default to epoll transport if available #402
- Simplify NodeSelection implementation #408
- Allow setting client name with RedisURI #416
- Extend RedisConnectionStateListener.onRedisConnected by adding SocketAddress #419
- Connect asynchronously in cluster topology refresh #424 (Thanks to @szabowexler)
- Propagate asynchronous connection initialization #429
- Reuse stale connections collection when closing stale connections #443
- Add ReadFrom.SLAVE_PREFERRED #452 (Thanks to @Spikhalskiy)
- Avoid or reduce connection attempts to nodes in fail state #453 (Thanks to @Spikhalskiy)
- Store ReadOnly commands and query these as bitmask #457
- Initialize RedisStateMachine.LongProcessor in static initializer #481 (Thanks to @hellyguo)
- Add shutdownAsync for RedisClient #485 (Thanks to @jongyeol)
- Resolve hostnames using netty's DNS resolver #498
- Introduce NettyCustomizer API #499
- Use asynchronous connect in NodeSelection API #500
- Gracefully degrade to successfully connected Cluster read candidates #503 (Thanks to @eliotw)
- CommandHandler performs expensive queue check if requestQueueSize != Integer.MAX_VALUE #507 (Thanks to @CodingFabian)
- Consider using ThreadLocalRandom instead of Random in RedisAdvancedCluster…CommandsImpl #510
- Lots of memory occupied by firstInteger in CommandArgs #511 (Thanks to @CodingFabian)
- Close/reconnect the connection when Redis protocol is corrupted #512 (Thanks to @jongyeol)
- Allow setting the Redis password as char-array #513
- Replace synchronized reconnect in ConnectionWatchdog with asynchronous connect #514
- Align log prefix for CommandHandler and ConnectionWatchdog #538
- Add support for kqueue transport #539
- Add support for client certificate authentication #540
- Reduce cross-thread queue sharing #544
- Use pre-instantiated ByteBufProcessor in RedisStateMachine to find EOL #557
- Replace CountDownLatch in AsyncCommand with AtomicFieldUpdater #559
- Allocate lazily of array outputs targets #573
- Enhance SingularArgument caching #575
- Reuse CommandHandler decoding via PubSubCommandHandler #576
- Introduce MethodTranslator caching #580
Fixes
- Fail to second call pool.borrowObject() using StatefulRedisMasterSlaveConnection in 4.3.0.Final #411 (Thanks to @krisjey)
- Deprecate addListener/removeListener methods from execution-specific Pub/Sub interfaces. #412
- Unexpected 'Invalid database number' exception for database > 15 #420 (Thanks to @ChitraGuru)
- Dynamic API: array of arguments are not supported #421 (Thanks to @coolmeen)
- ClusterClientOptions.socketOptions returns ClientOptions.Builder #425 (Thanks to @maxd)
- Lettuce suppresses initial exception in Redis Cluster #427 (Thanks to @maxd)
- CDI can't create RedisClusterClient because of missing default constructor #438 (Thanks to @wuhuaxu)
- RoundRobinSocketAddressSupplier may contain more RedisClusterNodes than the current topology view #440
- Partitions.addPartition and reload not correctly synchronized #442
- pingBeforeActivateConnection and authentication fails using Redis Sentinel #448 (Thanks to @coolmeen)
- PooledClusterConnectionProvider.close does not close connections #460
- Possible race condition in ReconnectHandler.prepareClose() #465
- Dynamic API: Interface implementation fails for non-string connections #467
- ChannelInitializer (PING before connect) waits indefinite #470
- RedisClient.shutdown() does not synchronize on clientResources.shutdown future #475
- Unknown channel option warnings in log using UDS #476 (Thanks to @magdkudama)
- BlockingOperationException using RedisClusterClient with rxjava keys operation #486 (Thanks to @jeniok)
- Latency metrics is reset even if set to false #487 (Thanks to @ameenhere)
- firstResponseLatency depends on command completion time #491
- Shutdown PauseDetector if DefaultCommandLatencyCollector is shut down and PauseDetector is no longer required #516
- LatencyStats leaves PauseDetectorListener registered #517
- Shaded JAR contains too many dependencies #519
- Fix static initialization of PauseDetector when LatencyUtils are not on the class path #520
- jcl-over-slf4j is a compile dependency instead of test dependency #526
- NumberFormatException on "inf" zscore #528 (Thanks to @DarkSeraphim)
- Connection pool deadlock #531 (Thanks to @DarkSeraphim)
- Improve Epoll availability detection #535
- Close connections in pooling destroy hook #545
- Adopt to changed SLOWLOG output #551
- CommandHandler.write contains isConnected verification #556
- Reduce (eliminate byte[]) duplication during slot hash calculation #558
- clientSetname does not set client name on default connection #563
- Avoid getBytes() calls on constant value in ExperimentalByteArrayCodec #574(Thanks to @CodingFabian)
- Prevent dead listener callback failure in shutdown sequence #581
Other
- Test with JDK 9 Early Access builds #310
- Fix README #410 (Thanks to @changeworld)
- Annotate deprecated items with @deprecated #414
- Disable WAIT as Read-Only command #418
- Upgrade to netty 4.1.7/4.0.43 #436
- Fix ClientResources usage in tests #445
- Enable JMH tests on TravisCI #454
- Upgrade to TravisCI trusty #461
- Upgrade to Mockito 2 #469
- Improve JavaDoc #472
- Upgrade dependencies #474
- Switch optional dependencies from provided to optional #482
- Update Netty version to 4.1.9 #489 (Thanks to @odiszapc)
- Move to lettuce.io ...
5.0.0.RC1
This release comes with 29 completed issues and drops support for netty 4.0.
This release introduces ships with few breaking changes such as Duration
use for timeouts and delays and changes the return type for configGet
from List<String>
to Map<String, String>
.
Lettuce now contains a range of performance improvements to lower GC pressure, introduces kqueue native transport on BSD-like systems and asynchronous, connection initialization.
This release asserts compatibility in class-path mode with Java 9 requiring at least netty 4.1.11.Final.
Redis Cluster Pub/Sub on Node-Selections
RedisClusterClient.connectPubSub()
now returns a StatefulRedisClusterPubSubConnection
that allows registration of RedisClusterPubSubListener
s and subscription on particular cluster nodes.
Cluster node-specific subscriptions allow usage of keyspace notifications. Keyspace notifications are different from userspace Pub/Sub since keyspace notifications don't broadcast to the entire cluster but are published only on the node the notification happens. A common usecase is when a key expires in the cluster.
StatefulRedisClusterPubSubConnection connection = client.connectPubSub();
connection.addListener(…);
connection.setNodeMessagePropagation(true);
RedisClusterPubSubCommands<String, String> sync = connection.sync();
sync.slaves().commands().psubscribe("__key*__:expire");
Native Transports
Lettuce now uses native transports by default, if the operating system is qualified and dependencies are available. Lettuce supports epoll (on Linux-based systems) since 4.0 and since this version kqueue (BSD-based systems, like macOS).
Epoll usage can be disabled with system properties by settingio.lettuce.core.epoll=false
. In a similar way, kqueue can be disabled with io.lettuce.core.kqueue=false
.
Epoll dependency:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty-version}</version>
<classifier>linux-x86_64</classifier>
</dependency>
Kqueue dependency:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-kqueue</artifactId>
<version>${netty-version}</version>
<classifier>osx-x86_64</classifier>
</dependency>
Asynchronous Connections in Redis Cluster
RedisClusterClient now connects asynchronously without intermediate synchronization to cluster nodes. The connection progress is shared between multiple threads that request a cluster node connection for the first time. Previously, connection was sequential-synchronous. Each connection attempt blocked subsequent attempts from other threads. If a cluster node connection ran into a timeout, threads were penalized with a growing wait time. If, say, 10 threads waited for a connection, the last thread had to wait up to 10 times the connection timeout.
Asynchronous connection initiates the connection once using internally a Future
so multiple concurrent connection attempts share the resulting Future
. Errors fail now faster and cluster node usage is fully asynchronous without synchronization and without the danger to run into a threading deadlock.
Find the full change log at the end of this document. Thanks to all contributors that made Lettuce 5.0.0.RC1 possible.
Enhancements
- Drop netty 4.0 compatibility #518
- Support default methods on Command Interfaces #527
- Align log prefix for CommandHandler and ConnectionWatchdog #538
- Add support for kqueue transport #539
- Add support for client certificate authentication #540
- Adopt to changed SLOWLOG output #551
- Use pre-instantiated ByteBufProcessor in RedisStateMachine to find EOL #557
- SlotHash.getSlot(…) duplicates bytes while slot calculation #558
- Replace CountDownLatch in AsyncCommand with AtomicFieldUpdater #559
- Expose asynchronous connection creation API #561
- [BREAKING] Refactor CONFIG GET output from List to Map<String, String> #562
- Adopt to read-only variant GEORADIUS(BYMEMBER)_RO #564
- [BREAKING] Switch to Duration for timeouts #570
Fixes
- NumberFormatException on
inf
zscore #528 (Thanks to @DarkSeraphim) - Connection pool deadlock #531 (Thanks to @DarkSeraphim)
- Improve Epoll availability detection #535
- Fix FastCountingDeque not recording correct size. #544 (Thanks to @kojilin)
- Lettuce doesn't call QUIT when a pooled connection is destroyed. #545 (Thanks to @robbiemc)
- clientSetname does not set client name on default connection #563
Other
- Test with JDK 9 Early Access builds #310
- Upgrade to netty 4.1.10 #532
- Upgrade to netty 4.0.11 #537
- Upgrade to netty 4.1.12 (4.0.48) #548
- Upgrade to Reactor 3.1 M2 #549
- Allow Redis version pinning for build #552
- Upgrade to netty 4.1.13/4.0.49 #565
- Upgrade to Reactor 3.1.0 M3 (Bismuth M3) #567
- Use BOM to manage netty and Spring dependencies #568
- Upgrade dependencies #569
Documentation
Browse the docs at https://github.com/lettuce-io/lettuce-core/wiki.
JavaDoc: https://lettuce.io/core/5.0.0.RC1/api/
4.3.3.Final
This release fixes bugs and ships some enhancements. One of them adopts to Redis recent
GEORADIUS(BYMEMBER)_RO change for Redis Cluster. Find all 12 tickets assigned in GitHub's milestone view.
Lettuce was moved meanwhile to a new organization in GitHub: https://github.com/lettuce-io and
has a new website at https://lettuce.io. Maven coordinates for the 4.x branch remain stable.
Find the full change log at the end of this document.
Thanks to all contributors who made Lettuce 4.3.3 possible.
Fixes
- Fix zset score parsing for infinite scores #528 (Thanks to @DarkSeraphim)
- Remove method synchronization in ConnectionPoolSupport #531 (Thanks to @DarkSeraphim)
- Activate connection before signaling activation completion #536 (Thanks to @goldobin)
- Close connections in pooling destroy hook #545 (Thanks to @robbiemc)
- Apply client name via clientSetname(…) also to default connection #563
Enhancements
- Improve epoll availability detection #535
- Align log prefix for CommandHandler and ConnectionWatchdog #538
- Adopt to read-only variant GEORADIUS(BYMEMBER)_RO #564
Other
- Upgrade to netty 4.1.10 #532
- Adopt to changed SLOWLOG output #551
- Allow Redis version pinning for build #552
- Upgrade to netty 4.1.13/4.0.49 #565
Documentation
Browse the docs at https://github.com/lettuce-io/lettuce-core/wiki.
JavaDoc: https://lettuce.io/lettuce-4/4.3.3.Final/api/