December 14, 2020·4 min read·engineeringvalkeyredisreplicationlists

Redis 6.2 RC1 expands commands across a replication boundary

Redis 6.2 RC1 begins testing under the core team with many smaller additions. LMOVE illustrates why a concise new operation still needs compatibility planning and a release-candidate cycle.

A small new command can still create a version boundary in a replicated database. Redis 6.2 RC1 adds many command extensions that did not fit the 6.0 maintenance line. Its release explanation identifies a direct reason. An older replica cannot necessarily execute a newly introduced command, even when the operation looks like a modest convenience to its caller.

The release notes date RC1 to December 14, 2020. The tagged notes describe it as the first significant release managed by the core team under the new governance model. They also say the changes need a longer release-candidate test cycle. This is a candidate for evaluation, with low upgrade urgency and further candidates planned.

I have used Redis since its release, and I like additions that express common data operations without elaborate application code. That preference still leaves compatibility work to do. The command available to an application and the command understood by every process receiving its effects are related parts of the system.

LMOVE makes the two directions explicit

One new command is LMOVE, accompanied by a blocking variant, BLMOVE. The candidate implementation parses a source-side direction and a destination-side direction. Each names the head or tail of the corresponding list.

The existing RPOPLPUSH operation expresses one particular combination. Its source comment describes removing an element from the source tail, pushing it onto the destination head and returning the element. LMOVE makes the two directions arguments, allowing other combinations through the same operation.

For two disposable example keys, the following sequence moves the first source element onto the destination tail.

DEL move-example-source move-example-destination
RPUSH move-example-source first second
LMOVE move-example-source move-example-destination LEFT RIGHT

The returned element is first. Afterwards, the source retains second, and the destination receives the moved value. The example uses the new direction parameters rather than requiring an application to model the transfer as two separate list commands.

The implementation checks the destination type before removing the source element. A wrong-type destination therefore reaches an error before the pop in this path. That order is part of making the combined operation meaningful. Performing a pop first and only then discovering that the destination is unusable would be a different behaviour.

After the transfer, the handler removes an empty source list and signals that the source key changed. These details show that the command participates in the existing list and key-notification machinery. A concise interface still requires accounting for the lifecycle of both keys.

Moving an item does not finish an application's job

The source comment for the older operation explains its reliability motivation. An item is both returned to the caller and placed into another list. That makes a processing-list arrangement possible, with the moved value still represented in Redis after the transfer.

A processing-list arrangement is not a complete acknowledgement protocol by itself. The move says where the item resides after the command. It does not establish that an external action triggered by a worker completed. An application needs its own meaning for removal from the processing list and for items left there after a worker stops.

This distinction is useful when assessing the new command. Arbitrary directions make the transfer more flexible. They do not change what the database can know about work performed outside it. The command provides a state transition on lists, and the application supplies the relationship between that transition and its external operation.

The example also does not claim that every pair of keys can be used together under every deployment topology. Its purpose is to show the command's directional semantics. The release notes' replication warning remains relevant independently of this local data example.

Blocking changes the waiting state

BLMOVE adds a timeout to the source and destination directions. The handler parses that duration in seconds and passes it to the generic blocking implementation. Waiting for an item and moving an available item therefore share the same directional choices.

The source also shows how a completed blocking operation is rewritten for propagation. A BLMOVE path becomes LMOVE with the source, destination and directions. The waiting interval is not reproduced as a fresh blocking wait on the replication stream.

This is a concrete example of the compatibility question in the release notes. Replication receives an operation that represents the completed transfer. A process expected to execute that propagated command must understand its name and arguments. Application support on the primary alone does not establish that condition for an older replica.

The candidate does not promise that the new syntax can be introduced into an otherwise unchanged version mix. Its introductory explanation explicitly treats new and extended commands as a reason for a separate release. That provides a more useful adoption boundary than counting the number of lines a feature adds.

The candidate also changes existing behaviour

RC1 contains changes beyond new commands. The notes say EXISTS no longer alters LRU or LFU information as it did in Redis 5 and 6.0. They also say OBJECT stops revealing logically expired keys. These alter what observation commands do or expose, even though the command names remain familiar.

Startup and persistence configuration also receive attention. The candidate can fail startup when a requested bind address is unavailable, with a configuration option for deployments relying on the former behaviour. Configuration rewriting requires write access to the containing directory as part of its atomic file handling.

These are concrete reasons for a candidate cycle. Testing only whether the new list operation returns the expected item would not exercise changed startup conditions or observation behaviour. The release notes give those areas separate descriptions so that compatibility work can include them.

I welcome the command additions while keeping the candidate's stated scope in view. LMOVE makes list-transfer directions explicit, and the implementation shows the completed blocking form becoming a nonblocking propagated operation. That relationship explains why the new command belongs in a release whose compatibility boundary includes replicas as well as application clients.