Skip to content

Releases: redis/lettuce

6.1.0.RELEASE

30 Mar 13:36
d151952
Compare
Choose a tag to compare

The Lettuce team is delighted to announce general availability of Lettuce 6.1.

This is a massive release thanks to all the community contributions.
Most notable changes that ship with this release are:

  • Support for Redis 6.2 commands and modifier/argument updates
  • Micrometer integration
  • CommandListeners API to intercept Redis commands
  • extended Keep-Alive options
  • Coroutine variant of ScanStream
  • TCP NoDelay enabled by default
  • Experimental support for io_uring
  • Java Flight Recorder Integration for Connection and Cluster Events

Lettuce 6 supports Redis 2.6+ up to Redis 6.x. In terms of Java runtime, Lettuce requires at least Java 8 and works with Java 16.

Thanks to all contributors who made Lettuce 6.1.0 possible.

Documentation

Reference documentation: https://lettuce.io/core/6.1.0.RELEASE/reference/
Javadoc: https://lettuce.io/core/6.1.0.RELEASE/api/

Micrometer Integration

Lettuce ships an integration for Micrometer. Commands are tracked by using two Micrometer Times: lettuce.command.firstresponse and lettuce.command.completion. The following tags are attached to each timer:

  • command: Name of the command (GET, SET, …)
  • local: Local socket (localhost/127.0.0.1:45243 or ANY when local distinction is disabled, which is the default behavior)
  • remote: Remote socket (localhost/127.0.0.1:6379)

To enable Micrometer, create MicrometerCommandLatencyRecorder from MeterRegistry and register it in ClientResources:

MeterRegistry meterRegistry = …;
MicrometerOptions options = MicrometerOptions.create();
ClientResources resources = ClientResources.builder().commandLatencyRecorder(new MicrometerCommandLatencyRecorder(meterRegistry, options)).build();

RedisClient client = RedisClient.create(resources);

Make sure to have Micrometer on your class path (example from a Maven pom.xml):

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
    <version>${micrometer.version}</version>
</dependency>

See also: https://github.com/lettuce-io/lettuce-core/wiki/Command-Latency-Metrics#command.latency.metrics.micrometer

CommandListeners

Command listeners allow intercepting Redis Command calls before the command is sent and upon completion (success/failure). A CommandListener can be registered with RedisClient and RedisClusterClient:

RedisClient client = …;

client.addListener(new CommandListener() {
    @Override
    public void commandStarted(CommandStartedEvent event) {
        Map<String, Object> context = event.getContext();
        context.put(…);
    }

    @Override
    public void commandSucceeded(CommandSucceededEvent event) {
        Map<String, Object> context = event.getContext();
    }

    @Override
    public void commandFailed(CommandFailedEvent event) {
        CommandListener.super.commandFailed(event);
    }
});


StatefulRedisConnection<String, String> connection = client.connect();

Command events allow attaching contextual details that can be accessed upon completion.

Experimental support for io_uring

We've adopted Netty's experimental io_uring support for Linux-based systems to allow participating in improved I/O performance.

io_uring will be enabled automatically if you're running on Linux and you have the dependency on your classpath:

<dependency>
    <groupId>io.netty.incubator</groupId>
    <artifactId>netty-incubator-transport-native-io_uring</artifactId>
    <version>${netty.transport-native-io_uring.version}</version>
    <classifier>linux-x86_64</classifier>
</dependency>

When having both native transports enabled (io_uring and epoll), then io_uring has precedence over epoll.
We'd love to hear from you how io_uring works out for you.

Java Flight Recorder Integration

Lettuce emits Connection and Cluster events as Java Flight Recorder events. EventBus emits all events to EventRecorder and the actual event bus.

EventRecorder verifies whether your runtime provides the required JFR classes (available as of JDK 8 update 262 or later) and if so, then it creates Flight Recorder variants of the event and commits these to JFR.

The following events are supported out of the box:

Redis Connection Events

  • Connection Attempt
  • Connect, Disconnect, Connection Activated, Connection Deactivated
  • Reconnect Attempt and Reconnect Failed

Redis Cluster Events

  • Topology Refresh initiated
  • Topology Changed
  • ASK and MOVED redirects

Redis Master/Replica Events

  • Sentinel Topology Refresh initiated
  • Master/Replica Topology Changed

Events come with a rich set of event attributes such as channelId, epId (endpoint Id), Redis URI and many more.

You can record data by starting your application with:

java -XX:StartFlightRecording:filename=recording.jfr,duration=10s …

Hostname support for Redis Sentinel

Since Redis 6.2, Redis Sentinel and Redis itself can use hostnames to announce its replication partner.
Lettuce accepts this information as SocketAddress and passes on the address to Netty which then can perform the hostname resolution.

Please pay special attention when using ReadFrom.subnet(…) as ReadFrom operates on the raw addressing information reported by Redis without applying further hostname resolution.

