Many of the commands in Valkey accept key names as input arguments.
The 9th element in the reply of COMMAND
(and
COMMAND INFO
) is an array that consists of the command’s
key specifications.
A key specification describes a rule for extracting the names of one or more keys from the arguments of a given command. Key specifications provide a robust and flexible mechanism, compared to the first key, last key and step scheme employed until Redis OSS 7.0. Before introducing these specifications, Valkey clients had no trivial programmatic means to extract key names for all commands.
Cluster-aware Valkey clients had to have the keys’ extraction logic
hard-coded in the cases of commands such as EVAL
and
ZUNIONSTORE
that rely on a numkeys argument or
SORT
and its many clauses. Alternatively, the
COMMAND GETKEYS
can be used to achieve a similar extraction
effect but at a higher latency.
A Valkey client isn’t obligated to support key specifications. It can continue using the legacy first key, last key and step scheme along with the movablekeys flag that remain unchanged.
However, a Valkey client that implements key specifications support
can consolidate most of its keys’ extraction logic. Even if the client
encounters an unfamiliar type of key specification, it can always revert
to the COMMAND GETKEYS
command.
That said, most cluster-aware clients only require a single key name to perform correct command routing, so it is possible that although a command features one unfamiliar specification, its other specification may still be usable by the client.
Key specifications are maps with the following keys:
The begin_search value of a specification informs the client
of the extraction’s beginning. The value is a map. There are three types
of begin_search
:
The index type of begin_search
indicates that
input keys appear at a constant index. It is a map under the
spec key with a single key:
The keyword type of begin_search
means a
literal token precedes key name arguments. It is a map under the
spec with two keys:
More examples of the keyword search type include:
SET
has a begin_search
specification of
type index with a value of 1.XREAD
has a begin_search
specification of
type keyword with the values “STREAMS” and 1
as keyword and startfrom, respectively.MIGRATE
has a start_search specification of
type keyword with the values of “KEYS” and
-2.The find_keys
value of a key specification tells the
client how to continue the search for key names. find_keys
has three possible types:
The range type of find_keys
is a map under the
spec key with three keys:
begin_search
, of the last key argument. This can be a
negative value, in which case it isn’t relative. For example,
-1 indicates to keep extracting keys until the last argument,
-2 until one before the last, and so on.The keynum type of find_keys
is a map under the
spec key with three keys:
begin_search
, of the argument containing the number of
keys.begin_search
, of the first key. This is usually the next
argument after keynumidx, and its value, in this case, is
greater by one.Examples:
SET
command has a range of 0,
1 and 0.MSET
command has a range of -1,
2 and 0.XREAD
command has a range of -1,
1 and 2.ZUNION
command has a start_search type
index with the value 1, and find_keys
of
type keynum with values of 0, 1 and
1.Note: this isn’t a perfect solution as the module writers can come up with anything. However, this mechanism should allow the extraction of key name arguments for the vast majority of commands.
Notes about non-obvious key specs considerations, if applicable.
A key specification can have additional flags that provide more details about the key. These flags are divided into three groups, as described below.
The following flags declare the type of access the command uses to a key’s value or its metadata. A key’s metadata includes LRU/LFU counters, type, and cardinality. These flags do not relate to the reply sent back to the client.
Every key specification has precisely one of the following flags:
The following flags declare the type of operations performed on the data stored as the key’s value and its TTL (if any), not the metadata. These flags describe the logical operation that the command executes on data, driven by the input arguments. The flags do not relate to modifying or returning metadata (such as a key’s type, cardinality, or existence).
Every key specification may include the following flag:
In addition, the specification may include precisely one of the following:
Key specifications may have the following flags:
Some commands feature exotic approaches when it comes to specifying
their keys, which makes extraction difficult. Consider, for example,
what would happen with a call to MIGRATE
that includes the
literal string “KEYS” as an argument to its AUTH
clause. Our key specifications would miss the mark, and extraction would
begin at the wrong index.
Thus, we recognize that key specifications are incomplete and may fail to extract all keys. However, we assure that even incomplete specifications never yield the wrong names of keys, providing that the command is syntactically correct.
In the case of MIGRATE
, the search begins at the end
(startfrom has the value of -1). If and when we
encounter a key named “KEYS”, we’ll only extract the subset of
the key name arguments after it. That’s why MIGRATE
has the
incomplete flag in its key specification.
Another case of incompleteness is the SORT
command.
Here, the begin_search
and find_keys
are of
type unknown. The client should revert to calling the
COMMAND GETKEYS
command to extract key names from the
arguments, short of implementing it natively. The difficulty arises, for
example, because the string “STORE” is both a keyword (token)
and a valid literal argument for SORT
.
Note: the only commands with incomplete key
specifications are SORT
and MIGRATE
. We don’t
expect the addition of such commands in the future.
In some commands, the flags for the same key name argument can depend
on other arguments. For example, consider the SET
command
and its optional GET argument. Without the GET
argument, SET
is write-only, but it becomes a read and
write command with it. When this flag is present, it means that the key
specification flags cover all possible options, but the effective flags
depend on other arguments.
SET
’s key
specifications 1) 1) "flags"
2) 1) RW
2) access
3) update
3) "begin_search"
4) 1) "type"
2) "index"
3) "spec"
4) 1) "index"
2) (integer) 1
5) "find_keys"
6) 1) "type"
2) "range"
3) "spec"
4) 1) "lastkey"
2) (integer) 0
3) "keystep"
4) (integer) 1
5) "limit"
6) (integer) 0
ZUNION
’s key
specifications 1) 1) "flags"
2) 1) RO
2) access
3) "begin_search"
4) 1) "type"
2) "index"
3) "spec"
4) 1) "index"
2) (integer) 1
5) "find_keys"
6) 1) "type"
2) "keynum"
3) "spec"
4) 1) "keynumidx"
2) (integer) 0
3) "firstkey"
4) (integer) 1
5) "keystep"
6) (integer) 1