Option to configure SSL/TLS verification level

RedisURI.setVerifyPeer(…) now accepts SslVerifyMode which can be one of NONE (corresponds with setVerifyPeer(false)), CA and FULL (corresponds with setVerifyPeer(true)).

Peer verification settings update on SSLParameters for CA and FULL verification mode and NONE overwrites trustManager(…) during SSL bootstrapping.

Commands

  • Add support for SET … GET option #1442
  • Add support for (B)LMOVE source destination LEFT|RIGHT LEFT|RIGHT command #1448
  • Add support for ZMSCORE key member [member ...] command #1449
  • Add support for ZINTER/ZUNION commands #1450
  • Add support for ZADD GT/LT options #1451
  • Add support for SMISMEMBER key member [member ...] command #1452
  • Support NOMKSTREAM option in XADD command #1502
  • Support option CREATECONSUMER in XGROUP command #1505 (Thanks to @dengliming)
  • Add support for ZRANGESTORE command #1506
  • Add support for ZDIFF and ZDIFFSTORE commands #1507
  • Add support for COPY command #1508
  • Add support for local addr in CLIENT KILL #1536
  • Add support for IDLE option in XPENDING #1537
  • Support for ACL commands #1538 (Thanks to @GraemeMitchell84)
  • Add support for LPOP and RPOP with COUNT #1545
  • Missing support for TYPE parameter of SCAN command #1559 (Thanks to @mvmn)
  • Add support for GEOSEARCH and GEOSEARCHSTORE #1561
  • Add support for ReadFrom.subnet #1569 (Thanks to @yueki1993)
  • Add support for MINID trimming strategy and the LIMIT argument to XADD and XTRIM #1582
  • Add exclusive range query to XPENDING #1585
  • Add support for GEOADD [CH] [NX|XX] options #1584
  • Add support for HRANDFIELD and ZRANDMEMBER commands #1605
  • Add support for GETEX, GETDEL commands #1606
  • Add support for PXAT/EXAT arguments to SET command #1607
  • Add FlushMode to FLUSHALL and FLUSHDB, and to SCRIPT FLUSH #1608
  • Add support for MIGRATE AUTH2 option #1633
  • Add support for RESTORE ABSTTL #1634
  • Add support for XAUTOCLAIM #1574
  • Add support for CLIENT KILL USER #1672 (Thanks to @dengliming)
  • Add support IDLETIME and FREQ args to RESTORE command #1683 (Thanks to @dengliming)
  • Add support for OBJECT FREQ #1684 (Thanks to @dengliming)

Enhancements

  • Add Micrometer integration #795
  • Add support for CommandListeners #1382 (Thanks to @sokomishalov)
  • Add support for Java Flight Recorder #1430
  • Provide a Coroutine variant of ScanStream/ScanIterator #1435
  • Introduce extended Keep-Alive options #1437
  • Add anyReplica setting for ReadFrom #1444 (Thanks to @omer-cilingir)
  • Option to configure SSL/TLS verification level #1460 (Thanks to @Lucas3oo)
  • Use Netty's asynchronous DNS resolver #1498 (Thanks to @yueki1993)
  • Extend CommandDetailParser to include ACL details #1503
  • Consider reinstating master-replica wording #1518 (Thanks to @perlun)
  • Add support for io_uring #1522
  • Provide VoidOutput for Fire&Forget command usage #1529 (Thanks to @jaredpetersen)
  • Improve unsupported error logging for CommandOutput #1532
  • Allow providing custom ClusterTopologyRefresh implementation. #1598 (Thanks to @alessandrosimi-sa)
  • Introduce LettuceStrings.isEmpty(String) overload with optimized isEmpty checking #1609
  • Add hostname support to Sentinel #1635
  • Introduce GeoValue value type #1643
  • Add overload to ScanArgs to accept a binary match #1675

Fixes

  • Fix EXEC without MULTI when using coroutines over async #1441 (Thanks to @sokomishalov)
  • Lettuce with Tracing enabled fails to connect to a Redis Sentinel #1470 (Thanks to @jsonwan)
  • Lettuce doesn't handle deleted stream items (NullPointerException) #1474 (Thanks to @chemist777)
  • LettuceStrings does not handle -nan which is returned by FT.INFO in redisearch #1482 (Thanks to @krm1312)
  • Improperly decoding command responses #1512 (Thanks to @johnny-costanzo)
  • Fix timeout parameter for nanoseconds in RedisURI #1528 (Thanks to @izeye)
  • Fix build break when missing netty-dns-resolver #1546 (Thanks to @yueki1993)
  • Sentinel lookup connection leaks if no master address reported #1558 (Thanks to @wwwjinlong)
  • Lettuce 6.0.1 fails with GraalVM 20.3 #1562 (Thanks to @atrianac)
  • Reactive stream spec violation when using command timeout #157...
Read more

6.1.0.RC1

16 Mar 11:35
92b314e
Compare
Choose a tag to compare
6.1.0.RC1 Pre-release
Pre-release

The Lettuce team is delighted to announce the availability of Lettuce 6.1 RC1.

This is a massive release thanks to all the community contributions. This release ships mostly with command updates to support Redis 6.2.
Besides that, Lettuce publishes now events to Java Flight Recorder if your Java runtime supports JFR events (JDK 8 update 262 or later).

Lettuce 6 supports Redis 2.6+ up to Redis 6.x. In terms of Java runtime, Lettuce requires at least Java 8 and works with Java 16.
Thanks to all contributors who made Lettuce 6.1.0.RC1 possible.

Documentation

Reference documentation: https://lettuce.io/core/6.1.0.RC1/reference/
Javadoc: https://lettuce.io/core/6.1.0.RC1/api/

Commands

  • Add support for IDLE option in XPENDING #1537
  • Support for ACL commands #1538 (Thanks to @GraemeMitchell84)
  • Add support for MINID trimming strategy and the LIMIT argument to XADD and XTRIM #1582
  • Add support for GEOADD [CH] [NX|XX] options #1584
  • Add support for HRANDFIELD and ZRANDMEMBER commands #1605
  • Add support for GETEX, GETDEL commands #1606
  • Add FlushMode to FLUSHALL and FLUSHDB, and to SCRIPT FLUSH #1608
  • Add support for MIGRATE AUTH2 option #1633
  • Add support for RESTORE ABSTTL #1634

Enhancements

  • Add support for Java Flight Recorder #1430
  • Add hostname support to Sentinel #1635
  • Introduce GeoValue value type #1643

Fixes

Other

  • Ping command is not supported in Pub/Sub connection #1601 (Thanks to @TsybulskyStepan)
  • Fix formatting indent in kotlin files #1603 (Thanks to @sokomishalov)
  • Upgrade kotlin to 1.4.30, kotlinx-coroutines to 1.4.2 #1620 (Thanks to @sokomishalov)
  • Typo in string reactive commands #1632 (Thanks to @paualarco)
  • Let nullable ScoredValue factory methods return Value instead of ScoredValue #1644
  • Cleanup MULTI state if MULTI command fails #1650
  • Upgrade to Kotlin 1.4.31 #1657
  • Use kotlin and kotlinx-coroutines bills of materials #1660 (Thanks to @sokomishalov)
  • Fix travis links due to its domain name migration #1661 (Thanks to @sokomishalov)
  • Rename zrandmemberWithscores to zrandmemberWithScores #1663 (Thanks to @dengliming)

6.0.3.RELEASE

16 Mar 11:20
2e6a473
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 6.0.3 service release!
This release ships with bugfixes and selected enhancements along with dependency upgrades.

Find the full changelog at the end of this document.

Thanks to all contributors who made Lettuce 6.0.3.RELEASE possible.
Lettuce 6 supports Redis 2.6+ up to Redis 6.x. In terms of Java runtime, Lettuce requires at least Java 8 and works with Java 16. It is tested continuously against the latest Redis source-build.

Documentation

Reference documentation: https://lettuce.io/core/6.0.3.RELEASE/reference/
Javadoc: https://lettuce.io/core/6.0.3.RELEASE/api/

Enhancements

  • Consider reinstating master-replica wording #1518 (Thanks to @perlun)
  • Allow providing custom ClusterTopologyRefresh implementation. #1598 (Thanks to @alessandrosimi-sa)
  • Introduce LettuceStrings.isEmpty(String) overload with optimized isEmpty checking #1609

Fixes

  • Sentinel lookup connection leaks if no master address reported #1558 (Thanks to @wwwjinlong)
  • copyright replace bug #1589 (Thanks to @dengliming)
  • NullPointerException in BoundedAsyncPool.createIdle() when availableCapacity=0 #1611 (Thanks to @fbotis)
  • XREADGROUP skips messages if body is nil #1622 (Thanks to @asalabaev)
  • TransactionCommand applied incorrectly #1625 (Thanks to @checky)
  • Create traced endpoint when ready #1653 (Thanks to @anuraaga)

Other

6.1.0.M1

08 Feb 08:35
66c079a
Compare
Choose a tag to compare
6.1.0.M1 Pre-release
Pre-release

The Lettuce team is delighted to announce the availability of the first Lettuce 6.1 milestone.

This is a massive release thanks to all the community contributions. Most notable changes that ship with this release are:

  • Support for most Redis 6.2 commands and command changes
  • Micrometer integration
  • CommandListeners API to intercept Redis commands
  • extended Keep-Alive options
  • Coroutine variant of ScanStream
  • TCP NoDelay enabled by default
  • Experimental support for io_uring

Lettuce 6 supports Redis 2.6+ up to Redis 6.x. In terms of Java runtime, Lettuce requires at least Java 8 and works with Java 16.

Thanks to all contributors who made Lettuce 6.1.0.M1 possible.

Documentation

Reference documentation: https://lettuce.io/core/6.1.0.M1/reference/
Javadoc: https://lettuce.io/core/6.1.0.M1/api/

Micrometer Integration

Lettuce ships an integration for Micrometer. Commands are tracked by using two Micrometer Times: lettuce.command.firstresponse and lettuce.command.completion. The following tags are attached to each timer:

  • command: Name of the command (GET, SET, …)
  • local: Local socket (localhost/127.0.0.1:45243 or ANY when local distinction is disabled, which is the default behavior)
  • remote: Remote socket (localhost/127.0.0.1:6379)

To enable Micrometer, create MicrometerCommandLatencyRecorder from MeterRegistry and register it in ClientResources:

MeterRegistry meterRegistry = …;
MicrometerOptions options = MicrometerOptions.create();
ClientResources resources = ClientResources.builder().commandLatencyRecorder(new MicrometerCommandLatencyRecorder(meterRegistry, options)).build();

RedisClient client = RedisClient.create(resources);

Make sure to have Micrometer on your class path (example from a Maven pom.xml):

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
    <version>${micrometer.version}</version> <!-- e.g. micrometer.version==1.6.0 -->
</dependency>

See also: https://github.com/lettuce-io/lettuce-core/wiki/Command-Latency-Metrics#command.latency.metrics.micrometer

CommandListeners

Command listeners allow intercepting Redis Command calls before the command is sent and upon completion (success/failure). A CommandListener can be registered with RedisClient and RedisClusterClient:

RedisClient client = …;

client.addListener(new CommandListener() {
    @Override
    public void commandStarted(CommandStartedEvent event) {
        Map<String, Object> context = event.getContext();
        context.put(…);
    }

    @Override
    public void commandSucceeded(CommandSucceededEvent event) {
        Map<String, Object> context = event.getContext();
    }

    @Override
    public void commandFailed(CommandFailedEvent event) {
        CommandListener.super.commandFailed(event);
    }
});


StatefulRedisConnection<String, String> connection = client.connect();

Command events allow attaching contextual details that can be accessed upon completion.

Experimental support for io_uring

We've adopted Netty's experimental io_uring support for Linux-based systems to allow participating in improved I/O performance.

io_uring will be enabled automatically if you're running on Linux and you have the dependency on your classpath:

<dependency>
    <groupId>io.netty.incubator</groupId>
    <artifactId>netty-incubator-transport-native-io_uring</artifactId>
    <version>${netty.transport-native-io_uring.version}</version>
    <classifier>linux-x86_64</classifier>
</dependency>

When having both native transports enabled (io_uring and epoll), then io_uring has precedence over epoll.
We'd love to hear from you how io_uring works out for you.

Commands

  • Add support for SET … GET option #1442
  • Add support for (B)LMOVE source destination LEFT|RIGHT LEFT|RIGHT command #1448
  • Add support for ZMSCORE key member [member ...] command #1449
  • Add support for ZINTER/ZUNION commands #1450
  • Add support for SMISMEMBER key member [member ...] command #1452
  • Support NOMKSTREAM option in XADD command #1502
  • Support option CREATECONSUMER in XGROUP command #1505 (Thanks to @dengliming)
  • Add support for ZRANGESTORE command #1506
  • Add support for ZDIFF and ZDIFFSTORE commands #1507
  • Add support for COPY command #1508
  • Add support for local addr in CLIENT KILL #1536
  • Add support for LPOP and RPOP with COUNT #1545
  • Missing support for TYPE parameter of SCAN command #1559 (Thanks to @mvmn)
  • Add support for GEOSEARCH and GEOSEARCHSTORE #1561
  • Add support for ReadFrom.subnet #1569 (Thanks to @yueki1993)
  • Add exclusive range query to XPENDING #1585
  • Add support for PXAT/EXAT arguments to SET command #1607
  • Add support for ZADD GT/LT options #1451

Enhancements

  • Add Micrometer integration #795
  • Add support for CommandListeners #1382 (Thanks to @sokomishalov)
  • Provide a Coroutine variant of ScanStream/ScanIterator #1435
  • Introduce extended Keep-Alive options #1437
  • Add anyReplica setting for ReadFrom #1444 (Thanks to @omer-cilingir)
  • Option to configure SSL/TLS verification level #1460 (Thanks to @Lucas3oo)
  • netty's asynchronous DNS resolver seems not to be used #1498 (Thanks to @yueki1993)
  • Extend CommandDetailParser to include ACL details #1503
  • Consider reinstating master-replica wording #1518 (Thanks to @perlun)
  • Add support for io_uring #1522
  • Provide VoidOutput for Fire&Forget command usage #1529 (Thanks to @jaredpetersen)
  • Improve unsupported error logging for CommandOutput #1532
  • Allow providing custom ClusterTopologyRefresh implementation. #1598 (Thanks to @alessandrosimi-sa)
  • Introduce LettuceStrings.isEmpty(String) overload with optimized isEmpty checking #1609

Fixes

  • Fix EXEC without MULTI when using coroutines over async #1441 (Thanks to @sokomishalov)
  • Lettuce with Tracing enabled fails to connect to a Redis Sentinel #1470 (Thanks to @jsonwan)
  • Lettuce doesn't handle deleted stream items (NullPointerException) #1474 (Thanks to @chemist777)
  • LettuceStrings does not handle -nan which is returned by FT.INFO in redisearch #1482 (Thanks to @krm1312)
  • Improperly decoding command responses #1512 (Thanks to @johnny-costanzo)
  • Fix timeout parameter for nanoseconds in RedisURI #1528 (Thanks to @izeye)
  • Fix build break when missing netty-dns-resolver #1546 (Thanks to @yueki1993)
  • Sentinel lookup connection leaks if no master address reported #1558 (Thanks to @wwwjinlong)
  • Lettuce 6.0.1 fails with GraalVM 20.3 #1562 (Thanks to @atrianac)
  • Reactive stream spec violation when using command timeout #1576 (Thanks to @martin-tarjanyi)
  • Fix copyright replace bug for Kotlin api generator #1588 (Thanks to @dengliming)
  • FixNullPointerException in BoundedAsyncPool.createIdle() when at capacity #1611

Other

  • Fix integration test password #1445
  • Un-Deprecate io.lettuce.core.LettuceFutures #1453 (Thanks to @andrewsensus)
  • Switch to Flux/Mono.expand(…) for ScanStream #1458
  • Enable TCP NoDelay by default #1462
  • Update contrib guide #1472
  • Adapt tests to changed Redis response #1473
  • Upgrade dependencies #1476
  • Remove JUnit 4 dependency management #1477
  • Replace ClusterRule #1478
  • Remove Redis Command retrieval for Redis Cluster Connections #1481
  • Implement set(double) in NestedMultiOutput #1486 (Thanks to @jruaux)
  • Start HashWheelTimer in ClientResources to avoid blocking calls in EventLoop #1489
  • DefaultClientResources: fix typos #1497 (Thanks to @perlun)
  • API generator problems #1499 (Thanks to @sokomishalov)
  • Reduce build matrix to Java 8, 11, 15, and EA #1519
  • Upgrade to Netty 4.1.54.Final #1541
  • netty 4.1.56 #1556 (Thanks to @sullis)
  • Move Mailing list forum to GitHub discussions #1557
  • Let coroutines dispatch-method be flowable #1567 (Thanks to @sokomishalov)
  • Update copyright years to 2021 #1573
  • Upgrade to netty 4.1.58.Final #1610

6.0.2.RELEASE

12 Jan 10:17
5961456
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 6.0.2 service release!
This release ships with bugfixes and selected enhancements along with dependency upgrades.

Find the full changelog at the end of this document.

Thanks to all contributors who made Lettuce 6.0.2.RELEASE possible.
Lettuce 6 supports Redis 2.6+ up to Redis 6.x. In terms of Java runtime, Lettuce requires at least Java 8 and works with Java 15. It is tested continuously against the latest Redis source-build.

Documentation

Reference documentation: https://lettuce.io/core/6.0.2.RELEASE/reference/
Javadoc: https://lettuce.io/core/6.0.2.RELEASE/api/

Enhancements

  • API generator problems #1499 (Thanks to @sokomishalov)
  • Provide VoidOutput for Fire&Forget command usage #1529 (Thanks to @jaredpetersen)
  • Improve unsupported error logging for CommandOutput #1532
  • Add support for local addr in CLIENT KILL #1536

Fixes

  • LettuceStrings does not handle -nan which is returned by FT.INFO in redisearch #1482 (Thanks to @krm1312)
  • Improperly decoding command responses #1512 (Thanks to @johnny-costanzo)
  • Fix timeout parameter for nanoseconds in RedisURI #1528 (Thanks to @izeye)
  • Lettuce 6.0.2 fails with GraalVM 20.3 #1562 (Thanks to @atrianac)
  • Reactive stream spec violation when using command timeout #1576 (Thanks to @martin-tarjanyi)

Other

  • Remove or replace ClusterRule #1478
  • Implement set(double) in NestedMultiOutput #1486 (Thanks to @jruaux)
  • Start HashWheelTimer in ClientResources to avoid blocking calls in EventLoop #1489
  • Reduce build matrix to Java 8, 11, 15, and EA #1519
  • Upgrade to Netty 4.1.54.Final #1541
  • netty 4.1.56 #1556 (Thanks to @sullis)
  • Move Mailing list forum to GitHub discussions #1557
  • Let coroutines dispatch-method be flowable #1567 (Thanks to @sokomishalov)
  • Update copyright years to 2021 #1573
  • Upgrade dependencies #1578

5.3.6.RELEASE

12 Jan 10:06
3fb1eab
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.3.6 service release!
This release ships with 7 tickets fixed along with dependency upgrades.

Find the full changelog at the end of this document.

Thanks to all contributors who made Lettuce 5.3.6.RELEASE possible.
Lettuce 6 supports Redis 2.6+ up to Redis 6.x. In terms of Java runtime, Lettuce requires at least Java 8 and works with Java 15. It is tested continuously against the latest Redis source-build.

Documentation

Reference documentation: https://lettuce.io/core/5.3.6.RELEASE/reference/
Javadoc: https://lettuce.io/core/5.3.6.RELEASE/api/

Enhancements

  • Add support for local addr in CLIENT KILL #1536

Fixes

  • LettuceStrings does not handle -nan which is returned by FT.INFO in redisearch #1482 (Thanks to @krm1312)
  • Reactive stream spec violation when using command timeout #1576 (Thanks to @martin-tarjanyi)

Other

  • Upgrade to Netty 4.1.54.Final #1541
  • netty 4.1.56 #1556 (Thanks to @sullis)
  • Update copyright years to 2021 #1573
  • Upgrade dependencies #1578

6.0.1.RELEASE

27 Oct 21:18
e6e22b6
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 6.0.1 service release!
This release ships with bugfixes and selected enhancements along with dependency upgrades.

Find the full changelog at the end of this document.

Thanks to all contributors who made Lettuce 6.0.1.RELEASE possible.
Lettuce 6 supports Redis 2.6+ up to Redis 6.x. In terms of Java runtime, Lettuce requires at least Java 8 and works with Java 15. It is tested continuously against the latest Redis source-build.

Documentation

Reference documentation: https://lettuce.io/core/6.0.1.RELEASE/reference/
Javadoc: https://lettuce.io/core/6.0.1.RELEASE/api/

Enhancements

Fixes

  • Fix EXEC without MULTI when using coroutines over async #1441 (Thanks to @sokomishalov)
  • Lettuce with Tracing enabled fails to connect to a Redis Sentinel #1470 (Thanks to @jsonwan)
  • Lettuce doesn't handle deleted stream items (NullPointerException) #1474 (Thanks to @chemist777)

Other

  • Fix integration test password #1445
  • Un-Deprecate io.lettuce.core.LettuceFutures #1453 (Thanks to @andrewsensus)
  • Switch to Flux/Mono.expand(…) for ScanStream #1458
  • Enable TCP NoDelay by default #1462
  • Adapt tests to changed Redis response #1473
  • Upgrade dependencies #1476
  • Remove JUnit 4 dependency management #1477

5.3.5.RELEASE

27 Oct 21:28
1351ab3
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.3.5 service release!
This release ships with 5 tickets fixed along with dependency upgrades.

Find the full changelog at the end of this document.

Thanks to all contributors who made Lettuce 5.3.5.RELEASE possible.
Lettuce 6 supports Redis 2.6+ up to Redis 6.x. In terms of Java runtime, Lettuce requires at least Java 8 and works with Java 15. It is tested continuously against the latest Redis source-build.

Documentation

Reference documentation: https://lettuce.io/core/5.3.5.RELEASE/reference/
Javadoc: https://lettuce.io/core/5.3.5.RELEASE/api/

Fixes

  • Lettuce with Tracing enabled fails to connect to a Redis Sentinel #1470 (Thanks to @jsonwan)
  • Lettuce doesn't handle deleted stream items (NullPointerException) #1474 (Thanks to @chemist777)

Other

  • Correctly report isDone if Command completed with completeExceptionally #1433
  • Upgrade dependencies #1476
  • Remove JUnit 4 dependency management #1477

6.0.0.RELEASE

02 Oct 10:20
edf471b
Compare
Choose a tag to compare

The Lettuce team is delighted to announce the availability of Lettuce 6.

Lettuce 6 aligns with Redis 6 in terms of API and protocol changes. Both protocols, RESP and RESP3 are supported side-by-side defaulting to RESP.

Most notable changes that ship with this release are:

  • RESP3 support
  • ACL Authentication with username/password
  • Asynchronous Cluster Topology Refresh
  • Client-side caching support
  • Registration of push message listeners
  • Configuration files for GraalVM Native Image compilation
  • Kotlin Coroutine API
  • Redesign command latency metrics publishing
  • API cleanups/Breaking Changes

Lettuce 6 supports Redis 2.6+ up to Redis 6.x. In terms of Java runtime, Lettuce requires at least Java 8 and works with Java 15.

Thanks to all contributors who made Lettuce 6.0.0.RELEASE possible.
Lettuce requires a minimum of Java 8 to build and run and is compatible with Java 15. It is tested continuously against the latest Redis source-build.

Documentation

Reference documentation: https://lettuce.io/core/6.0.0.RELEASE/reference/
Javadoc: https://lettuce.io/core/6.0.0.RELEASE/api/

RESP3 Support

Redis 6 ships with support for a new protocol version. RESP3 brings support for additional data types to distinguish better between responses. The following response types were introduced with RESP3:

  • Null: a single null value replacing RESP v2 *-1 and $-1 null values.
  • Double: a floating-point number.
  • Boolean: true or false.
  • Blob error: binary-safe error code and message.
  • Verbatim string: a binary-safe string that is typically used as user message without any escaping or filtering.
  • Map: an ordered collection of key-value pairs. Keys and values can be any other RESP3 type.
  • Set: an unordered collection of N other types.
  • Attribute: Like the Map type, but the client should keep reading the reply ignoring the attribute type, and return it to the client as additional information.
  • Push: Out-of-band data.
  • Streamed strings: A large response using chunked transfer.
  • Hello: Like the Map type, but is sent only when the connection between the client and the server is established, in order to welcome the client with different information like the name of the server, its version, and so forth.
  • Big number: a large number non-representable by the Number type

Lettuce supports all response types except attributes. Push messages are only supported for Pub/Sub messages.

The protocol version can be changed through ClientOptions which disables protocol discovery:

ClientOptions options = ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).build();

Future versions are going to discover the protocol version as part of the connection handshake and use the newest available protocol version.

ACL Authentication

Redis 6 supports authentication using username and password. Lettuce's RedisURI adapts to this change by allowing to specify a username:

redis://username:password@host:port/database

Using RESP3 or PING on connect authenticates the connection during the handshake phase. Already connected connections may switch the user context by issuing an AUTH command with username and password:

StatefulRedisConnection<String, String> connection = client.connect();
RedisCommands<String, String> commands = connection.sync();
commands.auth("username", "password");

Asynchronous Cluster Topology Refresh

Cluster Topology Refresh was in Lettuce 4 and 5 a blocking and fully synchronous task that required a worker thread. A side-effect of the topology refresh was that command timeouts could be delayed as the worker thread pool was used for timeout tasks and the topology refresh. Lettuce 6 ships with a fully non-blocking topology refresh mechanism which is basically a reimplementation of the previous refresh mechanism but using non-blocking components instead.

Server-assisted Client-side caching support

Redis can notify clients about cache invalidations when you use Redis as a read-through cache.
That is when applications keep a local copy of the cached value and use Redis to back up the local cache before.
When a cache values gets changed (that were fetched from Redis), then Redis notifies interested clients so they can invalidate their near-cache and potentially fetch the changed value.

Redis 6 allows for tracking clients and sending push messages using RESP3 push messages.
Lettuce provides a CacheFrontend that can be used to interact with a cache.

Client-side caching assumes a near cache that can be queried, updated and evicted for individual keys.
Cache values are represented as strings and the entire functionality is exposed through a CacheFrontend.

See the following example that uses a ConcurrentHashMap as near cache and outlines the interaction between involved parties:

Map<String, String> clientCache = new ConcurrentHashMap<>();

RedisCommands<String, String> otherParty = redisClient.connect().sync();

// creates a key
otherParty.set(key, value);

StatefulRedisConnection<String, String> myself = redisClient.connect();
CacheFrontend<String, String> frontend = ClientSideCaching.enable(CacheAccessor.forMap(clientCache), myself,
        TrackingArgs.Builder.enabled().noloop());

// Read-through into Redis
String cachedValue = frontend.get(key);
assertThat(cachedValue).isNotNull();

// client-side cache holds the same value
assertThat(clientCache).hasSize(1);

// now, the key expires
commands.pexpire(key, 1);

// a while later
Thread.sleep(200);

// the expiration reflects in the client-side cache
assertThat(clientCache).isEmpty();

assertThat(frontend.get(key)).isNull()

Lettuce ships out of the box with a CacheAccessor for the Map interface.
You can implement a CacheAccessor for your cache if it doesn't implement the Map interface.
Client-side caching support is only supported when using RESP3. The Pub/Sub mode isn't supported through ClientSideCaching and we don't support Pub/Sub redirection.
Since push messages are node-local, client-side caching is supported only on Redis Standalone setups.
Master/Replica or Clustering operating modes are not supported as multi-node operations and connection failover impose severe complexity onto key tracking.

Read more: https://redis.io/topics/client-side-caching

Registration of push message listeners

Registration of push message listeners completes Lettuce's RESP3 support.
You can register PushMessage listeners on Standalone and Redis Cluster connections by implementing PushListener respective RedisClusterPushListener:

connection.addListener(message -> {

    if (message.getType().equals("invalidate")) {
        invalidations.addAll((List) message.getContent(StringCodec.UTF8::decodeKey).get(1));
    }
});

Using push messages with Redis Cluster are subject to node-locality, therefore RedisClusterPushListener provides access to the RedisClusterNode from which the push message originated.

The content of push messages may consist of arbitrary data structures and vary across various push message types.
PushMessage exposes the message type and access to its content as List<Object>. Bulk content can be decoded into more specific data types.

Kotlin Coroutine API

Kotlin users can now use a Coroutine API that exposes suspended methods and uses Flow where appropriate.
The API can be obtained through an extension function for Standalone, Cluster, and Sentinel connections exposing the appropriate API.

val api: RedisCoroutinesCommands<String, String> = connection.coroutines()

val foo1 = api.set("foo", "bar")
val foo2 = api.keys("fo*")

Additionally, we ship two extensions that simplify transactional usage by providing a multi closure:

val result: TransactionResult = connection.async().multi {
    set("foo", "bar")
    get("foo")
}

The API is marked experimental and requires opt-in through @ExperimentalLettuceCoroutinesApi to avoid Compiler warnings.
We expect further evolution of the API towards a more Flow-oriented API where now List is returned to enable streaming of large responses.

Redesign command latency metrics publishing

This is a mostly internal change that switches from CommandLatencyCollector to the newly introduced CommandLatencyRecorder interface.
Unless you're implementing or configuring CommandLatencyCollector yourself, you should not see any changes.

This change is motivated by support for libraries that provide latency observability without publishing metrics to the EventBus.

API cleanups/Breaking Changes

With this release, we took the opportunity to introduce a series of changes that put the API into a cleaner shape.

  • Redesign command latency metrics publishing #1409
  • Remove JavaRuntime class and move LettuceStrings to internal package #1329
  • Remove Spring support classes #1358
  • Replace io.lettuce.core.resource.Futures utility with Netty's PromiseCombiner #1283
  • XGROUP DELCONSUMER should return pending message count #1377 (xgroupDelconsumer(…) now returns Long)
  • Change hgetall return type from Mono to Flux #1434
  • Script Commands: eval, digest, scriptLoad methods now only accept String and byte[] argument types. Previously digest and scriptLoad accepted the script contents as Codec value type which caused issues especially when marshalling values using JSON or Java Serialization. The script charset can be configured via ClientOptions (ClientOptions.builder().scriptCharset(StandardCharsets.US_ASCII).build();...
Read more

6.0.0.RC2

15 Sep 13:07
b4e28e9
Compare
Choose a tag to compare
6.0.0.RC2 Pre-release
Pre-release

The Lettuce team is delighted to announce the availability of the second and final Lettuce 6 release candidate.

Most notable changes that ship with this release are

  • Kotlin Coroutine API
  • Redesign command latency metrics publishing

We're working now towards the final release of Lettuce 6.0 by incorporating feedback from this release candidate.

Kotlin Coroutine API

Kotlin users can now use a Coroutine API that exposes suspended methods and uses Flow where appropriate.
The API can be obtained through an extension function for Standalone, Cluster, and Sentinel connections exposing the appropriate API.

val suspendableCommands: RedisSuspendableCommands<String, String> = connection.suspendable()

val foo1 = suspendableCommands.set("foo", "bar")
val foo2 = suspendableCommands.keys("fo*")

Additionally, we ship two extensions that simplify transactional usage by providing a multi closure:

val result: TransactionResult = connection.async().multi {
    set("foo", "bar")
    get("foo")
}

The API is marked experimental and requires opt-in through @ExperimentalLettuceCoroutinesApi to avoid Compiler warnings.
We expect further evolution of the API towards a more Flow-oriented API where now List is returned to enable streaming of large responses.

Redesign command latency metrics publishing

This is a mostly internal change that switches from CommandLatencyCollector to the newly introduced CommandLatencyRecorder interface.
Unless you're implementing or configuring CommandLatencyCollector yourself, you should not see any changes.

This change is motivated by support for libraries that provide latency observability without publishing metrics to the EventBus.

Thanks to all contributors who made Lettuce 6.0.0.RC2 possible.
Lettuce requires a minimum of Java 8 to build and run and is compatible with Java 15. It is tested continuously against the latest Redis source-build.

API cleanups/Breaking Changes

With this release, we took the opportunity to introduce a series of changes that put the API into a cleaner shape.

  • Redesign command latency metrics publishing #1409

Enhancements

Fixes

  • Wrong cast in StringCodec may lead to IndexOutOfBoundsException #1367 (Thanks to @dmandalidis)
  • Sentinel authentication failed when using the pingBeforeActivateConnection parameter #1401 (Thanks to @viniciusxyz)
  • RedisURI.toString() should not reveal password #1405
  • MasterReplica.connect(…) doesn't consider username with Redis 6 #1406
  • LPOS command sends FIRST instead of RANK #1410 (Thanks to @christophstrobl)

Other

  • Upgrade to Reactor 3.3.9.RELEASE #1384
  • Upgrade to Project Reactor 3.3.10.RELEASE #1411
  • Upgrade to netty 4.1.52.Final #1412
  • Upgrade test/optional dependencies #1413

Documentation

Reference documentation: https://lettuce.io/core/6.0.0.RC2/reference/
Javadoc: https://lettuce.io/core/6.0.0.RC2/api/