diff --git a/README.md b/README.md index 0913ee1140..1a93bea2d1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ # Redis documentation +> **Important**: This repository got replaced by the new [Redis docs](https://github.com/redis/docs) repository and will be archived soon. + + +## License vs Trademarks + +OPEN SOURCE LICENSE VS. TRADEMARKS. The three-clause BSD license gives you the right to redistribute and use the software in source and binary forms, with or without modification, under certain conditions. However, open source licenses like the three-clause BSD license do not address trademarks. For further details please read the [Redis Trademark Policy](https://www.redis.com/legal/trademark-policy)." + ## Clients All clients are listed under language specific sub-folders of [clients](./clients) @@ -41,16 +48,49 @@ into account: These keywords will get expanded and auto-linked to relevant parts of the documentation. -There should be at least two predefined sections: description and return value. -The return value section is marked using the @return keyword: +Each command will have a description and both RESP2 and RESP3 return values. +Regarding the return values, these are contained in the files: -``` -Returns all keys matching the given pattern. +* `resp2_replies.json` +* `resp3_replies.json` -@return +Each file is a dictionary with a matching set of keys. Each key is an array of strings that, +when processed, produce Markdown content. Here's an example: -@multi-bulk-reply: all the keys that matched the pattern. ``` +{ + ... + "ACL CAT": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array of [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) elements representing ACL categories or commands in a given category.", + "* [Simple error reply](/docs/reference/protocol-spec#simple-errors): the command returns an error if an invalid category name is given." + ], + ... +} +``` + +**Important**: when adding or editing return values, be sure to edit both files. Use the following +links for the reply type. Note: do not use `@reply-type` specifiers; use only the Markdown link. + +```md +@simple-string-reply: [Simple string reply](https://redis.io/docs/reference/protocol-spec#simple-strings) +@simple-error-reply: [Simple error reply](https://redis.io/docs/reference/protocol-spec#simple-errors) +@integer-reply: [Integer reply](https://redis.io/docs/reference/protocol-spec#integers) +@bulk-string-reply: [Bulk string reply](https://redis.io/docs/reference/protocol-spec#bulk-strings) +@array-reply: [Array reply](https://redis.io/docs/reference/protocol-spec#arrays) +@nil-reply: [Nil reply](https://redis.io/docs/reference/protocol-spec#bulk-strings) +@null-reply: [Null reply](https://redis.io/docs/reference/protocol-spec#nulls) +@boolean-reply: [Boolean reply](https://redis.io/docs/reference/protocol-spec#booleans) +@double-reply: [Double reply](https://redis.io/docs/reference/protocol-spec#doubles) +@big-number-reply: [Big number reply](https://redis.io/docs/reference/protocol-spec#big-numbers) +@bulk-error-reply: [Bulk error reply](https://redis.io/docs/reference/protocol-spec#bulk-errors) +@verbatim-string-reply: [Verbatim string reply](https://redis.io/docs/reference/protocol-spec#verbatim-strings) +@map-reply: [Map reply](https://redis.io/docs/reference/protocol-spec#maps) +@set-reply: [Set reply](https://redis.io/docs/reference/protocol-spec#sets) +@push-reply: [Push reply](https://redis.io/docs/reference/protocol-spec#pushes) +``` + +**Note:** RESP3 return schemas are not currently included in the `resp2/resp3_replies.json` files for Redis Stack modules. ## Styling guidelines diff --git a/clients/ballerina/github.com/ballerina-platform/module-ballerinax-redis.json b/clients/ballerina/github.com/ballerina-platform/module-ballerinax-redis.json new file mode 100644 index 0000000000..49340f841d --- /dev/null +++ b/clients/ballerina/github.com/ballerina-platform/module-ballerinax-redis.json @@ -0,0 +1,7 @@ +{ + "name": "Ballerina Redis Client", + "description": "Official Redis client for Ballerina language with the support for Redis clusters, connection pooling and secure connections.", + "homepage": "https://central.ballerina.io/ballerinax/redis/latest", + "repository": "https://github.com/ballerina-platform/module-ballerinax-redis", + "recommended": true +} diff --git a/clients/gleam/github.com/massivefermion/radish.json b/clients/gleam/github.com/massivefermion/radish.json new file mode 100644 index 0000000000..519ed4bf82 --- /dev/null +++ b/clients/gleam/github.com/massivefermion/radish.json @@ -0,0 +1,8 @@ +{ + "name": "Radish", + "description": "Simple and Fast Redis client written in and for Gleam", + "homepage": "https://hexdocs.pm/radish", + "twitter": [ + "massivefermion" + ] +} \ No newline at end of file diff --git a/clients/kotlin/github.com/domgew/kedis.json b/clients/kotlin/github.com/domgew/kedis.json new file mode 100644 index 0000000000..a620f65a5c --- /dev/null +++ b/clients/kotlin/github.com/domgew/kedis.json @@ -0,0 +1,4 @@ +{ + "name": "Kedis", + "description": "Redis client library for Kotlin Multiplatform (JVM + Native)" +} diff --git a/clients/nodejs/github.com/AWS/GLIDE-for-Redis.json b/clients/nodejs/github.com/AWS/GLIDE-for-Redis.json new file mode 100644 index 0000000000..cfb35fce02 --- /dev/null +++ b/clients/nodejs/github.com/AWS/GLIDE-for-Redis.json @@ -0,0 +1,4 @@ +{ + "name": "GLIDE for Redis", + "description": "General Language Independent Driver for the Enterprise (GLIDE) for Redis is an advanced multi-language Redis client that is feature rich, highly performant, and built for reliability and operational stability. GLIDE for Redis is supported by AWS." +} diff --git a/clients/perl/github.com/plainbanana/Redis-Cluster-Fast.json b/clients/perl/github.com/plainbanana/Redis-Cluster-Fast.json new file mode 100644 index 0000000000..c23ba9a1a0 --- /dev/null +++ b/clients/perl/github.com/plainbanana/Redis-Cluster-Fast.json @@ -0,0 +1,8 @@ +{ + "name": "Redis::Cluster::Fast", + "description": "A fast Perl binding for Redis Cluster", + "homepage": "http://search.cpan.org/dist/Redis-Cluster-Fast/", + "twitter": [ + "plainbanana" + ] +} \ No newline at end of file diff --git a/clients/python/github.com/AWS/GLIDE-for-Redis.json b/clients/python/github.com/AWS/GLIDE-for-Redis.json new file mode 100644 index 0000000000..cfb35fce02 --- /dev/null +++ b/clients/python/github.com/AWS/GLIDE-for-Redis.json @@ -0,0 +1,4 @@ +{ + "name": "GLIDE for Redis", + "description": "General Language Independent Driver for the Enterprise (GLIDE) for Redis is an advanced multi-language Redis client that is feature rich, highly performant, and built for reliability and operational stability. GLIDE for Redis is supported by AWS." +} diff --git a/commands.json b/commands.json index 268c9bfd5c..63637edabd 100644 --- a/commands.json +++ b/commands.json @@ -56,6 +56,10 @@ "noscript", "loading", "stale" + ], + "hints": [ + "request_policy:all_nodes", + "response_policy:all_succeeded" ] }, "ACL DRYRUN": { @@ -263,6 +267,10 @@ "noscript", "loading", "stale" + ], + "hints": [ + "request_policy:all_nodes", + "response_policy:all_succeeded" ] }, "ACL SETUSER": { @@ -305,6 +313,10 @@ "noscript", "loading", "stale" + ], + "hints": [ + "request_policy:all_nodes", + "response_policy:all_succeeded" ] }, "ACL USERS": { @@ -2169,6 +2181,10 @@ "noscript", "loading", "stale" + ], + "hints": [ + "request_policy:all_nodes", + "response_policy:all_succeeded" ] }, "CLIENT SETNAME": { @@ -2192,6 +2208,10 @@ "noscript", "loading", "stale" + ], + "hints": [ + "request_policy:all_nodes", + "response_policy:all_succeeded" ] }, "CLIENT TRACKING": { @@ -3359,6 +3379,10 @@ "noscript", "loading", "stale" + ], + "hints": [ + "request_policy:all_nodes", + "response_policy:all_succeeded" ] }, "CONFIG REWRITE": { @@ -3377,6 +3401,10 @@ "noscript", "loading", "stale" + ], + "hints": [ + "request_policy:all_nodes", + "response_policy:all_succeeded" ] }, "CONFIG SET": { @@ -8088,7 +8116,7 @@ ], "hints": [ "request_policy:all_nodes", - "response_policy:all_succeeded" + "response_policy:agg_sum" ] }, "LCS": { @@ -11045,14 +11073,44 @@ "arity": 3, "arguments": [ { - "name": "host", - "type": "string", - "display_text": "host" - }, - { - "name": "port", - "type": "integer", - "display_text": "port" + "name": "args", + "type": "oneof", + "arguments": [ + { + "name": "host-port", + "type": "block", + "arguments": [ + { + "name": "host", + "type": "string", + "display_text": "host" + }, + { + "name": "port", + "type": "integer", + "display_text": "port" + } + ] + }, + { + "name": "no-one", + "type": "block", + "arguments": [ + { + "name": "no", + "type": "pure-token", + "display_text": "no", + "token": "NO" + }, + { + "name": "one", + "type": "pure-token", + "display_text": "one", + "token": "ONE" + } + ] + } + ] } ], "command_flags": [ @@ -12715,14 +12773,44 @@ "arity": 3, "arguments": [ { - "name": "host", - "type": "string", - "display_text": "host" - }, - { - "name": "port", - "type": "integer", - "display_text": "port" + "name": "args", + "type": "oneof", + "arguments": [ + { + "name": "host-port", + "type": "block", + "arguments": [ + { + "name": "host", + "type": "string", + "display_text": "host" + }, + { + "name": "port", + "type": "integer", + "display_text": "port" + } + ] + }, + { + "name": "no-one", + "type": "block", + "arguments": [ + { + "name": "no", + "type": "pure-token", + "display_text": "no", + "token": "NO" + }, + { + "name": "one", + "type": "pure-token", + "display_text": "one", + "token": "ONE" + } + ] + } + ] } ], "command_flags": [ diff --git a/commands/acl-cat.md b/commands/acl-cat.md index 0eb256fab8..97e35d16fa 100644 --- a/commands/acl-cat.md +++ b/commands/acl-cat.md @@ -76,7 +76,3 @@ Then we may want to know what commands are part of a given category: 30) "psync" 31) "sort" ``` - -@return - -@array-reply: a list of ACL categories or a list of commands inside a given category. The command may return an error if an invalid category name is given as argument. diff --git a/commands/acl-deluser.md b/commands/acl-deluser.md index e3f443e4d7..620183db8f 100644 --- a/commands/acl-deluser.md +++ b/commands/acl-deluser.md @@ -4,10 +4,6 @@ removed from the system, this is the default user that every new connection is authenticated with. The list of users may include usernames that do not exist, in such case no operation is performed for the non existing users. -@return - -@integer-reply: The number of users that were deleted. This number will not always match the number of arguments since certain users may not exist. - @examples ``` diff --git a/commands/acl-dryrun.md b/commands/acl-dryrun.md index 4afb3cd1de..78cca1e76d 100644 --- a/commands/acl-dryrun.md +++ b/commands/acl-dryrun.md @@ -1,11 +1,6 @@ Simulate the execution of a given command by a given user. This command can be used to test the permissions of a given user without having to enable the user or cause the side effects of running the command. -@return - -@simple-string-reply: `OK` on success. -@bulk-string-reply: An error describing why the user can't execute the command. - @examples ``` @@ -13,6 +8,6 @@ This command can be used to test the permissions of a given user without having "OK" > ACL DRYRUN VIRGINIA SET foo bar "OK" -> ACL DRYRUN VIRGINIA GET foo bar -"This user has no permissions to run the 'GET' command" +> ACL DRYRUN VIRGINIA GET foo +"User VIRGINIA has no permissions to run the 'get' command" ``` diff --git a/commands/acl-genpass.md b/commands/acl-genpass.md index 2afbaecf5e..0b7a274334 100644 --- a/commands/acl-genpass.md +++ b/commands/acl-genpass.md @@ -25,10 +25,6 @@ rounded to the next multiple of 4. So for instance asking for just 1 bit password will result in 4 bits to be emitted, in the form of a single hex character. -@return - -@bulk-string-reply: by default 64 bytes string representing 256 bits of pseudorandom data. Otherwise if an argument if needed, the output string length is the number of specified bits (rounded to the next multiple of 4) divided by 4. - @examples ``` diff --git a/commands/acl-getuser.md b/commands/acl-getuser.md index 6c2eeedb07..c952e6483a 100644 --- a/commands/acl-getuser.md +++ b/commands/acl-getuser.md @@ -9,10 +9,6 @@ Note: This description of command rules reflects the user's effective permission Selectors are listed in the order they were applied to the user, and include information about commands, key patterns, and channel patterns. -@array-reply: a list of ACL rule definitions for the user. - -If `user` does not exist a @nil-reply is returned. - @examples Here's an example configuration for a user diff --git a/commands/acl-help.md b/commands/acl-help.md index ddb9432f3c..bccd37b243 100644 --- a/commands/acl-help.md +++ b/commands/acl-help.md @@ -1,5 +1,2 @@ The `ACL HELP` command returns a helpful text describing the different subcommands. -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/acl-list.md b/commands/acl-list.md index e21e710437..df7cecde26 100644 --- a/commands/acl-list.md +++ b/commands/acl-list.md @@ -4,10 +4,6 @@ same used in the redis.conf file or the external ACL file, so you can cut and paste what is returned by the ACL LIST command directly inside a configuration file if you wish (but make sure to check `ACL SAVE`). -@return - -An array of strings. - @examples ``` diff --git a/commands/acl-load.md b/commands/acl-load.md index 521c1a6594..f425937ef5 100644 --- a/commands/acl-load.md +++ b/commands/acl-load.md @@ -6,12 +6,6 @@ sure to have an *all or nothing* behavior, that is: * If every line in the file is valid, all the ACLs are loaded. * If one or more line in the file is not valid, nothing is loaded, and the old ACL rules defined in the server memory continue to be used. -@return - -@simple-string-reply: `OK` on success. - -The command may fail with an error for several reasons: if the file is not readable, if there is an error inside the file, and in such case the error will be reported to the user in the error. Finally the command will fail if the server is not configured to use an external ACL file. - @examples ``` diff --git a/commands/acl-log.md b/commands/acl-log.md index c29ce2877d..eb102f66a6 100644 --- a/commands/acl-log.md +++ b/commands/acl-log.md @@ -8,16 +8,6 @@ The optional argument specifies how many entries to show. By default up to ten failures are returned. The special `RESET` argument clears the log. Entries are displayed starting from the most recent. -@return - -When called to show security events: - -@array-reply: a list of ACL security events. - -When called with `RESET`: - -@simple-string-reply: `OK` if the security log was cleared. - @examples ``` diff --git a/commands/acl-save.md b/commands/acl-save.md index 57badc8b78..bfa59a5969 100644 --- a/commands/acl-save.md +++ b/commands/acl-save.md @@ -1,12 +1,6 @@ When Redis is configured to use an ACL file (with the `aclfile` configuration option), this command will save the currently defined ACLs from the server memory to the ACL file. -@return - -@simple-string-reply: `OK` on success. - -The command may fail with an error for several reasons: if the file cannot be written or if the server is not configured to use an external ACL file. - @examples ``` diff --git a/commands/acl-setuser.md b/commands/acl-setuser.md index 15e872c124..3bc31cc0ee 100644 --- a/commands/acl-setuser.md +++ b/commands/acl-setuser.md @@ -84,12 +84,6 @@ This is a list of all the supported Redis ACL rules: * `clearselectors`: (Available in Redis 7.0 and later) Deletes all of the selectors attached to the user. * `reset`: Removes any capability from the user. They are set to off, without passwords, unable to execute any command, unable to access any key. -@return - -@simple-string-reply: `OK` on success. - -If the rules contain errors, the error is returned. - @examples ``` diff --git a/commands/acl-users.md b/commands/acl-users.md index 9b0fe1bf38..b8a40c4c16 100644 --- a/commands/acl-users.md +++ b/commands/acl-users.md @@ -1,10 +1,6 @@ The command shows a list of all the usernames of the currently configured users in the Redis ACL system. -@return - -An array of strings. - @examples ``` diff --git a/commands/acl-whoami.md b/commands/acl-whoami.md index 5ec7b8485b..04a759477b 100644 --- a/commands/acl-whoami.md +++ b/commands/acl-whoami.md @@ -2,10 +2,6 @@ Return the username the current connection is authenticated with. New connections are authenticated with the "default" user. They can change user using `AUTH`. -@return - -@bulk-string-reply: the username of the current connection. - @examples ``` diff --git a/commands/append.md b/commands/append.md index 2c8bd7432f..2f10c8c1e8 100644 --- a/commands/append.md +++ b/commands/append.md @@ -3,10 +3,6 @@ end of the string. If `key` does not exist it is created and set as an empty string, so `APPEND` will be similar to `SET` in this special case. -@return - -@integer-reply: the length of the string after the append operation. - @examples ```cli diff --git a/commands/asking.md b/commands/asking.md index d98643c25c..39b0acb72b 100644 --- a/commands/asking.md +++ b/commands/asking.md @@ -4,7 +4,3 @@ This is normally done automatically by cluster clients. If an `-ASK` redirect is received during a transaction, only one ASKING command needs to be sent to the target node before sending the complete transaction to the target node. See [ASK redirection in the Redis Cluster Specification](/topics/cluster-spec#ask-redirection) for details. - -@return - -@simple-string-reply: `OK`. diff --git a/commands/auth.md b/commands/auth.md index 5062718f69..144aec9a21 100644 --- a/commands/auth.md +++ b/commands/auth.md @@ -30,7 +30,3 @@ Because of the high performance nature of Redis, it is possible to try a lot of passwords in parallel in very short time, so make sure to generate a strong and very long password so that this attack is infeasible. A good way to generate strong passwords is via the `ACL GENPASS` command. - -@return - -@simple-string-reply or an error if the password, or username/password pair, is invalid. diff --git a/commands/bgrewriteaof.md b/commands/bgrewriteaof.md index 85f52040b4..2424a8631f 100644 --- a/commands/bgrewriteaof.md +++ b/commands/bgrewriteaof.md @@ -23,8 +23,3 @@ Please refer to the [persistence documentation][tp] for detailed information. [tp]: /topics/persistence -@return - -@simple-string-reply: A simple string reply indicating that the rewriting started or is about to start ASAP, when the call is executed with success. - -The command may reply with an error in certain cases, as documented above. diff --git a/commands/bgsave.md b/commands/bgsave.md index 714d960716..f6f676326e 100644 --- a/commands/bgsave.md +++ b/commands/bgsave.md @@ -19,6 +19,3 @@ Please refer to the [persistence documentation][tp] for detailed information. [tp]: /topics/persistence -@return - -@simple-string-reply: `Background saving started` if `BGSAVE` started correctly or `Background saving scheduled` when used with the `SCHEDULE` subcommand. diff --git a/commands/bitcount.md b/commands/bitcount.md index 95bd3a3882..3b33703751 100644 --- a/commands/bitcount.md +++ b/commands/bitcount.md @@ -15,12 +15,6 @@ We can use an additional argument `BIT` to specify a bit index. So 0 is the first bit, 1 is the second bit, and so forth. For negative values, -1 is the last bit, -2 is the penultimate, and so forth. -@return - -@integer-reply - -The number of bits set to 1. - @examples ```cli diff --git a/commands/bitfield.md b/commands/bitfield.md index 6609c85b13..0a549acff9 100644 --- a/commands/bitfield.md +++ b/commands/bitfield.md @@ -78,12 +78,6 @@ By default, **WRAP** is used if not otherwise specified. 1) (integer) 0 2) (integer) 3 -## Return value - -The command returns an array with each entry being the corresponding result of -the sub command given at the same position. `OVERFLOW` subcommands don't count -as generating a reply. - The following is an example of `OVERFLOW FAIL` returning NULL. > BITFIELD mykey OVERFLOW FAIL incrby u2 102 1 diff --git a/commands/bitfield_ro.md b/commands/bitfield_ro.md index 94057a1183..26ec064ded 100644 --- a/commands/bitfield_ro.md +++ b/commands/bitfield_ro.md @@ -13,7 +13,3 @@ See original `BITFIELD` for more details. ``` BITFIELD_RO hello GET i8 16 ``` - -@return - -@array-reply: An array with each entry being the corresponding result of the subcommand given at the same position. diff --git a/commands/bitop.md b/commands/bitop.md index fd5aca9b17..e679b449bf 100644 --- a/commands/bitop.md +++ b/commands/bitop.md @@ -24,13 +24,6 @@ zero-padded up to the length of the longest string. The same holds true for non-existent keys, that are considered as a stream of zero bytes up to the length of the longest string. -@return - -@integer-reply - -The size of the string stored in the destination key, that is equal to the -size of the longest input string. - @examples ```cli diff --git a/commands/bitpos.md b/commands/bitpos.md index 1016941418..689926dbc0 100644 --- a/commands/bitpos.md +++ b/commands/bitpos.md @@ -22,20 +22,6 @@ bit, -2 is the penultimate, and so forth. Non-existent keys are treated as empty strings. -@return - -@integer-reply - -The command returns the position of the first bit set to 1 or 0 according to the request. - -If we look for set bits (the bit argument is 1) and the string is empty or composed of just zero bytes, -1 is returned. - -If we look for clear bits (the bit argument is 0) and the string only contains bit set to 1, the function returns the first bit not part of the string on the right. So if the string is three bytes set to the value `0xff` the command `BITPOS key 0` will return 24, since up to bit 23 all the bits are 1. - -Basically, the function considers the right of the string as padded with zeros if you look for clear bits and specify no range or the _start_ argument **only**. - -However, this behavior changes if you are looking for clear bits and specify a range with both __start__ and __end__. If no clear bit is found in the specified range, the function returns -1 as the user specified a clear range and there are no 0 bits in that range. - @examples ```cli diff --git a/commands/blmove.md b/commands/blmove.md index 463a2dca28..7a45b13e89 100644 --- a/commands/blmove.md +++ b/commands/blmove.md @@ -10,11 +10,6 @@ This command comes in place of the now deprecated `BRPOPLPUSH`. Doing See `LMOVE` for more information. -@return - -@bulk-string-reply: the element being popped from `source` and pushed to `destination`. -If `timeout` is reached, a @nil-reply is returned. - ## Pattern: Reliable queue Please see the pattern description in the `LMOVE` documentation. diff --git a/commands/blmpop.md b/commands/blmpop.md index 262713ef31..73bac9d284 100644 --- a/commands/blmpop.md +++ b/commands/blmpop.md @@ -6,10 +6,3 @@ When all lists are empty, Redis will block the connection until another client p A `timeout` of zero can be used to block indefinitely. See `LMPOP` for more information. - -@return - -@array-reply: specifically: - -* A `nil` when no element could be popped, and timeout is reached. -* A two-element array with the first element being the name of the key from which elements were popped, and the second element is an array of elements. diff --git a/commands/blpop.md b/commands/blpop.md index 1d73fff19d..5ce6ffb447 100644 --- a/commands/blpop.md +++ b/commands/blpop.md @@ -82,15 +82,6 @@ thing that happens when the timeout is reached. If you like science fiction, think of time flowing at infinite speed inside a `MULTI` / `EXEC` block... -@return - -@array-reply: specifically: - -* A `nil` multi-bulk when no element could be popped and the timeout expired. -* A two-element multi-bulk with the first element being the name of the key - where an element was popped and the second element being the value of the - popped element. - @examples ``` diff --git a/commands/brpop.md b/commands/brpop.md index dfa2b91cac..08806cff53 100644 --- a/commands/brpop.md +++ b/commands/brpop.md @@ -10,15 +10,6 @@ the tail of a list instead of popping from the head. [cb]: /commands/blpop -@return - -@array-reply: specifically: - -* A `nil` multi-bulk when no element could be popped and the timeout expired. -* A two-element multi-bulk with the first element being the name of the key - where an element was popped and the second element being the value of the - popped element. - @examples ``` diff --git a/commands/brpoplpush.md b/commands/brpoplpush.md index 9a6fe376d9..3989fd67fe 100644 --- a/commands/brpoplpush.md +++ b/commands/brpoplpush.md @@ -7,11 +7,6 @@ A `timeout` of zero can be used to block indefinitely. See `RPOPLPUSH` for more information. -@return - -@bulk-string-reply: the element being popped from `source` and pushed to `destination`. -If `timeout` is reached, a @nil-reply is returned. - ## Pattern: Reliable queue Please see the pattern description in the `RPOPLPUSH` documentation. diff --git a/commands/bzmpop.md b/commands/bzmpop.md index dc0c077d96..50c25709c0 100644 --- a/commands/bzmpop.md +++ b/commands/bzmpop.md @@ -6,11 +6,3 @@ When all sorted sets are empty, Redis will block the connection until another cl A `timeout` of zero can be used to block indefinitely. See `ZMPOP` for more information. - -@return - -@array-reply: specifically: - -* A `nil` when no element could be popped. -* A two-element array with the first element being the name of the key from which elements were popped, and the second element is an array of the popped elements. Every entry in the elements array is also an array that contains the member and its score. - diff --git a/commands/bzpopmax.md b/commands/bzpopmax.md index 8155ed8b99..c6d726f4db 100644 --- a/commands/bzpopmax.md +++ b/commands/bzpopmax.md @@ -14,15 +14,6 @@ with the highest scores instead of popping the ones with the lowest scores. [cb]: /commands/bzpopmin -@return - -@array-reply: specifically: - -* A `nil` multi-bulk when no element could be popped and the timeout expired. -* A three-element multi-bulk with the first element being the name of the key - where a member was popped, the second element is the popped member itself, - and the third element is the score of the popped element. - @examples ``` diff --git a/commands/bzpopmin.md b/commands/bzpopmin.md index b48a4fb759..936154d051 100644 --- a/commands/bzpopmin.md +++ b/commands/bzpopmin.md @@ -14,15 +14,6 @@ popped from. [cl]: /commands/blpop -@return - -@array-reply: specifically: - -* A `nil` multi-bulk when no element could be popped and the timeout expired. -* A three-element multi-bulk with the first element being the name of the key - where a member was popped, the second element is the popped member itself, - and the third element is the score of the popped element. - @examples ``` diff --git a/commands/client-caching.md b/commands/client-caching.md index 1f4b8b8a3e..e3bf90ee86 100644 --- a/commands/client-caching.md +++ b/commands/client-caching.md @@ -16,7 +16,3 @@ tracked using `CLIENT CACHING no`. Basically the command sets a state in the connection, that is valid only for the next command execution, that will modify the behavior of client tracking. - -@return - -@simple-string-reply: `OK` or an error if the argument is not yes or no. diff --git a/commands/client-getname.md b/commands/client-getname.md index f60539dd02..0991c6eea9 100644 --- a/commands/client-getname.md +++ b/commands/client-getname.md @@ -1,5 +1 @@ The `CLIENT GETNAME` returns the name of the current connection as set by `CLIENT SETNAME`. Since every new connection starts without an associated name, if no name was assigned a null bulk reply is returned. - -@return - -@bulk-string-reply: The connection name, or a null bulk reply if no name is set. diff --git a/commands/client-getredir.md b/commands/client-getredir.md index 2cc326957f..dcc623c1a8 100644 --- a/commands/client-getredir.md +++ b/commands/client-getredir.md @@ -5,7 +5,3 @@ order to avoid forcing client libraries implementations to remember the ID notifications are redirected to, this command exists in order to improve introspection and allow clients to check later if redirection is active and towards which client ID. - -@return - -@integer-reply: the ID of the client we are redirecting the notifications to. The command returns `-1` if client tracking is not enabled, or `0` if client tracking is enabled but we are not redirecting the notifications to any client. diff --git a/commands/client-help.md b/commands/client-help.md index 964a625740..6745f6cf24 100644 --- a/commands/client-help.md +++ b/commands/client-help.md @@ -1,5 +1 @@ The `CLIENT HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/client-id.md b/commands/client-id.md index fe6723c513..53fcac5016 100644 --- a/commands/client-id.md +++ b/commands/client-id.md @@ -12,9 +12,3 @@ introduced also in Redis 5 together with `CLIENT ID`. Check the `CLIENT UNBLOCK` ```cli CLIENT ID ``` - -@return - -@integer-reply - -The id of the client. diff --git a/commands/client-info.md b/commands/client-info.md index f60592e175..5eea826ba8 100644 --- a/commands/client-info.md +++ b/commands/client-info.md @@ -7,7 +7,3 @@ The reply format is identical to that of `CLIENT LIST`, and the content consists ```cli CLIENT INFO ``` - -@return - -@bulk-string-reply: a unique string, as described at the `CLIENT LIST` page, for the current client. diff --git a/commands/client-kill.md b/commands/client-kill.md index ea65aaf3ea..e54529a7c8 100644 --- a/commands/client-kill.md +++ b/commands/client-kill.md @@ -17,6 +17,7 @@ instead of killing just by address. The following filters are available: * `CLIENT KILL TYPE type`, where *type* is one of `normal`, `master`, `replica` and `pubsub`. This closes the connections of **all the clients** in the specified class. Note that clients blocked into the `MONITOR` command are considered to belong to the `normal` class. * `CLIENT KILL USER username`. Closes all the connections that are authenticated with the specified [ACL](/topics/acl) username, however it returns an error if the username does not map to an existing ACL user. * `CLIENT KILL SKIPME yes/no`. By default this option is set to `yes`, that is, the client calling the command will not get killed, however setting this option to `no` will have the effect of also killing the client calling the command. +* `CLIENT KILL MAXAGE maxage`. Closes all the connections that are older than the specified age, in seconds. It is possible to provide multiple filters at the same time. The command will handle multiple filters via logical AND. For example: @@ -41,13 +42,3 @@ the client point of view, the connection can never be closed in the middle of the execution of a command. However, the client will notice the connection has been closed only when the next command is sent (and results in network error). - -@return - -When called with the three arguments format: - -@simple-string-reply: `OK` if the connection exists and has been closed - -When called with the filter / value format: - -@integer-reply: the number of clients killed. diff --git a/commands/client-list.md b/commands/client-list.md index 6241425ba7..653e75a8ef 100644 --- a/commands/client-list.md +++ b/commands/client-list.md @@ -5,14 +5,6 @@ You can use one of the optional subcommands to filter the list. The `TYPE type` The `ID` filter only returns entries for clients with IDs matching the `client-id` arguments. -@return - -@bulk-string-reply: a unique string, formatted as follows: - -* One client connection per line (separated by LF) -* Each line is composed of a succession of `property=value` fields separated - by a space character. - Here is the meaning of the fields: * `id`: a unique 64-bit client ID @@ -28,6 +20,7 @@ Here is the meaning of the fields: * `psub`: number of pattern matching subscriptions * `ssub`: number of shard channel subscriptions. Added in Redis 7.0.3 * `multi`: number of commands in a MULTI/EXEC context +* `watch`: number of keys this client is currently watching. Added in Redis 8.0 * `qbuf`: query buffer length (0 means no query pending) * `qbuf-free`: free space of the query buffer (0 means the buffer is full) * `argv-mem`: incomplete arguments for the next command (already extracted from query buffer) @@ -49,6 +42,7 @@ A: connection to be closed ASAP b: the client is waiting in a blocking operation c: connection to be closed after writing entire reply d: a watched keys has been modified - EXEC will fail +e: the client is excluded from the client eviction mechanism i: the client is waiting for a VM I/O (deprecated) M: the client is a master N: no specific flag set @@ -60,6 +54,7 @@ u: the client is unblocked U: the client is connected via a Unix domain socket x: the client is in a MULTI/EXEC context t: the client enabled keys tracking in order to perform client side caching +T: the client will not touch the LRU/LFU of the keys it accesses R: the client tracking target client is invalid B: the client enabled broadcast tracking mode ``` diff --git a/commands/client-no-evict.md b/commands/client-no-evict.md index 70070a6abb..2a18898e41 100644 --- a/commands/client-no-evict.md +++ b/commands/client-no-evict.md @@ -5,7 +5,3 @@ When turned on and client eviction is configured, the current connection will be When turned off, the current client will be re-included in the pool of potential clients to be evicted (and evicted if needed). See [client eviction](/topics/clients#client-eviction) for more details. - -@return - -@simple-string-reply: `OK`. diff --git a/commands/client-no-touch.md b/commands/client-no-touch.md index 36e69dec77..da723058bc 100644 --- a/commands/client-no-touch.md +++ b/commands/client-no-touch.md @@ -3,7 +3,3 @@ The `CLIENT NO-TOUCH` command controls whether commands sent by the client will When turned on, the current client will not change LFU/LRU stats, unless it sends the `TOUCH` command. When turned off, the client touches LFU/LRU stats just as a normal client. - -@return - -@simple-string-reply: `OK`. diff --git a/commands/client-pause.md b/commands/client-pause.md index 6f778da1e7..d7c381f9c0 100644 --- a/commands/client-pause.md +++ b/commands/client-pause.md @@ -35,10 +35,6 @@ Since Redis 3.2.10 / 4.0.0, this command also prevents keys to be evicted or expired during the time clients are paused. This way the dataset is guaranteed to be static not just from the point of view of clients not being able to write, but also from the point of view of internal operations. -@return - -@simple-string-reply: The command returns OK or an error if the timeout is invalid. - ## Behavior change history * `>= 3.2.0`: Client pause prevents client pause and key eviction as well. \ No newline at end of file diff --git a/commands/client-reply.md b/commands/client-reply.md index f2c3ed8b42..63608e60a9 100644 --- a/commands/client-reply.md +++ b/commands/client-reply.md @@ -5,9 +5,3 @@ The `CLIENT REPLY` command controls whether the server will reply the client's c * `ON`. This is the default mode in which the server returns a reply to every command. * `OFF`. In this mode the server will not reply to client commands. * `SKIP`. This mode skips the reply of command immediately after it. - -@return - -When called with either `OFF` or `SKIP` subcommands, no reply is made. When called with `ON`: - -@simple-string-reply: `OK`. diff --git a/commands/client-setinfo.md b/commands/client-setinfo.md index b6ff217411..64a66f3734 100644 --- a/commands/client-setinfo.md +++ b/commands/client-setinfo.md @@ -10,7 +10,3 @@ Currently the supported attributes are: There is no limit to the length of these attributes. However it is not possible to use spaces, newlines, or other non-printable characters that would violate the format of the `CLIENT LIST` reply. Note that these attributes are **not** cleared by the RESET command. - -@return - -@simple-string-reply: `OK` if the attribute name was successfully set. diff --git a/commands/client-setname.md b/commands/client-setname.md index c1e70af259..f0a147921b 100644 --- a/commands/client-setname.md +++ b/commands/client-setname.md @@ -13,7 +13,3 @@ The connection name can be inspected using `CLIENT GETNAME`. Every new connection starts without an assigned name. Tip: setting names to connections is a good way to debug connection leaks due to bugs in the application using Redis. - -@return - -@simple-string-reply: `OK` if the connection name was successfully set. diff --git a/commands/client-tracking.md b/commands/client-tracking.md index e77f7d907e..503d4dca62 100644 --- a/commands/client-tracking.md +++ b/commands/client-tracking.md @@ -27,7 +27,3 @@ command when enabling tracking: * `OPTIN`: when broadcasting is NOT active, normally don't track keys in read only commands, unless they are called immediately after a `CLIENT CACHING yes` command. * `OPTOUT`: when broadcasting is NOT active, normally track keys in read only commands, unless they are called immediately after a `CLIENT CACHING no` command. * `NOLOOP`: don't send notifications about keys modified by this connection itself. - -@return - -@simple-string-reply: `OK` if the connection was successfully put in tracking mode or if the tracking mode was successfully disabled. Otherwise an error is returned. diff --git a/commands/client-trackinginfo.md b/commands/client-trackinginfo.md index 82de43e255..6cc0df14ab 100644 --- a/commands/client-trackinginfo.md +++ b/commands/client-trackinginfo.md @@ -1,8 +1,6 @@ The command returns information about the current client connection's use of the [server assisted client side caching](/topics/client-side-caching) feature. -@return - -@array-reply: a list of tracking information sections and their respective values, specifically: +Here's the list of tracking information sections and their respective values: * **flags**: A list of tracking flags used by the connection. The flags and their meanings are as follows: * `off`: The connection isn't using server assisted client side caching. diff --git a/commands/client-unblock.md b/commands/client-unblock.md index 11dff98ce7..36e70b2924 100644 --- a/commands/client-unblock.md +++ b/commands/client-unblock.md @@ -49,10 +49,3 @@ NULL > BRPOP key1 key2 key3 key4 0 (client is blocked again) ``` - -@return - -@integer-reply, specifically: - -* `1` if the client was unblocked successfully. -* `0` if the client wasn't unblocked. diff --git a/commands/client-unpause.md b/commands/client-unpause.md index c43848522f..9878ee1b3c 100644 --- a/commands/client-unpause.md +++ b/commands/client-unpause.md @@ -1,5 +1 @@ `CLIENT UNPAUSE` is used to resume command processing for all clients that were paused by `CLIENT PAUSE`. - -@return - -@simple-string-reply: The command returns `OK` diff --git a/commands/cluster-addslots.md b/commands/cluster-addslots.md index 9c9a8c012e..101f671506 100644 --- a/commands/cluster-addslots.md +++ b/commands/cluster-addslots.md @@ -45,7 +45,3 @@ This means that this command should be used with care only by applications orchestrating Redis Cluster, like `redis-cli`, and the command if used out of the right context can leave the cluster in a wrong state or cause data loss. - -@return - -@simple-string-reply: `OK` if the command was successful. Otherwise an error is returned. diff --git a/commands/cluster-addslotsrange.md b/commands/cluster-addslotsrange.md index 6e7c545fc1..1fc1cd3d8b 100644 --- a/commands/cluster-addslotsrange.md +++ b/commands/cluster-addslotsrange.md @@ -21,7 +21,3 @@ This command only works in cluster mode and is useful in the following Redis Clu 1. To create a new cluster, `CLUSTER ADDSLOTSRANGE` is used to initially set up master nodes splitting the available hash slots among them. 2. In order to fix a broken cluster where certain slots are unassigned. - -@return - -@simple-string-reply: `OK` if the command was successful. Otherwise an error is returned. diff --git a/commands/cluster-bumpepoch.md b/commands/cluster-bumpepoch.md index b05694a442..68bce48797 100644 --- a/commands/cluster-bumpepoch.md +++ b/commands/cluster-bumpepoch.md @@ -3,7 +3,3 @@ Advances the cluster config epoch. The `CLUSTER BUMPEPOCH` command triggers an increment to the cluster's config epoch from the connected node. The epoch will be incremented if the node's config epoch is zero, or if it is less than the cluster's greatest epoch. **Note:** config epoch management is performed internally by the cluster, and relies on obtaining a consensus of nodes. The `CLUSTER BUMPEPOCH` attempts to increment the config epoch **WITHOUT** getting the consensus, so using it may violate the "last failover wins" rule. Use it with caution. - -@return - -@simple-string-reply: `BUMPED` if the epoch was incremented, or `STILL` if the node already has the greatest config epoch in the cluster. diff --git a/commands/cluster-count-failure-reports.md b/commands/cluster-count-failure-reports.md index ac1ef71c0e..399a6bc000 100644 --- a/commands/cluster-count-failure-reports.md +++ b/commands/cluster-count-failure-reports.md @@ -16,7 +16,3 @@ This command returns the number of failure reports for the current node which ar This command is mainly useful for debugging, when the failure detector of Redis Cluster is not operating as we believe it should. - -@return - -@integer-reply: the number of active failure reports for the node. diff --git a/commands/cluster-countkeysinslot.md b/commands/cluster-countkeysinslot.md index 0bffec84b5..2a6e6af4f8 100644 --- a/commands/cluster-countkeysinslot.md +++ b/commands/cluster-countkeysinslot.md @@ -7,7 +7,3 @@ zero being returned. > CLUSTER COUNTKEYSINSLOT 7000 (integer) 50341 ``` - -@return - -@integer-reply: The number of keys in the specified hash slot, or an error if the hash slot is invalid. diff --git a/commands/cluster-delslots.md b/commands/cluster-delslots.md index 77204e1e95..4fdb4a5180 100644 --- a/commands/cluster-delslots.md +++ b/commands/cluster-delslots.md @@ -41,8 +41,3 @@ This command only works in cluster mode and may be useful for debugging and in order to manually orchestrate a cluster configuration when a new cluster is created. It is currently not used by `redis-cli`, and mainly exists for API completeness. - -@return - -@simple-string-reply: `OK` if the command was successful. Otherwise -an error is returned. diff --git a/commands/cluster-delslotsrange.md b/commands/cluster-delslotsrange.md index e4c1f2b89d..af902ff586 100644 --- a/commands/cluster-delslotsrange.md +++ b/commands/cluster-delslotsrange.md @@ -25,8 +25,3 @@ This command only works in cluster mode and may be useful for debugging and in order to manually orchestrate a cluster configuration when a new cluster is created. It is currently not used by `redis-cli`, and mainly exists for API completeness. - -@return - -@simple-string-reply: `OK` if the command was successful. Otherwise -an error is returned. diff --git a/commands/cluster-failover.md b/commands/cluster-failover.md index 911eaea894..85834cba67 100644 --- a/commands/cluster-failover.md +++ b/commands/cluster-failover.md @@ -61,7 +61,3 @@ Because of this the **TAKEOVER** option should be used with care. To check that the masters are aware of a new replica, you can send `CLUSTER NODES` or `CLUSTER REPLICAS` to each of the master nodes and check that it appears as a replica, before sending `CLUSTER FAILOVER` to the replica. * To check that the failover has actually happened you can use `ROLE`, `INFO REPLICATION` (which indicates "role:master" after successful failover), or `CLUSTER NODES` to verify that the state of the cluster has changed sometime after the command was sent. * To check if the failover has failed, check the replica's log for "Manual failover timed out", which is logged if the replica has given up after a few seconds. - -@return - -@simple-string-reply: `OK` if the command was accepted and a manual failover is going to be attempted. An error if the operation cannot be executed, for example if we are talking with a node which is already a master. diff --git a/commands/cluster-flushslots.md b/commands/cluster-flushslots.md index b0b3fdfba6..0c8984ff23 100644 --- a/commands/cluster-flushslots.md +++ b/commands/cluster-flushslots.md @@ -1,7 +1,3 @@ Deletes all slots from a node. The `CLUSTER FLUSHSLOTS` deletes all information about slots from the connected node. It can only be called when the database is empty. - -@return - -@simple-string-reply: `OK` diff --git a/commands/cluster-forget.md b/commands/cluster-forget.md index 6bff5061fe..afc06414df 100644 --- a/commands/cluster-forget.md +++ b/commands/cluster-forget.md @@ -51,7 +51,3 @@ The command does not succeed and returns an error in the following cases: 1. The specified node ID is not found in the nodes table. 2. The node receiving the command is a replica, and the specified node ID identifies its current master. 3. The node ID identifies the same node we are sending the command to. - -@return - -@simple-string-reply: `OK` if the command was executed successfully, otherwise an error is returned. diff --git a/commands/cluster-getkeysinslot.md b/commands/cluster-getkeysinslot.md index 120bf4412d..dec113df05 100644 --- a/commands/cluster-getkeysinslot.md +++ b/commands/cluster-getkeysinslot.md @@ -14,7 +14,3 @@ of the `CLUSTER SETSLOT` command documentation. 2) "key_89793" 3) "key_92937" ``` - -@return - -@array-reply: From 0 to *count* key names in a Redis array reply. diff --git a/commands/cluster-help.md b/commands/cluster-help.md index 3b1e159006..85579bd446 100644 --- a/commands/cluster-help.md +++ b/commands/cluster-help.md @@ -1,5 +1 @@ The `CLUSTER HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/cluster-info.md b/commands/cluster-info.md index 372cc73906..3f49280aca 100644 --- a/commands/cluster-info.md +++ b/commands/cluster-info.md @@ -46,7 +46,3 @@ Here are the explanation of these fields: * `cluster_stats_messages_publishshard_sent` and `cluster_stats_messages_publishshard_received`: Pub/Sub Publish shard propagation, see [Sharded Pubsub](/topics/pubsub#sharded-pubsub). More information about the Current Epoch and Config Epoch variables are available in the [Redis Cluster specification document](/topics/cluster-spec#cluster-current-epoch). - -@return - -@bulk-string-reply: A map between named fields and values in the form of `:` lines separated by newlines composed by the two bytes `CRLF`. diff --git a/commands/cluster-keyslot.md b/commands/cluster-keyslot.md index 7e0358785c..1556874255 100644 --- a/commands/cluster-keyslot.md +++ b/commands/cluster-keyslot.md @@ -18,7 +18,3 @@ Example use cases for this command: ``` Note that the command implements the full hashing algorithm, including support for **hash tags**, that is the special property of Redis Cluster key hashing algorithm, of hashing just what is between `{` and `}` if such a pattern is found inside the key name, in order to force multiple keys to be handled by the same node. - -@return - -@integer-reply: The hash slot number. diff --git a/commands/cluster-links.md b/commands/cluster-links.md index 7b3376298c..12e7630e68 100644 --- a/commands/cluster-links.md +++ b/commands/cluster-links.md @@ -42,7 +42,3 @@ Each map is composed of the following attributes of the corresponding cluster li 4. `events`: Events currently registered for the link. `r` means readable event, `w` means writable event. 5. `send-buffer-allocated`: Allocated size of the link's send buffer, which is used to buffer outgoing messages toward the peer. 6. `send-buffer-used`: Size of the portion of the link's send buffer that is currently holding data(messages). - -@return - -@array-reply: An array of maps where each map contains various attributes and their values of a cluster link. diff --git a/commands/cluster-meet.md b/commands/cluster-meet.md index b33c9fb749..0ce7c212f6 100644 --- a/commands/cluster-meet.md +++ b/commands/cluster-meet.md @@ -36,7 +36,3 @@ the node to force the receiver to accept it as a trusted node, it sends a `MEET` packet instead of a `PING` packet. The two packets have exactly the same format, but the former forces the receiver to acknowledge the node as trusted. - -@return - -@simple-string-reply: `OK` if the command was successful. If the address or port specified are invalid an error is returned. diff --git a/commands/cluster-myid.md b/commands/cluster-myid.md index 02e8b1d3b6..594c28b3f4 100644 --- a/commands/cluster-myid.md +++ b/commands/cluster-myid.md @@ -1,7 +1,3 @@ Returns the node's id. The `CLUSTER MYID` command returns the unique, auto-generated identifier that is associated with the connected cluster node. - -@return - -@bulk-string-reply: The node id. \ No newline at end of file diff --git a/commands/cluster-myshardid.md b/commands/cluster-myshardid.md index 4334b150a0..6ffb3c5b9b 100644 --- a/commands/cluster-myshardid.md +++ b/commands/cluster-myshardid.md @@ -1,7 +1,3 @@ Returns the node's shard id. The `CLUSTER MYSHARDID` command returns the unique, auto-generated identifier that is associated with the shard to which the connected cluster node belongs. - -@return - -@bulk-string-reply: The node's shard id. diff --git a/commands/cluster-nodes.md b/commands/cluster-nodes.md index e5bfb7bc95..a802fe7cff 100644 --- a/commands/cluster-nodes.md +++ b/commands/cluster-nodes.md @@ -38,7 +38,8 @@ Each line is composed of the following fields: The meaning of each field is the following: 1. `id`: The node ID, a 40-character globally unique string generated when a node is created and never changed again (unless `CLUSTER RESET HARD` is used). -2. `ip:port@cport`: The node address that clients should contact to run queries. +2. `ip:port@cport`: The node address that clients should contact to run queries, along with the used cluster bus port. + `:0@0` can be expected when the address is no longer known for this node ID, hence flagged with `noaddr`. 3. `hostname`: A human readable string that can be configured via the `cluster-annouce-hostname` setting. The max length of the string is 256 characters, excluding the null terminator. The name can contain ASCII alphanumeric characters, '-', and '.' only. 5. `flags`: A list of comma separated flags: `myself`, `master`, `slave`, `fail?`, `fail`, `handshake`, `noaddr`, `nofailover`, `noflags`. Flags are explained below. 6. `master`: If the node is a replica, and the primary is known, the primary node ID, otherwise the "-" character. @@ -104,8 +105,4 @@ Note that: 1. Migration and importing slots are only added to the node flagged as `myself`. This information is local to a node, for its own slots. 2. Importing and migrating slots are provided as **additional info**. If the node has a given hash slot assigned, it will be also a plain number in the list of hash slots, so clients that don't have a clue about hash slots migrations can just skip this special fields. -@return - -@bulk-string-reply: The serialized cluster configuration. - **A note about the word slave used in this man page and command name**: Starting with Redis 5, if not for backward compatibility, the Redis project no longer uses the word slave. Unfortunately in this command the word slave is part of the protocol, so we'll be able to remove such occurrences only when this API will be naturally deprecated. diff --git a/commands/cluster-replicas.md b/commands/cluster-replicas.md index 4e6192e117..6d0e63708e 100644 --- a/commands/cluster-replicas.md +++ b/commands/cluster-replicas.md @@ -9,7 +9,3 @@ and we ask `CLUSTER REPLICAS` to a node that has not yet received the configuration update, it may show stale information. However eventually (in a matter of seconds if there are no network partitions) all the nodes will agree about the set of nodes associated with a given master. - -@return - -The command returns data in the same format as `CLUSTER NODES`. diff --git a/commands/cluster-replicate.md b/commands/cluster-replicate.md index 5b403aaa8b..9d3c36d280 100644 --- a/commands/cluster-replicate.md +++ b/commands/cluster-replicate.md @@ -20,7 +20,3 @@ only if the following additional conditions are met: 2. The node is empty, no keys are stored at all in the key space. If the command succeeds the new replica will immediately try to contact its master in order to replicate from it. - -@return - -@simple-string-reply: `OK` if the command was executed successfully, otherwise an error is returned. diff --git a/commands/cluster-reset.md b/commands/cluster-reset.md index 02ffe9eb95..1d76229342 100644 --- a/commands/cluster-reset.md +++ b/commands/cluster-reset.md @@ -19,7 +19,3 @@ is also extensively used by the Redis Cluster testing framework in order to reset the state of the cluster every time a new test unit is executed. If no reset type is specified, the default is **soft**. - -@return - -@simple-string-reply: `OK` if the command was successful. Otherwise an error is returned. diff --git a/commands/cluster-saveconfig.md b/commands/cluster-saveconfig.md index 31308c2028..3f23701963 100644 --- a/commands/cluster-saveconfig.md +++ b/commands/cluster-saveconfig.md @@ -9,7 +9,3 @@ configuration via the `CLUSTER` command in order to ensure the new configuration is persisted on disk, however all the commands should normally be able to auto schedule to persist the configuration on disk when it is important to do so for the correctness of the system in the event of a restart. - -@return - -@simple-string-reply: `OK` or an error if the operation fails. diff --git a/commands/cluster-set-config-epoch.md b/commands/cluster-set-config-epoch.md index 71f458f33e..5eb7fca262 100644 --- a/commands/cluster-set-config-epoch.md +++ b/commands/cluster-set-config-epoch.md @@ -19,7 +19,3 @@ configuration epoch. So, using `CLUSTER SET-CONFIG-EPOCH`, when a new cluster is created, we can assign a different progressive configuration epoch to each node before joining the cluster together. - -@return - -@simple-string-reply: `OK` if the command was executed successfully, otherwise an error is returned. diff --git a/commands/cluster-setslot.md b/commands/cluster-setslot.md index e712d36ba6..ab32c6772c 100644 --- a/commands/cluster-setslot.md +++ b/commands/cluster-setslot.md @@ -60,10 +60,6 @@ command: It is important to note that step 3 is the only time when a Redis Cluster node will create a new config epoch without agreement from other nodes. This only happens when a manual configuration is operated. However it is impossible that this creates a non-transient setup where two nodes have the same config epoch, since Redis Cluster uses a config epoch collision resolution algorithm. -@return - -@simple-string-reply: All the subcommands return `OK` if the command was successful. Otherwise an error is returned. - ## Redis Cluster live resharding explained The `CLUSTER SETSLOT` command is an important piece used by Redis Cluster in order to migrate all the keys contained in one hash slot from one node to another. This is how the migration is orchestrated, with the help of other commands as well. We'll call the node that has the current ownership of the hash slot the `source` node, and the node where we want to migrate the `destination` node. diff --git a/commands/cluster-shards.md b/commands/cluster-shards.md index 8d5c8fd4cc..a6989a3910 100644 --- a/commands/cluster-shards.md +++ b/commands/cluster-shards.md @@ -50,10 +50,6 @@ This can happen in a cluster that consists of only one node or the node has not The value `?` is displayed if the node is incorrectly configured to use announced hostnames but no hostname is configured using `cluster-announce-hostname`. Clients may treat the empty string in the same way as NULL, that is the same endpoint it used to send the current command to, while `"?"` should be treated as an unknown node, not necessarily the same node as the one serving the current command. -@return - -@array-reply: nested list of a map of hash ranges and shard nodes. - @examples ``` diff --git a/commands/cluster-slaves.md b/commands/cluster-slaves.md index d90eaf38c5..2f4f9628af 100644 --- a/commands/cluster-slaves.md +++ b/commands/cluster-slaves.md @@ -11,7 +11,3 @@ and we ask `CLUSTER SLAVES` to a node that has not yet received the configuration update, it may show stale information. However eventually (in a matter of seconds if there are no network partitions) all the nodes will agree about the set of nodes associated with a given master. - -@return - -The command returns data in the same format as `CLUSTER NODES`. diff --git a/commands/cluster-slots.md b/commands/cluster-slots.md index b3166bbf28..be07af62e8 100644 --- a/commands/cluster-slots.md +++ b/commands/cluster-slots.md @@ -41,12 +41,6 @@ All networking information after the third nested reply are replicas of the mast If a cluster instance has non-contiguous slots (e.g. 1-400,900,1800-6000) then master and replica networking information results will be duplicated for each top-level slot range reply. -@return - -@array-reply: nested list of slot ranges with networking information. - -@examples - ``` > CLUSTER SLOTS 1) 1) (integer) 0 diff --git a/commands/command-count.md b/commands/command-count.md index a198dd35ac..2eee36f22e 100644 --- a/commands/command-count.md +++ b/commands/command-count.md @@ -1,9 +1,5 @@ Returns @integer-reply of number of total commands in this Redis server. -@return - -@integer-reply: number of commands returned by `COMMAND` - @examples ```cli diff --git a/commands/command-docs.md b/commands/command-docs.md index 35ea017f2a..98943d73a7 100644 --- a/commands/command-docs.md +++ b/commands/command-docs.md @@ -35,7 +35,7 @@ The following keys may be included in the mapped reply: - _syscmd:_ a system command that isn't meant to be called by users. * **deprecated_since:** the Redis version that deprecated the command (or for module commands, the module version).. * **replaced_by:** the alternative for a deprecated command. -* **history:** an array of historical notes describing changes to the command's behavior or arguments. +* **history:** an array of historical notes describing changes to the command's output or arguments. It should not contain information about behavioral changes. Each entry is an array itself, made up of two elements: 1. The Redis version that the entry applies to. 2. The description of the change. @@ -44,10 +44,6 @@ The following keys may be included in the mapped reply: [td]: /topics/command-arguments -@return - -@array-reply: a map as a flattened array as described above. - @examples ```cli diff --git a/commands/command-getkeys.md b/commands/command-getkeys.md index 6b8f300253..6e9b756adf 100644 --- a/commands/command-getkeys.md +++ b/commands/command-getkeys.md @@ -7,11 +7,6 @@ from a full Redis command. but in some cases it's not possible to find keys of certain commands and then the entire command must be parsed to discover some / all key names. You can use `COMMAND GETKEYS` or `COMMAND GETKEYSANDFLAGS` to discover key names directly from how Redis parses the commands. - -@return - -@array-reply: list of keys from your command. - @examples ```cli diff --git a/commands/command-getkeysandflags.md b/commands/command-getkeysandflags.md index 3fa479d02d..0f83afa7db 100644 --- a/commands/command-getkeysandflags.md +++ b/commands/command-getkeysandflags.md @@ -8,11 +8,6 @@ You can use `COMMAND GETKEYS` or `COMMAND GETKEYSANDFLAGS` to discover key names Refer to [key specifications](/topics/key-specs#logical-operation-flags) for information about the meaning of the key flags. -@return - -@array-reply: list of keys from your command. -Each element of the array is an array containing key name in the first entry, and flags in the second. - @examples ```cli diff --git a/commands/command-help.md b/commands/command-help.md index 73d4cc4812..80aa033dea 100644 --- a/commands/command-help.md +++ b/commands/command-help.md @@ -1,5 +1 @@ The `COMMAND HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/command-info.md b/commands/command-info.md index e16a5550c7..568f70a47b 100644 --- a/commands/command-info.md +++ b/commands/command-info.md @@ -6,11 +6,6 @@ get returned. If you request details about non-existing commands, their return position will be nil. - -@return - -@array-reply: nested list of command details. - @examples ```cli diff --git a/commands/command-list.md b/commands/command-list.md index 85cc453afb..60b6981b43 100644 --- a/commands/command-list.md +++ b/commands/command-list.md @@ -5,7 +5,3 @@ You can use the optional _FILTERBY_ modifier to apply one of the following filte - **MODULE module-name**: get the commands that belong to the module specified by _module-name_. - **ACLCAT category**: get the commands in the [ACL category](/docs/management/security/acl/#command-categories) specified by _category_. - **PATTERN pattern**: get the commands that match the given glob-like _pattern_. - -@return - -@array-reply: a list of command names. diff --git a/commands/command.md b/commands/command.md index 37545f9bd9..9a66f6cd07 100644 --- a/commands/command.md +++ b/commands/command.md @@ -196,12 +196,6 @@ Each element in the array represents one subcommand and follows the same specifi [td]: /topics/key-specs [tr]: /topics/key-specs -@return - -@array-reply: a nested list of command details. - -The order of commands in the array is random. - @examples The following is `COMMAND`'s output for the `GET` command: diff --git a/commands/config-get.md b/commands/config-get.md index d2e85a38c7..312abd4137 100644 --- a/commands/config-get.md +++ b/commands/config-get.md @@ -38,8 +38,3 @@ configuration parameter used in the [redis.conf][hgcarr22rc] file: Note that you should look at the redis.conf file relevant to the version you're working with as configuration options might change between versions. The link above is to the latest development version. - - -@return - -The return type of the command is a @array-reply. diff --git a/commands/config-help.md b/commands/config-help.md index 5f8bc48248..b45bebd154 100644 --- a/commands/config-help.md +++ b/commands/config-help.md @@ -1,5 +1 @@ The `CONFIG HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/config-resetstat.md b/commands/config-resetstat.md index be5dee9ebc..0c8789e7d0 100644 --- a/commands/config-resetstat.md +++ b/commands/config-resetstat.md @@ -8,7 +8,3 @@ The following is a non-exhaustive list of values that are reset: * Connections received, rejected and evicted * Persistence statistics * Active defragmentation statistics - -@return - -@simple-string-reply: always `OK`. diff --git a/commands/config-rewrite.md b/commands/config-rewrite.md index c1031561bf..f4714975fd 100644 --- a/commands/config-rewrite.md +++ b/commands/config-rewrite.md @@ -13,8 +13,3 @@ CONFIG REWRITE is also able to rewrite the configuration file from scratch if th ## Atomic rewrite process In order to make sure the redis.conf file is always consistent, that is, on errors or crashes you always end with the old file, or the new one, the rewrite is performed with a single `write(2)` call that has enough content to be at least as big as the old file. Sometimes additional padding in the form of comments is added in order to make sure the resulting file is big enough, and later the file gets truncated to remove the padding at the end. - -@return - -@simple-string-reply: `OK` when the configuration was rewritten properly. -Otherwise an error is returned. diff --git a/commands/config-set.md b/commands/config-set.md index 4b0841e049..02576fadc4 100644 --- a/commands/config-set.md +++ b/commands/config-set.md @@ -34,8 +34,3 @@ Redis server that started with AOF turned on since the start. You can have both the AOF enabled with RDB snapshotting if you want, the two options are not mutually exclusive. - -@return - -@simple-string-reply: `OK` when the configuration was set properly. -Otherwise an error is returned. diff --git a/commands/copy.md b/commands/copy.md index 62b04fc651..247c6c6478 100644 --- a/commands/copy.md +++ b/commands/copy.md @@ -8,13 +8,6 @@ index for the destination key. The command returns zero when the `destination` key already exists. The `REPLACE` option removes the `destination` key before copying the value to it. -@return - -@integer-reply, specifically: - -* `1` if `source` was copied. -* `0` if `source` was not copied. - @examples ``` diff --git a/commands/dbsize.md b/commands/dbsize.md index fe82aa78cb..7aa2fb857e 100644 --- a/commands/dbsize.md +++ b/commands/dbsize.md @@ -1,5 +1 @@ Return the number of keys in the currently-selected database. - -@return - -@integer-reply diff --git a/commands/decr.md b/commands/decr.md index cda121a932..ca6150a40e 100644 --- a/commands/decr.md +++ b/commands/decr.md @@ -6,10 +6,6 @@ This operation is limited to **64 bit signed integers**. See `INCR` for extra information on increment/decrement operations. -@return - -@integer-reply: the value of `key` after the decrement - @examples ```cli diff --git a/commands/decrby.md b/commands/decrby.md index b2e823b7e6..b0b4ebadb3 100644 --- a/commands/decrby.md +++ b/commands/decrby.md @@ -6,10 +6,6 @@ This operation is limited to 64 bit signed integers. See `INCR` for extra information on increment/decrement operations. -@return - -@integer-reply: the value of `key` after the decrement - @examples ```cli diff --git a/commands/del.md b/commands/del.md index d5fcbaced5..b20b1e863f 100644 --- a/commands/del.md +++ b/commands/del.md @@ -1,10 +1,6 @@ Removes the specified keys. A key is ignored if it does not exist. -@return - -@integer-reply: The number of keys that were removed. - @examples ```cli diff --git a/commands/discard.md b/commands/discard.md index d84b50331c..a4064ddd74 100644 --- a/commands/discard.md +++ b/commands/discard.md @@ -4,7 +4,3 @@ connection state to normal. [tt]: /topics/transactions If `WATCH` was used, `DISCARD` unwatches all keys watched by the connection. - -@return - -@simple-string-reply: always `OK`. diff --git a/commands/dump.md b/commands/dump.md index 0446386cc1..e06b501911 100644 --- a/commands/dump.md +++ b/commands/dump.md @@ -21,10 +21,6 @@ should be used. If `key` does not exist a nil bulk reply is returned. -@return - -@bulk-string-reply: the serialized value. - @examples ``` diff --git a/commands/echo.md b/commands/echo.md index 642d0f3a1d..e158e8910d 100644 --- a/commands/echo.md +++ b/commands/echo.md @@ -1,9 +1,5 @@ Returns `message`. -@return - -@bulk-string-reply - @examples ```cli diff --git a/commands/eval.md b/commands/eval.md index 079edeb001..4dd5c8f452 100644 --- a/commands/eval.md +++ b/commands/eval.md @@ -12,6 +12,12 @@ to ensure the correct execution of scripts, both in standalone and clustered dep The script **should only** access keys whose names are given as input arguments. Scripts **should never** access keys with programmatically-generated names or based on the contents of data structures stored in the database. +**Note:** +in some cases, users will abuse Lua EVAL by embedding values in the script instead of providing them as argument, and thus generating a different script on each call to EVAL. +These are added to the Lua interpreter and cached to redis-server, consuming a large amount of memory over time. +Starting from Redis 8.0, scripts loaded with `EVAL` or `EVAL_RO` will be deleted from redis after a certain number (least recently used order). +The number of evicted scripts can be viewed through `INFO`'s `evicted_scripts`. + Please refer to the [Redis Programmability](/topics/programmability) and [Introduction to Eval Scripts](/topics/eval-intro) for more information about Lua scripts. @examples diff --git a/commands/exec.md b/commands/exec.md index b2f58fef8b..2dada72b72 100644 --- a/commands/exec.md +++ b/commands/exec.md @@ -7,10 +7,3 @@ When using `WATCH`, `EXEC` will execute commands only if the watched keys were not modified, allowing for a [check-and-set mechanism][ttc]. [ttc]: /topics/transactions#cas - -@return - -@array-reply: each element being the reply to each of the commands in the -atomic transaction. - -When using `WATCH`, `EXEC` can return a @nil-reply if the execution was aborted. diff --git a/commands/exists.md b/commands/exists.md index a9a89afbad..c8a20239d7 100644 --- a/commands/exists.md +++ b/commands/exists.md @@ -2,10 +2,6 @@ Returns if `key` exists. The user should be aware that if the same existing key is mentioned in the arguments multiple times, it will be counted multiple times. So if `somekey` exists, `EXISTS somekey somekey` will return 2. -@return - -@integer-reply, specifically the number of keys that exist from those specified as arguments. - @examples ```cli diff --git a/commands/expire.md b/commands/expire.md index ddb4c9ad12..7aca62f81f 100644 --- a/commands/expire.md +++ b/commands/expire.md @@ -60,13 +60,6 @@ are now fixed. `EXPIRE` would return 0 and not alter the timeout for a key with a timeout set. -@return - -@integer-reply, specifically: - -* `1` if the timeout was set. -* `0` if the timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments. - @examples ```cli diff --git a/commands/expireat.md b/commands/expireat.md index cbc10c6770..fed6bff7a8 100644 --- a/commands/expireat.md +++ b/commands/expireat.md @@ -27,13 +27,6 @@ The `EXPIREAT` command supports a set of options: A non-volatile key is treated as an infinite TTL for the purpose of `GT` and `LT`. The `GT`, `LT` and `NX` options are mutually exclusive. -@return - -@integer-reply, specifically: - -* `1` if the timeout was set. -* `0` if the timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments. - @examples ```cli diff --git a/commands/expiretime.md b/commands/expiretime.md index b524dcc34f..afcd37b8b9 100644 --- a/commands/expiretime.md +++ b/commands/expiretime.md @@ -2,13 +2,6 @@ Returns the absolute Unix timestamp (since January 1, 1970) in seconds at which See also the `PEXPIRETIME` command which returns the same information with milliseconds resolution. -@return - -@integer-reply: Expiration Unix timestamp in seconds, or a negative value in order to signal an error (see the description below). - -* The command returns `-1` if the key exists but has no associated expiration time. -* The command returns `-2` if the key does not exist. - @examples ```cli diff --git a/commands/failover.md b/commands/failover.md index 719d19943b..dd4ce43399 100644 --- a/commands/failover.md +++ b/commands/failover.md @@ -42,7 +42,3 @@ The command has no side effects if issued in the `waiting-for-sync` state but ca If a multi-master scenario is encountered, you will need to manually identify which master has the latest data and designate it as the master and have the other replicas. NOTE: `REPLICAOF` is disabled while a failover is in progress, this is to prevent unintended interactions with the failover that might cause data loss. - -@return - -@simple-string-reply: `OK` if the command was accepted and a coordinated failover is in progress. An error if the operation cannot be executed. diff --git a/commands/flushall.md b/commands/flushall.md index 5a562d0cf4..68ec53c0b5 100644 --- a/commands/flushall.md +++ b/commands/flushall.md @@ -11,10 +11,6 @@ It is possible to use one of the following modifiers to dictate the flushing mod Note: an asynchronous `FLUSHALL` command only deletes keys that were present at the time the command was invoked. Keys created during an asynchronous flush will be unaffected. -@return - -@simple-string-reply - ## Behavior change history * `>= 6.2.0`: Default flush behavior now configurable by the **lazyfree-lazy-user-flush** configuration directive. \ No newline at end of file diff --git a/commands/flushdb.md b/commands/flushdb.md index f8235639b2..112a9db3eb 100644 --- a/commands/flushdb.md +++ b/commands/flushdb.md @@ -11,10 +11,6 @@ It is possible to use one of the following modifiers to dictate the flushing mod Note: an asynchronous `FLUSHDB` command only deletes keys that were present at the time the command was invoked. Keys created during an asynchronous flush will be unaffected. -@return - -@simple-string-reply - ## Behavior change history * `>= 6.2.0`: Default flush behavior now configurable by the **lazyfree-lazy-user-flush** configuration directive. \ No newline at end of file diff --git a/commands/function-delete.md b/commands/function-delete.md index 5b90f81733..557ce4d1c3 100644 --- a/commands/function-delete.md +++ b/commands/function-delete.md @@ -5,15 +5,11 @@ If the library doesn't exist, the server returns an error. For more information please refer to [Introduction to Redis Functions](/topics/functions-intro). -@return - -@simple-string-reply - @examples ``` -redis> FUNCTION LOAD Lua mylib "redis.register_function('myfunc', function(keys, args) return 'hello' end)" -OK +redis> FUNCTION LOAD "#!lua name=mylib \n redis.register_function('myfunc', function(keys, args) return 'hello' end)" +"mylib" redis> FCALL myfunc 0 "hello" redis> FUNCTION DELETE mylib diff --git a/commands/function-dump.md b/commands/function-dump.md index cf144bc0ad..167001c3cb 100644 --- a/commands/function-dump.md +++ b/commands/function-dump.md @@ -3,32 +3,30 @@ You can restore the serialized payload later with the `FUNCTION RESTORE` command For more information please refer to [Introduction to Redis Functions](/topics/functions-intro). -@return - -@bulk-string-reply: the serialized payload - @examples The following example shows how to dump loaded libraries using `FUNCTION DUMP` and then it calls `FUNCTION FLUSH` deletes all the libraries. Then, it restores the original libraries from the serialized payload with `FUNCTION RESTORE`. ``` +redis> FUNCTION LOAD "#!lua name=mylib \n redis.register_function('myfunc', function(keys, args) return args[1] end)" +"mylib" redis> FUNCTION DUMP -"\xf6\x05mylib\x03LUA\x00\xc3@D@J\x1aredis.register_function('my@\x0b\x02', @\x06`\x12\x11keys, args) return`\x0c\a[1] end)\n\x00@\n)\x11\xc8|\x9b\xe4" +"\xf5\xc3@X@]\x1f#!lua name=mylib \n redis.registe\rr_function('my@\x0b\x02', @\x06`\x12\nkeys, args) 6\x03turn`\x0c\a[1] end)\x0c\x00\xba\x98\xc2\xa2\x13\x0e$\a" redis> FUNCTION FLUSH OK -redis> FUNCTION RESTORE "\xf6\x05mylib\x03LUA\x00\xc3@D@J\x1aredis.register_function('my@\x0b\x02', @\x06`\x12\x11keys, args) return`\x0c\a[1] end)\n\x00@\n)\x11\xc8|\x9b\xe4" +redis> FUNCTION RESTORE "\xf5\xc3@X@]\x1f#!lua name=mylib \n redis.registe\rr_function('my@\x0b\x02', @\x06`\x12\nkeys, args) 6\x03turn`\x0c\a[1] end)\x0c\x00\xba\x98\xc2\xa2\x13\x0e$\a" OK redis> FUNCTION LIST 1) 1) "library_name" 2) "mylib" 3) "engine" 4) "LUA" - 5) "description" - 6) (nil) - 7) "functions" - 8) 1) 1) "name" + 5) "functions" + 6) 1) 1) "name" 2) "myfunc" 3) "description" 4) (nil) + 5) "flags" + 6) (empty array) ``` diff --git a/commands/function-flush.md b/commands/function-flush.md index 38c412a19a..7d9a2836a0 100644 --- a/commands/function-flush.md +++ b/commands/function-flush.md @@ -6,7 +6,3 @@ Unless called with the optional mode argument, the `lazyfree-lazy-user-flush` co * `!SYNC`: Synchronously flush the libraries. For more information please refer to [Introduction to Redis Functions](/topics/functions-intro). - -@return - -@simple-string-reply diff --git a/commands/function-help.md b/commands/function-help.md index 38c300d590..9190a9b082 100644 --- a/commands/function-help.md +++ b/commands/function-help.md @@ -1,5 +1 @@ The `FUNCTION HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/function-kill.md b/commands/function-kill.md index 2db5ea58bc..1a61c9eb91 100644 --- a/commands/function-kill.md +++ b/commands/function-kill.md @@ -4,7 +4,3 @@ Kill a function that is currently executing. The `FUNCTION KILL` command can be used only on functions that did not modify the dataset during their execution (since stopping a read-only function does not violate the scripting engine's guaranteed atomicity). For more information please refer to [Introduction to Redis Functions](/topics/functions-intro). - -@return - -@simple-string-reply diff --git a/commands/function-list.md b/commands/function-list.md index bb66dba4ed..7cd3853d7f 100644 --- a/commands/function-list.md +++ b/commands/function-list.md @@ -15,7 +15,3 @@ The following information is provided for each of the libraries in the response: * **library_code:** the library's source code (when given the `WITHCODE` modifier). For more information please refer to [Introduction to Redis Functions](/topics/functions-intro). - -@return - -@array-reply diff --git a/commands/function-load.md b/commands/function-load.md index 16f125baff..2bb36d3e71 100644 --- a/commands/function-load.md +++ b/commands/function-load.md @@ -20,10 +20,6 @@ The command will return an error in the following circumstances: For more information please refer to [Introduction to Redis Functions](/topics/functions-intro). -@return - -@string - the library name that was loaded - @examples The following example will create a library named `mylib` with a single function, `myfunc`, that returns the first argument it gets. diff --git a/commands/function-restore.md b/commands/function-restore.md index 2868d160b6..f50edda58f 100644 --- a/commands/function-restore.md +++ b/commands/function-restore.md @@ -9,7 +9,3 @@ The following policies are allowed: * **REPLACE:** appends the restored libraries to the existing libraries, replacing any existing ones in case of name collisions. Note that this policy doesn't prevent function name collisions, only libraries. For more information please refer to [Introduction to Redis Functions](/topics/functions-intro). - -@return - -@simple-string-reply diff --git a/commands/function-stats.md b/commands/function-stats.md index 005b47b912..1746d0e0e7 100644 --- a/commands/function-stats.md +++ b/commands/function-stats.md @@ -15,7 +15,3 @@ The reply is map with two keys: You can use this command to inspect the invocation of a long-running function and decide whether kill it with the `FUNCTION KILL` command. For more information please refer to [Introduction to Redis Functions](/topics/functions-intro). - -@return - -@array-reply \ No newline at end of file diff --git a/commands/geoadd.md b/commands/geoadd.md index ecdd6e877b..fdc696d277 100644 --- a/commands/geoadd.md +++ b/commands/geoadd.md @@ -39,13 +39,6 @@ The model assumes that the Earth is a sphere since it uses the Haversine formula The introduced errors are not an issue when used, for example, by social networks and similar applications requiring this type of querying. However, in the worst case, the error may be up to 0.5%, so you may want to consider other systems for error-critical applications. -@return - -@integer-reply, specifically: - -* When used without optional arguments, the number of elements added to the sorted set (excluding score updates). -* If the `CH` option is specified, the number of elements that were changed (added or updated). - @examples ```cli diff --git a/commands/geodist.md b/commands/geodist.md index af78cdff71..257d97f7f3 100644 --- a/commands/geodist.md +++ b/commands/geodist.md @@ -13,13 +13,6 @@ The unit must be one of the following, and defaults to meters: The distance is computed assuming that the Earth is a perfect sphere, so errors up to 0.5% are possible in edge cases. -@return - -@bulk-string-reply, specifically: - -The command returns the distance as a double (represented as a string) -in the specified unit, or NULL if one or both the elements are missing. - @examples ```cli diff --git a/commands/geohash.md b/commands/geohash.md index a99ade2f43..0d43056747 100644 --- a/commands/geohash.md +++ b/commands/geohash.md @@ -18,13 +18,6 @@ have the following properties: 2. It is possible to use them in `geohash.org` URLs such as `http://geohash.org/`. This is an [example of such URL](http://geohash.org/sqdtr74hyu0). 3. Strings with a similar prefix are nearby, but the contrary is not true, it is possible that strings with different prefixes are nearby too. -@return - -@array-reply, specifically: - -The command returns an array where each element is the Geohash corresponding to -each member name passed as argument to the command. - @examples ```cli diff --git a/commands/geopos.md b/commands/geopos.md index 19dd377f1c..c23a879978 100644 --- a/commands/geopos.md +++ b/commands/geopos.md @@ -4,16 +4,6 @@ Given a sorted set representing a geospatial index, populated using the `GEOADD` The command can accept a variable number of arguments so it always returns an array of positions even when a single element is specified. -@return - -@array-reply, specifically: - -The command returns an array where each element is a two elements array -representing longitude and latitude (x,y) of each member name passed as -argument to the command. - -Non existing elements are reported as NULL elements of the array. - @examples ```cli diff --git a/commands/georadius.md b/commands/georadius.md index 3d0bba4688..27e9fdc78b 100644 --- a/commands/georadius.md +++ b/commands/georadius.md @@ -33,23 +33,6 @@ By default the command returns the items to the client. It is possible to store * `!STORE`: Store the items in a sorted set populated with their geospatial information. * `!STOREDIST`: Store the items in a sorted set populated with their distance from the center as a floating point number, in the same unit specified in the radius. -@return - -@array-reply, specifically: - -* Without any `WITH` option specified, the command just returns a linear array like ["New York","Milan","Paris"]. -* If `WITHCOORD`, `WITHDIST` or `WITHHASH` options are specified, the command returns an array of arrays, where each sub-array represents a single item. - -When additional information is returned as an array of arrays for each item, the first item in the sub-array is always the name of the returned item. The other information is returned in the following order as successive elements of the sub-array. - -1. The distance from the center as a floating point number, in the same unit specified in the radius. -2. The geohash integer. -3. The coordinates as a two items x,y array (longitude,latitude). - -So for example the command `GEORADIUS Sicily 15 37 200 km WITHCOORD WITHDIST` will return each item in the following way: - - ["Palermo","190.4424",["13.361389338970184","38.115556395496299"]] - ## Read-only variants Since `GEORADIUS` and `GEORADIUSBYMEMBER` have a `STORE` and `STOREDIST` option they are technically flagged as writing commands in the Redis command table. For this reason read-only replicas will flag them, and Redis Cluster replicas will redirect them to the master instance even if the connection is in read-only mode (see the `READONLY` command of Redis Cluster). diff --git a/commands/georadius_ro.md b/commands/georadius_ro.md index d2e3399b9c..df6c42b147 100644 --- a/commands/georadius_ro.md +++ b/commands/georadius_ro.md @@ -1,7 +1,3 @@ Read-only variant of the `GEORADIUS` command. This command is identical to the `GEORADIUS` command, except that it doesn't support the optional `STORE` and `STOREDIST` parameters. - -@return - -@array-reply: An array with each entry being the corresponding result of the subcommand given at the same position. diff --git a/commands/geosearch.md b/commands/geosearch.md index 972c1c984d..b094a93bce 100644 --- a/commands/geosearch.md +++ b/commands/geosearch.md @@ -28,19 +28,6 @@ When the `ANY` option is used, the command returns as soon as enough matches are When `ANY` is not provided, the command will perform an effort that is proportional to the number of items matching the specified area and sort them, so to query very large areas with a very small `COUNT` option may be slow even if just a few results are returned. -@return - -@array-reply, specifically: - -* Without any `WITH` option specified, the command just returns a linear array like ["New York","Milan","Paris"]. -* If `WITHCOORD`, `WITHDIST` or `WITHHASH` options are specified, the command returns an array of arrays, where each sub-array represents a single item. - -When additional information is returned as an array of arrays for each item, the first item in the sub-array is always the name of the returned item. The other information is returned in the following order as successive elements of the sub-array. - -1. The distance from the center as a floating point number, in the same unit specified in the shape. -2. The geohash integer. -3. The coordinates as a two items x,y array (longitude,latitude). - @examples ```cli diff --git a/commands/geosearchstore.md b/commands/geosearchstore.md index 53e5ebe603..b27d40125a 100644 --- a/commands/geosearchstore.md +++ b/commands/geosearchstore.md @@ -6,10 +6,6 @@ By default, it stores the results in the `destination` sorted set with their geo When using the `STOREDIST` option, the command stores the items in a sorted set populated with their distance from the center of the circle or box, as a floating-point number, in the same unit specified for that shape. -@return - -@integer-reply: the number of elements in the resulting set. - @examples ```cli diff --git a/commands/get.md b/commands/get.md index 2e1517afb7..2706dec616 100644 --- a/commands/get.md +++ b/commands/get.md @@ -3,10 +3,6 @@ If the key does not exist the special value `nil` is returned. An error is returned if the value stored at `key` is not a string, because `GET` only handles string values. -@return - -@bulk-string-reply: the value of `key`, or `nil` when `key` does not exist. - @examples ```cli diff --git a/commands/getbit.md b/commands/getbit.md index 1506af304a..ec0d7414cd 100644 --- a/commands/getbit.md +++ b/commands/getbit.md @@ -6,10 +6,6 @@ When _key_ does not exist it is assumed to be an empty string, so _offset_ is always out of range and the value is also assumed to be a contiguous space with 0 bits. -@return - -@integer-reply: the bit value stored at _offset_. - @examples ```cli diff --git a/commands/getdel.md b/commands/getdel.md index 8474e93105..68867d3490 100644 --- a/commands/getdel.md +++ b/commands/getdel.md @@ -1,10 +1,6 @@ Get the value of `key` and delete the key. This command is similar to `GET`, except for the fact that it also deletes the key on success (if and only if the key's value type is a string). -@return - -@bulk-string-reply: the value of `key`, `nil` when `key` does not exist, or an error if the key's value type isn't a string. - @examples ```cli diff --git a/commands/getex.md b/commands/getex.md index 89ce809de6..4b11b47384 100644 --- a/commands/getex.md +++ b/commands/getex.md @@ -11,10 +11,6 @@ The `GETEX` command supports a set of options that modify its behavior: * `PXAT` *timestamp-milliseconds* -- Set the specified Unix time at which the key will expire, in milliseconds. * `PERSIST` -- Remove the time to live associated with the key. -@return - -@bulk-string-reply: the value of `key`, or `nil` when `key` does not exist. - @examples ```cli diff --git a/commands/getrange.md b/commands/getrange.md index 7283defc49..c188f95494 100644 --- a/commands/getrange.md +++ b/commands/getrange.md @@ -7,10 +7,6 @@ So -1 means the last character, -2 the penultimate and so forth. The function handles out of range requests by limiting the resulting range to the actual length of the string. -@return - -@bulk-string-reply - @examples ```cli diff --git a/commands/getset.md b/commands/getset.md index dd7aee765c..ba3f82ac51 100644 --- a/commands/getset.md +++ b/commands/getset.md @@ -17,10 +17,6 @@ GETSET mycounter "0" GET mycounter ``` -@return - -@bulk-string-reply: the old value stored at `key`, or `nil` when `key` did not exist. - @examples ```cli diff --git a/commands/hdel.md b/commands/hdel.md index ab6874e1ef..b0dceb2baf 100644 --- a/commands/hdel.md +++ b/commands/hdel.md @@ -3,11 +3,6 @@ Specified fields that do not exist within this hash are ignored. If `key` does not exist, it is treated as an empty hash and this command returns `0`. -@return - -@integer-reply: the number of fields that were removed from the hash, not -including specified but non existing fields. - @examples ```cli diff --git a/commands/hello.md b/commands/hello.md index 776fd814f3..92c6604214 100644 --- a/commands/hello.md +++ b/commands/hello.md @@ -55,7 +55,3 @@ protocol to the specified version and also accepts the following options: * `AUTH `: directly authenticate the connection in addition to switching to the specified protocol version. This makes calling `AUTH` before `HELLO` unnecessary when setting up a new connection. Note that the `username` can be set to "default" to authenticate against a server that does not use ACLs, but rather the simpler `requirepass` mechanism of Redis prior to version 6. * `SETNAME `: this is the equivalent of calling `CLIENT SETNAME`. - -@return - -@array-reply: a list of server properties. The reply is a map instead of an array when RESP3 is selected. The command returns an error if the `protover` requested does not exist. diff --git a/commands/hexists.md b/commands/hexists.md index f27678a67a..b63b63f443 100644 --- a/commands/hexists.md +++ b/commands/hexists.md @@ -1,12 +1,5 @@ Returns if `field` is an existing field in the hash stored at `key`. -@return - -@integer-reply, specifically: - -* `1` if the hash contains `field`. -* `0` if the hash does not contain `field`, or `key` does not exist. - @examples ```cli diff --git a/commands/hget.md b/commands/hget.md index b8d91016eb..d6bef72f81 100644 --- a/commands/hget.md +++ b/commands/hget.md @@ -1,10 +1,5 @@ Returns the value associated with `field` in the hash stored at `key`. -@return - -@bulk-string-reply: the value associated with `field`, or `nil` when `field` is not -present in the hash or `key` does not exist. - @examples ```cli diff --git a/commands/hgetall.md b/commands/hgetall.md index 3717f001db..4fbd625f84 100644 --- a/commands/hgetall.md +++ b/commands/hgetall.md @@ -2,11 +2,6 @@ Returns all fields and values of the hash stored at `key`. In the returned value, every field name is followed by its value, so the length of the reply is twice the size of the hash. -@return - -@array-reply: list of fields and their values stored in the hash, or an -empty list when `key` does not exist. - @examples ```cli diff --git a/commands/hincrby.md b/commands/hincrby.md index 3d24c254d8..c2f1b63960 100644 --- a/commands/hincrby.md +++ b/commands/hincrby.md @@ -6,10 +6,6 @@ performed. The range of values supported by `HINCRBY` is limited to 64 bit signed integers. -@return - -@integer-reply: the value at `field` after the increment operation. - @examples Since the `increment` argument is signed, both increment and decrement diff --git a/commands/hincrbyfloat.md b/commands/hincrbyfloat.md index d6eb472597..f83d7d124d 100644 --- a/commands/hincrbyfloat.md +++ b/commands/hincrbyfloat.md @@ -4,7 +4,7 @@ is negative, the result is to have the hash field value **decremented** instead If the field does not exist, it is set to `0` before performing the operation. An error is returned if one of the following conditions occur: -* The field contains a value of the wrong type (not a string). +* The key contains a value of the wrong type (not a hash). * The current field content or the specified increment are not parsable as a double precision floating point number. @@ -12,10 +12,6 @@ The exact behavior of this command is identical to the one of the `INCRBYFLOAT` command, please refer to the documentation of `INCRBYFLOAT` for further information. -@return - -@bulk-string-reply: the value of `field` after the increment. - @examples ```cli diff --git a/commands/hkeys.md b/commands/hkeys.md index c74b01e0f6..945b8f6204 100644 --- a/commands/hkeys.md +++ b/commands/hkeys.md @@ -1,10 +1,5 @@ Returns all field names in the hash stored at `key`. -@return - -@array-reply: list of fields in the hash, or an empty list when `key` does -not exist. - @examples ```cli diff --git a/commands/hlen.md b/commands/hlen.md index 2c18193435..ab19a35656 100644 --- a/commands/hlen.md +++ b/commands/hlen.md @@ -1,9 +1,5 @@ Returns the number of fields contained in the hash stored at `key`. -@return - -@integer-reply: number of fields in the hash, or `0` when `key` does not exist. - @examples ```cli diff --git a/commands/hmget.md b/commands/hmget.md index b10c43b3fa..ff322a15d8 100644 --- a/commands/hmget.md +++ b/commands/hmget.md @@ -5,11 +5,6 @@ For every `field` that does not exist in the hash, a `nil` value is returned. Because non-existing keys are treated as empty hashes, running `HMGET` against a non-existing `key` will return a list of `nil` values. -@return - -@array-reply: list of values associated with the given fields, in the same -order as they are requested. - ```cli HSET myhash field1 "Hello" HSET myhash field2 "World" diff --git a/commands/hmset.md b/commands/hmset.md index 8cec77585e..b89a13fc5e 100644 --- a/commands/hmset.md +++ b/commands/hmset.md @@ -3,10 +3,6 @@ Sets the specified fields to their respective values in the hash stored at This command overwrites any specified fields already existing in the hash. If `key` does not exist, a new key holding a hash is created. -@return - -@simple-string-reply - @examples ```cli diff --git a/commands/hrandfield.md b/commands/hrandfield.md index 389a1095ff..e019e8a946 100644 --- a/commands/hrandfield.md +++ b/commands/hrandfield.md @@ -8,17 +8,10 @@ In this case, the number of returned fields is the absolute value of the specifi The optional `WITHVALUES` modifier changes the reply so it includes the respective values of the randomly selected hash fields. -@return - -@bulk-string-reply: without the additional `count` argument, the command returns a Bulk Reply with the randomly selected field, or `nil` when `key` does not exist. - -@array-reply: when the additional `count` argument is passed, the command returns an array of fields, or an empty array when `key` does not exist. -If the `WITHVALUES` modifier is used, the reply is a list fields and their values from the hash. - @examples ```cli -HMSET coin heads obverse tails reverse edge null +HSET coin heads obverse tails reverse edge null HRANDFIELD coin HRANDFIELD coin HRANDFIELD coin -5 WITHVALUES diff --git a/commands/hset.md b/commands/hset.md index 0572b01cf5..92c34f3d30 100644 --- a/commands/hset.md +++ b/commands/hset.md @@ -3,10 +3,6 @@ Sets the specified fields to their respective values in the hash stored at `key` This command overwrites the values of specified fields that exist in the hash. If `key` doesn't exist, a new key holding a hash is created. -@return - -@integer-reply: The number of fields that were added. - @examples ```cli diff --git a/commands/hsetnx.md b/commands/hsetnx.md index c60eaa071b..cc2dbdc020 100644 --- a/commands/hsetnx.md +++ b/commands/hsetnx.md @@ -3,13 +3,6 @@ yet exist. If `key` does not exist, a new key holding a hash is created. If `field` already exists, this operation has no effect. -@return - -@integer-reply, specifically: - -* `1` if `field` is a new field in the hash and `value` was set. -* `0` if `field` already exists in the hash and no operation was performed. - @examples ```cli diff --git a/commands/hstrlen.md b/commands/hstrlen.md index b187f75fb7..e473ecffeb 100644 --- a/commands/hstrlen.md +++ b/commands/hstrlen.md @@ -1,13 +1,9 @@ Returns the string length of the value associated with `field` in the hash stored at `key`. If the `key` or the `field` do not exist, 0 is returned. -@return - -@integer-reply: the string length of the value associated with `field`, or zero when `field` is not present in the hash or `key` does not exist at all. - @examples ```cli -HMSET myhash f1 HelloWorld f2 99 f3 -256 +HSET myhash f1 HelloWorld f2 99 f3 -256 HSTRLEN myhash f1 HSTRLEN myhash f2 HSTRLEN myhash f3 diff --git a/commands/hvals.md b/commands/hvals.md index 5526959276..f54f780519 100644 --- a/commands/hvals.md +++ b/commands/hvals.md @@ -1,10 +1,5 @@ Returns all values in the hash stored at `key`. -@return - -@array-reply: list of values in the hash, or an empty list when `key` does -not exist. - @examples ```cli diff --git a/commands/incr.md b/commands/incr.md index 6abee168b4..e8aae005d0 100644 --- a/commands/incr.md +++ b/commands/incr.md @@ -13,10 +13,6 @@ Redis stores integers in their integer representation, so for string values that actually hold an integer, there is no overhead for storing the string representation of the integer. -@return - -@integer-reply: the value of `key` after the increment - @examples ```cli @@ -82,7 +78,7 @@ END ``` Basically we have a counter for every IP, for every different second. -But this counters are always incremented setting an expire of 10 seconds so that +But these counters are always incremented setting an expire of 10 seconds so that they'll be removed by Redis automatically when the current second is a different one. diff --git a/commands/incrby.md b/commands/incrby.md index 9734351e80..d67a2dae54 100644 --- a/commands/incrby.md +++ b/commands/incrby.md @@ -6,10 +6,6 @@ This operation is limited to 64 bit signed integers. See `INCR` for extra information on increment/decrement operations. -@return - -@integer-reply: the value of `key` after the increment - @examples ```cli diff --git a/commands/incrbyfloat.md b/commands/incrbyfloat.md index 9efca1d9f7..d44bec435d 100644 --- a/commands/incrbyfloat.md +++ b/commands/incrbyfloat.md @@ -23,10 +23,6 @@ Trailing zeroes are always removed. The precision of the output is fixed at 17 digits after the decimal point regardless of the actual internal precision of the computation. -@return - -@bulk-string-reply: the value of `key` after the increment. - @examples ```cli diff --git a/commands/info.md b/commands/info.md index 0ea28bd41b..117a5da638 100644 --- a/commands/info.md +++ b/commands/info.md @@ -26,13 +26,6 @@ It can also take the following values: When no parameter is provided, the `default` option is assumed. -@return - -@bulk-string-reply: as a collection of text lines. - -Lines can contain a section name (starting with a # character) or a property. -All the properties are in the form of `field:value` terminated by `\r\n`. - ```cli INFO ``` @@ -90,7 +83,10 @@ Here is the meaning of all fields in the **clients** section: * `blocked_clients`: Number of clients pending on a blocking call (`BLPOP`, `BRPOP`, `BRPOPLPUSH`, `BLMOVE`, `BZPOPMIN`, `BZPOPMAX`) * `tracking_clients`: Number of clients being tracked (`CLIENT TRACKING`) +* `pubsub_clients`: Number of clients in pubsub mode (`SUBSCRIBE`, `PSUBSCRIBE`, `SSUBSCRIBE`). Added in Redis 8.0 +* `watching_clients`: Number of clients in watching mode (`WATCH`). Added in Redis 8.0 * `clients_in_timeout_table`: Number of clients in the clients timeout table +* `total_watched_keys`: Number of watched keys. Added in Redis 8.0. * `total_blocking_keys`: Number of blocking keys. Added in Redis 7.2. * `total_blocking_keys_on_nokey`: Number of blocking keys that one or more clients that would like to be unblocked when the key is deleted. Added in Redis 7.2. @@ -118,9 +114,18 @@ Here is the meaning of all fields in the **memory** section: the net memory usage (`used_memory` minus `used_memory_startup`) * `total_system_memory`: The total amount of memory that the Redis host has * `total_system_memory_human`: Human readable representation of previous value -* `used_memory_lua`: Number of bytes used by the Lua engine -* `used_memory_lua_human`: Human readable representation of previous value -* `used_memory_scripts`: Number of bytes used by cached Lua scripts +* `used_memory_lua`: Number of bytes used by the Lua engine for EVAL scripts. Deprecated in Redis 7.0, renamed to `used_memory_vm_eval` +* `used_memory_vm_eval`: Number of bytes used by the script VM engines for EVAL framework (not part of used_memory). Added in Redis 7.0 +* `used_memory_lua_human`: Human readable representation of previous value. Deprecated in Redis 7.0 +* `used_memory_scripts_eval`: Number of bytes overhead by the EVAL scripts (part of used_memory). Added in Redis 7.0 +* `number_of_cached_scripts`: The number of EVAL scripts cached by the server. Added in Redis 7.0 +* `number_of_functions`: The number of functions. Added in Redis 7.0 +* `number_of_libraries`: The number of libraries. Added in Redis 7.0 +* `used_memory_vm_functions`: Number of bytes used by the script VM engines for Functions framework (not part of used_memory). Added in Redis 7.0 +* `used_memory_vm_total`: `used_memory_vm_eval` + `used_memory_vm_functions` (not part of used_memory). Added in Redis 7.0 +* `used_memory_vm_total_human`: Human readable representation of previous value. +* `used_memory_functions`: Number of bytes overhead by Function scripts (part of used_memory). Added in Redis 7.0 +* `used_memory_scripts`: `used_memory_scripts_eval` + `used_memory_functions` (part of used_memory). Added in Redis 7.0 * `used_memory_scripts_human`: Human readable representation of previous value * `maxmemory`: The value of the `maxmemory` configuration directive * `maxmemory_human`: Human readable representation of previous value @@ -139,6 +144,7 @@ Here is the meaning of all fields in the **memory** section: * `allocator_allocated`: Total bytes allocated form the allocator, including internal-fragmentation. Normally the same as `used_memory`. * `allocator_active`: Total bytes in the allocator active pages, this includes external-fragmentation. * `allocator_resident`: Total bytes resident (RSS) in the allocator, this includes pages that can be released to the OS (by `MEMORY PURGE`, or just waiting). +* `allocator_muzzy`: Total bytes of 'muzzy' memory (RSS) in the allocator. Muzzy memory is memory that has been freed, but not yet fully returned to the operating system. It can be reused immediately when needed or reclaimed by the OS when system pressure increases. * `mem_not_counted_for_evict`: Used memory that's not counted for key eviction. This is basically transient replica and AOF buffers. * `mem_clients_slaves`: Memory used by replica clients - Starting Redis 7.0, replica buffers share memory with the replication backlog, so this field can show 0 when replicas don't trigger an increase of memory usage. * `mem_clients_normal`: Memory used by normal clients @@ -147,6 +153,7 @@ Here is the meaning of all fields in the **memory** section: * `mem_replication_backlog`: Memory used by replication backlog * `mem_total_replication_buffers`: Total memory consumed for replication buffers - Added in Redis 7.0. * `mem_allocator`: Memory allocator, chosen at compile time. +* `mem_overhead_db_hashtable_rehashing`: Temporary memory overhead of database dictionaries currently being rehashed - Added in 8.0. * `active_defrag_running`: When `activedefrag` is enabled, this indicates whether defragmentation is currently active, and the CPU percentage it intends to utilize. * `lazyfree_pending_objects`: The number of objects waiting to be freed (as a result of calling `UNLINK`, or `FLUSHDB` and `FLUSHALL` with the **ASYNC** @@ -269,6 +276,7 @@ Here is the meaning of all fields in the **stats** section: * `expire_cycle_cpu_milliseconds`: The cumulative amount of time spent on active expiry cycles * `evicted_keys`: Number of evicted keys due to `maxmemory` limit * `evicted_clients`: Number of evicted clients due to `maxmemory-clients` limit. Added in Redis 7.0. +* `evicted_scripts`: Number of evicted EVAL scripts due to LRU policy, see `EVAL` for more details. Added in Redis 8.0. * `total_eviction_exceeded_time`: Total time `used_memory` was greater than `maxmemory` since server startup, in milliseconds * `current_eviction_exceeded_time`: The time passed since `used_memory` last rose above `maxmemory`, in milliseconds * `keyspace_hits`: Number of successful lookup of keys in the main dictionary @@ -307,8 +315,10 @@ Here is the meaning of all fields in the **stats** section: * `total_writes_processed`: Total number of write events processed * `io_threaded_reads_processed`: Number of read events processed by the main and I/O threads * `io_threaded_writes_processed`: Number of write events processed by the main and I/O threads -* `stat_reply_buffer_shrinks`: Total number of output buffer shrinks -* `stat_reply_buffer_expands`: Total number of output buffer expands +* `client_query_buffer_limit_disconnections`: Total number of disconnections due to client reaching query buffer limit +* `client_output_buffer_limit_disconnections`: Total number of disconnections due to client reaching output buffer limit +* `reply_buffer_shrinks`: Total number of output buffer shrinks +* `reply_buffer_expands`: Total number of output buffer expands * `eventloop_cycles`: Total number of eventloop cycles * `eventloop_duration_sum`: Total time spent in the eventloop in microseconds (including I/O and command processing) * `eventloop_duration_cmd_sum`: Total time spent on executing commands in microseconds diff --git a/commands/keys.md b/commands/keys.md index 186caca66c..f51e0ea51a 100644 --- a/commands/keys.md +++ b/commands/keys.md @@ -26,9 +26,12 @@ Supported glob-style patterns: Use `\` to escape special characters if you want to match them verbatim. -@return - -@array-reply: list of keys matching `pattern`. +When using [Redis Cluster](/docs/management/scaling/), the search is optimized for patterns that imply a single slot. +If a pattern can only match keys of one slot, +Redis only iterates over keys in that slot, rather than the whole database, +when searching for keys matching the pattern. +For example, with the pattern `{a}h*llo`, Redis would only try to match it with the keys in slot 15495, which hash tag `{a}` implies. +To use pattern with hash tag, see [Hash tags](/docs/reference/cluster-spec/#hash-tags) in the Cluster specification for more information. @examples diff --git a/commands/lastsave.md b/commands/lastsave.md index eec80e5b67..1e38f6f626 100644 --- a/commands/lastsave.md +++ b/commands/lastsave.md @@ -2,7 +2,3 @@ Return the UNIX TIME of the last DB save executed with success. A client may check if a `BGSAVE` command succeeded reading the `LASTSAVE` value, then issuing a `BGSAVE` command and checking at regular intervals every N seconds if `LASTSAVE` changed. Redis considers the database saved successfully at startup. - -@return - -@integer-reply: an UNIX time stamp. diff --git a/commands/latency-doctor.md b/commands/latency-doctor.md index 8f493aaa55..6693eff2f5 100644 --- a/commands/latency-doctor.md +++ b/commands/latency-doctor.md @@ -39,7 +39,3 @@ I have a few advices for you: For more information refer to the [Latency Monitoring Framework page][lm]. [lm]: /topics/latency-monitor - -@return - -@bulk-string-reply diff --git a/commands/latency-graph.md b/commands/latency-graph.md index f1cfa5e996..285b2488ea 100644 --- a/commands/latency-graph.md +++ b/commands/latency-graph.md @@ -58,7 +58,3 @@ in the lower row) is the minimum, and a # in the higher row is the maximum. For more information refer to the [Latency Monitoring Framework page][lm]. [lm]: /topics/latency-monitor - -@return - -@bulk-string-reply \ No newline at end of file diff --git a/commands/latency-help.md b/commands/latency-help.md index 8077bf07d9..59f3999370 100644 --- a/commands/latency-help.md +++ b/commands/latency-help.md @@ -4,7 +4,3 @@ subcommands. For more information refer to the [Latency Monitoring Framework page][lm]. [lm]: /topics/latency-monitor - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/latency-histogram.md b/commands/latency-histogram.md index 02496acf31..9d984bc9e4 100644 --- a/commands/latency-histogram.md +++ b/commands/latency-histogram.md @@ -34,10 +34,3 @@ To delete the latency histograms' data use the `CONFIG RESETSTAT` command. 5# (integer) 16 => (integer) 99968 6# (integer) 33 => (integer) 100000 ``` - -@return - -@array-reply: specifically: - -The command returns a map where each key is a command name. -The value is a map with a key for the total calls, and a map of the histogram time buckets. diff --git a/commands/latency-history.md b/commands/latency-history.md index 815e644fff..4207727a1a 100644 --- a/commands/latency-history.md +++ b/commands/latency-history.md @@ -35,10 +35,3 @@ Valid values for `event` are: For more information refer to the [Latency Monitoring Framework page][lm]. [lm]: /topics/latency-monitor - -@return - -@array-reply: specifically: - -The command returns an array where each element is a two elements array -representing the timestamp and the latency of the event. \ No newline at end of file diff --git a/commands/latency-latest.md b/commands/latency-latest.md index 918435b8d8..26a1e4d4ed 100644 --- a/commands/latency-latest.md +++ b/commands/latency-latest.md @@ -28,10 +28,3 @@ OK For more information refer to the [Latency Monitoring Framework page][lm]. [lm]: /topics/latency-monitor - -@return - -@array-reply: specifically: - -The command returns an array where each element is a four elements array -representing the event's name, timestamp, latest and all-time latency measurements. diff --git a/commands/latency-reset.md b/commands/latency-reset.md index 9762869b9f..f2d87cc121 100644 --- a/commands/latency-reset.md +++ b/commands/latency-reset.md @@ -28,7 +28,3 @@ Valid values for `event` are: For more information refer to the [Latency Monitoring Framework page][lm]. [lm]: /topics/latency-monitor - -@return - -@integer-reply: the number of event time series that were reset. diff --git a/commands/lcs.md b/commands/lcs.md index b554686263..09e9048534 100644 --- a/commands/lcs.md +++ b/commands/lcs.md @@ -70,10 +70,3 @@ Finally to also have the match len: 3) "len" 4) (integer) 6 ``` - -@return - -* Without modifiers the string representing the longest common substring is returned. -* When `LEN` is given the command returns the length of the longest common substring. -* When `IDX` is given the command returns an array with the LCS length and all the ranges in both the strings, start and end offset for each string, where there are matches. When `WITHMATCHLEN` is given each array representing a match will also have the length of the match (see examples). - diff --git a/commands/lindex.md b/commands/lindex.md index 229c63deab..0f6438e42e 100644 --- a/commands/lindex.md +++ b/commands/lindex.md @@ -7,10 +7,6 @@ Here, `-1` means the last element, `-2` means the penultimate and so forth. When the value at `key` is not a list, an error is returned. -@return - -@bulk-string-reply: the requested element, or `nil` when `index` is out of range. - @examples ```cli diff --git a/commands/linsert.md b/commands/linsert.md index df80725136..fdbdaf9c8c 100644 --- a/commands/linsert.md +++ b/commands/linsert.md @@ -6,10 +6,6 @@ performed. An error is returned when `key` exists but does not hold a list value. -@return - -@integer-reply: the list length after a successful insert operation, `0` if the `key` doesn't exist, and `-1` when the `pivot` wasn't found. - @examples ```cli diff --git a/commands/llen.md b/commands/llen.md index 8c7c70fac1..4c9a7862ee 100644 --- a/commands/llen.md +++ b/commands/llen.md @@ -2,10 +2,6 @@ Returns the length of the list stored at `key`. If `key` does not exist, it is interpreted as an empty list and `0` is returned. An error is returned when the value stored at `key` is not a list. -@return - -@integer-reply: the length of the list at `key`. - @examples ```cli diff --git a/commands/lmove.md b/commands/lmove.md index a35f177685..7dd02fa4e2 100644 --- a/commands/lmove.md +++ b/commands/lmove.md @@ -18,10 +18,6 @@ no-op if `wherefrom` is the same as `whereto`). This command comes in place of the now deprecated `RPOPLPUSH`. Doing `LMOVE RIGHT LEFT` is equivalent. -@return - -@bulk-string-reply: the element being popped and pushed. - @examples ```cli diff --git a/commands/lmpop.md b/commands/lmpop.md index aad5b6a3e6..ee053e2378 100644 --- a/commands/lmpop.md +++ b/commands/lmpop.md @@ -10,13 +10,6 @@ See `BLMPOP` for the blocking variant of this command. Elements are popped from either the left or right of the first non-empty list based on the passed argument. The number of returned elements is limited to the lower between the non-empty list's length, and the count argument (which defaults to 1). -@return - -@array-reply: specifically: - -* A `nil` when no element could be popped. -* A two-element array with the first element being the name of the key from which elements were popped, and the second element is an array of elements. - @examples ```cli diff --git a/commands/lolwut.md b/commands/lolwut.md index a767a381ea..027c9b177e 100644 --- a/commands/lolwut.md +++ b/commands/lolwut.md @@ -23,7 +23,3 @@ LOLWUT version should have the following properties: 3. LOLWUT output should be fast to generate so that the command can be called in production instances without issues. It should remain fast even when the user experiments with odd parameters. 4. LOLWUT implementations should be safe and carefully checked for security, and resist to untrusted inputs if they take arguments. 5. LOLWUT must always display the Redis version at the end. - -@return - -@bulk-string-reply (or verbatim reply when using the RESP3 protocol): the string containing the generative computer art, and a text with the Redis version. diff --git a/commands/lpop.md b/commands/lpop.md index c6e77c2d97..ed7dc9cf4e 100644 --- a/commands/lpop.md +++ b/commands/lpop.md @@ -4,16 +4,6 @@ By default, the command pops a single element from the beginning of the list. When provided with the optional `count` argument, the reply will consist of up to `count` elements, depending on the list's length. -@return - -When called without the `count` argument: - -@bulk-string-reply: the value of the first element, or `nil` when `key` does not exist. - -When called with the `count` argument: - -@array-reply: list of popped elements, or `nil` when `key` does not exist. - @examples ```cli diff --git a/commands/lpos.md b/commands/lpos.md index 93fe579447..b4485acb56 100644 --- a/commands/lpos.md +++ b/commands/lpos.md @@ -57,10 +57,6 @@ Finally, the `MAXLEN` option tells the command to compare the provided element o When `MAXLEN` is used, it is possible to specify 0 as the maximum number of comparisons, as a way to tell the command we want unlimited comparisons. This is better than giving a very large `MAXLEN` option because it is more general. -@return - -The command returns the integer representing the matching element, or `nil` if there is no match. However, if the `COUNT` option is given the command returns an array (empty if there are no matches). - @examples ```cli diff --git a/commands/lpush.md b/commands/lpush.md index e8b97203db..c1d198bad9 100644 --- a/commands/lpush.md +++ b/commands/lpush.md @@ -10,10 +10,6 @@ leftmost element to the rightmost element. So for instance the command `LPUSH mylist a b c` will result into a list containing `c` as first element, `b` as second element and `a` as third element. -@return - -@integer-reply: the length of the list after the push operations. - @examples ```cli diff --git a/commands/lpushx.md b/commands/lpushx.md index e98c9037d7..69182df8a8 100644 --- a/commands/lpushx.md +++ b/commands/lpushx.md @@ -3,10 +3,6 @@ already exists and holds a list. In contrary to `LPUSH`, no operation will be performed when `key` does not yet exist. -@return - -@integer-reply: the length of the list after the push operation. - @examples ```cli diff --git a/commands/lrange.md b/commands/lrange.md index 7634f3e6c3..c59de57e1b 100644 --- a/commands/lrange.md +++ b/commands/lrange.md @@ -23,10 +23,6 @@ If `start` is larger than the end of the list, an empty list is returned. If `stop` is larger than the actual end of the list, Redis will treat it like the last element of the list. -@return - -@array-reply: list of elements in the specified range. - @examples ```cli diff --git a/commands/lrem.md b/commands/lrem.md index 36c0c7df00..dd2f7e7fbc 100644 --- a/commands/lrem.md +++ b/commands/lrem.md @@ -12,10 +12,6 @@ For example, `LREM list -2 "hello"` will remove the last two occurrences of Note that non-existing keys are treated like empty lists, so when `key` does not exist, the command will always return `0`. -@return - -@integer-reply: the number of removed elements. - @examples ```cli diff --git a/commands/lset.md b/commands/lset.md index 8f1c391594..c6fb635758 100644 --- a/commands/lset.md +++ b/commands/lset.md @@ -3,10 +3,6 @@ For more information on the `index` argument, see `LINDEX`. An error is returned for out of range indexes. -@return - -@simple-string-reply - @examples ```cli diff --git a/commands/ltrim.md b/commands/ltrim.md index 7cae0c7caf..61ae3f6e26 100644 --- a/commands/ltrim.md +++ b/commands/ltrim.md @@ -31,10 +31,6 @@ It is important to note that when used in this way `LTRIM` is an O(1) operation because in the average case just one element is removed from the tail of the list. -@return - -@simple-string-reply - @examples ```cli diff --git a/commands/memory-doctor.md b/commands/memory-doctor.md index dbb9db3e33..8a61604542 100644 --- a/commands/memory-doctor.md +++ b/commands/memory-doctor.md @@ -1,6 +1,2 @@ The `MEMORY DOCTOR` command reports about different memory-related issues that the Redis server experiences, and advises about possible remedies. - -@return - -@bulk-string-reply \ No newline at end of file diff --git a/commands/memory-help.md b/commands/memory-help.md index c0f4086f53..1b86c43a32 100644 --- a/commands/memory-help.md +++ b/commands/memory-help.md @@ -1,6 +1,2 @@ The `MEMORY HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/memory-malloc-stats.md b/commands/memory-malloc-stats.md index 8da8e72e96..f0b645ca38 100644 --- a/commands/memory-malloc-stats.md +++ b/commands/memory-malloc-stats.md @@ -3,7 +3,3 @@ the memory allocator. This command is currently implemented only when using **jemalloc** as an allocator, and evaluates to a benign NOOP for all others. - -@return - -@bulk-string-reply: the memory allocator's internal statistics report diff --git a/commands/memory-purge.md b/commands/memory-purge.md index 5ebe43356d..947a4fea45 100644 --- a/commands/memory-purge.md +++ b/commands/memory-purge.md @@ -3,7 +3,3 @@ reclaimed by the allocator. This command is currently implemented only when using **jemalloc** as an allocator, and evaluates to a benign NOOP for all others. - -@return - -@simple-string-reply diff --git a/commands/memory-stats.md b/commands/memory-stats.md index 39cd68e9f8..3d88350dad 100644 --- a/commands/memory-stats.md +++ b/commands/memory-stats.md @@ -20,27 +20,38 @@ values. The following metrics are reported: * `aof.buffer`: The summed size in bytes of AOF related buffers. * `lua.caches`: the summed size in bytes of the overheads of the Lua scripts' caches +* `functions.caches`: the summed size in bytes of the overheads of the Function scripts' + caches * `dbXXX`: For each of the server's databases, the overheads of the main and expiry dictionaries (`overhead.hashtable.main` and `overhead.hashtable.expires`, respectively) are reported in bytes +* `overhead.db.hashtable.lut`: Total overhead of dictionary buckets in databases (Added in Redis 8.0) +* `overhead.db.hashtable.rehashing`: Temporary memory overhead of database dictionaries currently being rehashed (Added in Redis 8.0) * `overhead.total`: The sum of all overheads, i.e. `startup.allocated`, `replication.backlog`, `clients.slaves`, `clients.normal`, `aof.buffer` and those of the internal data structures that are used in managing the Redis keyspace (see `INFO`'s `used_memory_overhead`) +* `db.dict.rehashing.count`: Number of DB dictionaries currently being rehashed (Added in Redis 8.0) * `keys.count`: The total number of keys stored across all databases in the server -* `keys.bytes-per-key`: The ratio between **net memory usage** (`total.allocated` - minus `startup.allocated`) and `keys.count` +* `keys.bytes-per-key`: The ratio between `dataset.bytes` and `keys.count` * `dataset.bytes`: The size in bytes of the dataset, i.e. `overhead.total` subtracted from `total.allocated` (see `INFO`'s `used_memory_dataset`) -* `dataset.percentage`: The percentage of `dataset.bytes` out of the net +* `dataset.percentage`: The percentage of `dataset.bytes` out of the total memory usage -* `peak.percentage`: The percentage of `peak.allocated` out of - `total.allocated` +* `peak.percentage`: The percentage of `total.allocated` out of + `peak.allocated` +* `allocator.allocated`: See `INFO`'s `allocator_allocated` +* `allocator.active`: See `INFO`'s `allocator_active` +* `allocator.resident`: See `INFO`'s `allocator_resident` +* `allocator.muzzy`: See `INFO`'s `allocator_muzzy` +* `allocator-fragmentation.ratio`: See `INFO`'s `allocator_frag_ratio` +* `allocator-fragmentation.bytes`: See `INFO`'s `allocator_frag_bytes` +* `allocator-rss.ratio`: See `INFO`'s `allocator_rss_ratio` +* `allocator-rss.bytes`: See `INFO`'s `allocator_rss_bytes` +* `rss-overhead.ratio`: See `INFO`'s `rss_overhead_ratio` +* `rss-overhead.bytes`: See `INFO`'s `rss_overhead_bytes` * `fragmentation`: See `INFO`'s `mem_fragmentation_ratio` - -@return - -@array-reply: nested list of memory usage metrics and their values +* `fragmentation.bytes`: See `INFO`'s `mem_fragmentation_bytes` **A note about the word slave used in this man page**: Starting with Redis 5, if not for backward compatibility, the Redis project no longer uses the word slave. Unfortunately in this command the word slave is part of the protocol, so we'll be able to remove such occurrences only when this API will be naturally deprecated. diff --git a/commands/memory-usage.md b/commands/memory-usage.md index 68b23aec1b..b436292373 100644 --- a/commands/memory-usage.md +++ b/commands/memory-usage.md @@ -2,7 +2,7 @@ The `MEMORY USAGE` command reports the number of bytes that a key and its value require to be stored in RAM. The reported usage is the total of memory allocations for data and -administrative overheads that a key its value require. +administrative overheads that a key and its value require. For nested data types, the optional `SAMPLES` option can be provided, where `count` is the number of sampled nested values. The samples are averaged to estimate the total size. @@ -37,7 +37,3 @@ OK > MEMORY USAGE foo3 (integer) 160 ``` - -@return - -@integer-reply: the memory usage in bytes, or `nil` when the key does not exist. diff --git a/commands/mget.md b/commands/mget.md index 8bca6ca81a..97de1cc61d 100644 --- a/commands/mget.md +++ b/commands/mget.md @@ -3,10 +3,6 @@ For every key that does not hold a string value or does not exist, the special value `nil` is returned. Because of this, the operation never fails. -@return - -@array-reply: list of values at the specified keys. - @examples ```cli diff --git a/commands/migrate.md b/commands/migrate.md index 318e0e253f..1bc5913302 100644 --- a/commands/migrate.md +++ b/commands/migrate.md @@ -65,8 +65,3 @@ just a single key exists. * `!KEYS` -- If the key argument is an empty string, the command will instead migrate all the keys that follow the `!KEYS` option (see the above section for more info). * `!AUTH` -- Authenticate with the given password to the remote instance. * `AUTH2` -- Authenticate with the given username and password pair (Redis 6 or greater ACL auth style). - -@return - -@simple-string-reply: The command returns OK on success, or `NOKEY` if no keys were -found in the source instance. diff --git a/commands/module-help.md b/commands/module-help.md index a05bf1e965..6759bfe0fe 100644 --- a/commands/module-help.md +++ b/commands/module-help.md @@ -1,5 +1 @@ The `MODULE HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/module-list.md b/commands/module-list.md index 1bfa3e232b..3f91414b05 100644 --- a/commands/module-list.md +++ b/commands/module-list.md @@ -1,10 +1 @@ Returns information about the modules loaded to the server. - -@return - -@array-reply: list of loaded modules. Each element in the list represents a -module, and is in itself a list of property names and their values. The -following properties is reported for each loaded module: - -* `name`: Name of the module -* `ver`: Version of the module diff --git a/commands/module-load.md b/commands/module-load.md index 99777c3886..7232257a1d 100644 --- a/commands/module-load.md +++ b/commands/module-load.md @@ -7,7 +7,3 @@ unmodified to the module. **Note**: modules can also be loaded at server startup with `loadmodule` configuration directive in `redis.conf`. - -@return - -@simple-string-reply: `OK` if module was loaded. diff --git a/commands/module-loadex.md b/commands/module-loadex.md index f7a55dbd51..a863aae32c 100644 --- a/commands/module-loadex.md +++ b/commands/module-loadex.md @@ -9,7 +9,3 @@ Any additional arguments that follow the `ARGS` keyword are passed unmodified to **Note**: modules can also be loaded at server startup with `loadmodule` configuration directive in `redis.conf`. - -@return - -@simple-string-reply: `OK` if module was loaded. diff --git a/commands/module-unload.md b/commands/module-unload.md index 84ebebf010..4214e750f0 100644 --- a/commands/module-unload.md +++ b/commands/module-unload.md @@ -7,7 +7,3 @@ library's filename. Known limitations: * Modules that register custom data types can not be unloaded. - -@return - -@simple-string-reply: `OK` if module was unloaded. diff --git a/commands/monitor.md b/commands/monitor.md index 2622cdd53a..5a7a70c575 100644 --- a/commands/monitor.md +++ b/commands/monitor.md @@ -80,11 +80,6 @@ In this particular case, running a single `MONITOR` client can reduce the throughput by more than 50%. Running more `MONITOR` clients will reduce throughput even more. -@return - -**Non standard return value**, just dumps the received commands in an infinite -flow. - ## Behavior change history * `>= 6.0.0`: `AUTH` excluded from the command's output. diff --git a/commands/move.md b/commands/move.md index ceb212caac..1e9f6cdbf9 100644 --- a/commands/move.md +++ b/commands/move.md @@ -3,10 +3,3 @@ destination database. When `key` already exists in the destination database, or it does not exist in the source database, it does nothing. It is possible to use `MOVE` as a locking primitive because of this. - -@return - -@integer-reply, specifically: - -* `1` if `key` was moved. -* `0` if `key` was not moved. diff --git a/commands/mset.md b/commands/mset.md index f070d29329..d22b0de5da 100644 --- a/commands/mset.md +++ b/commands/mset.md @@ -6,10 +6,6 @@ See `MSETNX` if you don't want to overwrite existing values. It is not possible for clients to see that some of the keys were updated while others are unchanged. -@return - -@simple-string-reply: always `OK` since `MSET` can't fail. - @examples ```cli diff --git a/commands/msetnx.md b/commands/msetnx.md index 795bfc9812..71b4117c30 100644 --- a/commands/msetnx.md +++ b/commands/msetnx.md @@ -10,13 +10,6 @@ that either all the fields or none at all are set. It is not possible for clients to see that some of the keys were updated while others are unchanged. -@return - -@integer-reply, specifically: - -* `1` if the all the keys were set. -* `0` if no key was set (at least one key already existed). - @examples ```cli diff --git a/commands/multi.md b/commands/multi.md index dc8789249d..1b2ba22659 100644 --- a/commands/multi.md +++ b/commands/multi.md @@ -2,7 +2,3 @@ Marks the start of a [transaction][tt] block. Subsequent commands will be queued for atomic execution using `EXEC`. [tt]: /topics/transactions - -@return - -@simple-string-reply: always `OK`. diff --git a/commands/object-encoding.md b/commands/object-encoding.md index 3a9583d0d9..685debf912 100644 --- a/commands/object-encoding.md +++ b/commands/object-encoding.md @@ -9,13 +9,34 @@ Redis objects can be encoded in different ways: - `embstr`, an embedded string, which is an object where the internal simple dynamic string, `sds`, is an unmodifiable string allocated in the same chuck as the object itself. `embstr` can be strings with lengths up to the hardcoded limit of `OBJ_ENCODING_EMBSTR_SIZE_LIMIT` or 44 bytes. -* Lists can be encoded as `ziplist` or `linkedlist`. The `ziplist` is the special representation that is used to save space for small lists. -* Sets can be encoded as `intset` or `hashtable`. The `intset` is a special encoding used for small sets composed solely of integers. -* Hashes can be encoded as `ziplist` or `hashtable`. The `ziplist` is a special encoding used for small hashes. -* Sorted Sets can be encoded as `ziplist` or `skiplist` format. As for the List type small sorted sets can be specially encoded using `ziplist`, while the `skiplist` encoding is the one that works with sorted sets of any size. +* Lists can be encoded as: + + - `linkedlist`, simple list encoding. No longer used, an old list encoding. + - `ziplist`, Redis <= 6.2, a space-efficient encoding used for small lists. + - `listpack`, Redis >= 7.0, a space-efficient encoding used for small lists. + - `quicklist`, encoded as linkedlist of ziplists or listpacks. -All the specially encoded types are automatically converted to the general type once you perform an operation that makes it impossible for Redis to retain the space saving encoding. +* Sets can be encoded as: + + - `hashtable`, normal set encoding. + - `intset`, a special encoding used for small sets composed solely of integers. + - `listpack`, Redis >= 7.2, a space-efficient encoding used for small sets. + +* Hashes can be encoded as: + + - `zipmap`, no longer used, an old hash encoding. + - `hashtable`, normal hash encoding. + - `ziplist`, Redis <= 6.2, a space-efficient encoding used for small hashes. + - `listpack`, Redis >= 7.0, a space-efficient encoding used for small hashes. -@return +* Sorted Sets can be encoded as: -@bulk-string-reply: the encoding of the object, or `nil` if the key doesn't exist + - `skiplist`, normal sorted set encoding. + - `ziplist`, Redis <= 6.2, a space-efficient encoding used for small sorted sets. + - `listpack`, Redis >= 7.0, a space-efficient encoding used for small sorted sets. + +* Streams can be encoded as: + + - `stream`, encoded as a radix tree of listpacks. + +All the specially encoded types are automatically converted to the general type once you perform an operation that makes it impossible for Redis to retain the space saving encoding. diff --git a/commands/object-freq.md b/commands/object-freq.md index fdf891e83d..5c75bfb787 100644 --- a/commands/object-freq.md +++ b/commands/object-freq.md @@ -1,9 +1,3 @@ This command returns the logarithmic access frequency counter of a Redis object stored at ``. The command is only available when the `maxmemory-policy` configuration directive is set to one of the LFU policies. - -@return - -@integer-reply - -The counter's value. \ No newline at end of file diff --git a/commands/object-help.md b/commands/object-help.md index f98196c5e1..d528d40751 100644 --- a/commands/object-help.md +++ b/commands/object-help.md @@ -1,5 +1 @@ The `OBJECT HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/object-idletime.md b/commands/object-idletime.md index 2a89641746..791d8fb00a 100644 --- a/commands/object-idletime.md +++ b/commands/object-idletime.md @@ -1,9 +1,3 @@ This command returns the time in seconds since the last access to the value stored at ``. The command is only available when the `maxmemory-policy` configuration directive is not set to one of the LFU policies. - -@return - -@integer-reply - -The idle time in seconds. \ No newline at end of file diff --git a/commands/object-refcount.md b/commands/object-refcount.md index 639c899dbd..e526681640 100644 --- a/commands/object-refcount.md +++ b/commands/object-refcount.md @@ -1,7 +1 @@ This command returns the reference count of the stored at ``. - -@return - -@integer-reply - -The number of references. \ No newline at end of file diff --git a/commands/persist.md b/commands/persist.md index 67a00147da..44f067d7d8 100644 --- a/commands/persist.md +++ b/commands/persist.md @@ -2,13 +2,6 @@ Remove the existing timeout on `key`, turning the key from _volatile_ (a key with an expire set) to _persistent_ (a key that will never expire as no timeout is associated). -@return - -@integer-reply, specifically: - -* `1` if the timeout was removed. -* `0` if `key` does not exist or does not have an associated timeout. - @examples ```cli diff --git a/commands/pexpire.md b/commands/pexpire.md index bc2e6f109e..2e0df07063 100644 --- a/commands/pexpire.md +++ b/commands/pexpire.md @@ -13,13 +13,6 @@ The `PEXPIRE` command supports a set of options since Redis 7.0: A non-volatile key is treated as an infinite TTL for the purpose of `GT` and `LT`. The `GT`, `LT` and `NX` options are mutually exclusive. -@return - -@integer-reply, specifically: - -* `1` if the timeout was set. -* `0` if the timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments. - @examples ```cli diff --git a/commands/pexpireat.md b/commands/pexpireat.md index 21e2853e39..748d491a72 100644 --- a/commands/pexpireat.md +++ b/commands/pexpireat.md @@ -13,13 +13,6 @@ The `PEXPIREAT` command supports a set of options since Redis 7.0: A non-volatile key is treated as an infinite TTL for the purpose of `GT` and `LT`. The `GT`, `LT` and `NX` options are mutually exclusive. -@return - -@integer-reply, specifically: - -* `1` if the timeout was set. -* `0` if the timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments. - @examples ```cli diff --git a/commands/pexpiretime.md b/commands/pexpiretime.md index 9fcda95507..ffde6be48b 100644 --- a/commands/pexpiretime.md +++ b/commands/pexpiretime.md @@ -1,12 +1,5 @@ `PEXPIRETIME` has the same semantic as `EXPIRETIME`, but returns the absolute Unix expiration timestamp in milliseconds instead of seconds. -@return - -@integer-reply: Expiration Unix timestamp in milliseconds, or a negative value in order to signal an error (see the description below). - -* The command returns `-1` if the key exists but has no associated expiration time. -* The command returns `-2` if the key does not exist. - @examples ```cli diff --git a/commands/pfadd.md b/commands/pfadd.md index 5d0128b1a0..f621a00d4e 100644 --- a/commands/pfadd.md +++ b/commands/pfadd.md @@ -8,12 +8,6 @@ To call the command without elements but just the variable name is valid, this w For an introduction to HyperLogLog data structure check the `PFCOUNT` command page. -@return - -@integer-reply, specifically: - -* 1 if at least 1 HyperLogLog internal register was altered. 0 otherwise. - @examples ```cli diff --git a/commands/pfcount.md b/commands/pfcount.md index 71d10930c0..ac6f712a6a 100644 --- a/commands/pfcount.md +++ b/commands/pfcount.md @@ -11,12 +11,6 @@ For example in order to take the count of all the unique search queries performe Note: as a side effect of calling this function, it is possible that the HyperLogLog is modified, since the last 8 bytes encode the latest computed cardinality for caching purposes. So `PFCOUNT` is technically a write command. -@return - -@integer-reply, specifically: - -* The approximated number of unique elements observed via `PFADD`. - @examples ```cli diff --git a/commands/pfmerge.md b/commands/pfmerge.md index c59c930182..4eb1b90966 100644 --- a/commands/pfmerge.md +++ b/commands/pfmerge.md @@ -9,10 +9,6 @@ If the destination variable exists, it is treated as one of the source sets and its cardinality will be included in the cardinality of the computed HyperLogLog. -@return - -@simple-string-reply: The command just returns `OK`. - @examples ```cli diff --git a/commands/ping.md b/commands/ping.md index 1667e1eab5..f1631d4a2c 100644 --- a/commands/ping.md +++ b/commands/ping.md @@ -10,12 +10,6 @@ multi-bulk with a "pong" in the first position and an empty bulk in the second position, unless an argument is provided in which case it returns a copy of the argument. -@return - -@simple-string-reply, and specifically `PONG`, when no argument is provided. - -@bulk-string-reply the argument provided, when applicable. - @examples ```cli diff --git a/commands/psubscribe.md b/commands/psubscribe.md index c5936489f2..abb80b9975 100644 --- a/commands/psubscribe.md +++ b/commands/psubscribe.md @@ -13,11 +13,6 @@ However, if RESP3 is used (see `HELLO`) it is possible for a client to issue any For more information, see [Pub/sub](/docs/interact/pubsub/). -@return - -When successful, this command doesn't return anything. -Instead, for each pattern, one message with the first element being the string "psubscribe" is pushed as a confirmation that the command succeeded. - ## Behavior change history * `>= 6.2.0`: `RESET` can be called to exit subscribed state. diff --git a/commands/psync.md b/commands/psync.md index 8cbacf2fa6..d9eac2ab9a 100644 --- a/commands/psync.md +++ b/commands/psync.md @@ -7,7 +7,3 @@ For more information about replication in Redis please check the [replication page][tr]. [tr]: /topics/replication - -@return - -**Non standard return value**, a bulk transfer of the data followed by `PING` and write requests from the master. diff --git a/commands/pttl.md b/commands/pttl.md index 4e0807971b..302194b46a 100644 --- a/commands/pttl.md +++ b/commands/pttl.md @@ -9,10 +9,6 @@ Starting with Redis 2.8 the return value in case of error changed: * The command returns `-2` if the key does not exist. * The command returns `-1` if the key exists but has no associated expire. -@return - -@integer-reply: TTL in milliseconds, or a negative value in order to signal an error (see the description above). - @examples ```cli diff --git a/commands/publish.md b/commands/publish.md index 62283f8dc1..cd61d04678 100644 --- a/commands/publish.md +++ b/commands/publish.md @@ -3,9 +3,3 @@ Posts a message to the given channel. In a Redis Cluster clients can publish to every node. The cluster makes sure that published messages are forwarded as needed, so clients can subscribe to any channel by connecting to any one of the nodes. - -@return - -@integer-reply: the number of clients that received the message. Note that in a -Redis Cluster, only clients that are connected to the same node as the -publishing client are included in the count. diff --git a/commands/pubsub-channels.md b/commands/pubsub-channels.md index 8b9a06eefd..8e0b3e36fd 100644 --- a/commands/pubsub-channels.md +++ b/commands/pubsub-channels.md @@ -5,7 +5,3 @@ An active channel is a Pub/Sub channel with one or more subscribers (excluding c If no `pattern` is specified, all the channels are listed, otherwise if pattern is specified only channels matching the specified glob-style pattern are listed. Cluster note: in a Redis Cluster clients can subscribe to every node, and can also publish to every other node. The cluster will make sure that published messages are forwarded as needed. That said, `PUBSUB`'s replies in a cluster only report information from the node's Pub/Sub context, rather than the entire cluster. - -@return - -@array-reply: a list of active channels, optionally matching the specified pattern. diff --git a/commands/pubsub-help.md b/commands/pubsub-help.md index a7ab2a359f..f711c27db2 100644 --- a/commands/pubsub-help.md +++ b/commands/pubsub-help.md @@ -1,5 +1 @@ The `PUBSUB HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/pubsub-numpat.md b/commands/pubsub-numpat.md index 6f3a7c9e14..2a3282c5c6 100644 --- a/commands/pubsub-numpat.md +++ b/commands/pubsub-numpat.md @@ -3,7 +3,3 @@ Returns the number of unique patterns that are subscribed to by clients (that ar Note that this isn't the count of clients subscribed to patterns, but the total number of unique patterns all the clients are subscribed to. Cluster note: in a Redis Cluster clients can subscribe to every node, and can also publish to every other node. The cluster will make sure that published messages are forwarded as needed. That said, `PUBSUB`'s replies in a cluster only report information from the node's Pub/Sub context, rather than the entire cluster. - -@return - -@integer-reply: the number of patterns all the clients are subscribed to. diff --git a/commands/pubsub-numsub.md b/commands/pubsub-numsub.md index d4d6b85e7b..604c317900 100644 --- a/commands/pubsub-numsub.md +++ b/commands/pubsub-numsub.md @@ -3,9 +3,3 @@ Returns the number of subscribers (exclusive of clients subscribed to patterns) Note that it is valid to call this command without channels. In this case it will just return an empty list. Cluster note: in a Redis Cluster clients can subscribe to every node, and can also publish to every other node. The cluster will make sure that published messages are forwarded as needed. That said, `PUBSUB`'s replies in a cluster only report information from the node's Pub/Sub context, rather than the entire cluster. - -@return - -@array-reply: a list of channels and number of subscribers for every channel. - -The format is channel, count, channel, count, ..., so the list is flat. The order in which the channels are listed is the same as the order of the channels specified in the command call. diff --git a/commands/pubsub-shardchannels.md b/commands/pubsub-shardchannels.md index b2b5da3355..c6c460bd79 100644 --- a/commands/pubsub-shardchannels.md +++ b/commands/pubsub-shardchannels.md @@ -6,10 +6,6 @@ If no `pattern` is specified, all the channels are listed, otherwise if pattern The information returned about the active shard channels are at the shard level and not at the cluster level. -@return - -@array-reply: a list of active channels, optionally matching the specified pattern. - @examples ``` diff --git a/commands/pubsub-shardnumsub.md b/commands/pubsub-shardnumsub.md index 8d09d4381f..8119fe9b56 100644 --- a/commands/pubsub-shardnumsub.md +++ b/commands/pubsub-shardnumsub.md @@ -4,12 +4,6 @@ Note that it is valid to call this command without channels, in this case it wil Cluster note: in a Redis Cluster, `PUBSUB`'s replies in a cluster only report information from the node's Pub/Sub context, rather than the entire cluster. -@return - -@array-reply: a list of channels and number of subscribers for every channel. - -The format is channel, count, channel, count, ..., so the list is flat. The order in which the channels are listed is the same as the order of the shard channels specified in the command call. - @examples ``` diff --git a/commands/punsubscribe.md b/commands/punsubscribe.md index 65045f60e2..af8ee7e021 100644 --- a/commands/punsubscribe.md +++ b/commands/punsubscribe.md @@ -5,8 +5,3 @@ When no patterns are specified, the client is unsubscribed from all the previously subscribed patterns. In this case, a message for every unsubscribed pattern will be sent to the client. - -@return - -When successful, this command doesn't return anything. -Instead, for each pattern, one message with the first element being the string "punsubscribe" is pushed as a confirmation that the command succeeded. diff --git a/commands/quit.md b/commands/quit.md index b4cf337338..e0507d43d2 100644 --- a/commands/quit.md +++ b/commands/quit.md @@ -5,7 +5,3 @@ client. **Note:** Clients should not use this command. Instead, clients should simply close the connection when they're not used anymore. Terminating a connection on the client side is preferable, as it eliminates `TIME_WAIT` lingering sockets on the server side. - -@return - -@simple-string-reply: always OK. diff --git a/commands/randomkey.md b/commands/randomkey.md index d8233224ff..37a2d759ab 100644 --- a/commands/randomkey.md +++ b/commands/randomkey.md @@ -1,5 +1 @@ Return a random key from the currently selected database. - -@return - -@bulk-string-reply: the random key, or `nil` when the database is empty. diff --git a/commands/readonly.md b/commands/readonly.md index bc73b9b980..9bd4f96a7e 100644 --- a/commands/readonly.md +++ b/commands/readonly.md @@ -13,7 +13,3 @@ master node. This may happen because: 1. The client sent a command about hash slots never served by the master of this replica. 2. The cluster was reconfigured (for example resharded) and the replica is no longer able to serve commands for a given hash slot. - -@return - -@simple-string-reply diff --git a/commands/readwrite.md b/commands/readwrite.md index d6d7089be4..9b50eefd80 100644 --- a/commands/readwrite.md +++ b/commands/readwrite.md @@ -4,7 +4,3 @@ Read queries against a Redis Cluster replica node are disabled by default, but you can use the `READONLY` command to change this behavior on a per- connection basis. The `READWRITE` command resets the readonly mode flag of a connection back to readwrite. - -@return - -@simple-string-reply diff --git a/commands/rename.md b/commands/rename.md index 471ecf4187..82c503c219 100644 --- a/commands/rename.md +++ b/commands/rename.md @@ -4,10 +4,6 @@ If `newkey` already exists it is overwritten, when this happens `RENAME` execute In Cluster mode, both `key` and `newkey` must be in the same **hash slot**, meaning that in practice only keys that have the same hash tag can be reliably renamed in cluster. -@return - -@simple-string-reply - @examples ```cli diff --git a/commands/renamenx.md b/commands/renamenx.md index c132af4a73..15b951e4ca 100644 --- a/commands/renamenx.md +++ b/commands/renamenx.md @@ -3,13 +3,6 @@ It returns an error when `key` does not exist. In Cluster mode, both `key` and `newkey` must be in the same **hash slot**, meaning that in practice only keys that have the same hash tag can be reliably renamed in cluster. -@return - -@integer-reply, specifically: - -* `1` if `key` was renamed to `newkey`. -* `0` if `newkey` already exists. - @examples ```cli diff --git a/commands/replicaof.md b/commands/replicaof.md index 1c3ec93dce..8351f1453e 100644 --- a/commands/replicaof.md +++ b/commands/replicaof.md @@ -6,10 +6,6 @@ If a server is already a replica of some master, `REPLICAOF` hostname port will The form `REPLICAOF` NO ONE will stop replication, turning the server into a MASTER, but will not discard the replication. So, if the old master stops working, it is possible to turn the replica into a master and set the application to use this new master in read/write. Later when the other Redis server is fixed, it can be reconfigured to work as a replica. -@return - -@simple-string-reply - @examples ``` diff --git a/commands/reset.md b/commands/reset.md index e6bbc1ace6..78434755a4 100644 --- a/commands/reset.md +++ b/commands/reset.md @@ -19,7 +19,3 @@ following: authentication is enabled. * Turns off `NO-EVICT` mode. * Turns off `NO-TOUCH` mode. - -@return - -@simple-string-reply: always 'RESET'. diff --git a/commands/restore.md b/commands/restore.md index eb605be703..d756a33bb4 100644 --- a/commands/restore.md +++ b/commands/restore.md @@ -18,10 +18,6 @@ exists unless you use the `REPLACE` modifier. `!RESTORE` checks the RDB version and data checksum. If they don't match an error is returned. -@return - -@simple-string-reply: The command returns OK on success. - @examples ``` diff --git a/commands/role.md b/commands/role.md index c308c934f4..08bf21df1f 100644 --- a/commands/role.md +++ b/commands/role.md @@ -69,10 +69,6 @@ The sentinel output is composed of the following parts: 1. The string `sentinel`. 2. An array of master names monitored by this Sentinel instance. -@return - -@array-reply: where the first element is one of `master`, `slave`, `sentinel` and the additional elements are role-specific as illustrated above. - @examples ```cli diff --git a/commands/rpop.md b/commands/rpop.md index 99c863cd23..1f66fe2711 100644 --- a/commands/rpop.md +++ b/commands/rpop.md @@ -4,16 +4,6 @@ By default, the command pops a single element from the end of the list. When provided with the optional `count` argument, the reply will consist of up to `count` elements, depending on the list's length. -@return - -When called without the `count` argument: - -@bulk-string-reply: the value of the last element, or `nil` when `key` does not exist. - -When called with the `count` argument: - -@array-reply: list of popped elements, or `nil` when `key` does not exist. - @examples ```cli diff --git a/commands/rpoplpush.md b/commands/rpoplpush.md index d00e8c99c5..55f38bb555 100644 --- a/commands/rpoplpush.md +++ b/commands/rpoplpush.md @@ -13,10 +13,6 @@ If `source` and `destination` are the same, the operation is equivalent to removing the last element from the list and pushing it as first element of the list, so it can be considered as a list rotation command. -@return - -@bulk-string-reply: the element being popped and pushed. - @examples ```cli diff --git a/commands/rpush.md b/commands/rpush.md index def4ee10cf..9b50a44450 100644 --- a/commands/rpush.md +++ b/commands/rpush.md @@ -10,10 +10,6 @@ leftmost element to the rightmost element. So for instance the command `RPUSH mylist a b c` will result into a list containing `a` as first element, `b` as second element and `c` as third element. -@return - -@integer-reply: the length of the list after the push operation. - @examples ```cli diff --git a/commands/rpushx.md b/commands/rpushx.md index daab019a7e..88e0da657e 100644 --- a/commands/rpushx.md +++ b/commands/rpushx.md @@ -3,10 +3,6 @@ already exists and holds a list. In contrary to `RPUSH`, no operation will be performed when `key` does not yet exist. -@return - -@integer-reply: the length of the list after the push operation. - @examples ```cli diff --git a/commands/sadd.md b/commands/sadd.md index f8232bb220..93ad38d388 100644 --- a/commands/sadd.md +++ b/commands/sadd.md @@ -5,11 +5,6 @@ members. An error is returned when the value stored at `key` is not a set. -@return - -@integer-reply: the number of elements that were added to the set, not including -all the elements already present in the set. - @examples ```cli diff --git a/commands/save.md b/commands/save.md index c66c5e90a7..e2f32aa4d8 100644 --- a/commands/save.md +++ b/commands/save.md @@ -12,7 +12,3 @@ good last resort to perform the dump of the latest dataset. Please refer to the [persistence documentation][tp] for detailed information. [tp]: /topics/persistence - -@return - -@simple-string-reply: The commands returns OK on success. diff --git a/commands/scan.md b/commands/scan.md index 5a10ec6e8b..7ef81e47e9 100644 --- a/commands/scan.md +++ b/commands/scan.md @@ -9,19 +9,228 @@ Since these commands allow for incremental iteration, returning only a small num However while blocking commands like `SMEMBERS` are able to provide all the elements that are part of a Set in a given moment, The SCAN family of commands only offer limited guarantees about the returned elements since the collection that we incrementally iterate can change during the iteration process. -Note that `SCAN`, `SSCAN`, `HSCAN` and `ZSCAN` all work very similarly, so this documentation covers all the four commands. However an obvious difference is that in the case of `SSCAN`, `HSCAN` and `ZSCAN` the first argument is the name of the key holding the Set, Hash or Sorted Set value. The `SCAN` command does not need any key name argument as it iterates keys in the current database, so the iterated object is the database itself. +Note that `SCAN`, `SSCAN`, `HSCAN` and `ZSCAN` all work very similarly, so this documentation covers all four commands. However an obvious difference is that in the case of `SSCAN`, `HSCAN` and `ZSCAN` the first argument is the name of the key holding the Set, Hash or Sorted Set value. The `SCAN` command does not need any key name argument as it iterates keys in the current database, so the iterated object is the database itself. +## SCAN basic usage -For more information on `SCAN` please refer to the [The Redis Keyspace](/docs/manual/keyspace) tutorial. +SCAN is a cursor based iterator. This means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. + +An iteration starts when the cursor is set to 0, and terminates when the cursor returned by the server is 0. The following is an example of SCAN iteration: + +``` +redis 127.0.0.1:6379> scan 0 +1) "17" +2) 1) "key:12" + 2) "key:8" + 3) "key:4" + 4) "key:14" + 5) "key:16" + 6) "key:17" + 7) "key:15" + 8) "key:10" + 9) "key:3" + 10) "key:7" + 11) "key:1" +redis 127.0.0.1:6379> scan 17 +1) "0" +2) 1) "key:5" + 2) "key:18" + 3) "key:0" + 4) "key:2" + 5) "key:19" + 6) "key:13" + 7) "key:6" + 8) "key:9" + 9) "key:11" +``` + +In the example above, the first call uses zero as a cursor, to start the iteration. The second call uses the cursor returned by the previous call as the first element of the reply, that is, 17. + +As you can see the **SCAN return value** is an array of two values: the first value is the new cursor to use in the next call, the second value is an array of elements. + +Since in the second call the returned cursor is 0, the server signaled to the caller that the iteration finished, and the collection was completely explored. Starting an iteration with a cursor value of 0, and calling `SCAN` until the returned cursor is 0 again is called a **full iteration**. ## Return value -`SCAN`, `SSCAN`, `HSCAN` and `ZSCAN` return a two elements multi-bulk reply, where the first element is a string representing an unsigned 64 bit number (the cursor), and the second element is a multi-bulk with an array of elements. +`SCAN`, `SSCAN`, `HSCAN` and `ZSCAN` return a two element multi-bulk reply, where the first element is a string representing an unsigned 64 bit number (the cursor), and the second element is a multi-bulk with an array of elements. * `SCAN` array of elements is a list of keys. * `SSCAN` array of elements is a list of Set members. * `HSCAN` array of elements contain two elements, a field and a value, for every returned element of the Hash. -* `ZSCAN` array of elements contain two elements, a member and its associated score, for every returned element of the sorted set. +* `ZSCAN` array of elements contain two elements, a member and its associated score, for every returned element of the Sorted Set. + +## Scan guarantees + +The `SCAN` command, and the other commands in the `SCAN` family, are able to provide to the user a set of guarantees associated to full iterations. + +* A full iteration always retrieves all the elements that were present in the collection from the start to the end of a full iteration. This means that if a given element is inside the collection when an iteration is started, and is still there when an iteration terminates, then at some point `SCAN` returned it to the user. +* A full iteration never returns any element that was NOT present in the collection from the start to the end of a full iteration. So if an element was removed before the start of an iteration, and is never added back to the collection for all the time an iteration lasts, `SCAN` ensures that this element will never be returned. + +However because `SCAN` has very little state associated (just the cursor) it has the following drawbacks: + +* A given element may be returned multiple times. It is up to the application to handle the case of duplicated elements, for example only using the returned elements in order to perform operations that are safe when re-applied multiple times. +* Elements that were not constantly present in the collection during a full iteration, may be returned or not: it is undefined. + +## Number of elements returned at every SCAN call + +`SCAN` family functions do not guarantee that the number of elements returned per call are in a given range. The commands are also allowed to return zero elements, and the client should not consider the iteration complete as long as the returned cursor is not zero. + +However the number of returned elements is reasonable, that is, in practical terms `SCAN` may return a maximum number of elements in the order of a few tens of elements when iterating a large collection, or may return all the elements of the collection in a single call when the iterated collection is small enough to be internally represented as an encoded data structure (this happens for small Sets, Hashes and Sorted Sets). + +However there is a way for the user to tune the order of magnitude of the number of returned elements per call using the **COUNT** option. + +## The COUNT option + +While `SCAN` does not provide guarantees about the number of elements returned at every iteration, it is possible to empirically adjust the behavior of `SCAN` using the **COUNT** option. Basically with COUNT the user specifies the *amount of work that should be done at every call in order to retrieve elements from the collection*. This is **just a hint** for the implementation, however generally speaking this is what you could expect most of the times from the implementation. + +* The default `COUNT` value is 10. +* When iterating the key space, or a Set, Hash or Sorted Set that is big enough to be represented by a hash table, assuming no **MATCH** option is used, the server will usually return *count* or a few more than *count* elements per call. Please check the *why SCAN may return all the elements at once* section later in this document. +* When iterating Sets encoded as intsets (small sets composed of just integers), or Hashes and Sorted Sets encoded as ziplists (small hashes and sets composed of small individual values), usually all the elements are returned in the first `SCAN` call regardless of the `COUNT` value. + +Important: **there is no need to use the same COUNT value** for every iteration. The caller is free to change the count from one iteration to the other as required, as long as the cursor passed in the next call is the one obtained in the previous call to the command. + +## The MATCH option + +It is possible to only iterate elements matching a given glob-style pattern, similarly to the behavior of the `KEYS` command that takes a pattern as its only argument. + +To do so, just append the `MATCH ` arguments at the end of the `SCAN` command (it works with all the `SCAN` family commands). + +This is an example of iteration using **MATCH**: + +``` +redis 127.0.0.1:6379> sadd myset 1 2 3 foo foobar feelsgood +(integer) 6 +redis 127.0.0.1:6379> sscan myset 0 match f* +1) "0" +2) 1) "foo" + 2) "feelsgood" + 3) "foobar" +redis 127.0.0.1:6379> +``` + +It is important to note that the **MATCH** filter is applied after elements are retrieved from the collection, just before returning data to the client. This means that if the pattern matches very little elements inside the collection, `SCAN` will likely return no elements in most iterations. An example is shown below: + +``` +redis 127.0.0.1:6379> scan 0 MATCH *11* +1) "288" +2) 1) "key:911" +redis 127.0.0.1:6379> scan 288 MATCH *11* +1) "224" +2) (empty list or set) +redis 127.0.0.1:6379> scan 224 MATCH *11* +1) "80" +2) (empty list or set) +redis 127.0.0.1:6379> scan 80 MATCH *11* +1) "176" +2) (empty list or set) +redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000 +1) "0" +2) 1) "key:611" + 2) "key:711" + 3) "key:118" + 4) "key:117" + 5) "key:311" + 6) "key:112" + 7) "key:111" + 8) "key:110" + 9) "key:113" + 10) "key:211" + 11) "key:411" + 12) "key:115" + 13) "key:116" + 14) "key:114" + 15) "key:119" + 16) "key:811" + 17) "key:511" + 18) "key:11" +redis 127.0.0.1:6379> +``` + +As you can see most of the calls returned zero elements, but the last call where a `COUNT` of 1000 was used in order to force the command to do more scanning for that iteration. + +When using [Redis Cluster](/docs/management/scaling/), the search is optimized for patterns that imply a single slot. +If a pattern can only match keys of one slot, +Redis only iterates over keys in that slot, rather than the whole database, +when searching for keys matching the pattern. +For example, with the pattern `{a}h*llo`, Redis would only try to match it with the keys in slot 15495, which hash tag `{a}` implies. +To use pattern with hash tag, see [Hash tags](/docs/reference/cluster-spec/#hash-tags) in the Cluster specification for more information. + +## The TYPE option + +You can use the `!TYPE` option to ask `SCAN` to only return objects that match a given `type`, allowing you to iterate through the database looking for keys of a specific type. The **TYPE** option is only available on the whole-database `SCAN`, not `HSCAN` or `ZSCAN` etc. + +The `type` argument is the same string name that the `TYPE` command returns. Note a quirk where some Redis types, such as GeoHashes, HyperLogLogs, Bitmaps, and Bitfields, may internally be implemented using other Redis types, such as a string or zset, so can't be distinguished from other keys of that same type by `SCAN`. For example, a ZSET and GEOHASH: + +``` +redis 127.0.0.1:6379> GEOADD geokey 0 0 value +(integer) 1 +redis 127.0.0.1:6379> ZADD zkey 1000 value +(integer) 1 +redis 127.0.0.1:6379> TYPE geokey +zset +redis 127.0.0.1:6379> TYPE zkey +zset +redis 127.0.0.1:6379> SCAN 0 TYPE zset +1) "0" +2) 1) "geokey" + 2) "zkey" +``` + +It is important to note that the **TYPE** filter is also applied after elements are retrieved from the database, so the option does not reduce the amount of work the server has to do to complete a full iteration, and for rare types you may receive no elements in many iterations. + +## The NOVALUES option + +When using `HSCAN`, you can use the `NOVALUES` option to make Redis return only the keys in the hash table without their corresponding values. + +``` +redis 127.0.0.1:6379> HSET myhash a 1 b 2 +OK +redis 127.0.0.1:6379> HSCAN myhash 0 +1) "0" +2) 1) "a" + 2) "1" + 3) "b" + 4) "2" +redis 127.0.0.1:6379> HSCAN myhash 0 NOVALUES +1) "0" +2) 1) "a" + 2) "b" +``` + +## Multiple parallel iterations + +It is possible for an infinite number of clients to iterate the same collection at the same time, as the full state of the iterator is in the cursor, that is obtained and returned to the client at every call. No server side state is taken at all. + +## Terminating iterations in the middle + +Since there is no state server side, but the full state is captured by the cursor, the caller is free to terminate an iteration half-way without signaling this to the server in any way. An infinite number of iterations can be started and never terminated without any issue. + +## Calling SCAN with a corrupted cursor + +Calling `SCAN` with a broken, negative, out of range, or otherwise invalid cursor, will result in undefined behavior but never in a crash. What will be undefined is that the guarantees about the returned elements can no longer be ensured by the `SCAN` implementation. + +The only valid cursors to use are: + +* The cursor value of 0 when starting an iteration. +* The cursor returned by the previous call to SCAN in order to continue the iteration. + +## Guarantee of termination + +The `SCAN` algorithm is guaranteed to terminate only if the size of the iterated collection remains bounded to a given maximum size, otherwise iterating a collection that always grows may result into `SCAN` to never terminate a full iteration. + +This is easy to see intuitively: if the collection grows there is more and more work to do in order to visit all the possible elements, and the ability to terminate the iteration depends on the number of calls to `SCAN` and its COUNT option value compared with the rate at which the collection grows. + +## Why SCAN may return all the items of an aggregate data type in a single call? + +In the `COUNT` option documentation, we state that sometimes this family of commands may return all the elements of a Set, Hash or Sorted Set at once in a single call, regardless of the `COUNT` option value. The reason why this happens is that the cursor-based iterator can be implemented, and is useful, only when the aggregate data type that we are scanning is represented as a hash table. However Redis uses a [memory optimization](/topics/memory-optimization) where small aggregate data types, until they reach a given amount of items or a given max size of single elements, are represented using a compact single-allocation packed encoding. When this is the case, `SCAN` has no meaningful cursor to return, and must iterate the whole data structure at once, so the only sane behavior it has is to return everything in a call. + +However once the data structures are bigger and are promoted to use real hash tables, the `SCAN` family of commands will resort to the normal behavior. Note that since this special behavior of returning all the elements is true only for small aggregates, it has no effects on the command complexity or latency. However the exact limits to get converted into real hash tables are [user configurable](/topics/memory-optimization), so the maximum number of elements you can see returned in a single call depends on how big an aggregate data type could be and still use the packed representation. + +Also note that this behavior is specific of `SSCAN`, `HSCAN` and `ZSCAN`. `SCAN` itself never shows this behavior because the key space is always represented by hash tables. + +## Further reading + +For more information about managing keys, please refer to the [The Redis Keyspace](/docs/manual/keyspace) tutorial. ## Additional examples diff --git a/commands/scard.md b/commands/scard.md index 85d3c01059..1bbbc0c8bd 100644 --- a/commands/scard.md +++ b/commands/scard.md @@ -1,10 +1,5 @@ Returns the set cardinality (number of elements) of the set stored at `key`. -@return - -@integer-reply: the cardinality (number of elements) of the set, or `0` if `key` -does not exist. - @examples ```cli diff --git a/commands/script-debug.md b/commands/script-debug.md index 3779ed5e47..5a2e845f69 100644 --- a/commands/script-debug.md +++ b/commands/script-debug.md @@ -20,8 +20,3 @@ is active and retains all changes to the data set once it ends. * `NO`. Disables scripts debug mode. For more information about `EVAL` scripts please refer to [Introduction to Eval Scripts](/topics/eval-intro). - -@return - -@simple-string-reply: `OK`. - diff --git a/commands/script-exists.md b/commands/script-exists.md index 758660cf9b..5681628f25 100644 --- a/commands/script-exists.md +++ b/commands/script-exists.md @@ -9,10 +9,3 @@ operation can be performed solely using `EVALSHA` instead of `EVAL` to save bandwidth. For more information about `EVAL` scripts please refer to [Introduction to Eval Scripts](/topics/eval-intro). - -@return - -@array-reply The command returns an array of integers that correspond to -the specified SHA1 digest arguments. -For every corresponding SHA1 digest of a script that actually exists in the -script cache, a 1 is returned, otherwise 0 is returned. diff --git a/commands/script-flush.md b/commands/script-flush.md index 705d0142d4..d1e65a109d 100644 --- a/commands/script-flush.md +++ b/commands/script-flush.md @@ -10,10 +10,6 @@ It is possible to use one of the following modifiers to dictate the flushing mod For more information about `EVAL` scripts please refer to [Introduction to Eval Scripts](/topics/eval-intro). -@return - -@simple-string-reply - ## Behavior change history * `>= 6.2.0`: Default flush behavior now configurable by the **lazyfree-lazy-user-flush** configuration directive. \ No newline at end of file diff --git a/commands/script-help.md b/commands/script-help.md index 02b716326f..ed745e1389 100644 --- a/commands/script-help.md +++ b/commands/script-help.md @@ -1,5 +1 @@ The `SCRIPT HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/script-kill.md b/commands/script-kill.md index 5b4c646edb..b6dae1486e 100644 --- a/commands/script-kill.md +++ b/commands/script-kill.md @@ -13,7 +13,3 @@ the Redis process in a hard way and preventing it from persisting with half-writ information. For more information about `EVAL` scripts please refer to [Introduction to Eval Scripts](/topics/eval-intro). - -@return - -@simple-string-reply diff --git a/commands/script-load.md b/commands/script-load.md index ed5ab2dbc1..e85c6de628 100644 --- a/commands/script-load.md +++ b/commands/script-load.md @@ -10,8 +10,3 @@ The command works in the same way even if the script was already present in the script cache. For more information about `EVAL` scripts please refer to [Introduction to Eval Scripts](/topics/eval-intro). - -@return - -@bulk-string-reply This command returns the SHA1 digest of the script added into the -script cache. diff --git a/commands/sdiff.md b/commands/sdiff.md index 5d458eca34..7815877126 100644 --- a/commands/sdiff.md +++ b/commands/sdiff.md @@ -12,10 +12,6 @@ SDIFF key1 key2 key3 = {b,d} Keys that do not exist are considered to be empty sets. -@return - -@array-reply: list with members of the resulting set. - @examples ```cli diff --git a/commands/sdiffstore.md b/commands/sdiffstore.md index e941016742..23cd591532 100644 --- a/commands/sdiffstore.md +++ b/commands/sdiffstore.md @@ -3,10 +3,6 @@ is stored in `destination`. If `destination` already exists, it is overwritten. -@return - -@integer-reply: the number of elements in the resulting set. - @examples ```cli diff --git a/commands/select.md b/commands/select.md index 9ebc04e969..5f76dedbab 100644 --- a/commands/select.md +++ b/commands/select.md @@ -8,7 +8,3 @@ In practical terms, Redis databases should be used to separate different keys be When using Redis Cluster, the `SELECT` command cannot be used, since Redis Cluster only supports database zero. In the case of a Redis Cluster, having multiple databases would be useless and an unnecessary source of complexity. Commands operating atomically on a single database would not be possible with the Redis Cluster design and goals. Since the currently selected database is a property of the connection, clients should track the currently selected database and re-select it on reconnection. While there is no command in order to query the selected database in the current connection, the `CLIENT LIST` output shows, for each client, the currently selected database. - -@return - -@simple-string-reply diff --git a/commands/set.md b/commands/set.md index 2d8f626eed..1dc7322e96 100644 --- a/commands/set.md +++ b/commands/set.md @@ -6,10 +6,10 @@ Any previous time to live associated with the key is discarded on successful `SE The `SET` command supports a set of options that modify its behavior: -* `EX` *seconds* -- Set the specified expire time, in seconds. -* `PX` *milliseconds* -- Set the specified expire time, in milliseconds. -* `EXAT` *timestamp-seconds* -- Set the specified Unix time at which the key will expire, in seconds. -* `PXAT` *timestamp-milliseconds* -- Set the specified Unix time at which the key will expire, in milliseconds. +* `EX` *seconds* -- Set the specified expire time, in seconds (a positive integer). +* `PX` *milliseconds* -- Set the specified expire time, in milliseconds (a positive integer). +* `EXAT` *timestamp-seconds* -- Set the specified Unix time at which the key will expire, in seconds (a positive integer). +* `PXAT` *timestamp-milliseconds* -- Set the specified Unix time at which the key will expire, in milliseconds (a positive integer). * `NX` -- Only set the key if it does not already exist. * `XX` -- Only set the key if it already exists. * `KEEPTTL` -- Retain the time to live associated with the key. @@ -17,18 +17,6 @@ The `SET` command supports a set of options that modify its behavior: Note: Since the `SET` command options can replace `SETNX`, `SETEX`, `PSETEX`, `GETSET`, it is possible that in future versions of Redis these commands will be deprecated and finally removed. -@return - -@simple-string-reply: `OK` if `SET` was executed correctly. - -@nil-reply: `(nil)` if the `SET` operation was not performed because the user specified the `NX` or `XX` option but the condition was not met. - -If the command is issued with the `!GET` option, the above does not apply. It will instead reply as follows, regardless if the `SET` was actually performed: - -@bulk-string-reply: the old string value stored at key. - -@nil-reply: `(nil)` if the key did not exist. - @examples ```cli diff --git a/commands/setbit.md b/commands/setbit.md index e0b440b56c..a2e27ae840 100644 --- a/commands/setbit.md +++ b/commands/setbit.md @@ -20,10 +20,6 @@ allocation) takes ~8ms. Note that once this first allocation is done, subsequent calls to `SETBIT` for the same _key_ will not have the allocation overhead. -@return - -@integer-reply: the original bit value stored at _offset_. - @examples ```cli diff --git a/commands/setex.md b/commands/setex.md index f0d89d8b6d..c56718a11a 100644 --- a/commands/setex.md +++ b/commands/setex.md @@ -6,13 +6,8 @@ This command is equivalent to: SET key value EX seconds ``` - An error is returned when `seconds` is invalid. -@return - -@simple-string-reply - @examples ```cli diff --git a/commands/setnx.md b/commands/setnx.md index 833573c45e..72f5ac6a63 100644 --- a/commands/setnx.md +++ b/commands/setnx.md @@ -3,13 +3,6 @@ In that case, it is equal to `SET`. When `key` already holds a value, no operation is performed. `SETNX` is short for "**SET** if **N**ot e**X**ists". -@return - -@integer-reply, specifically: - -* `1` if the key was set -* `0` if the key was not set - @examples ```cli diff --git a/commands/setrange.md b/commands/setrange.md index 617e3d5dc3..3c7aa05b01 100644 --- a/commands/setrange.md +++ b/commands/setrange.md @@ -26,10 +26,6 @@ Thanks to `SETRANGE` and the analogous `GETRANGE` commands, you can use Redis strings as a linear array with O(1) random access. This is a very fast and efficient storage in many real world use cases. -@return - -@integer-reply: the length of the string after it was modified by the command. - @examples Basic usage: diff --git a/commands/shutdown.md b/commands/shutdown.md index 5dca6dec25..8bef39752d 100644 --- a/commands/shutdown.md +++ b/commands/shutdown.md @@ -62,12 +62,6 @@ This provides a best effort minimizing the risk of data loss in a situation wher Before version 7.0, shutting down a heavily loaded master node in a diskless setup was more likely to result in data loss. To minimize the risk of data loss in such setups, it's advised to trigger a manual `FAILOVER` (or `CLUSTER FAILOVER`) to demote the master to a replica and promote one of the replicas to be the new master, before shutting down a master node. -@return - -@simple-string-reply: `OK` if `ABORT` was specified and shutdown was aborted. -On successful shutdown, nothing is returned since the server quits and the connection is closed. -On failure, an error is returned. - ## Behavior change history * `>= 7.0.0`: Introduced waiting for lagging replicas before exiting. \ No newline at end of file diff --git a/commands/sinter.md b/commands/sinter.md index 465b3d73f7..e0b665b8a3 100644 --- a/commands/sinter.md +++ b/commands/sinter.md @@ -14,10 +14,6 @@ Keys that do not exist are considered to be empty sets. With one of the keys being an empty set, the resulting set is also empty (since set intersection with an empty set always results in an empty set). -@return - -@array-reply: list with members of the resulting set. - @examples ```cli diff --git a/commands/sintercard.md b/commands/sintercard.md index 24473e50b5..464e7bded5 100644 --- a/commands/sintercard.md +++ b/commands/sintercard.md @@ -8,10 +8,6 @@ By default, the command calculates the cardinality of the intersection of all gi When provided with the optional `LIMIT` argument (which defaults to 0 and means unlimited), if the intersection cardinality reaches limit partway through the computation, the algorithm will exit and yield limit as the cardinality. Such implementation ensures a significant speedup for queries where the limit is lower than the actual intersection cardinality. -@return - -@integer-reply: the number of elements in the resulting intersection. - @examples ```cli diff --git a/commands/sinterstore.md b/commands/sinterstore.md index 17dd0bf0b4..e3e712f036 100644 --- a/commands/sinterstore.md +++ b/commands/sinterstore.md @@ -3,10 +3,6 @@ it is stored in `destination`. If `destination` already exists, it is overwritten. -@return - -@integer-reply: the number of elements in the resulting set. - @examples ```cli diff --git a/commands/sismember.md b/commands/sismember.md index 219cd6e3e0..08b1c6c51f 100644 --- a/commands/sismember.md +++ b/commands/sismember.md @@ -1,12 +1,5 @@ Returns if `member` is a member of the set stored at `key`. -@return - -@integer-reply, specifically: - -* `1` if the element is a member of the set. -* `0` if the element is not a member of the set, or if `key` does not exist. - @examples ```cli diff --git a/commands/slaveof.md b/commands/slaveof.md index 34b95741ed..b42dc06160 100644 --- a/commands/slaveof.md +++ b/commands/slaveof.md @@ -16,7 +16,3 @@ So, if the old master stops working, it is possible to turn the replica into a master and set the application to use this new master in read/write. Later when the other Redis server is fixed, it can be reconfigured to work as a replica. - -@return - -@simple-string-reply diff --git a/commands/slowlog-get.md b/commands/slowlog-get.md index 3773cfbcd3..4b8f0c58d5 100644 --- a/commands/slowlog-get.md +++ b/commands/slowlog-get.md @@ -20,7 +20,3 @@ Each entry from the slow log is comprised of the following six values: The entry's unique ID can be used in order to avoid processing slow log entries multiple times (for instance you may have a script sending you an email alert for every new slow log entry). The ID is never reset in the course of the Redis server execution, only a server restart will reset it. - -@return - -@array-reply: a list of slow log entries. diff --git a/commands/slowlog-help.md b/commands/slowlog-help.md index a70f3a5d4e..86bf5b39a2 100644 --- a/commands/slowlog-help.md +++ b/commands/slowlog-help.md @@ -1,5 +1 @@ The `SLOWLOG HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/slowlog-len.md b/commands/slowlog-len.md index 6cc062f2a1..9515bb9473 100644 --- a/commands/slowlog-len.md +++ b/commands/slowlog-len.md @@ -4,9 +4,3 @@ A new entry is added to the slow log whenever a command exceeds the execution ti The maximum number of entries in the slow log is governed by the `slowlog-max-len` configuration directive. Once the slog log reaches its maximal size, the oldest entry is removed whenever a new entry is created. The slow log can be cleared with the `SLOWLOG RESET` command. - -@return - -@integer-reply - -The number of entries in the slow log. diff --git a/commands/slowlog-reset.md b/commands/slowlog-reset.md index 2b6d436aaf..a860f4433f 100644 --- a/commands/slowlog-reset.md +++ b/commands/slowlog-reset.md @@ -1,7 +1,3 @@ This command resets the slow log, clearing all entries in it. Once deleted the information is lost forever. - -@return - -@simple-string-reply: `OK` diff --git a/commands/smembers.md b/commands/smembers.md index 2272859352..20a8e23872 100644 --- a/commands/smembers.md +++ b/commands/smembers.md @@ -2,10 +2,6 @@ Returns all the members of the set value stored at `key`. This has the same effect as running `SINTER` with one argument `key`. -@return - -@array-reply: all elements of the set. - @examples ```cli diff --git a/commands/smismember.md b/commands/smismember.md index c4cec64a6b..4b8885996c 100644 --- a/commands/smismember.md +++ b/commands/smismember.md @@ -2,11 +2,6 @@ Returns whether each `member` is a member of the set stored at `key`. For every `member`, `1` is returned if the value is a member of the set, or `0` if the element is not a member of the set or if `key` does not exist. -@return - -@array-reply: list representing the membership of the given elements, in the same -order as they are requested. - @examples ```cli diff --git a/commands/smove.md b/commands/smove.md index 6b2400b6b0..241125cd2b 100644 --- a/commands/smove.md +++ b/commands/smove.md @@ -12,13 +12,6 @@ removed from the source set. An error is returned if `source` or `destination` does not hold a set value. -@return - -@integer-reply, specifically: - -* `1` if the element is moved. -* `0` if the element is not a member of `source` and no operation was performed. - @examples ```cli diff --git a/commands/sort.md b/commands/sort.md index 2a091db48c..a5843d86e7 100644 --- a/commands/sort.md +++ b/commands/sort.md @@ -105,8 +105,11 @@ SORT mylist BY weight_* GET object_* GET # ## Restrictions for using external keys -When enabling `Redis cluster-mode` there is no way to guarantee the existence of the external keys on the node which the command is processed on. -In this case, any use of `GET` or `BY` which reference external key pattern will cause the command to fail with an error. +Before 8.0, when enabling `Redis cluster-mode` there is no way to guarantee the existence of the external keys on the node which the command is processed on. In this case, any use of `GET` or `BY` which reference external key pattern will cause the command to fail with an error. + +Starting from 8.0, pattern with hash tag can be mapped to a slot, and so in `Redis cluster-mode`, the use of `BY` or `GET` is allowed when pattern contains hash tag and implies a specific slot which the key is also in, which means any key matching this pattern must be in the same slot as the key, and therefore in the same node. For example, in cluster mode, `{mylist}weight_*` is acceptable as a pattern when sorting `mylist`, while pattern `{abc}weight_*` will be denied, causing the command to fail with an error. + +To use pattern with hash tag, see [Hash tags](/docs/reference/cluster-spec/#hash-tags) for more information. Starting from Redis 7.0, any use of `GET` or `BY` which reference external key pattern will only be allowed in case the current user running the command has full key read permissions. Full key read permissions can be set for the user by, for example, specifying `'%R~*'` or `'~*` with the relevant command access rules. @@ -147,8 +150,3 @@ SORT mylist BY weight_*->fieldname GET object_*->fieldname The string `->` is used to separate the key name from the hash field name. The key is substituted as documented above, and the hash stored at the resulting key is accessed to retrieve the specified hash field. - -@return - -@array-reply: without passing the `store` option the command returns a list of sorted elements. -@integer-reply: when the `store` option is specified the command returns the number of sorted elements in the destination list. diff --git a/commands/sort_ro.md b/commands/sort_ro.md index 66223a32e5..82dc85ee8d 100644 --- a/commands/sort_ro.md +++ b/commands/sort_ro.md @@ -11,7 +11,3 @@ See original `SORT` for more details. ``` SORT_RO mylist BY weight_*->fieldname GET object_*->fieldname ``` - -@return - -@array-reply: a list of sorted elements. diff --git a/commands/spop.md b/commands/spop.md index 8c86a9ab36..5ebfaed881 100644 --- a/commands/spop.md +++ b/commands/spop.md @@ -6,16 +6,6 @@ By default, the command pops a single member from the set. When provided with the optional `count` argument, the reply will consist of up to `count` members, depending on the set's cardinality. -@return - -When called without the `count` argument: - -@bulk-string-reply: the removed member, or `nil` when `key` does not exist. - -When called with the `count` argument: - -@array-reply: the removed members, or an empty array when `key` does not exist. - @examples ```cli diff --git a/commands/spublish.md b/commands/spublish.md index 762ff8ed75..0b8e65d09a 100644 --- a/commands/spublish.md +++ b/commands/spublish.md @@ -6,11 +6,6 @@ The cluster makes sure that published shard messages are forwarded to all the no For more information about sharded pubsub, see [Sharded Pubsub](/topics/pubsub#sharded-pubsub). -@return - -@integer-reply: the number of clients that received the message. -Note that in a Redis Cluster, only clients that are connected to the same node as the publishing client are included in the count. - @examples For example the following command publish to channel `orders` with a subscriber already waiting for message(s). diff --git a/commands/srandmember.md b/commands/srandmember.md index dd2d4a837d..b90dd23b7b 100644 --- a/commands/srandmember.md +++ b/commands/srandmember.md @@ -6,12 +6,6 @@ The array's length is either `count` or the set's cardinality (`SCARD`), whichev If called with a negative `count`, the behavior changes and the command is allowed to return the **same element multiple times**. In this case, the number of returned elements is the absolute value of the specified `count`. -@return - -@bulk-string-reply: without the additional `count` argument, the command returns a Bulk Reply with the randomly selected element, or `nil` when `key` does not exist. - -@array-reply: when the additional `count` argument is passed, the command returns an array of elements, or an empty array when `key` does not exist. - @examples ```cli diff --git a/commands/srem.md b/commands/srem.md index fca5b75d3c..2a85a99e6b 100644 --- a/commands/srem.md +++ b/commands/srem.md @@ -5,11 +5,6 @@ If `key` does not exist, it is treated as an empty set and this command returns An error is returned when the value stored at `key` is not a set. -@return - -@integer-reply: the number of members that were removed from the set, not -including non existing members. - @examples ```cli diff --git a/commands/ssubscribe.md b/commands/ssubscribe.md index 71c975cb7e..bf7d30e859 100644 --- a/commands/ssubscribe.md +++ b/commands/ssubscribe.md @@ -7,12 +7,6 @@ A client can subscribe to channels across different slots over separate `SSUBSCR For more information about sharded Pub/Sub, see [Sharded Pub/Sub](/topics/pubsub#sharded-pubsub). -@return - -When successful, this command doesn't return anything. -Instead, for each shard channel, one message with the first element being the string "ssubscribe" is pushed as a confirmation that the command succeeded. -Note that this command can also return a -MOVED redirect. - @examples ``` diff --git a/commands/strlen.md b/commands/strlen.md index e504180f01..f4b1fee52d 100644 --- a/commands/strlen.md +++ b/commands/strlen.md @@ -1,11 +1,6 @@ Returns the length of the string value stored at `key`. An error is returned when `key` holds a non-string value. -@return - -@integer-reply: the length of the string at `key`, or `0` when `key` does not -exist. - @examples ```cli diff --git a/commands/subscribe.md b/commands/subscribe.md index b9b4682775..1bde8ebe9c 100644 --- a/commands/subscribe.md +++ b/commands/subscribe.md @@ -7,11 +7,6 @@ However, if RESP3 is used (see `HELLO`) it is possible for a client to issue any For more information, see [Pub/sub](/docs/interact/pubsub/). -@return - -When successful, this command doesn't return anything. -Instead, for each channel, one message with the first element being the string "subscribe" is pushed as a confirmation that the command succeeded. - ## Behavior change history * `>= 6.2.0`: `RESET` can be called to exit subscribed state. diff --git a/commands/substr.md b/commands/substr.md index 7283defc49..c188f95494 100644 --- a/commands/substr.md +++ b/commands/substr.md @@ -7,10 +7,6 @@ So -1 means the last character, -2 the penultimate and so forth. The function handles out of range requests by limiting the resulting range to the actual length of the string. -@return - -@bulk-string-reply - @examples ```cli diff --git a/commands/sunion.md b/commands/sunion.md index 205646893a..31315484b6 100644 --- a/commands/sunion.md +++ b/commands/sunion.md @@ -11,10 +11,6 @@ SUNION key1 key2 key3 = {a,b,c,d,e} Keys that do not exist are considered to be empty sets. -@return - -@array-reply: list with members of the resulting set. - @examples ```cli diff --git a/commands/sunionstore.md b/commands/sunionstore.md index 716caf13f0..28b752640a 100644 --- a/commands/sunionstore.md +++ b/commands/sunionstore.md @@ -3,10 +3,6 @@ it is stored in `destination`. If `destination` already exists, it is overwritten. -@return - -@integer-reply: the number of elements in the resulting set. - @examples ```cli diff --git a/commands/sunsubscribe.md b/commands/sunsubscribe.md index 36dc8d9a40..7ce76c333e 100644 --- a/commands/sunsubscribe.md +++ b/commands/sunsubscribe.md @@ -6,8 +6,3 @@ In this case a message for every unsubscribed shard channel will be sent to the Note: The global channels and shard channels needs to be unsubscribed from separately. For more information about sharded Pub/Sub, see [Sharded Pub/Sub](/topics/pubsub#sharded-pubsub). - -@return - -When successful, this command doesn't return anything. -Instead, for each shard channel, one message with the first element being the string "sunsubscribe" is pushed as a confirmation that the command succeeded. diff --git a/commands/swapdb.md b/commands/swapdb.md index ead2db07c0..7037f477f0 100644 --- a/commands/swapdb.md +++ b/commands/swapdb.md @@ -6,10 +6,6 @@ the other way around. Example: This will swap database 0 with database 1. All the clients connected with database 0 will immediately see the new data, exactly like all the clients connected with database 1 will see the data that was formerly of database 0. -@return - -@simple-string-reply: `OK` if `SWAPDB` was executed correctly. - @examples ``` diff --git a/commands/sync.md b/commands/sync.md index cb958479ca..5d9ad047f9 100644 --- a/commands/sync.md +++ b/commands/sync.md @@ -8,7 +8,3 @@ For more information about replication in Redis please check the [replication page][tr]. [tr]: /topics/replication - -@return - -**Non standard return value**, a bulk transfer of the data followed by `PING` and write requests from the master. diff --git a/commands/time.md b/commands/time.md index 2cf1af6828..b7adb8f164 100644 --- a/commands/time.md +++ b/commands/time.md @@ -3,15 +3,6 @@ timestamp and the amount of microseconds already elapsed in the current second. Basically the interface is very similar to the one of the `gettimeofday` system call. -@return - -@array-reply, specifically: - -A multi bulk reply containing two elements: - -* unix time in seconds. -* microseconds. - @examples ```cli diff --git a/commands/touch.md b/commands/touch.md index a369354503..ba5bc9b0db 100644 --- a/commands/touch.md +++ b/commands/touch.md @@ -1,10 +1,6 @@ Alters the last access time of a key(s). A key is ignored if it does not exist. -@return - -@integer-reply: The number of keys that were touched. - @examples ```cli diff --git a/commands/ttl.md b/commands/ttl.md index 15821e1140..1cc0a86f90 100644 --- a/commands/ttl.md +++ b/commands/ttl.md @@ -11,10 +11,6 @@ Starting with Redis 2.8 the return value in case of error changed: See also the `PTTL` command that returns the same information with milliseconds resolution (Only available in Redis 2.6 or greater). -@return - -@integer-reply: TTL in seconds, or a negative value in order to signal an error (see the description above). - @examples ```cli diff --git a/commands/type.md b/commands/type.md index 8a818e0544..7bdd48407d 100644 --- a/commands/type.md +++ b/commands/type.md @@ -2,10 +2,6 @@ Returns the string representation of the type of the value stored at `key`. The different types that can be returned are: `string`, `list`, `set`, `zset`, `hash` and `stream`. -@return - -@simple-string-reply: type of `key`, or `none` when `key` does not exist. - @examples ```cli diff --git a/commands/unlink.md b/commands/unlink.md index c91dd664de..0d5ade0217 100644 --- a/commands/unlink.md +++ b/commands/unlink.md @@ -5,10 +5,6 @@ blocking, while `DEL` is. This is where the command name comes from: the command just **unlinks** the keys from the keyspace. The actual removal will happen later asynchronously. -@return - -@integer-reply: The number of keys that were unlinked. - @examples ```cli diff --git a/commands/unsubscribe.md b/commands/unsubscribe.md index e5f53a0e9c..7bdf1d15e5 100644 --- a/commands/unsubscribe.md +++ b/commands/unsubscribe.md @@ -5,8 +5,3 @@ When no channels are specified, the client is unsubscribed from all the previously subscribed channels. In this case, a message for every unsubscribed channel will be sent to the client. - -@return - -When successful, this command doesn't return anything. -Instead, for each channel, one message with the first element being the string "unsubscribe" is pushed as a confirmation that the command succeeded. diff --git a/commands/unwatch.md b/commands/unwatch.md index b60bcb8040..dcdda08dab 100644 --- a/commands/unwatch.md +++ b/commands/unwatch.md @@ -3,7 +3,3 @@ Flushes all the previously watched keys for a [transaction][tt]. [tt]: /topics/transactions If you call `EXEC` or `DISCARD`, there's no need to manually call `UNWATCH`. - -@return - -@simple-string-reply: always `OK`. diff --git a/commands/wait.md b/commands/wait.md index a76f644784..b671faff4e 100644 --- a/commands/wait.md +++ b/commands/wait.md @@ -37,10 +37,6 @@ write command was executed in the context of a given client. When `WAIT` is called Redis checks if the specified number of replicas already acknowledged this offset or a greater one. -@return - -@integer-reply: The command returns the number of replicas reached by all the writes performed in the context of the current connection. - @examples ``` diff --git a/commands/waitaof.md b/commands/waitaof.md index 58b4c7abab..a6269e2375 100644 --- a/commands/waitaof.md +++ b/commands/waitaof.md @@ -1,4 +1,9 @@ This command blocks the current client until all previous write commands by that client are acknowledged as having been fsynced to the AOF of the local Redis and/or at least the specified number of replicas. + +`numlocal` represents the number of local fsyncs required to be confirmed before proceeding. +When `numlocal` is set to 1, the command blocks until the data written to the Redis instance is confirmed to be persisted to the local AOF file. +The value 0 disables this check. + If the timeout, specified in milliseconds, is reached, the command returns even if the specified number of acknowledgments has not been met. The command **will always return** the number of masters and replicas that have fsynced all write commands sent by the current client before the `WAITAOF` command, both in the case where the specified thresholds were met, and when the timeout is reached. @@ -35,10 +40,6 @@ In addition, Redis replicas asynchronously ping their master with two replicatio Redis remembers, for each client, the replication offset of the produced replication stream when the last write command was executed in the context of that client. When `WAITAOF` is called, Redis checks if the local Redis and/or the specified number of replicas have confirmed fsyncing this offset or a greater one to their AOF. -@return - -@array-reply: The command returns an array of two integers: The first is the number of local Redises (0 or 1) that have fsynced to AOF all writes performed in the context of the current connection; The second is the number of replicas that have acknowledged doing the same. - @examples ``` diff --git a/commands/watch.md b/commands/watch.md index 08f823ff7f..2121bd5cb5 100644 --- a/commands/watch.md +++ b/commands/watch.md @@ -2,7 +2,3 @@ Marks the given keys to be watched for conditional execution of a [transaction][tt]. [tt]: /topics/transactions - -@return - -@simple-string-reply: always `OK`. diff --git a/commands/xack.md b/commands/xack.md index aae2db5586..daeb7c21c8 100644 --- a/commands/xack.md +++ b/commands/xack.md @@ -14,15 +14,6 @@ so that such message does not get processed again, and as a side effect, the PEL entry about this message is also purged, releasing memory from the Redis server. -@return - -@integer-reply, specifically: - -The command returns the number of messages successfully acknowledged. -Certain message IDs may no longer be part of the PEL (for example because -they have already been acknowledged), and XACK will not count them as -successfully acknowledged. - @examples ``` diff --git a/commands/xadd.md b/commands/xadd.md index d651a6858c..3f431a133b 100644 --- a/commands/xadd.md +++ b/commands/xadd.md @@ -72,17 +72,6 @@ Will add a new entry but will also evict old entries so that the stream will con For further information about Redis streams please check our [introduction to Redis Streams document](/topics/streams-intro). -@return - -@bulk-string-reply, specifically: - -The command returns the ID of the added entry. The ID is the one auto-generated -if `*` is passed as ID argument, otherwise the command just returns the same ID -specified by the user during insertion. - -The command returns a @nil-reply when used with the `NOMKSTREAM` option and the -key doesn't exist. - @examples ```cli diff --git a/commands/xautoclaim.md b/commands/xautoclaim.md index 5ff44f2fd2..4b65eba3ae 100644 --- a/commands/xautoclaim.md +++ b/commands/xautoclaim.md @@ -25,16 +25,6 @@ These message IDs are returned to the caller as a part of `XAUTOCLAIM`s reply. Lastly, claiming a message with `XAUTOCLAIM` also increments the attempted deliveries count for that message, unless the `JUSTID` option has been specified (which only delivers the message ID, not the message itself). Messages that cannot be processed for some reason - for example, because consumers systematically crash when processing them - will exhibit high attempted delivery counts that can be detected by monitoring. -@return - -@array-reply, specifically: - -An array with three elements: - -1. A stream ID to be used as the `` argument for the next call to `XAUTOCLAIM`. -2. An array containing all the successfully claimed messages in the same format as `XRANGE`. -3. An array containing message IDs that no longer exist in the stream, and were deleted from the PEL in which they were found. - @examples ``` diff --git a/commands/xclaim.md b/commands/xclaim.md index bc7b7be3a6..50fd8d23c2 100644 --- a/commands/xclaim.md +++ b/commands/xclaim.md @@ -35,14 +35,6 @@ useful to normal users: 4. `FORCE`: Creates the pending message entry in the PEL even if certain specified IDs are not already in the PEL assigned to a different client. However the message must be exist in the stream, otherwise the IDs of non existing messages are ignored. 5. `JUSTID`: Return just an array of IDs of messages successfully claimed, without returning the actual message. Using this option means the retry counter is not incremented. -@return - -@array-reply, specifically: - -The command returns all the messages successfully claimed, in the same format -as `XRANGE`. However if the `JUSTID` option was specified, only the message -IDs are reported, without including the actual message. - @examples ``` diff --git a/commands/xdel.md b/commands/xdel.md index 3ee4a3d067..57b9a8ba47 100644 --- a/commands/xdel.md +++ b/commands/xdel.md @@ -26,10 +26,6 @@ collection in case a given macro-node reaches a given amount of deleted entries. Currently with the usage we anticipate for this data structure, it is not a good idea to add such complexity. -@return - -@integer-reply: the number of entries actually deleted. - @examples ``` diff --git a/commands/xgroup-create.md b/commands/xgroup-create.md index 4fdc149f61..124a8a14f4 100644 --- a/commands/xgroup-create.md +++ b/commands/xgroup-create.md @@ -19,7 +19,3 @@ To enable consumer group lag tracking, specify the optional `entries_read` named An arbitrary ID is any ID that isn't the ID of the stream's first entry, last entry, or zero ("0-0") ID. Use it to find out how many entries are between the arbitrary ID (excluding it) and the stream's last entry. Set the `entries_read` the stream's `entries_added` subtracted by the number of entries. - -@return - -@simple-string-reply: `OK` on success. diff --git a/commands/xgroup-createconsumer.md b/commands/xgroup-createconsumer.md index 3b27b1d123..f81d468a02 100644 --- a/commands/xgroup-createconsumer.md +++ b/commands/xgroup-createconsumer.md @@ -2,7 +2,3 @@ Create a consumer named `` in the consumer group `` of Consumers are also created automatically whenever an operation, such as `XREADGROUP`, references a consumer that doesn't exist. This is valid for `XREADGROUP` only when there is data in the stream. - -@return - -@integer-reply: the number of created consumers (0 or 1) \ No newline at end of file diff --git a/commands/xgroup-delconsumer.md b/commands/xgroup-delconsumer.md index 9e73da8922..57c71adb12 100644 --- a/commands/xgroup-delconsumer.md +++ b/commands/xgroup-delconsumer.md @@ -4,7 +4,3 @@ Sometimes it may be useful to remove old consumers since they are no longer used Note, however, that any pending messages that the consumer had will become unclaimable after it was deleted. It is strongly recommended, therefore, that any pending messages are claimed or acknowledged prior to deleting the consumer from the group. - -@return - -@integer-reply: the number of pending messages that the consumer had before it was deleted diff --git a/commands/xgroup-destroy.md b/commands/xgroup-destroy.md index 448468ba14..29af5f73cb 100644 --- a/commands/xgroup-destroy.md +++ b/commands/xgroup-destroy.md @@ -1,7 +1,3 @@ The `XGROUP DESTROY` command completely destroys a consumer group. The consumer group will be destroyed even if there are active consumers, and pending messages, so make sure to call this command only when really needed. - -@return - -@integer-reply: the number of destroyed consumer groups (0 or 1) \ No newline at end of file diff --git a/commands/xgroup-help.md b/commands/xgroup-help.md index 1eb1a7bb34..405008ac80 100644 --- a/commands/xgroup-help.md +++ b/commands/xgroup-help.md @@ -1,5 +1 @@ The `XGROUP HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/xgroup-setid.md b/commands/xgroup-setid.md index 0808404f25..5ea91accdc 100644 --- a/commands/xgroup-setid.md +++ b/commands/xgroup-setid.md @@ -10,7 +10,3 @@ The optional `entries_read` argument can be specified to enable consumer group l An arbitrary ID is any ID that isn't the ID of the stream's first entry, its last entry or the zero ("0-0") ID. This can be useful you know exactly how many entries are between the arbitrary ID (excluding it) and the stream's last entry. In such cases, the `entries_read` can be set to the stream's `entries_added` subtracted with the number of entries. - -@return - -@simple-string-reply: `OK` on success. diff --git a/commands/xinfo-consumers.md b/commands/xinfo-consumers.md index d4bb878b8e..855a308ced 100644 --- a/commands/xinfo-consumers.md +++ b/commands/xinfo-consumers.md @@ -7,9 +7,8 @@ The following information is provided for each consumer in the group: * **idle**: the number of milliseconds that have passed since the consumer's last attempted interaction (Examples: `XREADGROUP`, `XCLAIM`, `XAUTOCLAIM`) * **inactive**: the number of milliseconds that have passed since the consumer's last successful interaction (Examples: `XREADGROUP` that actually read some entries into the PEL, `XCLAIM`/`XAUTOCLAIM` that actually claimed some entries) -@return - -@array-reply: a list of consumers. +Note that before Redis 7.2.0, **idle** used to denote the time passed since last successful interaction. +In 7.2.0, **inactive** was added and **idle** was changed to denote the time passed since last attempted interaction. @examples diff --git a/commands/xinfo-groups.md b/commands/xinfo-groups.md index 08af1c9ae1..3074725158 100644 --- a/commands/xinfo-groups.md +++ b/commands/xinfo-groups.md @@ -39,10 +39,6 @@ However, the lag is only temporarily unavailable. It is restored automatically during regular operation as consumers keep processing messages. Once the consumer group delivers the last message in the stream to its members, it will be set with the correct logical read counter, and tracking its lag can be resumed. -@return - -@array-reply: a list of consumer groups. - @examples ``` diff --git a/commands/xinfo-help.md b/commands/xinfo-help.md index 293892fd8f..34ad659b9c 100644 --- a/commands/xinfo-help.md +++ b/commands/xinfo-help.md @@ -1,5 +1 @@ The `XINFO HELP` command returns a helpful text describing the different subcommands. - -@return - -@array-reply: a list of subcommands and their descriptions diff --git a/commands/xinfo-stream.md b/commands/xinfo-stream.md index beba33e18e..4fcbe1e2ee 100644 --- a/commands/xinfo-stream.md +++ b/commands/xinfo-stream.md @@ -12,16 +12,42 @@ The informative details provided by this command are: * **first-entry**: the ID and field-value tuples of the first entry in the stream * **last-entry**: the ID and field-value tuples of the last entry in the stream +### The `FULL` modifier + The optional `FULL` modifier provides a more verbose reply. When provided, the `FULL` reply includes an **entries** array that consists of the stream entries (ID and field-value tuples) in ascending order. Furthermore, **groups** is also an array, and for each of the consumer groups it consists of the information reported by `XINFO GROUPS` and `XINFO CONSUMERS`. -The `COUNT` option can be used to limit the number of stream and PEL entries that are returned (The first `` entries are returned). -The default `COUNT` is 10 and a `COUNT` of 0 means that all entries will be returned (execution time may be long if the stream has a lot of entries). +The following information is provided for each of the groups: + +* **name**: the consumer group's name +* **last-delivered-id**: the ID of the last entry delivered to the group's consumers +* **entries-read**: the logical "read counter" of the last entry delivered to the group's consumers +* **lag**: the number of entries in the stream that are still waiting to be delivered to the group's consumers, or a NULL when that number can't be determined. +* **pel-count**: the length of the group's pending entries list (PEL), which are messages that were delivered but are yet to be acknowledged +* **pending**: an array with pending entries information (see below) +* **consumers**: an array with consumers information (see below) + +The following information is provided for each pending entry: -@return +1. The ID of the message. +2. The name of the consumer that fetched the message and has still to acknowledge it. We call it the current *owner* of the message. +3. The UNIX timestamp of when the message was delivered to this consumer. +4. The number of times this message was delivered. -@array-reply: a list of informational bits +The following information is provided for each consumer: + +* **name**: the consumer's name +* **seen-time**: the UNIX timestamp of the last attempted interaction (Examples: `XREADGROUP`, `XCLAIM`, `XAUTOCLAIM`) +* **active-time**: the UNIX timestamp of the last successful interaction (Examples: `XREADGROUP` that actually read some entries into the PEL, `XCLAIM`/`XAUTOCLAIM` that actually claimed some entries) +* **pel-count**: the number of entries in the PEL: pending messages for the consumer, which are messages that were delivered but are yet to be acknowledged +* **pending**: an array with pending entries information, has the same structure as described above, except the consumer name is omitted (redundant, since anyway we are in a specific consumer context) + +Note that before Redis 7.2.0, **seen-time** used to denote the last successful interaction. +In 7.2.0, **active-time** was added and **seen-time** was changed to denote the last attempted interaction. + +The `COUNT` option can be used to limit the number of stream and PEL entries that are returned (The first `` entries are returned). +The default `COUNT` is 10 and a `COUNT` of 0 means that all entries will be returned (execution time may be long if the stream has a lot of entries). @examples diff --git a/commands/xlen.md b/commands/xlen.md index 41c2010e7f..e996f7ee18 100644 --- a/commands/xlen.md +++ b/commands/xlen.md @@ -8,10 +8,6 @@ Streams are not auto-deleted once they have no entries inside (for instance after an `XDEL` call), because the stream may have consumer groups associated with it. -@return - -@integer-reply: the number of entries of the stream at `key`. - @examples ```cli diff --git a/commands/xpending.md b/commands/xpending.md index 48840aaa38..c22ae8e38d 100644 --- a/commands/xpending.md +++ b/commands/xpending.md @@ -127,11 +127,3 @@ The `XPENDING` command allows iterating over the pending entries just like prefixing the ID of the last-read pending entry with the `(` character that denotes an open (exclusive) range, and proving it to the subsequent call to the command. - -@return - -@array-reply, specifically: - -The command returns data in different format depending on the way it is -called, as previously explained in this page. However the reply is always -an array of items. diff --git a/commands/xrange.md b/commands/xrange.md index fa81b316a5..a8d4e89b67 100644 --- a/commands/xrange.md +++ b/commands/xrange.md @@ -200,15 +200,6 @@ of XRANGE: For further information about Redis streams please check our [introduction to Redis Streams document](/topics/streams-intro). -@return - -@array-reply, specifically: - -The command returns the entries with IDs matching the specified range. -The returned entries are complete, that means that the ID and all the fields -they are composed are returned. Moreover, the entries are returned with -their fields and values in the exact same order as `XADD` added them. - @examples ```cli diff --git a/commands/xread.md b/commands/xread.md index ea0f311ecc..0a6741519f 100644 --- a/commands/xread.md +++ b/commands/xread.md @@ -197,19 +197,6 @@ are not removed from the stream when clients are served, so every client waiting will be served as soon as an `XADD` command provides data to the stream. -@return - -@array-reply, specifically: - -The command returns an array of results: each element of the returned -array is an array composed of a two element containing the key name and -the entries reported for that key. The entries reported are full stream -entries, having IDs and the list of all the fields and values. Field and -values are guaranteed to be reported in the same order they were added -by `XADD`. - -When **BLOCK** is used, on timeout a null reply is returned. - Reading the [Redis Streams introduction](/topics/streams-intro) is highly suggested in order to understand more about the streams overall behavior -and semantics. +and semantics. \ No newline at end of file diff --git a/commands/xreadgroup.md b/commands/xreadgroup.md index 2e20d415f2..e94d2bb619 100644 --- a/commands/xreadgroup.md +++ b/commands/xreadgroup.md @@ -129,19 +129,6 @@ OK 2) (nil) ``` -@return - -@array-reply, specifically: - -The command returns an array of results: each element of the returned -array is an array composed of a two element containing the key name and -the entries reported for that key. The entries reported are full stream -entries, having IDs and the list of all the fields and values. Field and -values are guaranteed to be reported in the same order they were added -by `XADD`. - -When **BLOCK** is used, on timeout a null reply is returned. - Reading the [Redis Streams introduction](/topics/streams-intro) is highly suggested in order to understand more about the streams overall behavior and semantics. diff --git a/commands/xrevrange.md b/commands/xrevrange.md index d61b3f5073..ab10209082 100644 --- a/commands/xrevrange.md +++ b/commands/xrevrange.md @@ -14,16 +14,6 @@ enough to send: XREVRANGE somestream + - COUNT 1 -@return - -@array-reply, specifically: - -The command returns the entries with IDs matching the specified range, -from the higher ID to the lower ID matching. -The returned entries are complete, that means that the ID and all the fields -they are composed are returned. Moreover the entries are returned with -their fields and values in the exact same order as `XADD` added them. - @examples ```cli diff --git a/commands/xtrim.md b/commands/xtrim.md index 08d55d5a9e..b26fec018e 100644 --- a/commands/xtrim.md +++ b/commands/xtrim.md @@ -44,10 +44,6 @@ When used, it specifies the maximal `count` of entries that will be evicted. When `LIMIT` and `count` aren't specified, the default value of 100 * the number of entries in a macro node will be implicitly used as the `count`. Specifying the value 0 as `count` disables the limiting mechanism entirely. -@return - -@integer-reply: The number of entries deleted from the stream. - @examples ```cli diff --git a/commands/zadd.md b/commands/zadd.md index eb77de6790..1f11c6ed28 100644 --- a/commands/zadd.md +++ b/commands/zadd.md @@ -58,17 +58,6 @@ The lexicographic ordering used is binary, it compares strings as array of bytes If the user inserts all the elements in a sorted set with the same score (for example 0), all the elements of the sorted set are sorted lexicographically, and range queries on elements are possible using the command `ZRANGEBYLEX` (Note: it is also possible to query sorted sets by range of scores using `ZRANGEBYSCORE`). -@return - -@integer-reply, specifically: - -* When used without optional arguments, the number of elements added to the sorted set (excluding score updates). -* If the `CH` option is specified, the number of elements that were changed (added or updated). - -If the `INCR` option is specified, the return value will be @bulk-string-reply: - -* The new score of `member` (a double precision floating point number) represented as string, or `nil` if the operation was aborted (when called with either the `XX` or the `NX` option). - @examples ```cli diff --git a/commands/zcard.md b/commands/zcard.md index 5ad504335d..bacabd2883 100644 --- a/commands/zcard.md +++ b/commands/zcard.md @@ -1,11 +1,6 @@ Returns the sorted set cardinality (number of elements) of the sorted set stored at `key`. -@return - -@integer-reply: the cardinality (number of elements) of the sorted set, or `0` -if `key` does not exist. - @examples ```cli diff --git a/commands/zcount.md b/commands/zcount.md index 82ce39b81c..a90d7c4b37 100644 --- a/commands/zcount.md +++ b/commands/zcount.md @@ -6,10 +6,6 @@ The `min` and `max` arguments have the same semantic as described for Note: the command has a complexity of just O(log(N)) because it uses elements ranks (see `ZRANK`) to get an idea of the range. Because of this there is no need to do a work proportional to the size of the range. -@return - -@integer-reply: the number of elements in the specified score range. - @examples ```cli diff --git a/commands/zdiff.md b/commands/zdiff.md index d9449b7ef5..e2df52e424 100644 --- a/commands/zdiff.md +++ b/commands/zdiff.md @@ -1,11 +1,6 @@ This command is similar to `ZDIFFSTORE`, but instead of storing the resulting sorted set, it is returned to the client. -@return - -@array-reply: the result of the difference (optionally with their scores, in case -the `WITHSCORES` option is given). - @examples ```cli diff --git a/commands/zdiffstore.md b/commands/zdiffstore.md index abe3ba7e73..d9d2e2cac3 100644 --- a/commands/zdiffstore.md +++ b/commands/zdiffstore.md @@ -6,11 +6,6 @@ Keys that do not exist are considered to be empty sets. If `destination` already exists, it is overwritten. -@return - -@integer-reply: the number of elements in the resulting sorted set at -`destination`. - @examples ```cli diff --git a/commands/zincrby.md b/commands/zincrby.md index 0b8ccf0985..bbf48716b8 100644 --- a/commands/zincrby.md +++ b/commands/zincrby.md @@ -11,11 +11,6 @@ The `score` value should be the string representation of a numeric value, and accepts double precision floating point numbers. It is possible to provide a negative value to decrement the score. -@return - -@bulk-string-reply: the new score of `member` (a double precision floating point -number), represented as string. - @examples ```cli diff --git a/commands/zinter.md b/commands/zinter.md index 5a7adccd79..b796517797 100644 --- a/commands/zinter.md +++ b/commands/zinter.md @@ -3,11 +3,6 @@ sorted set, it is returned to the client. For a description of the `WEIGHTS` and `AGGREGATE` options, see `ZUNIONSTORE`. -@return - -@array-reply: the result of intersection (optionally with their scores, in case -the `WITHSCORES` option is given). - @examples ```cli diff --git a/commands/zintercard.md b/commands/zintercard.md index 613849fc2d..7ee7d1edeb 100644 --- a/commands/zintercard.md +++ b/commands/zintercard.md @@ -7,10 +7,6 @@ By default, the command calculates the cardinality of the intersection of all gi When provided with the optional `LIMIT` argument (which defaults to 0 and means unlimited), if the intersection cardinality reaches limit partway through the computation, the algorithm will exit and yield limit as the cardinality. Such implementation ensures a significant speedup for queries where the limit is lower than the actual intersection cardinality. -@return - -@integer-reply: the number of elements in the resulting intersection. - @examples ```cli diff --git a/commands/zinterstore.md b/commands/zinterstore.md index 0ecda0ddd7..1d386aa3a4 100644 --- a/commands/zinterstore.md +++ b/commands/zinterstore.md @@ -13,11 +13,6 @@ For a description of the `WEIGHTS` and `AGGREGATE` options, see `ZUNIONSTORE`. If `destination` already exists, it is overwritten. -@return - -@integer-reply: the number of elements in the resulting sorted set at -`destination`. - @examples ```cli diff --git a/commands/zlexcount.md b/commands/zlexcount.md index 15484f7973..2eeed5c27d 100644 --- a/commands/zlexcount.md +++ b/commands/zlexcount.md @@ -5,10 +5,6 @@ The `min` and `max` arguments have the same meaning as described for Note: the command has a complexity of just O(log(N)) because it uses elements ranks (see `ZRANK`) to get an idea of the range. Because of this there is no need to do a work proportional to the size of the range. -@return - -@integer-reply: the number of elements in the specified score range. - @examples ```cli diff --git a/commands/zmpop.md b/commands/zmpop.md index 16848a0e08..e3fd6944b3 100644 --- a/commands/zmpop.md +++ b/commands/zmpop.md @@ -12,13 +12,6 @@ The optional `COUNT` can be used to specify the number of elements to pop, and i The number of popped elements is the minimum from the sorted set's cardinality and `COUNT`'s value. -@return - -@array-reply: specifically: - -* A `nil` when no element could be popped. -* A two-element array with the first element being the name of the key from which elements were popped, and the second element is an array of the popped elements. Every entry in the elements array is also an array that contains the member and its score. - @examples ```cli diff --git a/commands/zmscore.md b/commands/zmscore.md index c2317e90b8..0111a4a01b 100644 --- a/commands/zmscore.md +++ b/commands/zmscore.md @@ -2,11 +2,6 @@ Returns the scores associated with the specified `members` in the sorted set sto For every `member` that does not exist in the sorted set, a `nil` value is returned. -@return - -@array-reply: list of scores or `nil` associated with the specified `member` values (a double precision floating point number), -represented as strings. - @examples ```cli diff --git a/commands/zpopmax.md b/commands/zpopmax.md index 8f6750a75d..c0245f28b6 100644 --- a/commands/zpopmax.md +++ b/commands/zpopmax.md @@ -6,10 +6,6 @@ value that is higher than the sorted set's cardinality will not produce an error. When returning multiple elements, the one with the highest score will be the first, followed by the elements with lower scores. -@return - -@array-reply: list of popped elements and scores. - @examples ```cli diff --git a/commands/zpopmin.md b/commands/zpopmin.md index 16f7c97ac1..2214e57dd6 100644 --- a/commands/zpopmin.md +++ b/commands/zpopmin.md @@ -6,10 +6,6 @@ value that is higher than the sorted set's cardinality will not produce an error. When returning multiple elements, the one with the lowest score will be the first, followed by the elements with greater scores. -@return - -@array-reply: list of popped elements and scores. - @examples ```cli diff --git a/commands/zrandmember.md b/commands/zrandmember.md index aae0b25434..d1f6ed983e 100644 --- a/commands/zrandmember.md +++ b/commands/zrandmember.md @@ -8,13 +8,6 @@ In this case, the number of returned elements is the absolute value of the speci The optional `WITHSCORES` modifier changes the reply so it includes the respective scores of the randomly selected elements from the sorted set. -@return - -@bulk-string-reply: without the additional `count` argument, the command returns a Bulk Reply with the randomly selected element, or `nil` when `key` does not exist. - -@array-reply: when the additional `count` argument is passed, the command returns an array of elements, or an empty array when `key` does not exist. -If the `WITHSCORES` modifier is used, the reply is a list elements and their scores from the sorted set. - @examples ```cli diff --git a/commands/zrange.md b/commands/zrange.md index e28d5c3994..a928689d71 100644 --- a/commands/zrange.md +++ b/commands/zrange.md @@ -100,11 +100,6 @@ Because of the first *normalized* part in every element (before the colon charac The binary nature of the comparison allows to use sorted sets as a general purpose index, for example, the first part of the element can be a 64-bit big-endian number. Since big-endian numbers have the most significant bytes in the initial positions, the binary comparison will match the numerical comparison of the numbers. This can be used in order to implement range queries on 64-bit values. As in the example below, after the first 8 bytes, we can store the value of the element we are indexing. -@return - -@array-reply: list of elements in the specified range (optionally with -their scores, in case the `WITHSCORES` option is given). - @examples ```cli diff --git a/commands/zrangebylex.md b/commands/zrangebylex.md index 4eefffc05a..b4663f674b 100644 --- a/commands/zrangebylex.md +++ b/commands/zrangebylex.md @@ -47,10 +47,6 @@ comparison of the numbers. This can be used in order to implement range queries on 64 bit values. As in the example below, after the first 8 bytes we can store the value of the element we are actually indexing. -@return - -@array-reply: list of elements in the specified score range. - @examples ```cli diff --git a/commands/zrangebyscore.md b/commands/zrangebyscore.md index bc81708533..5c4ea3a9fc 100644 --- a/commands/zrangebyscore.md +++ b/commands/zrangebyscore.md @@ -40,11 +40,6 @@ ZRANGEBYSCORE zset (5 (10 Will return all the elements with `5 < score < 10` (5 and 10 excluded). -@return - -@array-reply: list of elements in the specified score range (optionally -with their scores). - @examples ```cli diff --git a/commands/zrangestore.md b/commands/zrangestore.md index 8dc744c3e3..2a0bbfc9d9 100644 --- a/commands/zrangestore.md +++ b/commands/zrangestore.md @@ -1,9 +1,5 @@ This command is like `ZRANGE`, but stores the result in the `` destination key. -@return - -@integer-reply: the number of elements in the resulting sorted set. - @examples ```cli diff --git a/commands/zrank.md b/commands/zrank.md index f458f298da..8436883cd0 100644 --- a/commands/zrank.md +++ b/commands/zrank.md @@ -8,17 +8,6 @@ The optional `WITHSCORE` argument supplements the command's reply with the score Use `ZREVRANK` to get the rank of an element with the scores ordered from high to low. -@return - -* If `member` exists in the sorted set: - * using `WITHSCORE`, @array-reply: an array containing the rank and score of `member`. - * without using `WITHSCORE`, @integer-reply: the rank of `member`. -* If `member` does not exist in the sorted set or `key` does not exist: - * using `WITHSCORE`, @array-reply: `nil`. - * without using `WITHSCORE`, @bulk-string-reply: `nil`. - -Note that in RESP3 null and nullarray are the same, but in RESP2 they are not. - @examples ```cli diff --git a/commands/zrem.md b/commands/zrem.md index d97fd4ba94..642e2874bc 100644 --- a/commands/zrem.md +++ b/commands/zrem.md @@ -3,13 +3,6 @@ Non existing members are ignored. An error is returned when `key` exists and does not hold a sorted set. -@return - -@integer-reply, specifically: - -* The number of members removed from the sorted set, not including non existing - members. - @examples ```cli diff --git a/commands/zremrangebylex.md b/commands/zremrangebylex.md index 4264f1b072..83df974cdd 100644 --- a/commands/zremrangebylex.md +++ b/commands/zremrangebylex.md @@ -2,10 +2,6 @@ When all the elements in a sorted set are inserted with the same score, in order The meaning of `min` and `max` are the same of the `ZRANGEBYLEX` command. Similarly, this command actually removes the same elements that `ZRANGEBYLEX` would return if called with the same `min` and `max` arguments. -@return - -@integer-reply: the number of elements removed. - @examples ```cli diff --git a/commands/zremrangebyrank.md b/commands/zremrangebyrank.md index edd3cf39a5..30a068b673 100644 --- a/commands/zremrangebyrank.md +++ b/commands/zremrangebyrank.md @@ -7,10 +7,6 @@ the element with the highest score. For example: `-1` is the element with the highest score, `-2` the element with the second highest score and so forth. -@return - -@integer-reply: the number of elements removed. - @examples ```cli diff --git a/commands/zremrangebyscore.md b/commands/zremrangebyscore.md index fdf9a9869c..839b17b3c7 100644 --- a/commands/zremrangebyscore.md +++ b/commands/zremrangebyscore.md @@ -1,10 +1,6 @@ Removes all elements in the sorted set stored at `key` with a score between `min` and `max` (inclusive). -@return - -@integer-reply: the number of elements removed. - @examples ```cli diff --git a/commands/zrevrange.md b/commands/zrevrange.md index 3a19810c94..2a36390456 100644 --- a/commands/zrevrange.md +++ b/commands/zrevrange.md @@ -4,11 +4,6 @@ Descending lexicographical order is used for elements with equal score. Apart from the reversed ordering, `ZREVRANGE` is similar to `ZRANGE`. -@return - -@array-reply: list of elements in the specified range (optionally with -their scores). - @examples ```cli diff --git a/commands/zrevrangebylex.md b/commands/zrevrangebylex.md index c6772c9128..eb9ad8f436 100644 --- a/commands/zrevrangebylex.md +++ b/commands/zrevrangebylex.md @@ -2,10 +2,6 @@ When all the elements in a sorted set are inserted with the same score, in order Apart from the reversed ordering, `ZREVRANGEBYLEX` is similar to `ZRANGEBYLEX`. -@return - -@array-reply: list of elements in the specified score range. - @examples ```cli diff --git a/commands/zrevrangebyscore.md b/commands/zrevrangebyscore.md index e95d771bb3..c6e2e3e537 100644 --- a/commands/zrevrangebyscore.md +++ b/commands/zrevrangebyscore.md @@ -9,11 +9,6 @@ order. Apart from the reversed ordering, `ZREVRANGEBYSCORE` is similar to `ZRANGEBYSCORE`. -@return - -@array-reply: list of elements in the specified score range (optionally -with their scores). - @examples ```cli diff --git a/commands/zrevrank.md b/commands/zrevrank.md index 11aad62bbe..c79868920b 100644 --- a/commands/zrevrank.md +++ b/commands/zrevrank.md @@ -8,17 +8,6 @@ The optional `WITHSCORE` argument supplements the command's reply with the score Use `ZRANK` to get the rank of an element with the scores ordered from low to high. -@return - -* If `member` exists in the sorted set: - * using `WITHSCORE`, @array-reply: an array containing the rank and score of `member`. - * without using `WITHSCORE`, @integer-reply: the rank of `member`. -* If `member` does not exist in the sorted set or `key` does not exist: - * using `WITHSCORE`, @array-reply: `nil`. - * without using `WITHSCORE`, @bulk-string-reply: `nil`. - -Note that in RESP3 null and nullarray are the same, but in RESP2 they are not. - @examples ```cli diff --git a/commands/zscore.md b/commands/zscore.md index 8b1e74dd88..324019d940 100644 --- a/commands/zscore.md +++ b/commands/zscore.md @@ -3,11 +3,6 @@ Returns the score of `member` in the sorted set at `key`. If `member` does not exist in the sorted set, or `key` does not exist, `nil` is returned. -@return - -@bulk-string-reply: the score of `member` (a double precision floating point number), -represented as string. - @examples ```cli diff --git a/commands/zunion.md b/commands/zunion.md index d77d81f47c..f85bfd821a 100644 --- a/commands/zunion.md +++ b/commands/zunion.md @@ -3,11 +3,6 @@ sorted set, it is returned to the client. For a description of the `WEIGHTS` and `AGGREGATE` options, see `ZUNIONSTORE`. -@return - -@array-reply: the result of union (optionally with their scores, in case -the `WITHSCORES` option is given). - @examples ```cli diff --git a/commands/zunionstore.md b/commands/zunionstore.md index 49e2d506e9..efa2fbba55 100644 --- a/commands/zunionstore.md +++ b/commands/zunionstore.md @@ -21,11 +21,6 @@ the minimum or maximum score of an element across the inputs where it exists. If `destination` already exists, it is overwritten. -@return - -@integer-reply: the number of elements in the resulting sorted set at -`destination`. - @examples ```cli diff --git a/community/_index.md b/community/_index.md index 09e6949d5c..b67d2a2aaf 100644 --- a/community/_index.md +++ b/community/_index.md @@ -3,7 +3,7 @@ title: Community linkTitle: Community --- -Since 2009, the Redis open source project has inspired an enthusiastic and active community of users and contributors. We continue to be committed to fostering an open, welcoming, diverse, inclusive, and healthy community. +Since 2009, the Redis project has inspired an enthusiastic and active community of users and contributors. We continue to be committed to fostering an open, welcoming, diverse, inclusive, and healthy community. ## Code of Conduct @@ -29,29 +29,15 @@ For occasional updates on the new Redis releases, you can either [subscribe to t To keep up with the latest from Redis Inc., including news on Redis Cloud and Redis Stack, consider [following the Redis Twitter feed](https://twitter.com/redisinc). -## Project governance - -Redis has adopted a [light governance model](/docs/about/governance) led by individuals who have made significant contributions to Redis and demonstrated a long-term commitment to the project. - -Learn more about the project's governance and the Redis Core Team on the [Redis governance page](/docs/about/governance). - -## Conferences and meetups - -Redis regularly sponsors conferences and meetups. Recent conferences include: - -* [Redis Days 2022](https://redis.com/redisdays/) - -* [RedisConf 2021](https://redis.com/redisconf/) - -* [RedisConf 2020](https://www.youtube.com/c/Redisinc/playlists?view=50&sort=dd&shelf_id=4) - ## Contributing to Redis -There are many ways to contribute to Redis, starting with documentation all the way to changes to the open source Redis server. Here are a few ways you can get involved. +> Future releases of Redis will be dual-licensed under a source-available license. You can choose between the [Redis Source Available License 2.0 (RSALv2)](/docs/about/license) or the Server Side Public License v1 (SSPLv1). + +There are many ways to contribute to Redis, starting with documentation all the way to changes to the Redis server. Here are a few ways you can get involved. ### Contributing to docs -The [Redis docs](https://github.com/redis/redis-doc) are open source, and we'd love to incorporate your contributions. For small changes and typos, we recommend creating a pull request against [redis-doc repo](https://github.com/redis/redis-doc/pulls). +We welcome contributions to the [Redis docs](https://github.com/redis/redis-doc). For small changes and typos, we recommend creating a pull request against [redis-doc repo](https://github.com/redis/redis-doc/pulls). ### Reporting bugs @@ -61,8 +47,4 @@ For larger doc changes, we ask that you first create an issue describing your pr ### Client libraries -The Redis client libraries are nearly always open source and accepting of contributions. Consult the contribution guidelines for the library you're interested in. - -### Hacktoberfest - -Redis is participating in [Hacktoberfest 2022](/community/hacktoberfest/). +The Redis client libraries are nearly always open source and accepting of contributions. Consult the contribution guidelines for the library you're interested in. \ No newline at end of file diff --git a/docs/about/_index.md b/docs/about/_index.md index 4b80f25497..56dc574a12 100644 --- a/docs/about/_index.md +++ b/docs/about/_index.md @@ -2,14 +2,17 @@ title: Introduction to Redis linkTitle: "About" weight: 10 -description: Learn about the Redis open source project +description: Learn about Redis aliases: - /topics/introduction - /buzz --- -Redis is an open source (BSD licensed), in-memory __data structure store__ used as a database, cache, message broker, and streaming engine. Redis provides [data structures](/docs/data-types/) such as -[strings](/docs/data-types/strings/), [hashes](/docs/data-types/hashes/), [lists](/docs/data-types/lists/), [sets](/docs/data-types/sets/), [sorted sets](/docs/data-types/sorted-sets/) with range queries, [bitmaps](/docs/data-types/bitmaps/), [hyperloglogs](/docs/data-types/hyperloglogs/), [geospatial indexes](/docs/data-types/geospatial/), and [streams](/docs/data-types/streams/). Redis has built-in [replication](/topics/replication), [Lua scripting](/commands/eval), [LRU eviction](/docs/reference/eviction/), [transactions](/topics/transactions), and different levels of [on-disk persistence](/topics/persistence), and provides high availability via [Redis Sentinel](/topics/sentinel) and automatic partitioning with [Redis Cluster](/topics/cluster-tutorial). +Redis is an open source (BSD licensed), in-memory __data structure store__ used as a database, cache, message broker, and streaming engine. + +> Future releases of Redis will be dual-licensed under a source-available license. You can choose between the [Redis Source Available License 2.0 (RSALv2)](/docs/about/license) or the Server Side Public License v1 (SSPLv1). + +Redis provides [data structures](/docs/data-types/) such as [strings](/docs/data-types/strings/), [hashes](/docs/data-types/hashes/), [lists](/docs/data-types/lists/), [sets](/docs/data-types/sets/), [sorted sets](/docs/data-types/sorted-sets/) with range queries, [bitmaps](/docs/data-types/bitmaps/), [hyperloglogs](/docs/data-types/hyperloglogs/), [geospatial indexes](/docs/data-types/geospatial/), and [streams](/docs/data-types/streams/). Redis has built-in [replication](/topics/replication), [Lua scripting](/commands/eval), [LRU eviction](/docs/reference/eviction/), [transactions](/topics/transactions), and different levels of [on-disk persistence](/topics/persistence), and provides high availability via [Redis Sentinel](/topics/sentinel) and automatic partitioning with [Redis Cluster](/topics/cluster-tutorial). You can run __atomic operations__ on these types, like [appending to a string](/commands/append); @@ -40,4 +43,4 @@ Redis is written in **ANSI C** and works on most POSIX systems like Linux, \*BSD, and Mac OS X, without external dependencies. Linux and OS X are the two operating systems where Redis is developed and tested the most, and we **recommend using Linux for deployment**. Redis may work in Solaris-derived systems like SmartOS, but support is *best effort*. There is no official support for Windows builds. -
\ No newline at end of file +
diff --git a/docs/about/governance.md b/docs/about/governance.md deleted file mode 100644 index 879f109eb7..0000000000 --- a/docs/about/governance.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "Redis open source governance" -linkTitle: "Governance" -weight: 3 -description: > - Governance model for the Redis open source project -aliases: - - /topics/governance ---- - -From 2009-2020, Salvatore Sanfilippo built, led, and maintained the Redis open source project. During this time, Redis had no formal governance structure, operating primarily as a [BDFL](https://en.wikipedia.org/wiki/Benevolent_dictator_for_life)-style project. - -As Redis grew, matured, and expanded its user base, it became increasingly important to form a sustainable structure for its ongoing development and maintenance. Salvatore and the core Redis contributors wanted to ensure the project’s continuity and reflect its larger community. With this in mind, a new governance structure was adopted. - -## Current governance structure - -Starting on June 30, 2020, Redis adopted a _light governance_ model that matches the current size of the project and minimizes the changes from its earlier model. The governance model is intended to be a meritocracy, aiming to empower individuals who demonstrate a long-term commitment and make significant contributions. - -## The Redis core team - -Salvatore Sanfilippo named two successors to take over and lead the Redis project: Yossi Gottlieb ([yossigo](https://github.com/yossigo)) and Oran Agra ([oranagra](https://github.com/oranagra)) - -With the backing and blessing of Redis Ltd., we took this opportunity to create a more open, scalable, and community-driven “core team” structure to run the project. The core team consists of members selected based on demonstrated, long-term personal involvement and contributions. - -The current core team members are: - -* Project Lead: Yossi Gottlieb ([yossigo](https://github.com/yossigo)) from Redis Ltd. -* Project Lead: Oran Agra ([oranagra](https://github.com/oranagra)) from Redis Ltd. -* Community Lead: Itamar Haber ([itamarhaber](https://github.com/itamarhaber)) from Redis Ltd. -* Member: Zhao Zhao ([soloestoy](https://github.com/soloestoy)) from Alibaba -* Member: Madelyn Olson ([madolson](https://github.com/madolson)) from Amazon Web Services - -The Redis core team members serve the Redis open source project and community. They are expected to set a good example of behavior, culture, and tone in accordance with the adopted [Code of Conduct](https://www.contributor-covenant.org/). They should also consider and act upon the best interests of the project and the community in a way that is free from foreign or conflicting interests. - -The core team will be responsible for the Redis core project, which is the part of Redis that is hosted in the main Redis repository and is BSD licensed. It will also aim to maintain coordination and collaboration with other projects that make up the Redis ecosystem, including Redis clients, satellite projects, major middleware that relies on Redis, etc. - -#### Roles and responsibilities - -The core team has the following remit: - -* Managing the core Redis code and documentation -* Managing new Redis releases -* Maintaining a high-level technical direction/roadmap -* Providing a fast response, including fixes/patches, to address security vulnerabilities and other major issues -* Project governance decisions and changes -* Coordination of Redis core with the rest of the Redis ecosystem -* Managing the membership of the core team - -The core team aims to form and empower a community of contributors by further delegating tasks to individuals who demonstrate commitment, know-how, and skills. In particular, we hope to see greater community involvement in the following areas: - -* Support, troubleshooting, and bug fixes of reported issues -* Triage of contributions/pull requests - -#### Decision making - -* **Normal decisions** will be made by core team members based on a lazy consensus approach: each member may vote +1 (positive) or -1 (negative). A negative vote must include thorough reasoning and better yet, an alternative proposal. The core team will always attempt to reach a full consensus rather than a majority. Examples of normal decisions: - * Day-to-day approval of pull requests and closing issues - * Opening new issues for discussion -* **Major decisions** that have a significant impact on the Redis architecture, design, or philosophy as well as core-team structure or membership changes should preferably be determined by full consensus. If the team is not able to achieve a full consensus, a majority vote is required. Examples of major decisions: - * Fundamental changes to the Redis core - * Adding a new data structure - * Creating a new version of RESP (Redis Serialization Protocol) - * Changes that affect backward compatibility - * Adding or changing core team members -* Project leads have a right to veto major decisions - -#### Core team membership - -* The core team is not expected to serve for life, however, long-term participation is desired to provide stability and consistency in the Redis programming style and the community. -* If a core-team member whose work is funded by Redis Ltd. must be replaced, the replacement will be designated by Redis Ltd. after consultation with the remaining core-team members. -* If a core-team member not funded by Redis Ltd. will no longer participate, for whatever reason, the other team members will select a replacement. - -## Community forums and communications - -We want the Redis community to be as welcoming and inclusive as possible. To that end, we have adopted a [Code of Conduct](https://www.contributor-covenant.org/) that we ask all community members to read and observe. - -We encourage that all significant communications will be public, asynchronous, archived, and open for the community to actively participate in using the channels described [here](https://redis.io/community). The exception to that is sensitive security issues that require resolution prior to public disclosure. - -To contact the core team about sensitive matters, such as misconduct or security issues, please email [redis@redis.io](mailto:redis@redis.io). - -## New Redis repository and commits approval process - -The Redis core source repository is hosted under [https://github.com/redis/redis](https://github.com/redis/redis). Our target is to eventually host everything (the Redis core source and other ecosystem projects) under the Redis GitHub organization ([https://github.com/redis](https://github.com/redis)). Commits to the Redis source repository will require code review, approval of at least one core-team member who is not the author of the commit, and no objections. - -## Project and development updates - -Stay connected to the project and the community! For project and community updates, follow the project [channels](https://redis.io/community). Development announcements will be made via [the Redis mailing list](https://groups.google.com/forum/#!forum/redis-db). - -## Updates to these governance rules - -Any substantial changes to these rules will be treated as a major decision. Minor changes or ministerial corrections will be treated as normal decisions. diff --git a/docs/about/license.md b/docs/about/license.md index 31291c669e..6f78dd1f2a 100644 --- a/docs/about/license.md +++ b/docs/about/license.md @@ -10,76 +10,43 @@ aliases: --- -* Redis is **open source software** released under the terms of the **three clause BSD license**. Most of the Redis source code was written and is copyrighted by Salvatore Sanfilippo and Pieter Noordhuis. A list of other contributors can be found in the git history. +* Redis is source-available software, available under the terms of the RSALv2 and SSPLv1 licenses. Most of the Redis source code was written and is copyrighted by Salvatore Sanfilippo and Pieter Noordhuis. A list of other contributors can be found in the git history. The Redis trademark and logo are owned by Redis Ltd. and can be used in accordance with the [Redis Trademark Guidelines](https://redis.com/legal/trademark-guidelines/). * RedisInsight is licensed under the Server Side Public License (SSPL). -* Redis Stack Server, which combines open source Redis with Search and Query features, JSON, Time Series, and Probabilistic data structures is dual-licensed under the Redis Source Available License (RSALv2), as described below, and the [Server Side Public License](https://en.wikipedia.org/wiki/Server_Side_Public_License) (SSPL). For information about licensing per version, see [Versions and licenses](/docs/about/about-stack/#redis-stack-license). +* Redis Stack Server, which combines open source Redis with Search and Query features, JSON, Time Series, and Probabilistic data structures is dual-licensed under the Redis Source Available License (RSALv2), as described below, and the [Server Side Public License](https://redis.com/legal/server-side-public-license-sspl/) (SSPL). For information about licensing per version, see [Versions and licenses](/docs/about/about-stack/#redis-stack-license). -## Licences: - -### Three clause BSD license - -Every file in the Redis distribution, with the exceptions of third party files specified in the list below, contain the following license: - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -* Neither the name of Redis nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +## Licenses: ### REDIS SOURCE AVAILABLE LICENSE (RSAL) 2.0 - -_Last updated: November 15, 2022_ +Last updated: November 15, 2022 #### Acceptance By using the software, you agree to all of the terms and conditions below. - + #### Copyright License The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below. #### Limitations -You may not make the functionality of the software or a modified version available to third parties as a service, or distribute the software or a modified version in a manner that makes the functionality of the software available to third parties. -Making the functionality of the software or modified version available to third parties includes, without limitation, enabling third parties to interact with the functionality of the software or modified version in distributed form or remotely through a computer network, offering a product or service the value of which entirely or primarily derives from the value of the software or modified version, or offering a product or service that accomplishes for users the primary purpose of the software or modified version. +You may not make the functionality of the software or a modified version available to third parties as a service, or distribute the software or a modified version in a manner that makes the functionality of the software available to third parties. Making the functionality of the software or modified version available to third parties includes, without limitation, enabling third parties to interact with the functionality of the software or modified version in distributed form or remotely through a computer network, offering a product or service the value of which entirely or primarily derives from the value of the software or modified version, or offering a product or service that accomplishes for users the primary purpose of the software or modified version. You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law. - + #### Patents The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company. #### Notices -You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms. -If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software. +You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms. If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software. #### No Other Rights @@ -91,38 +58,38 @@ If you use the software in violation of these terms, such use is not licensed, a #### No Liability -_**As far as the law allows, the **software** comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.**_ +As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim. #### Definitions -The **licensor** is the entity offering these terms, and the software is the software the licensor makes available under these terms, including any portion of it. +The licensor is the entity offering these terms, and the software is the software the licensor makes available under these terms, including any portion of it. -To **modify** a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission other than making an exact copy. The resulting work is called a **modified version** of the earlier work. +To modify a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission other than making an exact copy. The resulting work is called a modified version of the earlier work. **you** refers to the individual or entity agreeing to these terms. -**your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. +**your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. -**your licenses** are all the licenses granted to you for the software under these terms. -use means anything you do with the software requiring one of your licenses. +**your licenses** are all the licenses granted to you for the software under these terms. -**trademark** means trademarks, service marks, and similar rights. +**use** means anything you do with the software requiring one of your licenses. +**trademark** means trademarks, service marks, and similar rights. -### Third-party files and licenses +#### Third-party files and licenses Redis uses source code from third parties. All this code contains a BSD or BSD-compatible license. The following is a list of third-party files and information about their copyright. -* Redis uses the [LHF compression library](http://oldhome.schmorp.de/marc/liblzf.html). LibLZF is copyright Marc Alexander Lehmann and is released under the terms of the **two-clause BSD license**. +* Redis uses the [LHF compression library](http://oldhome.schmorp.de/marc/liblzf.html). LibLZF is copyright Marc Alexander Lehmann and is released under the terms of the two-clause BSD license. -* Redis uses the `sha1.c` file that is copyright by Steve Reid and released under the **public domain**. This file is extremely popular and used among open source and proprietary code. +* Redis uses the sha1.c file that is copyright by Steve Reid and released under the public domain. This file is extremely popular and used among open source and proprietary code. -* When compiled on Linux, Redis uses the [Jemalloc allocator](https://github.com/jemalloc/jemalloc), which is copyrighted by Jason Evans, Mozilla Foundation, and Facebook, Inc and released under the **two-clause BSD license**. +* When compiled on Linux, Redis uses the [Jemalloc allocator](https://github.com/jemalloc/jemalloc), which is copyrighted by Jason Evans, Mozilla Foundation, and Facebook, Inc and released under the two-clause BSD license. -* Inside Jemalloc, the file `pprof` is copyrighted by Google Inc. and released under the **three-clause BSD license**. +* Inside Jemalloc, the file pprof is copyrighted by Google Inc. and released under the three-clause BSD license. -* Inside Jemalloc the files `inttypes.h`, `stdbool.h`, `stdint.h`, `strings.h` under the `msvc_compat` directory are copyright Alexander Chemeris and released under the **three-clause BSD license**. +* Inside Jemalloc the files inttypes.h, stdbool.h, stdint.h, strings.h under the msvc_compat directory are copyright Alexander Chemeris and released under the three-clause BSD license. -* The libraries **hiredis** and **linenoise** also included inside the Redis distribution are copyright Salvatore Sanfilippo and Pieter Noordhuis and released under the terms respectively of the **three-clause BSD license** and **two-clause BSD license**. \ No newline at end of file +* The libraries hiredis and linenoise also included inside the Redis distribution are copyright Salvatore Sanfilippo and Pieter Noordhuis and released under the terms respectively of the three-clause BSD license and two-clause BSD license. \ No newline at end of file diff --git a/docs/about/sponsors.md b/docs/about/sponsors.md deleted file mode 100644 index 1426a14509..0000000000 --- a/docs/about/sponsors.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "Redis sponsors" -linkTitle: "Sponsors" -weight: 4 -description: Current and former Redis sponsors -aliases: - - /topics/sponsors ---- - -From 2015 to 2020, Salvatore Sanfilippo's work on Redis was sponsored by [Redis Ltd.](https://redis.com) Since June 2020, Redis Ltd. has sponsored the [governance of Redis](/topics/governance). Redis Ltd. also sponsors the hosting and maintenance of [redis.io](https://redis.io). - -Past sponsorships: - -* The [Shuttleworth Foundation](https://en.wikipedia.org/wiki/Shuttleworth_Foundation) has donated 5000 USD to the Redis project in form of a flash grant. -* From May 2013 to June 2015, the work [Salvatore Sanfilippo](http://twitter.com/antirez) did to develop Redis was sponsored by [Pivotal](http://gopivotal.com). -* Before May 2013, the project was sponsored by VMware with the work of [Salvatore Sanfilippo](http://twitter.com/antirez) and [Pieter Noordhuis](http://twitter.com/pnoordhuis). -* [VMware](http://vmware.com) and later [Pivotal](http://pivotal.io) provided a 24 GB RAM workstation for Salvatore to run the Redis CI test and other long running tests. Later, Salvatore equipped the server with an SSD drive in order to test in the same hardware with rotating and flash drives. -* [Linode](https://linode.com), in January 2010, provided virtual machines for Redis testing in a virtualized environment. -* Slicehost, January 2010, provided Virtual Machines for Redis testing in a virtualized environment. -* [Citrusbyte](http://citrusbyte.com), in December 2009, contributed part of Virtual Memory implementation. -* [Hitmeister](http://www.hitmeister.de/), in December 2009, contributed part of Redis Cluster. -* [Engine Yard](http://engineyard.com), in December 2009, contributed blocking POP (BLPOP) and part of the Virtual Memory implementation. - -Also thanks to the following people or organizations that donated to the Project: - -* Emil Vladev -* [Brad Jasper](http://bradjasper.com/) -* [Mrkris](http://mrkris.com/) - -The Redis community is grateful to [Redis Ltd.](http://redis.com), [Pivotal](http://gopivotal.com), [VMware](http://vmware.com) and to the other companies and people who have donated to the Redis project. Thank you. - -## redis.io - -[Citrusbyte](https://citrusbyte.com) sponsored the creation of the official -Redis logo (designed by Carlos Prioglio) and -transferred its copyright to Salvatore Sanfilippo. - -They also sponsored the initial implementation of this site by -[Damian Janowski](https://twitter.com/djanowski) and [Michel -Martens](https://twitter.com/soveran). - -The `redis.io` domain was donated for a few years to the project by [I Want My -Name](https://iwantmyname.com). diff --git a/docs/connect/_index.md b/docs/connect/_index.md new file mode 100644 index 0000000000..a53d05d406 --- /dev/null +++ b/docs/connect/_index.md @@ -0,0 +1,39 @@ +--- +title: Connect to Redis +linkTitle: Connect +description: Learn how to use user interfaces and client libraries +weight: 35 +aliases: + - /docs/ui +--- + +You can connect to Redis in the following ways: + +* With the `redis-cli` command line tool +* Use RedisInsight as a graphical user interface +* Via a client library for your programming language + +## Redis command line interface + +The [Redis command line interface](/docs/connect/cli) (also known as `redis-cli`) is a terminal program that sends commands to and reads replies from the Redis server. It has the following two main modes: + +1. An interactive Read Eval Print Loop (REPL) mode where the user types Redis commands and receives replies. +2. A command mode where `redis-cli` is executed with additional arguments, and the reply is printed to the standard output. + +## RedisInsight + +[RedisInsight](/docs/connect/insight) combines a graphical user interface with Redis CLI to let you work with any Redis deployment. You can visually browse and interact with data, take advantage of diagnostic tools, learn by example, and much more. Best of all, RedisInsight is free. + +## Client libraries + +It's easy to connect your application to a Redis database. The official client libraries cover the following languages: + +* [C#/.NET](/docs/connect/clients/dotnet) +* [Go](/docs/connect/clients/go) +* [Java](/docs/connect/clients/java) +* [Node.js](/docs/connect/clients/nodejs) +* [Python](/docs/connect/clients/python) + +You can find a complete list of all client libraries, including the community-maintained ones, on the [clients page](/resources/clients/). + +
diff --git a/docs/ui/cli.md b/docs/connect/cli.md similarity index 99% rename from docs/ui/cli.md rename to docs/connect/cli.md index 936c0ec2e5..4a9a4b2e97 100644 --- a/docs/ui/cli.md +++ b/docs/connect/cli.md @@ -7,6 +7,7 @@ description: > aliases: - /docs/manual/cli - /docs/management/cli + - /docs/ui/cli --- In interactive mode, `redis-cli` has basic line editing capabilities to provide a familiar typing experience. @@ -121,6 +122,11 @@ option and the URI pattern `redis://user:password@host:port/dbnum`: $ redis-cli -u redis://LJenkins:p%40ssw0rd@redis-16379.hosted.com:16379/0 PING PONG +**NOTE:** +User, password and dbnum are optional. +For authentication without a username, use username `default`. +For TLS, use the scheme `rediss`. + ## SSL/TLS By default, `redis-cli` uses a plain TCP connection to connect to Redis. @@ -602,7 +608,7 @@ once you use the `MONITOR` command. All commands received by the active Redis in 1460100081.165665 [0 127.0.0.1:51706] "set" "shipment:8000736522714:status" "sorting" 1460100083.053365 [0 127.0.0.1:51707] "get" "shipment:8000736522714:status" -Note that it is possible to use to pipe the output, so you can monitor +Note that it is possible to pipe the output, so you can monitor for specific patterns using tools such as `grep`. ## Monitoring the latency of Redis instances diff --git a/docs/clients/_index.md b/docs/connect/clients/_index.md similarity index 82% rename from docs/clients/_index.md rename to docs/connect/clients/_index.md index a5d1b09dd0..d6e8fcff39 100644 --- a/docs/clients/_index.md +++ b/docs/connect/clients/_index.md @@ -1,11 +1,12 @@ --- -title: "Get started using Redis clients" -linkTitle: "Client quickstarts" -description: Get started using Redis clients. Select your library and connect your application to a Redis database. Then, try an example. +title: "Connect with Redis clients" +linkTitle: "Clients" +description: Connect your application to a Redis database and try an example weight: 45 aliases: - /docs/redis-clients - /docs/stack/get-started/clients/ + - /docs/clients/ --- Here, you will learn how to connect your application to a Redis database. If you're new to Redis, you might first want to [install Redis with Redis Stack and RedisInsight](/docs/getting-started/install-stack/). diff --git a/docs/clients/dotnet.md b/docs/connect/clients/dotnet.md similarity index 99% rename from docs/clients/dotnet.md rename to docs/connect/clients/dotnet.md index 4f62fd34b5..c38c7e3f3b 100644 --- a/docs/clients/dotnet.md +++ b/docs/connect/clients/dotnet.md @@ -3,7 +3,9 @@ title: "C#/.NET guide" linkTitle: "C#/.NET" description: Connect your .NET application to a Redis database weight: 1 - +aliases: + - /docs/clients/dotnet/ + - /docs/redis-clients/dotnet/ --- Install Redis and the Redis client, then connect your .NET application to a Redis database. diff --git a/docs/clients/go.md b/docs/connect/clients/go.md similarity index 99% rename from docs/clients/go.md rename to docs/connect/clients/go.md index cbbefe2b42..2b57e381a5 100644 --- a/docs/clients/go.md +++ b/docs/connect/clients/go.md @@ -3,7 +3,8 @@ title: "Go guide" linkTitle: "Go" description: Connect your Go application to a Redis database weight: 2 - +aliases: + - /docs/clients/go/ --- Install Redis and the Redis client, then connect your Go application to a Redis database. diff --git a/docs/connect/clients/java/_index.md b/docs/connect/clients/java/_index.md new file mode 100644 index 0000000000..21a90ffe4b --- /dev/null +++ b/docs/connect/clients/java/_index.md @@ -0,0 +1,11 @@ +--- +title: "Connect with Redis Java clients" +linkTitle: "Java" +description: Connect your application to a Redis database using Java and try an example +weight: 3 +--- + +You have two choices of Java clients that you can use with Redis: + +- Jedis, for synchronous applications. +- Lettuce, for asynchronous and reactive applications. diff --git a/docs/clients/java.md b/docs/connect/clients/java/jedis.md similarity index 50% rename from docs/clients/java.md rename to docs/connect/clients/java/jedis.md index ccde8b5b7e..7384fa6c77 100644 --- a/docs/clients/java.md +++ b/docs/connect/clients/java/jedis.md @@ -1,9 +1,11 @@ --- -title: "Java guide" -linkTitle: "Java" +title: "Jedis guide" +linkTitle: "Jedis" description: Connect your Java application to a Redis database -weight: 3 - +weight: 1 +aliases: + - /docs/clients/java/ + - /docs/redis-clients/java/ --- Install Redis and the Redis client, then connect your Java application to a Redis database. @@ -22,7 +24,7 @@ To include `Jedis` as a dependency in your application, edit the dependency file redis.clients jedis - 4.3.1 + 5.1.2 ``` @@ -34,7 +36,7 @@ To include `Jedis` as a dependency in your application, edit the dependency file } //... dependencies { - implementation 'redis.clients:jedis:4.3.1' + implementation 'redis.clients:jedis:5.1.2' //... } ``` @@ -185,104 +187,124 @@ public class Main { } ``` -### Example: Indexing and querying JSON documents - -Make sure that you have Redis Stack and `Jedis` installed. +### Production usage -Import dependencies and add a sample `User` class: +### Configuring Connection pool +As mentioned in the previous section, use `JedisPool` or `JedisPooled` to create a connection pool. +`JedisPooled`, added in Jedis version 4.0.0, provides capabilities similar to `JedisPool` but with a more straightforward API. +A connection pool holds a specified number of connections, creates more connections when necessary, and terminates them when they are no longer needed. -```java -import redis.clients.jedis.JedisPooled; -import redis.clients.jedis.search.*; -import redis.clients.jedis.search.aggr.*; -import redis.clients.jedis.search.schemafields.*; - -class User { - private String name; - private String email; - private int age; - private String city; - - public User(String name, String email, int age, String city) { - this.name = name; - this.email = email; - this.age = age; - this.city = city; - } +Here is a simplified connection lifecycle in a pool: - //... -} -``` +1. A connection is requested from the pool. +2. A connection is served: + - An idle connection is served when non-active connections are available, or + - A new connection is created when the number of connections is under `maxTotal`. +3. The connection becomes active. +4. The connection is released back to the pool. +5. The connection is marked as stale. +6. The connection is kept idle for `minEvictableIdleTime`. +7. The connection becomes evictable if the number of connections is greater than `minIdle`. +8. The connection is ready to be closed. -Connect to your Redis database with `JedisPooled`. +It's important to configure the connection pool correctly. +Use `GenericObjectPoolConfig` from [Apache Commons Pool2](https://commons.apache.org/proper/commons-pool/apidocs/org/apache/commons/pool2/impl/GenericObjectPoolConfig.html). ```java -JedisPooled jedis = new JedisPooled("localhost", 6379); +ConnectionPoolConfig poolConfig = new ConnectionPoolConfig(); +// maximum active connections in the pool, +// tune this according to your needs and application type +// default is 8 +poolConfig.setMaxTotal(8); + +// maximum idle connections in the pool, default is 8 +poolConfig.setMaxIdle(8); +// minimum idle connections in the pool, default 0 +poolConfig.setMinIdle(0); + +// Enables waiting for a connection to become available. +poolConfig.setBlockWhenExhausted(true); +// The maximum number of seconds to wait for a connection to become available +poolConfig.setMaxWait(Duration.ofSeconds(1)); + +// Enables sending a PING command periodically while the connection is idle. +poolConfig.setTestWhileIdle(true); +// controls the period between checks for idle connections in the pool +poolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(1)); + +// JedisPooled does all hard work on fetching and releasing connection to the pool +// to prevent connection starvation +JedisPooled jedis = new JedisPooled(poolConfig, "localhost", 6379); ``` -Let's create some test data to add to your database. - -```java -User user1 = new User("Paul John", "paul.john@example.com", 42, "London"); -User user2 = new User("Eden Zamir", "eden.zamir@example.com", 29, "Tel Aviv"); -User user3 = new User("Paul Zamir", "paul.zamir@example.com", 35, "Tel Aviv"); -``` +### Timeout -Create an index. In this example, all JSON documents with the key prefix `user:` are indexed. For more information, see [Query syntax](/docs/interact/search-and-query/query/). +To set a timeout for a connection, use the `JedisPooled` or `JedisPool` constructor with the `timeout` parameter, or use `JedisClientConfig` with the `socketTimeout` and `connectionTimeout` parameters: ```java -jedis.ftCreate("idx:users", - FTCreateParams.createParams() - .on(IndexDataType.JSON) - .addPrefix("user:"), - TextField.of("$.name").as("name"), - TagField.of("$.city").as("city"), - NumericField.of("$.age").as("age") +HostAndPort hostAndPort = new HostAndPort("localhost", 6379); + +JedisPooled jedisWithTimeout = new JedisPooled(hostAndPort, + DefaultJedisClientConfig.builder() + .socketTimeoutMillis(5000) // set timeout to 5 seconds + .connectionTimeoutMillis(5000) // set connection timeout to 5 seconds + .build(), + poolConfig ); ``` -Use `JSON.SET` to set each user value at the specified path. +### Exception handling +The Jedis Exception Hierarchy is rooted on `JedisException`, which implements `RuntimeException`, and are therefore all unchecked exceptions. -```java -jedis.jsonSetWithEscape("user:1", user1); -jedis.jsonSetWithEscape("user:2", user2); -jedis.jsonSetWithEscape("user:3", user3); +``` +JedisException +├── JedisDataException +│ ├── JedisRedirectionException +│ │ ├── JedisMovedDataException +│ │ └── JedisAskDataException +│ ├── AbortedTransactionException +│ ├── JedisAccessControlException +│ └── JedisNoScriptException +├── JedisClusterException +│ ├── JedisClusterOperationException +│ ├── JedisConnectionException +│ └── JedisValidationException +└── InvalidURIException ``` -Let's find user `Paul` and filter the results by age. +#### General Exceptions +In general, Jedis can throw the following exceptions while executing commands: -```java -var query = new Query("Paul @age:[30 40]"); -var result = jedis.ftSearch("idx:users", query).getDocuments(); -System.out.println(result); -// Prints: [id:user:3, score: 1.0, payload:null, properties:[$={"name":"Paul Zamir","email":"paul.zamir@example.com","age":35,"city":"Tel Aviv"}]] -``` +- `JedisConnectionException` - when the connection to Redis is lost or closed unexpectedly. Configure failover to handle this exception automatically with Resilience4J and the built-in Jedis failover mechanism. +- `JedisAccessControlException` - when the user does not have the permission to execute the command or the user ID and/or password are incorrect. +- `JedisDataException` - when there is a problem with the data being sent to or received from the Redis server. Usually, the error message will contain more information about the failed command. +- `JedisException` - this exception is a catch-all exception that can be thrown for any other unexpected errors. -Return only the `city` field. +Conditions when `JedisException` can be thrown: +- Bad return from a health check with the `PING` command +- Failure during SHUTDOWN +- Pub/Sub failure when issuing commands (disconnect) +- Any unknown server messages +- Sentinel: can connect to sentinel but master is not monitored or all Sentinels are down. +- MULTI or DISCARD command failed +- Shard commands key hash check failed or no Reachable Shards +- Retry deadline exceeded/number of attempts (Retry Command Executor) +- POOL - pool exhausted, error adding idle objects, returning broken resources to the pool -```java -var city_query = new Query("Paul @age:[30 40]"); -var city_result = jedis.ftSearch("idx:users", city_query.returnFields("city")).getDocuments(); -System.out.println(city_result); -// Prints: [id:user:3, score: 1.0, payload:null, properties:[city=Tel Aviv]] -``` +All the Jedis exceptions are runtime exceptions and in most cases irrecoverable, so in general bubble up to the API capturing the error message. -Count all users in the same city. +## DNS cache and Redis -```java -AggregationBuilder ab = new AggregationBuilder("*") - .groupBy("@city", Reducers.count().as("count")); -AggregationResult ar = jedis.ftAggregate("idx:users", ab); +When you connect to a Redis with multiple endpoints, such as [Redis Enterprise Active-Active](https://redis.com/redis-enterprise/technology/active-active-geo-distribution/), it's recommended to disable the JVM's DNS cache to load-balance requests across multiple endpoints. -for (int idx=0; idx < ar.getTotalResults(); idx++) { - System.out.println(ar.getRow(idx).getString("city") + " - " + ar.getRow(idx).getString("count")); -} -// Prints: -// London - 1 -// Tel Aviv - 2 +You can do this in your application's code with the following snippet: +```java +java.security.Security.setProperty("networkaddress.cache.ttl","0"); +java.security.Security.setProperty("networkaddress.cache.negative.ttl", "0"); ``` ### Learn more * [Jedis API reference](https://www.javadoc.io/doc/redis.clients/jedis/latest/index.html) +* [Failover with Jedis](https://github.com/redis/jedis/blob/master/docs/failover.md) * [GitHub](https://github.com/redis/jedis) diff --git a/docs/connect/clients/java/lettuce.md b/docs/connect/clients/java/lettuce.md new file mode 100644 index 0000000000..47b182c5c6 --- /dev/null +++ b/docs/connect/clients/java/lettuce.md @@ -0,0 +1,246 @@ +--- +title: "Lettuce guide" +linkTitle: "Lettuce" +description: Connect your Lettuce application to a Redis database +weight: 2 +--- + +Install Redis and the Redis client, then connect your Lettuce application to a Redis database. + +## Lettuce + +Lettuce offers a powerful and efficient way to interact with Redis through its asynchronous and reactive APIs. By leveraging these capabilities, you can build high-performance, scalable Java applications that make optimal use of Redis's capabilities. + +## Install + +To include Lettuce as a dependency in your application, edit the appropriate dependency file as shown below. + +If you use Maven, add the following dependency to your `pom.xml`: + +```xml + + io.lettuce + lettuce-core + 6.3.2.RELEASE + +``` + +If you use Gradle, include this line in your `build.gradle` file: + +``` +dependencies { + compile 'io.lettuce:lettuce-core:6.3.2.RELEASE +} +``` + +If you wish to use the JAR files directly, download the latest Lettuce and, optionally, Apache Commons Pool2 JAR files from Maven Central or any other Maven repository. + +To build from source, see the instructions on the [Lettuce source code GitHub repo](https://github.com/lettuce-io/lettuce-core). + +## Connect + +Start by creating a connection to your Redis server. There are many ways to achieve this using Lettuce. Here are a few. + +### Asynchronous connection + +```java +package org.example; +import java.util.*; +import java.util.concurrent.ExecutionException; + +import io.lettuce.core.*; +import io.lettuce.core.api.async.RedisAsyncCommands; +import io.lettuce.core.api.StatefulRedisConnection; + +public class Async { + public static void main(String[] args) { + RedisClient redisClient = RedisClient.create("redis://localhost:6379"); + + try (StatefulRedisConnection connection = redisClient.connect()) { + RedisAsyncCommands asyncCommands = connection.async(); + + // Asynchronously store & retrieve a simple string + asyncCommands.set("foo", "bar").get(); + System.out.println(asyncCommands.get("foo").get()); // prints bar + + // Asynchronously store key-value pairs in a hash directly + Map hash = new HashMap<>(); + hash.put("name", "John"); + hash.put("surname", "Smith"); + hash.put("company", "Redis"); + hash.put("age", "29"); + asyncCommands.hset("user-session:123", hash).get(); + + System.out.println(asyncCommands.hgetall("user-session:123").get()); + // Prints: {name=John, surname=Smith, company=Redis, age=29} + } catch (ExecutionException | InterruptedException e) { + throw new RuntimeException(e); + } finally { + redisClient.shutdown(); + } + } +} +``` + +Learn more about asynchronous Lettuce API in [the reference guide](https://lettuce.io/core/release/reference/index.html#asynchronous-api). + +### Reactive connection + +```java +package org.example; +import java.util.*; +import io.lettuce.core.*; +import io.lettuce.core.api.reactive.RedisReactiveCommands; +import io.lettuce.core.api.StatefulRedisConnection; + +public class Main { + public static void main(String[] args) { + RedisClient redisClient = RedisClient.create("redis://localhost:6379"); + + try (StatefulRedisConnection connection = redisClient.connect()) { + RedisReactiveCommands reactiveCommands = connection.reactive(); + + // Reactively store & retrieve a simple string + reactiveCommands.set("foo", "bar").block(); + reactiveCommands.get("foo").doOnNext(System.out::println).block(); // prints bar + + // Reactively store key-value pairs in a hash directly + Map hash = new HashMap<>(); + hash.put("name", "John"); + hash.put("surname", "Smith"); + hash.put("company", "Redis"); + hash.put("age", "29"); + + reactiveCommands.hset("user-session:124", hash).then( + reactiveCommands.hgetall("user-session:124") + .collectMap(KeyValue::getKey, KeyValue::getValue).doOnNext(System.out::println)) + .block(); + // Prints: {surname=Smith, name=John, company=Redis, age=29} + + } finally { + redisClient.shutdown(); + } + } +} +``` + +Learn more about reactive Lettuce API in [the reference guide](https://lettuce.io/core/release/reference/index.html#reactive-api). + +### Redis Cluster connection + +```java +import io.lettuce.core.RedisURI; +import io.lettuce.core.cluster.RedisClusterClient; +import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; +import io.lettuce.core.cluster.api.async.RedisAdvancedClusterAsyncCommands; + +// ... + +RedisURI redisUri = RedisURI.Builder.redis("localhost").withPassword("authentication").build(); + +RedisClusterClient clusterClient = RedisClusterClient.create(redisUri); +StatefulRedisClusterConnection connection = clusterClient.connect(); +RedisAdvancedClusterAsyncCommands commands = connection.async(); + +// ... + +connection.close(); +clusterClient.shutdown(); +``` + +### TLS connection + +When you deploy your application, use TLS and follow the [Redis security guidelines](/docs/management/security/). + +```java +RedisURI redisUri = RedisURI.Builder.redis("localhost") + .withSsl(true) + .withPassword("secret!") // use your Redis password + .build(); + +RedisClient client = RedisClient.create(redisUri); +``` + + + +## Connection Management in Lettuce + +Lettuce uses `ClientResources` for efficient management of shared resources like event loop groups and thread pools. +For connection pooling, Lettuce leverages `RedisClient` or `RedisClusterClient`, which can handle multiple concurrent connections efficiently. + +A typical approach with Lettuce is to create a single `RedisClient` instance and reuse it to establish connections to your Redis server(s). +These connections are multiplexed; that is, multiple commands can be run concurrently over a single or a small set of connections, making explicit pooling less critical. + +Lettuce provides pool config to be used with Lettuce asynchronous connection methods. + + +```java +package org.example; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisURI; +import io.lettuce.core.TransactionResult; +import io.lettuce.core.api.StatefulRedisConnection; +import io.lettuce.core.api.async.RedisAsyncCommands; +import io.lettuce.core.codec.StringCodec; +import io.lettuce.core.support.*; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +public class Pool { + public static void main(String[] args) { + RedisClient client = RedisClient.create(); + + String host = "localhost"; + int port = 6379; + + CompletionStage>> poolFuture + = AsyncConnectionPoolSupport.createBoundedObjectPoolAsync( + () -> client.connectAsync(StringCodec.UTF8, RedisURI.create(host, port)), + BoundedPoolConfig.create()); + + // await poolFuture initialization to avoid NoSuchElementException: Pool exhausted when starting your application + AsyncPool> pool = poolFuture.toCompletableFuture() + .join(); + + // execute work + CompletableFuture transactionResult = pool.acquire() + .thenCompose(connection -> { + + RedisAsyncCommands async = connection.async(); + + async.multi(); + async.set("key", "value"); + async.set("key2", "value2"); + System.out.println("Executed commands in pipeline"); + return async.exec().whenComplete((s, throwable) -> pool.release(connection)); + }); + transactionResult.join(); + + // terminating + pool.closeAsync(); + + // after pool completion + client.shutdownAsync(); + } +} +``` + +In this setup, `LettuceConnectionFactory` is a custom class you would need to implement, adhering to Apache Commons Pool's `PooledObjectFactory` interface, to manage lifecycle events of pooled `StatefulRedisConnection` objects. + +## DNS cache and Redis + +When you connect to a Redis database with multiple endpoints, such as Redis Enterprise Active-Active, it's recommended to disable the JVM's DNS cache to load-balance requests across multiple endpoints. + +You can do this in your application's code with the following snippet: + +```java +java.security.Security.setProperty("networkaddress.cache.ttl","0"); +java.security.Security.setProperty("networkaddress.cache.negative.ttl", "0"); +``` + +## Learn more + +- [Lettuce reference documentation](https://lettuce.io/docs/) +- [Redis commands](https://redis.io/commands) +- [Project Reactor](https://projectreactor.io/) \ No newline at end of file diff --git a/docs/clients/nodejs.md b/docs/connect/clients/nodejs.md similarity index 54% rename from docs/clients/nodejs.md rename to docs/connect/clients/nodejs.md index 17faa6d7d1..4c7aa13c0f 100644 --- a/docs/clients/nodejs.md +++ b/docs/connect/clients/nodejs.md @@ -3,7 +3,9 @@ title: "Node.js guide" linkTitle: "Node.js" description: Connect your Node.js application to a Redis database weight: 4 - +aliases: + - /docs/clients/nodejs/ + - /docs/redis-clients/nodejs/ --- Install Redis and the Redis client, then connect your Node.js application to a Redis database. @@ -134,166 +136,77 @@ await client.disconnect(); You can also use discrete parameters and UNIX sockets. Details can be found in the [client configuration guide](https://github.com/redis/node-redis/blob/master/docs/client-configuration.md). -### Example: Indexing and querying JSON documents +### Production usage -Make sure that you have Redis Stack and `node-redis` installed. Import dependencies: +#### Handling errors +Node-Redis provides [multiple events to handle various scenarios](https://github.com/redis/node-redis?tab=readme-ov-file#events), among which the most critical is the `error` event. -```js -import {AggregateSteps, AggregateGroupByReducers, createClient, SchemaFieldTypes} from 'redis'; -const client = createClient(); -await client.connect(); -``` +This event is triggered whenever an error occurs within the client. -Create an index. +It is crucial to listen for error events. -```js -try { - await client.ft.create('idx:users', { - '$.name': { - type: SchemaFieldTypes.TEXT, - SORTABLE: true - }, - '$.city': { - type: SchemaFieldTypes.TEXT, - AS: 'city' - }, - '$.age': { - type: SchemaFieldTypes.NUMERIC, - AS: 'age' - } - }, { - ON: 'JSON', - PREFIX: 'user:' - }); -} catch (e) { - if (e.message === 'Index already exists') { - console.log('Index exists already, skipped creation.'); - } else { - // Something went wrong, perhaps RediSearch isn't installed... - console.error(e); - process.exit(1); - } -} -``` -Create JSON documents to add to your database. +If a client does not register at least one error listener and an error occurs, the system will throw that error, potentially causing the Node.js process to exit unexpectedly. +See [the EventEmitter docs](https://nodejs.org/api/events.html#events_error_events) for more details. -```js -await Promise.all([ - client.json.set('user:1', '$', { - "name": "Paul John", - "email": "paul.john@example.com", - "age": 42, - "city": "London" - }), - client.json.set('user:2', '$', { - "name": "Eden Zamir", - "email": "eden.zamir@example.com", - "age": 29, - "city": "Tel Aviv" - }), - client.json.set('user:3', '$', { - "name": "Paul Zamir", - "email": "paul.zamir@example.com", - "age": 35, - "city": "Tel Aviv" - }), -]); +```typescript +const client = createClient({ + // ... client options +}); +// Always ensure there's a listener for errors in the client to prevent process crashes due to unhandled errors +client.on('error', error => { + console.error(`Redis client error:`, error); +}); ``` -Let's find user 'Paul` and filter the results by age. -```js -let result = await client.ft.search( - 'idx:users', - 'Paul @age:[30 40]' -); -console.log(JSON.stringify(result, null, 2)); -/* -{ - "total": 1, - "documents": [ - { - "id": "user:3", - "value": { - "name": "Paul Zamir", - "email": "paul.zamir@example.com", - "age": 35, - "city": "Tel Aviv" - } - } - ] -} - */ -``` +#### Handling reconnections -Return only the city field. +If network issues or other problems unexpectedly close the socket, the client will reject all commands already sent, since the server might have already executed them. +The rest of the pending commands will remain queued in memory until a new socket is established. +This behaviour is controlled by the `enableOfflineQueue` option, which is enabled by default. -```js -result = await client.ft.search( - 'idx:users', - 'Paul @age:[30 40]', - { - RETURN: ['$.city'] - } -); -console.log(JSON.stringify(result, null, 2)); +The client uses `reconnectStrategy` to decide when to attempt to reconnect. +The default strategy is to calculate the delay before each attempt based on the attempt number `Math.min(retries * 50, 500)`. You can customize this strategy by passing a supported value to `reconnectStrategy` option: -/* -{ - "total": 1, - "documents": [ - { - "id": "user:3", - "value": { - "$.city": "Tel Aviv" - } + +1. Define a callback `(retries: number, cause: Error) => false | number | Error` **(recommended)** +```typescript +const client = createClient({ + socket: { + reconnectStrategy: function(retries) { + if (retries > 20) { + console.log("Too many attempts to reconnect. Redis connection was terminated"); + return new Error("Too many retries."); + } else { + return retries * 500; + } } - ] -} - */ + } +}); +client.on('error', error => console.error('Redis client error:', error)); ``` - -Count all users in the same city. +In the provided reconnection strategy callback, the client attempts to reconnect up to 20 times with a delay of `retries * 500` milliseconds between attempts. +After approximately two minutes, the client logs an error message and terminates the connection if the maximum retry limit is exceeded. -```js -result = await client.ft.aggregate('idx:users', '*', { - STEPS: [ - { - type: AggregateSteps.GROUPBY, - properties: ['@city'], - REDUCE: [ - { - type: AggregateGroupByReducers.COUNT, - AS: 'count' - } - ] - } - ] -}) -console.log(JSON.stringify(result, null, 2)); -/* -{ - "total": 2, - "results": [ - { - "city": "London", - "count": "1" - }, - { - "city": "Tel Aviv", - "count": "2" - } - ] -} - */ +2. Use a numerical value to set a fixed delay in milliseconds. +3. Use `false` to disable reconnection attempts. This option should only be used for testing purposes. + +#### Timeout -await client.quit(); +To set a timeout for a connection, use the `connectTimeout` option: +```typescript +const client = createClient({ + // setting a 10-second timeout + connectTimeout: 10000 // in milliseconds +}); +client.on('error', error => console.error('Redis client error:', error)); ``` ### Learn more +* [Node-Redis Configuration Options](https://github.com/redis/node-redis/blob/master/docs/client-configuration.md) * [Redis commands](https://redis.js.org/#node-redis-usage-redis-commands) * [Programmability](https://redis.js.org/#node-redis-usage-programmability) * [Clustering](https://redis.js.org/#node-redis-usage-clustering) diff --git a/docs/clients/python.md b/docs/connect/clients/python.md similarity index 91% rename from docs/clients/python.md rename to docs/connect/clients/python.md index 1a7610e3b6..7c0e5e87aa 100644 --- a/docs/clients/python.md +++ b/docs/connect/clients/python.md @@ -3,7 +3,9 @@ title: "Python guide" linkTitle: "Python" description: Connect your Python application to a Redis database weight: 5 - +aliases: + - /docs/clients/python/ + - /docs/redis-clients/python/ --- Install Redis and the Redis client, then connect your Python application to a Redis database. @@ -24,6 +26,10 @@ pip install redis For faster performance, install Redis with [`hiredis`](https://github.com/redis/hiredis) support. This provides a compiled response parser, and for most cases requires zero code changes. By default, if `hiredis` >= 1.0 is available, `redis-py` attempts to use it for response parsing. +{{% alert title="Note" %}} +The Python `distutils` packaging scheme is no longer part of Python 3.12 and greater. If you're having difficulties getting `redis-py` installed in a Python 3.12 environment, consider updating to a recent release of `redis-py`. +{{% /alert %}} + ```bash pip install redis[hiredis] ``` diff --git a/docs/data-types/_index.md b/docs/data-types/_index.md index 0d31ff18e3..ca95521d16 100644 --- a/docs/data-types/_index.md +++ b/docs/data-types/_index.md @@ -1,6 +1,6 @@ --- -title: "Redis data types" -linkTitle: "Data types" +title: "Understand Redis data types" +linkTitle: "Understand data types" description: Overview of data types supported by Redis weight: 35 aliases: diff --git a/docs/data-types/bitfields.md b/docs/data-types/bitfields.md index fb74fc5d1f..0f693c2277 100644 --- a/docs/data-types/bitfields.md +++ b/docs/data-types/bitfields.md @@ -21,37 +21,25 @@ Bitfields support atomic read, write and increment operations, making them a goo ## Examples -Suppose you're keeping track of activity in an online game. -You want to maintain two crucial metrics for each player: the total amount of gold and the number of monsters slain. -Because your game is highly addictive, these counters should be at least 32 bits wide. +## Example -You can represent these counters with one bitfield per player. +Suppose you want to maintain two metrics for various bicycles: the current price and the number of owners over time. You can represent these counters with a 32-bit wide bitfield per for each bike. -* New players start the tutorial with 1000 gold (counter in offset 0). -``` -> BITFIELD player:1:stats SET u32 #0 1000 -1) (integer) 0 -``` +* Bike 1 initially costs 1,000 (counter in offset 0) and has never had an owner. After being sold, it's now considered used and the price instantly drops to reflect its new condition, and it now has an owner (offset 1). After quite some time, the bike becomes a classic. The original owner sells it for a profit, so the price goes up and the number of owners does as well.Finally, you can look at the bike's current price and number of owners. -* After killing the goblin holding the prince captive, add the 50 gold earned and increment the "slain" counter (offset 1). -``` -> BITFIELD player:1:stats INCRBY u32 #0 50 INCRBY u32 #1 1 -1) (integer) 1050 -2) (integer) 1 -``` - -* Pay the blacksmith 999 gold to buy a legendary rusty dagger. -``` -> BITFIELD player:1:stats INCRBY u32 #0 -999 -1) (integer) 51 -``` - -* Read the player's stats: -``` -> BITFIELD player:1:stats GET u32 #0 GET u32 #1 -1) (integer) 51 +{{< clients-example bitfield_tutorial bf >}} +> BITFIELD bike:1:stats SET u32 #0 1000 +1) (integer) 0 +> BITFIELD bike:1:stats INCRBY u32 #0 -50 INCRBY u32 #1 1 +1) (integer) 950 2) (integer) 1 -``` +> BITFIELD bike:1:stats INCRBY u32 #0 500 INCRBY u32 #1 1 +1) (integer) 1450 +2) (integer) 2 +> BITFIELD bike:1:stats GET u32 #0 GET u32 #1 +1) (integer) 1450 +2) (integer) 2 +{{< /clients-example >}} ## Performance diff --git a/docs/data-types/bitmaps.md b/docs/data-types/bitmaps.md index 0d45d4fc67..d71ea742f1 100644 --- a/docs/data-types/bitmaps.md +++ b/docs/data-types/bitmaps.md @@ -1,4 +1,4 @@ ---- +--- title: "Redis bitmaps" linkTitle: "Bitmaps" weight: 120 @@ -21,37 +21,30 @@ Some examples of bitmap use cases include: * `SETBIT` sets a bit at the provided offset to 0 or 1. * `GETBIT` returns the value of a bit at a given offset. -* `BITOP` lets you perform bitwise operations against one or more strings. See the [complete list of bitmap commands](https://redis.io/commands/?group=bitmap). -## Examples +## Example -Suppose you have 1000 sensors deployed in the field, labeled 0-999. -You want to quickly determine whether a given sensor has pinged the server within the hour. +Suppose you have 1000 cyclists racing through the country-side, with sensors on their bikes labeled 0-999. +You want to quickly determine whether a given sensor has pinged a tracking server within the hour to check in on a rider. You can represent this scenario using a bitmap whose key references the current hour. -* Sensor 123 pings the server on January 1, 2024 within the 00:00 hour. -``` +* Rider 123 pings the server on January 1, 2024 within the 00:00 hour. You can then confirm that rider 123 pinged the server. You can also check to see if rider 456 has pinged the server for that same hour. + +{{< clients-example bitmap_tutorial ping >}} > SETBIT pings:2024-01-01-00:00 123 1 (integer) 0 -``` - -* Did sensor 123 ping the server on January 1, 2024 within the 00:00 hour? -``` > GETBIT pings:2024-01-01-00:00 123 1 -``` - -* What about sensor 456? -``` > GETBIT pings:2024-01-01-00:00 456 0 -``` +{{< /clients-example >}} +## Bit Operations Bit operations are divided into two groups: constant-time single bit operations, like setting a bit to 1 or 0, or getting its value, and @@ -64,15 +57,6 @@ where different users are represented by incremental user IDs, it is possible to remember a single bit information (for example, knowing whether a user wants to receive a newsletter) of 4 billion users using just 512 MB of memory. -Bits are set and retrieved using the `SETBIT` and `GETBIT` commands: - - > setbit key 10 1 - (integer) 0 - > getbit key 10 - (integer) 1 - > getbit key 11 - (integer) 0 - The `SETBIT` command takes as its first argument the bit number, and as its second argument the value to set the bit to, which is 1 or 0. The command automatically enlarges the string if the addressed bit is outside the @@ -89,15 +73,12 @@ There are three commands operating on group of bits: 3. `BITPOS` finds the first bit having the specified value of 0 or 1. Both `BITPOS` and `BITCOUNT` are able to operate with byte ranges of the -string, instead of running for the whole length of the string. The following -is a trivial example of `BITCOUNT` call: - - > setbit key 0 1 - (integer) 0 - > setbit key 100 1 - (integer) 0 - > bitcount key - (integer) 2 +string, instead of running for the whole length of the string. We can trivially see the number of bits that have been set in a bitmap. + +{{< clients-example bitmap_tutorial bitcount >}} +> BITCOUNT pings:2024-01-01-00:00 +(integer) 1 +{{< /clients-example >}} For example imagine you want to know the longest streak of daily visits of your web site users. You start counting days starting from zero, that is the diff --git a/docs/data-types/hashes.md b/docs/data-types/hashes.md index 2409955a13..68f9825e9d 100644 --- a/docs/data-types/hashes.md +++ b/docs/data-types/hashes.md @@ -10,13 +10,13 @@ Redis hashes are record types structured as collections of field-value pairs. You can use hashes to represent basic objects and to store groupings of counters, among other things. {{< clients-example hash_tutorial set_get_all >}} -> hset bike:1 model Deimos brand Ergonom type 'Enduro bikes' price 4972 +> HSET bike:1 model Deimos brand Ergonom type 'Enduro bikes' price 4972 (integer) 4 -> hget bike:1 model +> HGET bike:1 model "Deimos" -> hget bike:1 price +> HGET bike:1 price "4972" -> hgetall bike:1 +> HGETALL bike:1 1) "model" 2) "Deimos" 3) "brand" @@ -36,7 +36,7 @@ The command `HSET` sets multiple fields of the hash, while `HGET` retrieves a single field. `HMGET` is similar to `HGET` but returns an array of values: {{< clients-example hash_tutorial hmget >}} -> hmget bike:1 model price no-such-field +> HMGET bike:1 model price no-such-field 1) "Deimos" 2) "4972" 3) (nil) @@ -46,9 +46,9 @@ There are commands that are able to perform operations on individual fields as well, like `HINCRBY`: {{< clients-example hash_tutorial hincrby >}} -> hincrby bike:1 price 100 +> HINCRBY bike:1 price 100 (integer) 5072 -> hincrby bike:1 price -100 +> HINCRBY bike:1 price -100 (integer) 4972 {{< /clients-example >}} diff --git a/docs/data-types/lists.md b/docs/data-types/lists.md index a91cd40c40..f2275e2332 100644 --- a/docs/data-types/lists.md +++ b/docs/data-types/lists.md @@ -293,7 +293,7 @@ This is an example of a `BRPOP` call we could use in the worker: {{< clients-example list_tutorial brpop >}} > RPUSH bikes:repairs bike:1 bike:2 -(integer) 5 +(integer) 2 > BRPOP bikes:repairs 1 1) "bikes:repairs" 2) "bike:2" @@ -305,7 +305,7 @@ This is an example of a `BRPOP` call we could use in the worker: (2.01s) {{< /clients-example >}} -It means: "wait for elements in the list `tasks`, but return if after 5 seconds +It means: "wait for elements in the list `bikes:repairs`, but return if after 1 second no element is available". Note that you can use 0 as timeout to wait for elements forever, and you can @@ -346,7 +346,7 @@ Examples of rule 1: {{< clients-example list_tutorial rule_1 >}} > DEL new_bikes -(integer) 1 +(integer) 0 > LPUSH new_bikes bike:1 bike:2 bike:3 (integer) 3 {{< /clients-example >}} diff --git a/docs/data-types/probabilistic/hyperloglogs.md b/docs/data-types/probabilistic/hyperloglogs.md index 1f00455e74..89bbd11a38 100644 --- a/docs/data-types/probabilistic/hyperloglogs.md +++ b/docs/data-types/probabilistic/hyperloglogs.md @@ -1,4 +1,4 @@ ---- +--- title: "HyperLogLog" linkTitle: "HyperLogLog" weight: 1 @@ -37,12 +37,20 @@ only contains a state that does not include actual elements, the API is the same: * Every time you see a new element, you add it to the count with `PFADD`. -* Every time you want to retrieve the current approximation of the unique elements *added* with `PFADD` so far, you use the `PFCOUNT`. +* When you want to retrieve the current approximation of unique elements added using the `PFADD` command, you can use the `PFCOUNT` command. If you need to merge two different HLLs, the `PFMERGE` command is available. Since HLLs provide approximate counts of unique elements, the result of the merge will give you an approximation of the number of unique elements across both source HLLs. - > pfadd hll a b c d - (integer) 1 - > pfcount hll - (integer) 4 +{{< clients-example hll_tutorial pfadd >}} +> PFADD bikes Hyperion Deimos Phoebe Quaoar +(integer) 1 +> PFCOUNT bikes +(integer) 4 +> PFADD commuter_bikes Salacia Mimas Quaoar +(integer) 1 +> PFMERGE all_bikes bikes commuter_bikes +OK +> PFCOUNT all_bikes +(integer) 6 +{{< /clients-example >}} Some examples of use cases for this data structure is counting unique queries performed by users in a search form every day, number of unique visitors to a web page and other similar cases. @@ -68,25 +76,6 @@ Storing the IP address or any other kind of personal identifier is against the l One HyperLogLog is created per page (video/song) per period, and every IP/identifier is added to it on every visit. - -## Examples - -* Add some items to the HyperLogLog: -``` -> PFADD members 123 -(integer) 1 -> PFADD members 500 -(integer) 1 -> PFADD members 12 -(integer) 1 -``` - -* Estimate the number of members in the set: -``` -> PFCOUNT members -(integer) 3 -``` - ## Basic commands * `PFADD` adds an item to a HyperLogLog. @@ -108,3 +97,4 @@ The HyperLogLog can estimate the cardinality of sets with up to 18,446,744,073,7 * [Redis new data structure: the HyperLogLog](http://antirez.com/news/75) has a lot of details about the data structure and its implementation in Redis. * [Redis HyperLogLog Explained](https://www.youtube.com/watch?v=MunL8nnwscQ) shows you how to use Redis HyperLogLog data structures to build a traffic heat map. + diff --git a/docs/data-types/sets.md b/docs/data-types/sets.md index 6a71637983..f4f51f5e2f 100644 --- a/docs/data-types/sets.md +++ b/docs/data-types/sets.md @@ -141,7 +141,7 @@ set without removing it using the `SRANDMEMBER` command: {{< clients-example sets_tutorial srem >}} > SADD bikes:racing:france bike:1 bike:2 bike:3 bike:4 bike:5 -(integer) 3 +(integer) 5 > SREM bikes:racing:france bike:1 (integer) 1 > SPOP bikes:racing:france diff --git a/docs/data-types/sorted-sets.md b/docs/data-types/sorted-sets.md index a43fdbb0b8..9351e2a09c 100644 --- a/docs/data-types/sorted-sets.md +++ b/docs/data-types/sorted-sets.md @@ -1,4 +1,4 @@ ---- +--- title: "Redis sorted sets" linkTitle: "Sorted sets" weight: 50 @@ -29,27 +29,16 @@ represent sorted sets). They are ordered according to the following rule: * If B and A are two elements with a different score, then A > B if A.score is > B.score. * If B and A have exactly the same score, then A > B if the A string is lexicographically greater than the B string. B and A strings can't be equal since sorted sets only have unique elements. -Let's start with a simple example, adding a few selected hackers names as -sorted set elements, with their year of birth as "score". - - > zadd hackers 1940 "Alan Kay" - (integer) 1 - > zadd hackers 1957 "Sophie Wilson" - (integer) 1 - > zadd hackers 1953 "Richard Stallman" - (integer) 1 - > zadd hackers 1949 "Anita Borg" - (integer) 1 - > zadd hackers 1965 "Yukihiro Matsumoto" - (integer) 1 - > zadd hackers 1914 "Hedy Lamarr" - (integer) 1 - > zadd hackers 1916 "Claude Shannon" - (integer) 1 - > zadd hackers 1969 "Linus Torvalds" - (integer) 1 - > zadd hackers 1912 "Alan Turing" - (integer) 1 +Let's start with a simple example, we'll add all our racers and the score they got in the first race: + +{{< clients-example ss_tutorial zadd >}} +> ZADD racer_scores 10 "Norem" +(integer) 1 +> ZADD racer_scores 12 "Castilla" +(integer) 1 +> ZADD racer_scores 8 "Sam-Bodden" 10 "Royce" 6 "Ford" 14 "Prickett" +(integer) 4 +{{< /clients-example >}} As you can see `ZADD` is similar to `SADD`, but takes one additional argument @@ -64,92 +53,93 @@ Implementation note: Sorted sets are implemented via a dual-ported data structure containing both a skip list and a hash table, so every time we add an element Redis performs an O(log(N)) operation. That's good, but when we ask for sorted elements Redis does not have to do any work at -all, it's already all sorted: - - > zrange hackers 0 -1 - 1) "Alan Turing" - 2) "Hedy Lamarr" - 3) "Claude Shannon" - 4) "Alan Kay" - 5) "Anita Borg" - 6) "Richard Stallman" - 7) "Sophie Wilson" - 8) "Yukihiro Matsumoto" - 9) "Linus Torvalds" +all, it's already sorted. Note that the `ZRANGE` order is low to high, while the `ZREVRANGE` order is high to low: + +{{< clients-example ss_tutorial zrange >}} +> ZRANGE racer_scores 0 -1 +1) "Ford" +2) "Sam-Bodden" +3) "Norem" +4) "Royce" +5) "Castilla" +6) "Prickett" +> ZREVRANGE racer_scores 0 -1 +1) "Prickett" +2) "Castilla" +3) "Royce" +4) "Norem" +5) "Sam-Bodden" +6) "Ford" +{{< /clients-example >}} Note: 0 and -1 means from element index 0 to the last element (-1 works here just as it does in the case of the `LRANGE` command). -What if I want to order them the opposite way, youngest to oldest? -Use `ZREVRANGE` instead of `ZRANGE`: - - > zrevrange hackers 0 -1 - 1) "Linus Torvalds" - 2) "Yukihiro Matsumoto" - 3) "Sophie Wilson" - 4) "Richard Stallman" - 5) "Anita Borg" - 6) "Alan Kay" - 7) "Claude Shannon" - 8) "Hedy Lamarr" - 9) "Alan Turing" - It is possible to return scores as well, using the `WITHSCORES` argument: - > zrange hackers 0 -1 withscores - 1) "Alan Turing" - 2) "1912" - 3) "Hedy Lamarr" - 4) "1914" - 5) "Claude Shannon" - 6) "1916" - 7) "Alan Kay" - 8) "1940" - 9) "Anita Borg" - 10) "1949" - 11) "Richard Stallman" - 12) "1953" - 13) "Sophie Wilson" - 14) "1957" - 15) "Yukihiro Matsumoto" - 16) "1965" - 17) "Linus Torvalds" - 18) "1969" +{{< clients-example ss_tutorial zrange_withscores >}} +> ZRANGE racer_scores 0 -1 withscores + 1) "Ford" + 2) "6" + 3) "Sam-Bodden" + 4) "8" + 5) "Norem" + 6) "10" + 7) "Royce" + 8) "10" + 9) "Castilla" +10) "12" +11) "Prickett" +12) "14" +{{< /clients-example >}} ### Operating on ranges Sorted sets are more powerful than this. They can operate on ranges. -Let's get all the individuals that were born up to 1950 inclusive. We +Let's get all the racers with 10 or fewer points. We use the `ZRANGEBYSCORE` command to do it: - > zrangebyscore hackers -inf 1950 - 1) "Alan Turing" - 2) "Hedy Lamarr" - 3) "Claude Shannon" - 4) "Alan Kay" - 5) "Anita Borg" +{{< clients-example ss_tutorial zrangebyscore >}} +> ZRANGEBYSCORE racer_scores -inf 10 +1) "Ford" +2) "Sam-Bodden" +3) "Norem" +4) "Royce" +{{< /clients-example >}} We asked Redis to return all the elements with a score between negative -infinity and 1950 (both extremes are included). +infinity and 10 (both extremes are included). -It's also possible to remove ranges of elements. Let's remove all -the hackers born between 1940 and 1960 from the sorted set: +To remove an element we'd simply call `ZREM` with the racer's name. +It's also possible to remove ranges of elements. Let's remove racer Castilla along with all +the racers with strictly fewer than 10 points: - > zremrangebyscore hackers 1940 1960 - (integer) 4 +{{< clients-example ss_tutorial zremrangebyscore >}} +> ZREM racer_scores "Castilla" +(integer) 1 +> ZREMRANGEBYSCORE racer_scores -inf 9 +(integer) 2 +> ZRANGE racer_scores 0 -1 +1) "Norem" +2) "Royce" +3) "Prickett" +{{< /clients-example >}} `ZREMRANGEBYSCORE` is perhaps not the best command name, but it can be very useful, and returns the number of removed elements. Another extremely useful operation defined for sorted set elements is the get-rank operation. It is possible to ask what is the -position of an element in the set of the ordered elements. - - > zrank hackers "Anita Borg" - (integer) 4 - +position of an element in the set of ordered elements. The `ZREVRANK` command is also available in order to get the rank, considering -the elements sorted a descending way. +the elements sorted in a descending way. + +{{< clients-example ss_tutorial zrank >}} +> ZRANK racer_scores "Norem" +(integer) 0 +> ZREVRANK racer_scores "Norem" +(integer) 3 +{{< /clients-example >}} ### Lexicographical scores @@ -163,32 +153,22 @@ The main commands to operate with lexicographical ranges are `ZRANGEBYLEX`, `ZREVRANGEBYLEX`, `ZREMRANGEBYLEX` and `ZLEXCOUNT`. For example, let's add again our list of famous hackers, but this time -use a score of zero for all the elements: - - > zadd hackers 0 "Alan Kay" 0 "Sophie Wilson" 0 "Richard Stallman" 0 - "Anita Borg" 0 "Yukihiro Matsumoto" 0 "Hedy Lamarr" 0 "Claude Shannon" - 0 "Linus Torvalds" 0 "Alan Turing" - -Because of the sorted sets ordering rules, they are already sorted -lexicographically: - - > zrange hackers 0 -1 - 1) "Alan Kay" - 2) "Alan Turing" - 3) "Anita Borg" - 4) "Claude Shannon" - 5) "Hedy Lamarr" - 6) "Linus Torvalds" - 7) "Richard Stallman" - 8) "Sophie Wilson" - 9) "Yukihiro Matsumoto" - -Using `ZRANGEBYLEX` we can ask for lexicographical ranges: - - > zrangebylex hackers [B [P - 1) "Claude Shannon" - 2) "Hedy Lamarr" - 3) "Linus Torvalds" +using a score of zero for all the elements. We'll see that because of the sorted sets ordering rules, they are already sorted lexicographically. Using `ZRANGEBYLEX` we can ask for lexicographical ranges: + +{{< clients-example ss_tutorial zadd_lex >}} +> ZADD racer_scores 0 "Norem" 0 "Sam-Bodden" 0 "Royce" 0 "Castilla" 0 "Prickett" 0 "Ford" +(integer) 3 +> ZRANGE racer_scores 0 -1 +1) "Castilla" +2) "Ford" +3) "Norem" +4) "Prickett" +5) "Royce" +6) "Sam-Bodden" +> ZRANGEBYLEX racer_scores [A [L +1) "Castilla" +2) "Ford" +{{< /clients-example >}} Ranges can be inclusive or exclusive (depending on the first character), also string infinite and minus infinite are specified respectively with @@ -223,38 +203,21 @@ the #4932 best score here"). ## Examples -* Update a real-time leaderboard as players' scores change: -``` -> ZADD leaderboard:455 100 user:1 -(integer) 1 -> ZADD leaderboard:455 75 user:2 -(integer) 1 -> ZADD leaderboard:455 101 user:3 +* There are two ways we can use a sorted set to represent a leaderboard. If we know a racer's new score, we can update it directly via the `ZADD` command. However, if we want to add points to an existing score, we can use the `ZINCRBY` command. +{{< clients-example ss_tutorial leaderboard >}} +> ZADD racer_scores 100 "Wood" (integer) 1 -> ZADD leaderboard:455 15 user:4 +> ZADD racer_scores 100 "Henshaw" (integer) 1 -> ZADD leaderboard:455 275 user:2 +> ZADD racer_scores 150 "Henshaw" (integer) 0 -``` - -Notice that `user:2`'s score is updated in the final `ZADD` call. - -* Get the top 3 players' scores: -``` -> ZRANGE leaderboard:455 0 2 REV WITHSCORES -1) "user:2" -2) "275" -3) "user:3" -4) "101" -5) "user:1" -6) "100" -``` - -* What's the rank of user 2? -``` -> ZREVRANK leaderboard:455 user:2 -(integer) 0 -``` +> ZINCRBY racer_scores 50 "Wood" +"150" +> ZINCRBY racer_scores 50 "Henshaw" +"200" +{{< /clients-example >}} + +You'll see that `ZADD` returns 0 when the member already exists (the score is updated), while `ZINCRBY` returns the new score. The score for racer Henshaw went from 100, was changed to 150 with no regard for what score was there before, and then was incremented by 50 to 200. ## Basic commands diff --git a/docs/data-types/streams.md b/docs/data-types/streams.md index 807cc994d4..86152a6b82 100644 --- a/docs/data-types/streams.md +++ b/docs/data-types/streams.md @@ -19,7 +19,7 @@ Examples of Redis stream use cases include: * Notifications (e.g., storing a record of each user's notifications in a separate stream) Redis generates a unique ID for each stream entry. -You can use these IDs to retrieve their associated entries later or to read and process all subsequent entries in the stream. +You can use these IDs to retrieve their associated entries later or to read and process all subsequent entries in the stream. Note that because these IDs are related to time, the ones shown here may vary and will be different from the IDs you see in your own Redis instance. Redis streams support several trimming strategies (to prevent streams from growing unbounded) and more than one consumption strategy (see `XREAD`, `XREADGROUP`, and `XRANGE`). @@ -34,40 +34,44 @@ See the [complete list of stream commands](https://redis.io/commands/?group=stre ## Examples -* Add several temperature readings to a stream -``` -> XADD temperatures:us-ny:10007 * temp_f 87.2 pressure 29.69 humidity 46 -"1658354918398-0" -> XADD temperatures:us-ny:10007 * temp_f 83.1 pressure 29.21 humidity 46.5 -"1658354934941-0" -> XADD temperatures:us-ny:10007 * temp_f 81.9 pressure 28.37 humidity 43.7 -"1658354957524-0" -``` - -* Read the first two stream entries starting at ID `1658354934941-0`: -``` -> XRANGE temperatures:us-ny:10007 1658354934941-0 + COUNT 2 -1) 1) "1658354934941-0" - 2) 1) "temp_f" - 2) "83.1" - 3) "pressure" - 4) "29.21" - 5) "humidity" - 6) "46.5" -2) 1) "1658354957524-0" - 2) 1) "temp_f" - 2) "81.9" - 3) "pressure" - 4) "28.37" - 5) "humidity" - 6) "43.7" -``` +* When our racers pass a checkpoint, we add a stream entry for each racer that includes the racer's name, speed, position, and location ID: +{{< clients-example stream_tutorial xadd >}} +> XADD race:france * rider Castilla speed 30.2 position 1 location_id 1 +"1692632086370-0" +> XADD race:france * rider Norem speed 28.8 position 3 location_id 1 +"1692632094485-0" +> XADD race:france * rider Prickett speed 29.7 position 2 location_id 1 +"1692632102976-0" +{{< /clients-example >}} + +* Read two stream entries starting at ID `1692632086370-0`: +{{< clients-example stream_tutorial xrange >}} +> XRANGE race:france 1692632086370-0 + COUNT 2 +1) 1) "1692632086370-0" + 2) 1) "rider" + 2) "Castilla" + 3) "speed" + 4) "30.2" + 5) "position" + 6) "1" + 7) "location_id" + 8) "1" +2) 1) "1692632094485-0" + 2) 1) "rider" + 2) "Norem" + 3) "speed" + 4) "28.8" + 5) "position" + 6) "3" + 7) "location_id" + 8) "1" +{{< /clients-example >}} * Read up to 100 new stream entries, starting at the end of the stream, and block for up to 300 ms if no entries are being written: -``` -> XREAD COUNT 100 BLOCK 300 STREAMS temperatures:us-ny:10007 $ +{{< clients-example stream_tutorial xread_block >}} +> XREAD COUNT 100 BLOCK 300 STREAMS race:france $ (nil) -``` +{{< /clients-example >}} ## Performance @@ -84,21 +88,21 @@ See each command's time complexity for the details. Streams are an append-only data structure. The fundamental write command, called `XADD`, appends a new entry to the specified stream. -Each stream entry consists of one or more field-value pairs, somewhat like a record or a Redis hash: +Each stream entry consists of one or more field-value pairs, somewhat like a dictionary or a Redis hash: -``` -> XADD mystream * sensor-id 1234 temperature 19.8 -1518951480106-0 -``` +{{< clients-example stream_tutorial xadd_2 >}} +> XADD race:france * rider Castilla speed 29.9 position 1 location_id 2 +"1692632147973-0" +{{< /clients-example >}} -The above call to the `XADD` command adds an entry `sensor-id: 1234, temperature: 19.8` to the stream at key `mystream`, using an auto-generated entry ID, which is the one returned by the command, specifically `1518951480106-0`. It gets as its first argument the key name `mystream`, the second argument is the entry ID that identifies every entry inside a stream. However, in this case, we passed `*` because we want the server to generate a new ID for us. Every new ID will be monotonically increasing, so in more simple terms, every new entry added will have a higher ID compared to all the past entries. Auto-generation of IDs by the server is almost always what you want, and the reasons for specifying an ID explicitly are very rare. We'll talk more about this later. The fact that each Stream entry has an ID is another similarity with log files, where line numbers, or the byte offset inside the file, can be used in order to identify a given entry. Returning back at our `XADD` example, after the key name and ID, the next arguments are the field-value pairs composing our stream entry. +The above call to the `XADD` command adds an entry `rider: Castilla, speed: 29.9, position: 1, location_id: 2` to the stream at key `race:france`, using an auto-generated entry ID, which is the one returned by the command, specifically `1692632147973-0`. It gets as its first argument the key name `race:france`, the second argument is the entry ID that identifies every entry inside a stream. However, in this case, we passed `*` because we want the server to generate a new ID for us. Every new ID will be monotonically increasing, so in more simple terms, every new entry added will have a higher ID compared to all the past entries. Auto-generation of IDs by the server is almost always what you want, and the reasons for specifying an ID explicitly are very rare. We'll talk more about this later. The fact that each Stream entry has an ID is another similarity with log files, where line numbers, or the byte offset inside the file, can be used in order to identify a given entry. Returning back at our `XADD` example, after the key name and ID, the next arguments are the field-value pairs composing our stream entry. It is possible to get the number of items inside a Stream just using the `XLEN` command: -``` -> XLEN mystream -(integer) 1 -``` +{{< clients-example stream_tutorial xlen >}} +> XLEN race:france +(integer) 4 +{{< /clients-example >}} ### Entry IDs @@ -114,26 +118,26 @@ The format of such IDs may look strange at first, and the gentle reader may wond If for some reason the user needs incremental IDs that are not related to time but are actually associated to another external system ID, as previously mentioned, the `XADD` command can take an explicit ID instead of the `*` wildcard ID that triggers auto-generation, like in the following examples: -``` -> XADD somestream 0-1 field value +{{< clients-example stream_tutorial xadd_id >}} +> XADD race:usa 0-1 racer Castilla 0-1 -> XADD somestream 0-2 foo bar +> XADD race:usa 0-2 racer Norem 0-2 -``` +{{< /clients-example >}} Note that in this case, the minimum ID is 0-1 and that the command will not accept an ID equal or smaller than a previous one: -``` -> XADD somestream 0-1 foo bar +{{< clients-example stream_tutorial xadd_bad_id >}} +> XADD race:usa 0-1 racer Prickett (error) ERR The ID specified in XADD is equal or smaller than the target stream top item -``` +{{< /clients-example >}} If you're running Redis 7 or later, you can also provide an explicit ID consisting of the milliseconds part only. In this case, the sequence portion of the ID will be automatically generated. To do this, use the syntax below: -``` -> XADD somestream 0-* baz qux +{{< clients-example stream_tutorial xadd_7 >}} +> XADD race:usa 0-* racer Prickett 0-3 -``` +{{< /clients-example >}} ## Getting data from Streams @@ -149,65 +153,132 @@ Redis Streams support all three of the query modes described above via different To query the stream by range we are only required to specify two IDs, *start* and *end*. The range returned will include the elements having start or end as ID, so the range is inclusive. The two special IDs `-` and `+` respectively mean the smallest and the greatest ID possible. -``` -> XRANGE mystream - + -1) 1) 1518951480106-0 - 2) 1) "sensor-id" - 2) "1234" - 3) "temperature" - 4) "19.8" -2) 1) 1518951482479-0 - 2) 1) "sensor-id" - 2) "9999" - 3) "temperature" - 4) "18.2" -``` +{{< clients-example stream_tutorial xrange_all >}} +> XRANGE race:france - + +1) 1) "1692632086370-0" + 2) 1) "rider" + 2) "Castilla" + 3) "speed" + 4) "30.2" + 5) "position" + 6) "1" + 7) "location_id" + 8) "1" +2) 1) "1692632094485-0" + 2) 1) "rider" + 2) "Norem" + 3) "speed" + 4) "28.8" + 5) "position" + 6) "3" + 7) "location_id" + 8) "1" +3) 1) "1692632102976-0" + 2) 1) "rider" + 2) "Prickett" + 3) "speed" + 4) "29.7" + 5) "position" + 6) "2" + 7) "location_id" + 8) "1" +4) 1) "1692632147973-0" + 2) 1) "rider" + 2) "Castilla" + 3) "speed" + 4) "29.9" + 5) "position" + 6) "1" + 7) "location_id" + 8) "2" +{{< /clients-example >}} Each entry returned is an array of two items: the ID and the list of field-value pairs. We already said that the entry IDs have a relation with the time, because the part at the left of the `-` character is the Unix time in milliseconds of the local node that created the stream entry, at the moment the entry was created (however note that streams are replicated with fully specified `XADD` commands, so the replicas will have identical IDs to the master). This means that I could query a range of time using `XRANGE`. In order to do so, however, I may want to omit the sequence part of the ID: if omitted, in the start of the range it will be assumed to be 0, while in the end part it will be assumed to be the maximum sequence number available. This way, querying using just two milliseconds Unix times, we get all the entries that were generated in that range of time, in an inclusive way. For instance, if I want to query a two milliseconds period I could use: -``` -> XRANGE mystream 1518951480106 1518951480107 -1) 1) 1518951480106-0 - 2) 1) "sensor-id" - 2) "1234" - 3) "temperature" - 4) "19.8" -``` - -I have only a single entry in this range, however in real data sets, I could query for ranges of hours, or there could be many items in just two milliseconds, and the result returned could be huge. For this reason, `XRANGE` supports an optional **COUNT** option at the end. By specifying a count, I can just get the first *N* items. If I want more, I can get the last ID returned, increment the sequence part by one, and query again. Let's see this in the following example. We start adding 10 items with `XADD` (I won't show that, lets assume that the stream `mystream` was populated with 10 items). To start my iteration, getting 2 items per command, I start with the full range, but with a count of 2. - -``` -> XRANGE mystream - + COUNT 2 -1) 1) 1519073278252-0 - 2) 1) "foo" - 2) "value_1" -2) 1) 1519073279157-0 - 2) 1) "foo" - 2) "value_2" -``` - -In order to continue the iteration with the next two items, I have to pick the last ID returned, that is `1519073279157-0` and add the prefix `(` to it. The resulting exclusive range interval, that is `(1519073279157-0` in this case, can now be used as the new *start* argument for the next `XRANGE` call: - -``` -> XRANGE mystream (1519073279157-0 + COUNT 2 -1) 1) 1519073280281-0 - 2) 1) "foo" - 2) "value_3" -2) 1) 1519073281432-0 - 2) 1) "foo" - 2) "value_4" -``` - -And so forth. Since `XRANGE` complexity is *O(log(N))* to seek, and then *O(M)* to return M elements, with a small count the command has a logarithmic time complexity, which means that each step of the iteration is fast. So `XRANGE` is also the de facto *streams iterator* and does not require an **XSCAN** command. +{{< clients-example stream_tutorial xrange_time >}} +> XRANGE race:france 1692632086369 1692632086371 +1) 1) "1692632086370-0" + 2) 1) "rider" + 2) "Castilla" + 3) "speed" + 4) "30.2" + 5) "position" + 6) "1" + 7) "location_id" + 8) "1" +{{< /clients-example >}} + +I have only a single entry in this range. However in real data sets, I could query for ranges of hours, or there could be many items in just two milliseconds, and the result returned could be huge. For this reason, `XRANGE` supports an optional **COUNT** option at the end. By specifying a count, I can just get the first *N* items. If I want more, I can get the last ID returned, increment the sequence part by one, and query again. Let's see this in the following example. Let's assume that the stream `race:france` was populated with 4 items. To start my iteration, getting 2 items per command, I start with the full range, but with a count of 2. + +{{< clients-example stream_tutorial xrange_step_1 >}} +> XRANGE race:france - + COUNT 2 +1) 1) "1692632086370-0" + 2) 1) "rider" + 2) "Castilla" + 3) "speed" + 4) "30.2" + 5) "position" + 6) "1" + 7) "location_id" + 8) "1" +2) 1) "1692632094485-0" + 2) 1) "rider" + 2) "Norem" + 3) "speed" + 4) "28.8" + 5) "position" + 6) "3" + 7) "location_id" + 8) "1" +{{< /clients-example >}} + +To continue the iteration with the next two items, I have to pick the last ID returned, that is `1692632094485-0`, and add the prefix `(` to it. The resulting exclusive range interval, that is `(1692632094485-0` in this case, can now be used as the new *start* argument for the next `XRANGE` call: + +{{< clients-example stream_tutorial xrange_step_2 >}} +> XRANGE race:france (1692632094485-0 + COUNT 2 +1) 1) "1692632102976-0" + 2) 1) "rider" + 2) "Prickett" + 3) "speed" + 4) "29.7" + 5) "position" + 6) "2" + 7) "location_id" + 8) "1" +2) 1) "1692632147973-0" + 2) 1) "rider" + 2) "Castilla" + 3) "speed" + 4) "29.9" + 5) "position" + 6) "1" + 7) "location_id" + 8) "2" +{{< /clients-example >}} + +Now that we've retrieved 4 items out of a stream that only had 4 entries in it, if we try to retrieve more items, we'll get an empty array: + +{{< clients-example stream_tutorial xrange_empty >}} +> XRANGE race:france (1692632147973-0 + COUNT 2 +(empty array) +{{< /clients-example >}} + +Since `XRANGE` complexity is *O(log(N))* to seek, and then *O(M)* to return M elements, with a small count the command has a logarithmic time complexity, which means that each step of the iteration is fast. So `XRANGE` is also the de facto *streams iterator* and does not require an **XSCAN** command. The command `XREVRANGE` is the equivalent of `XRANGE` but returning the elements in inverted order, so a practical use for `XREVRANGE` is to check what is the last item in a Stream: -``` -> XREVRANGE mystream + - COUNT 1 -1) 1) 1519073287312-0 - 2) 1) "foo" - 2) "value_10" -``` +{{< clients-example stream_tutorial xrevrange >}} +> XREVRANGE race:france + - COUNT 1 +1) 1) "1692632147973-0" + 2) 1) "rider" + 2) "Castilla" + 3) "speed" + 4) "29.9" + 5) "position" + 6) "1" + 7) "location_id" + 8) "2" +{{< /clients-example >}} Note that the `XREVRANGE` command takes the *start* and *stop* arguments in reverse order. @@ -221,26 +292,38 @@ When we do not want to access items by a range in a stream, usually what we want The command that provides the ability to listen for new messages arriving into a stream is called `XREAD`. It's a bit more complex than `XRANGE`, so we'll start showing simple forms, and later the whole command layout will be provided. -``` -> XREAD COUNT 2 STREAMS mystream 0 -1) 1) "mystream" - 2) 1) 1) 1519073278252-0 - 2) 1) "foo" - 2) "value_1" - 2) 1) 1519073279157-0 - 2) 1) "foo" - 2) "value_2" -``` +{{< clients-example stream_tutorial xread >}} +> XREAD COUNT 2 STREAMS race:france 0 +1) 1) "race:france" + 2) 1) 1) "1692632086370-0" + 2) 1) "rider" + 2) "Castilla" + 3) "speed" + 4) "30.2" + 5) "position" + 6) "1" + 7) "location_id" + 8) "1" + 2) 1) "1692632094485-0" + 2) 1) "rider" + 2) "Norem" + 3) "speed" + 4) "28.8" + 5) "position" + 6) "3" + 7) "location_id" + 8) "1" +{{< /clients-example >}} The above is the non-blocking form of `XREAD`. Note that the **COUNT** option is not mandatory, in fact the only mandatory option of the command is the **STREAMS** option, that specifies a list of keys together with the corresponding maximum ID already seen for each stream by the calling consumer, so that the command will provide the client only with messages with an ID greater than the one we specified. -In the above command we wrote `STREAMS mystream 0` so we want all the messages in the Stream `mystream` having an ID greater than `0-0`. As you can see in the example above, the command returns the key name, because actually it is possible to call this command with more than one key to read from different streams at the same time. I could write, for instance: `STREAMS mystream otherstream 0 0`. Note how after the **STREAMS** option we need to provide the key names, and later the IDs. For this reason, the **STREAMS** option must always be the last option. +In the above command we wrote `STREAMS race:france 0` so we want all the messages in the Stream `race:france` having an ID greater than `0-0`. As you can see in the example above, the command returns the key name, because actually it is possible to call this command with more than one key to read from different streams at the same time. I could write, for instance: `STREAMS race:france race:italy 0 0`. Note how after the **STREAMS** option we need to provide the key names, and later the IDs. For this reason, the **STREAMS** option must always be the last option. Any other options must come before the **STREAMS** option. Apart from the fact that `XREAD` can access multiple streams at once, and that we are able to specify the last ID we own to just get newer messages, in this simple form the command is not doing something so different compared to `XRANGE`. However, the interesting part is that we can turn `XREAD` into a *blocking command* easily, by specifying the **BLOCK** argument: ``` -> XREAD BLOCK 0 STREAMS mystream $ +> XREAD BLOCK 0 STREAMS race:france $ ``` Note that in the example above, other than removing **COUNT**, I specified the new **BLOCK** option with a timeout of 0 milliseconds (that means to never timeout). Moreover, instead of passing a normal ID for the stream `mystream` I passed the special ID `$`. This special ID means that `XREAD` should use as last ID the maximum ID already stored in the stream `mystream`, so that we will receive only *new* messages, starting from the time we started listening. This is similar to the `tail -f` Unix command in some way. @@ -306,52 +389,46 @@ Now it's time to zoom in to see the fundamental consumer group commands. They ar ## Creating a consumer group -Assuming I have a key `mystream` of type stream already existing, in order to create a consumer group I just need to do the following: +Assuming I have a key `race:france` of type stream already existing, in order to create a consumer group I just need to do the following: -``` -> XGROUP CREATE mystream mygroup $ +{{< clients-example stream_tutorial xgroup_create >}} +> XGROUP CREATE race:france france_riders $ OK -``` +{{< /clients-example >}} As you can see in the command above when creating the consumer group we have to specify an ID, which in the example is just `$`. This is needed because the consumer group, among the other states, must have an idea about what message to serve next at the first consumer connecting, that is, what was the *last message ID* when the group was just created. If we provide `$` as we did, then only new messages arriving in the stream from now on will be provided to the consumers in the group. If we specify `0` instead the consumer group will consume *all* the messages in the stream history to start with. Of course, you can specify any other valid ID. What you know is that the consumer group will start delivering messages that are greater than the ID you specify. Because `$` means the current greatest ID in the stream, specifying `$` will have the effect of consuming only new messages. `XGROUP CREATE` also supports creating the stream automatically, if it doesn't exist, using the optional `MKSTREAM` subcommand as the last argument: -``` -> XGROUP CREATE newstream mygroup $ MKSTREAM +{{< clients-example stream_tutorial xgroup_create_mkstream >}} +> XGROUP CREATE race:italy italy_riders $ MKSTREAM OK -``` +{{< /clients-example >}} Now that the consumer group is created we can immediately try to read messages via the consumer group using the `XREADGROUP` command. We'll read from consumers, that we will call Alice and Bob, to see how the system will return different messages to Alice or Bob. `XREADGROUP` is very similar to `XREAD` and provides the same **BLOCK** option, otherwise it is a synchronous command. However there is a *mandatory* option that must be always specified, which is **GROUP** and has two arguments: the name of the consumer group, and the name of the consumer that is attempting to read. The option **COUNT** is also supported and is identical to the one in `XREAD`. -Before reading from the stream, let's put some messages inside: - -``` -> XADD mystream * message apple -1526569495631-0 -> XADD mystream * message orange -1526569498055-0 -> XADD mystream * message strawberry -1526569506935-0 -> XADD mystream * message apricot -1526569535168-0 -> XADD mystream * message banana -1526569544280-0 -``` - -Note: *here message is the field name, and the fruit is the associated value, remember that stream items are small dictionaries.* - -It is time to try reading something using the consumer group: - -``` -> XREADGROUP GROUP mygroup Alice COUNT 1 STREAMS mystream > -1) 1) "mystream" - 2) 1) 1) 1526569495631-0 - 2) 1) "message" - 2) "apple" -``` +We'll add riders to the race:italy stream and try reading something using the consumer group: +Note: *here rider is the field name, and the name is the associated value. Remember that stream items are small dictionaries.* + +{{< clients-example stream_tutorial xgroup_read >}} +> XADD race:italy * rider Castilla +"1692632639151-0" +> XADD race:italy * rider Royce +"1692632647899-0" +> XADD race:italy * rider Sam-Bodden +"1692632662819-0" +> XADD race:italy * rider Prickett +"1692632670501-0" +> XADD race:italy * rider Norem +"1692632678249-0" +> XREADGROUP GROUP italy_riders Alice COUNT 1 STREAMS race:italy > +1) 1) "race:italy" + 2) 1) 1) "1692632639151-0" + 2) 1) "rider" + 2) "Castilla" +{{< /clients-example >}} `XREADGROUP` replies are just like `XREAD` replies. Note however the `GROUP ` provided above. It states that I want to read from the stream using the consumer group `mygroup` and I'm the consumer `Alice`. Every time a consumer performs an operation with a consumer group, it must specify its name, uniquely identifying this consumer inside the group. @@ -362,42 +439,42 @@ This is almost always what you want, however it is also possible to specify a re * If the ID is the special ID `>` then the command will return only new messages never delivered to other consumers so far, and as a side effect, will update the consumer group's *last ID*. * If the ID is any other valid numerical ID, then the command will let us access our *history of pending messages*. That is, the set of messages that were delivered to this specified consumer (identified by the provided name), and never acknowledged so far with `XACK`. -We can test this behavior immediately specifying an ID of 0, without any **COUNT** option: we'll just see the only pending message, that is, the one about apples: +We can test this behavior immediately specifying an ID of 0, without any **COUNT** option: we'll just see the only pending message, that is, the one about Castilla: -``` -> XREADGROUP GROUP mygroup Alice STREAMS mystream 0 -1) 1) "mystream" - 2) 1) 1) 1526569495631-0 - 2) 1) "message" - 2) "apple" -``` +{{< clients-example stream_tutorial xgroup_read_id >}} +> XREADGROUP GROUP italy_riders Alice STREAMS race:italy 0 +1) 1) "race:italy" + 2) 1) 1) "1692632639151-0" + 2) 1) "rider" + 2) "Castilla" +{{< /clients-example >}} However, if we acknowledge the message as processed, it will no longer be part of the pending messages history, so the system will no longer report anything: -``` -> XACK mystream mygroup 1526569495631-0 +{{< clients-example stream_tutorial xack >}} +> XACK race:italy italy_riders 1692632639151-0 (integer) 1 -> XREADGROUP GROUP mygroup Alice STREAMS mystream 0 -1) 1) "mystream" - 2) (empty list or set) -``` +> XREADGROUP GROUP italy_riders Alice STREAMS race:italy 0 +1) 1) "race:italy" + 2) (empty array) +{{< /clients-example >}} Don't worry if you yet don't know how `XACK` works, the idea is just that processed messages are no longer part of the history that we can access. Now it's Bob's turn to read something: -``` -> XREADGROUP GROUP mygroup Bob COUNT 2 STREAMS mystream > -1) 1) "mystream" - 2) 1) 1) 1526569498055-0 - 2) 1) "message" - 2) "orange" - 2) 1) 1526569506935-0 - 2) 1) "message" - 2) "strawberry" -``` +{{< clients-example stream_tutorial xgroup_read_bob >}} +> XREADGROUP GROUP italy_riders Bob COUNT 2 STREAMS race:italy > +1) 1) "race:italy" + 2) 1) 1) "1692632647899-0" + 2) 1) "rider" + 2) "Royce" + 2) 1) "1692632662819-0" + 2) 1) "rider" + 2) "Sam-Bodden" +{{< /clients-example >}} -Bob asked for a maximum of two messages and is reading via the same group `mygroup`. So what happens is that Redis reports just *new* messages. As you can see the "apple" message is not delivered, since it was already delivered to Alice, so Bob gets orange and strawberry, and so forth. +Bob asked for a maximum of two messages and is reading via the same group `mygroup`. So what happens is that Redis reports just *new* messages. As you can see the "Castilla" message is not delivered, since it was already delivered to Alice, so Bob gets Royce and Sam-Bodden and so forth. This way Alice, Bob, and any other consumer in the group, are able to read different messages from the same stream, to read their history of yet to process messages, or to mark messages as processed. This allows creating different topologies and semantics for consuming messages from a stream. @@ -478,14 +555,14 @@ The first step of this process is just a command that provides observability of This is a read-only command which is always safe to call and will not change ownership of any message. In its simplest form, the command is called with two arguments, which are the name of the stream and the name of the consumer group. -``` -> XPENDING mystream mygroup +{{< clients-example stream_tutorial xpending >}} +> XPENDING race:italy italy_riders 1) (integer) 2 -2) 1526569498055-0 -3) 1526569506935-0 +2) "1692632647899-0" +3) "1692632662819-0" 4) 1) 1) "Bob" 2) "2" -``` +{{< /clients-example >}} When called in this way, the command outputs the total number of pending messages in the consumer group (two in this case), the lower and higher message ID among the pending messages, and finally a list of consumers and the number of pending messages they have. We have only Bob with two pending messages because the single message that Alice requested was acknowledged using `XACK`. @@ -498,31 +575,31 @@ XPENDING [[IDLE ] [ By providing a start and end ID (that can be just `-` and `+` as in `XRANGE`) and a count to control the amount of information returned by the command, we are able to know more about the pending messages. The optional final argument, the consumer name, is used if we want to limit the output to just messages pending for a given consumer, but won't use this feature in the following example. -``` -> XPENDING mystream mygroup - + 10 -1) 1) 1526569498055-0 +{{< clients-example stream_tutorial xpending_plus_minus >}} +> XPENDING race:italy italy_riders - + 10 +1) 1) "1692632647899-0" 2) "Bob" - 3) (integer) 74170458 + 3) (integer) 74642 4) (integer) 1 -2) 1) 1526569506935-0 +2) 1) "1692632662819-0" 2) "Bob" - 3) (integer) 74170458 + 3) (integer) 74642 4) (integer) 1 -``` +{{< /clients-example >}} Now we have the details for each message: the ID, the consumer name, the *idle time* in milliseconds, which is how many milliseconds have passed since the last time the message was delivered to some consumer, and finally the number of times that a given message was delivered. -We have two messages from Bob, and they are idle for 74170458 milliseconds, about 20 hours. +We have two messages from Bob, and they are idle for 60000+ milliseconds, about a minute. Note that nobody prevents us from checking what the first message content was by just using `XRANGE`. -``` -> XRANGE mystream 1526569498055-0 1526569498055-0 -1) 1) 1526569498055-0 - 2) 1) "message" - 2) "orange" -``` +{{< clients-example stream_tutorial xrange_pending >}} +> XRANGE race:italy 1692632647899-0 1692632647899-0 +1) 1) "1692632647899-0" + 2) 1) "rider" + 2) "Royce" +{{< /clients-example >}} -We have just to repeat the same ID twice in the arguments. Now that we have some ideas, Alice may decide that after 20 hours of not processing messages, Bob will probably not recover in time, and it's time to *claim* such messages and resume the processing in place of Bob. To do so, we use the `XCLAIM` command. +We have just to repeat the same ID twice in the arguments. Now that we have some ideas, Alice may decide that after 1 minute of not processing messages, Bob will probably not recover quickly, and it's time to *claim* such messages and resume the processing in place of Bob. To do so, we use the `XCLAIM` command. This command is very complex and full of options in its full form, since it is used for replication of consumer groups changes, but we'll use just the arguments that we need normally. In this case it is as simple as: @@ -533,20 +610,20 @@ XCLAIM ... Basically we say, for this specific key and group, I want that the message IDs specified will change ownership, and will be assigned to the specified consumer name ``. However, we also provide a minimum idle time, so that the operation will only work if the idle time of the mentioned messages is greater than the specified idle time. This is useful because maybe two clients are retrying to claim a message at the same time: ``` -Client 1: XCLAIM mystream mygroup Alice 3600000 1526569498055-0 -Client 2: XCLAIM mystream mygroup Lora 3600000 1526569498055-0 +Client 1: XCLAIM race:italy italy_riders Alice 60000 1692632647899-0 +Client 2: XCLAIM race:italy italy_riders Lora 60000 1692632647899-0 ``` However, as a side effect, claiming a message will reset its idle time and will increment its number of deliveries counter, so the second client will fail claiming it. In this way we avoid trivial re-processing of messages (even if in the general case you cannot obtain exactly once processing). This is the result of the command execution: -``` -> XCLAIM mystream mygroup Alice 3600000 1526569498055-0 -1) 1) 1526569498055-0 - 2) 1) "message" - 2) "orange" -``` +{{< clients-example stream_tutorial xclaim >}} +> XCLAIM race:italy italy_riders Alice 60000 1692632647899-0 +1) 1) "1692632647899-0" + 2) 1) "rider" + 2) "Royce" +{{< /clients-example >}} The message was successfully claimed by Alice, who can now process the message and acknowledge it, and move things forward even if the original consumer is not recovering. @@ -569,24 +646,25 @@ XAUTOCLAIM [COUNT count] [JUSTI So, in the example above, I could have used automatic claiming to claim a single message like this: -``` -> XAUTOCLAIM mystream mygroup Alice 3600000 0-0 COUNT 1 -1) 1526569498055-0 -2) 1) 1526569498055-0 - 2) 1) "message" - 2) "orange" -``` +{{< clients-example stream_tutorial xautoclaim >}} +> XAUTOCLAIM race:italy italy_riders Alice 60000 0-0 COUNT 1 +1) "0-0" +2) 1) 1) "1692632662819-0" + 2) 1) "rider" + 2) "Sam-Bodden" +{{< /clients-example >}} Like `XCLAIM`, the command replies with an array of the claimed messages, but it also returns a stream ID that allows iterating the pending entries. The stream ID is a cursor, and I can use it in my next call to continue in claiming idle pending messages: -``` -> XAUTOCLAIM mystream mygroup Lora 3600000 1526569498055-0 COUNT 1 -1) 0-0 -2) 1) 1526569506935-0 - 2) 1) "message" - 2) "strawberry" -``` +{{< clients-example stream_tutorial xautoclaim_cursor >}} +> XAUTOCLAIM race:italy italy_riders Lora 60000 (1692632662819-0 COUNT 1 +1) "1692632662819-0" +2) 1) 1) "1692632647899-0" + 2) 1) "rider" + 2) "Royce" +{{< /clients-example >}} + When `XAUTOCLAIM` returns the "0-0" stream ID as a cursor, that means that it reached the end of the consumer group pending entries list. That doesn't mean that there are no new idle pending messages, so the process continues by calling `XAUTOCLAIM` from the beginning of the stream. @@ -604,81 +682,67 @@ However we may want to do more than that, and the `XINFO` command is an observab This command uses subcommands in order to show different information about the status of the stream and its consumer groups. For instance **XINFO STREAM ** reports information about the stream itself. -``` -> XINFO STREAM mystream +{{< clients-example stream_tutorial xinfo >}} +> XINFO STREAM race:italy 1) "length" - 2) (integer) 2 + 2) (integer) 5 3) "radix-tree-keys" 4) (integer) 1 5) "radix-tree-nodes" 6) (integer) 2 7) "last-generated-id" - 8) "1638125141232-0" - 9) "max-deleted-entryid" -10) "0-0" -11) "entries-added" -12) (integer) 2 -13) "groups" -14) (integer) 1 -15) "first-entry" -16) 1) "1638125133432-0" - 2) 1) "message" - 2) "apple" -17) "last-entry" -18) 1) "1638125141232-0" - 2) 1) "message" - 2) "banana" -``` + 8) "1692632678249-0" + 9) "groups" +10) (integer) 1 +11) "first-entry" +12) 1) "1692632639151-0" + 2) 1) "rider" + 2) "Castilla" +13) "last-entry" +14) 1) "1692632678249-0" + 2) 1) "rider" + 2) "Norem" +{{< /clients-example >}} The output shows information about how the stream is encoded internally, and also shows the first and last message in the stream. Another piece of information available is the number of consumer groups associated with this stream. We can dig further asking for more information about the consumer groups. -``` -> XINFO GROUPS mystream -1) 1) "name" - 2) "mygroup" - 3) "consumers" - 4) (integer) 2 - 5) "pending" - 6) (integer) 2 - 7) "last-delivered-id" - 8) "1638126030001-0" - 9) "entries-read" - 10) (integer) 2 - 11) "lag" - 12) (integer) 0 -2) 1) "name" - 2) "some-other-group" - 3) "consumers" - 4) (integer) 1 - 5) "pending" - 6) (integer) 0 - 7) "last-delivered-id" - 8) "1638126028070-0" - 9) "entries-read" - 10) (integer) 1 - 11) "lag" - 12) (integer) 1 -``` +{{< clients-example stream_tutorial xinfo_groups >}} +> XINFO GROUPS race:italy +1) 1) "name" + 2) "italy_riders" + 3) "consumers" + 4) (integer) 3 + 5) "pending" + 6) (integer) 2 + 7) "last-delivered-id" + 8) "1692632662819-0" +{{< /clients-example >}} As you can see in this and in the previous output, the `XINFO` command outputs a sequence of field-value items. Because it is an observability command this allows the human user to immediately understand what information is reported, and allows the command to report more information in the future by adding more fields without breaking compatibility with older clients. Other commands that must be more bandwidth efficient, like `XPENDING`, just report the information without the field names. The output of the example above, where the **GROUPS** subcommand is used, should be clear observing the field names. We can check in more detail the state of a specific consumer group by checking the consumers that are registered in the group. -``` -> XINFO CONSUMERS mystream mygroup -1) 1) name +{{< clients-example stream_tutorial xinfo_consumers >}} +> XINFO CONSUMERS race:italy italy_riders +1) 1) "name" 2) "Alice" - 3) pending + 3) "pending" 4) (integer) 1 - 5) idle - 6) (integer) 9104628 -2) 1) name + 5) "idle" + 6) (integer) 177546 +2) 1) "name" 2) "Bob" - 3) pending + 3) "pending" + 4) (integer) 0 + 5) "idle" + 6) (integer) 424686 +3) 1) "name" + 2) "Lora" + 3) "pending" 4) (integer) 1 - 5) idle - 6) (integer) 83841983 -``` + 5) "idle" + 6) (integer) 72241 +{{< /clients-example >}} In case you do not remember the syntax of the command, just ask the command itself for help: @@ -715,45 +779,47 @@ So basically Kafka partitions are more similar to using N different Redis keys, Many applications do not want to collect data into a stream forever. Sometimes it is useful to have at maximum a given number of items inside a stream, other times once a given size is reached, it is useful to move data from Redis to a storage which is not in memory and not as fast but suited to store the history for, potentially, decades to come. Redis streams have some support for this. One is the **MAXLEN** option of the `XADD` command. This option is very simple to use: -``` -> XADD mystream MAXLEN 2 * value 1 -1526654998691-0 -> XADD mystream MAXLEN 2 * value 2 -1526654999635-0 -> XADD mystream MAXLEN 2 * value 3 -1526655000369-0 -> XLEN mystream +{{< clients-example stream_tutorial maxlen >}} +> XADD race:italy MAXLEN 2 * rider Jones +"1692633189161-0" +> XADD race:italy MAXLEN 2 * rider Wood +"1692633198206-0" +> XADD race:italy MAXLEN 2 * rider Henshaw +"1692633208557-0" +> XLEN race:italy (integer) 2 -> XRANGE mystream - + -1) 1) 1526654999635-0 - 2) 1) "value" - 2) "2" -2) 1) 1526655000369-0 - 2) 1) "value" - 2) "3" -``` +> XRANGE race:italy - + +1) 1) "1692633198206-0" + 2) 1) "rider" + 2) "Wood" +2) 1) "1692633208557-0" + 2) 1) "rider" + 2) "Henshaw" +{{< /clients-example >}} Using **MAXLEN** the old entries are automatically evicted when the specified length is reached, so that the stream is left at a constant size. There is currently no option to tell the stream to just retain items that are not older than a given period, because such command, in order to run consistently, would potentially block for a long time in order to evict items. Imagine for example what happens if there is an insertion spike, then a long pause, and another insertion, all with the same maximum time. The stream would block to evict the data that became too old during the pause. So it is up to the user to do some planning and understand what is the maximum stream length desired. Moreover, while the length of the stream is proportional to the memory used, trimming by time is less simple to control and anticipate: it depends on the insertion rate which often changes over time (and when it does not change, then to just trim by size is trivial). However trimming with **MAXLEN** can be expensive: streams are represented by macro nodes into a radix tree, in order to be very memory efficient. Altering the single macro node, consisting of a few tens of elements, is not optimal. So it's possible to use the command in the following special form: ``` -XADD mystream MAXLEN ~ 1000 * ... entry fields here ... +XADD race:italy MAXLEN ~ 1000 * ... entry fields here ... ``` -The `~` argument between the **MAXLEN** option and the actual count means, I don't really need this to be exactly 1000 items. It can be 1000 or 1010 or 1030, just make sure to save at least 1000 items. With this argument, the trimming is performed only when we can remove a whole node. This makes it much more efficient, and it is usually what you want. +The `~` argument between the **MAXLEN** option and the actual count means, I don't really need this to be exactly 1000 items. It can be 1000 or 1010 or 1030, just make sure to save at least 1000 items. With this argument, the trimming is performed only when we can remove a whole node. This makes it much more efficient, and it is usually what you want. You'll note here that the client libraries have various implementations of this. For example, the Python client defaults to approximate and has to be explicitly set to a true length. There is also the `XTRIM` command, which performs something very similar to what the **MAXLEN** option does above, except that it can be run by itself: -``` -> XTRIM mystream MAXLEN 10 -``` +{{< clients-example stream_tutorial xtrim >}} +> XTRIM race:italy MAXLEN 10 +(integer) 0 +{{< /clients-example >}} Or, as for the `XADD` option: -``` +{{< clients-example stream_tutorial xtrim2 >}} > XTRIM mystream MAXLEN ~ 10 -``` +(integer) 0 +{{< /clients-example >}} However, `XTRIM` is designed to accept different trimming strategies. Another trimming strategy is **MINID**, that evicts entries with IDs lower than the one specified. @@ -793,21 +859,21 @@ So when designing an application using Redis streams and consumer groups, make s Streams also have a special command for removing items from the middle of a stream, just by ID. Normally for an append only data structure this may look like an odd feature, but it is actually useful for applications involving, for instance, privacy regulations. The command is called `XDEL` and receives the name of the stream followed by the IDs to delete: -``` -> XRANGE mystream - + COUNT 2 -1) 1) 1526654999635-0 - 2) 1) "value" - 2) "2" -2) 1) 1526655000369-0 - 2) 1) "value" - 2) "3" -> XDEL mystream 1526654999635-0 +{{< clients-example stream_tutorial xdel >}} +> XRANGE race:italy - + COUNT 2 +1) 1) "1692633198206-0" + 2) 1) "rider" + 2) "Wood" +2) 1) "1692633208557-0" + 2) 1) "rider" + 2) "Henshaw" +> XDEL race:italy 1692633208557-0 (integer) 1 -> XRANGE mystream - + COUNT 2 -1) 1) 1526655000369-0 - 2) 1) "value" - 2) "3" -``` +> XRANGE race:italy - + COUNT 2 +1) 1) "1692633198206-0" + 2) 1) "rider" + 2) "Wood" +{{< /clients-example >}} However in the current implementation, memory is not really reclaimed until a macro node is completely empty, so you should not abuse this feature. diff --git a/docs/data-types/strings.md b/docs/data-types/strings.md index 55909e3185..52348dcf59 100644 --- a/docs/data-types/strings.md +++ b/docs/data-types/strings.md @@ -16,9 +16,9 @@ we are mapping a string to another string. The string data type is useful for a number of use cases, like caching HTML fragments or pages. {{< clients-example set_tutorial set_get >}} - > set bike:1 Deimos + > SET bike:1 Deimos OK - > get bike:1 + > GET bike:1 "Deimos" {{< /clients-example >}} diff --git a/docs/get-started/_index.md b/docs/get-started/_index.md new file mode 100644 index 0000000000..e94be52b99 --- /dev/null +++ b/docs/get-started/_index.md @@ -0,0 +1,20 @@ +--- +title: "Quick starts" +linkTitle: "Quick starts" +hideListLinks: true +weight: 20 +description: > + Redis quick start guides +aliases: + - /docs/getting-started/ +--- + +Redis can be used as a database, cache, streaming engine, message broker, and more. The following quick start guides will show you how to use Redis for the following specific purposes: + +1. [Data structure store](/docs/get-started/data-store) +2. [Document database](/docs/get-started/document-database) +3. [Vector database](/docs/get-started/vector-database) + +Please select the guide that aligns best with your specific usage scenario. + +You can find answers to frequently asked questions in the [FAQ](/docs/get-started/faq/). diff --git a/docs/get-started/data-store.md b/docs/get-started/data-store.md new file mode 100644 index 0000000000..7c9455a620 --- /dev/null +++ b/docs/get-started/data-store.md @@ -0,0 +1,88 @@ +--- +title: "Redis as an in-memory data structure store quick start guide" +linkTitle: "Data structure store" +weight: 1 +description: Understand how to use basic Redis data types +--- + +This quick start guide shows you how to: + +1. Get started with Redis +2. Store data under a key in Redis +3. Retrieve data with a key from Redis +4. Scan the keyspace for keys that match a specific pattern + +The examples in this article refer to a simple bicycle inventory. + +## Setup + +The easiest way to get started with Redis is to use Redis Cloud: + +1. Create a [free account](https://redis.com/try-free?utm_source=redisio&utm_medium=referral&utm_campaign=2023-09-try_free&utm_content=cu-redis_cloud_users). + + +2. Follow the instructions to create a free database. + +You can alternatively follow the [installation guides](/docs/install/install-stack/) to install Redis on your local machine. + +## Connect + +The first step is to connect to Redis. You can find further details about the connection options in this documentation site's [connection section](/docs/connect). The following example shows how to connect to a Redis server that runs on localhost (`-h 127.0.0.1`) and listens on the default port (`-p 6379`): + +{{< clients-example search_quickstart connect >}} +> redis-cli -h 127.0.0.1 -p 6379 +{{< /clients-example>}} +
+{{% alert title="Tip" color="warning" %}} +You can copy and paste the connection details from the Redis Cloud database configuration page. Here is an example connection string of a Cloud database that is hosted in the AWS region `us-east-1` and listens on port 16379: `redis-16379.c283.us-east-1-4.ec2.cloud.redislabs.com:16379`. The connection string has the format `host:port`. You must also copy and paste the username and password of your Cloud database and then either pass the credentials to your client or use the [AUTH command](/commands/auth/) after the connection is established. +{{% /alert %}} + +## Store and retrieve data + +Redis stands for Remote Dictionary Server. You can use the same data types as in your local programming environment but on the server side within Redis. + +Similar to byte arrays, Redis strings store sequences of bytes, including text, serialized objects, counter values, and binary arrays. The following example shows you how to set and get a string value: + +{{< clients-example set_and_get >}} +SET bike:1 "Process 134" +GET bike:1 +{{< /clients-example >}} + +Hashes are the equivalent of dictionaries (dicts or hash maps). Among other things, you can use hashes to represent plain objects and to store groupings of counters. The following example explains how to set and access field values of an object: + +{{< clients-example hash_tutorial set_get_all >}} +> HSET bike:1 model Deimos brand Ergonom type 'Enduro bikes' price 4972 +(integer) 4 +> HGET bike:1 model +"Deimos" +> HGET bike:1 price +"4972" +> HGETALL bike:1 +1) "model" +2) "Deimos" +3) "brand" +4) "Ergonom" +5) "type" +6) "Enduro bikes" +7) "price" +8) "4972" +{{< /clients-example >}} + +You can get a complete overview of available data types in this documentation site's [data types section](/docs/data-types/). Each data type has commands allowing you to manipulate or retrieve data. The [commands reference](/commands/) provides a sophisticated explanation. + +## Scan the keyspace + +Each item within Redis has a unique key. All items live within the Redis [keyspace](/docs/manual/keyspace/). You can scan the Redis keyspace via the [SCAN command](/commands/scan/). Here is an example that scans for the first 100 keys that have the prefix `bike:`: + +{{< clients-example scan_example >}} +SCAN 0 MATCH "bike:*" COUNT 100 +{{< /clients-example >}} + +[SCAN](/commands/scan/) returns a cursor position, allowing you to scan iteratively for the next batch of keys until you reach the cursor value 0. + +## Next steps + +You can address more use cases with Redis by learning about Redis Stack. Here are two additional quick start guides: + +* [Redis as a document database](/docs/get-started/document-database/) +* [Redis as a vector database](/docs/get-started/vector-database/) \ No newline at end of file diff --git a/docs/get-started/data/bikes.json b/docs/get-started/data/bikes.json new file mode 100644 index 0000000000..f8186ec93c --- /dev/null +++ b/docs/get-started/data/bikes.json @@ -0,0 +1,127 @@ +[ + { + "model": "Jigger", + "brand": "Velorim", + "price": 270, + "type": "Kids bikes", + "specs": { + "material": "aluminium", + "weight": "10" + }, + "description": "Small and powerful, the Jigger is the best ride for the smallest of tikes! This is the tiniest kids’ pedal bike on the market available without a coaster brake, the Jigger is the vehicle of choice for the rare tenacious little rider raring to go. We say rare because this smokin’ little bike is not ideal for a nervous first-time rider, but it’s a true giddy up for a true speedster. The Jigger is a 12 inch lightweight kids bicycle and it will meet your little one’s need for speed. It’s a single speed bike that makes learning to pump pedals simple and intuitive. It even has a handle in the bottom of the saddle so you can easily help your child during training! The Jigger is among the most lightweight children’s bikes on the planet. It is designed so that 2-3 year-olds fit comfortably in a molded ride position that allows for efficient riding, balanced handling and agility. The Jigger’s frame design and gears work together so your buddingbiker can stand up out of the seat, stop rapidly, rip over trails and pump tracks. The Jigger’s is amazing on dirt or pavement. Your tike will speed down the bike path in no time. The Jigger will ship with a coaster brake. A freewheel kit is provided at no cost. " + }, + { + "model": "Hillcraft", + "brand": "Bicyk", + "price": 1200, + "type": "Kids Mountain Bikes", + "specs": { + "material": "carbon", + "weight": "11" + }, + "description": "Kids want to ride with as little weight as possible. Especially on an incline! They may be at the age when a 27.5\" wheel bike is just too clumsy coming off a 24\" bike. The Hillcraft 26 is just the solution they need! Imagine 120mm travel. Boost front/rear. You have NOTHING to tweak because it is easy to assemble right out of the box. The Hillcraft 26 is an efficient trail trekking machine. Up or down does not matter - dominate the trails going both down and up with this amazing bike. The name Monarch comes from Monarch trail in Colorado where we love to ride. It’s a highly technical, steep and rocky trail but the rip on the waydown is so fulfilling. Don’t ride the trail on a hardtail! It is so much more fun on the full suspension Hillcraft! Hit your local trail with the Hillcraft Monarch 26 to get to where you want to go. " + }, + { + "model": "Chook air 5", + "brand": "Nord", + "price": 815, + "type": "Kids Mountain Bikes", + "specs": { + "material": "alloy", + "weight": "9.1" + }, + "description": "The Chook Air 5 gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. The lower top tube makes it easy to mount and dismount in any situation, giving your kids greater safety on the trails. The Chook Air 5 is the perfect intro to mountain biking." + }, + { + "model": "Eva 291", + "brand": "Eva", + "price": 3400, + "type": "Mountain Bikes", + "specs": { + "material": "carbon", + "weight": "9.1" + }, + "description": "The sister company to Nord, Eva launched in 2005 as the first and only women-dedicated bicycle brand. Designed by women for women, allEva bikes are optimized for the feminine physique using analytics from a body metrics database. If you like 29ers, try the Eva 291. It’s a brand new bike for 2022.. This full-suspension, cross-country ride has been designed for velocity. The 291 has 100mm of front and rear travel, a superlight aluminum frame and fast-rolling 29-inch wheels. Yippee!" + }, + { + "model": "Kahuna", + "brand": "Noka Bikes", + "price": 3200, + "type": "Mountain Bikes", + "specs": { + "material": "alloy", + "weight": "9.8" + }, + "description": "Whether you want to try your hand at XC racing or are looking for a lively trail bike that's just as inspiring on the climbs as it is over rougher ground, the Wilder is one heck of a bike built specifically for short women. Both the frames and components have been tweaked to include a women’s saddle, different bars and unique colourway." + }, + { + "model": "XBN 2.1 Alloy", + "brand": "Breakout", + "price": 810, + "type": "Road Bikes", + "specs": { + "material": "alloy", + "weight": "7.2" + }, + "description": "The XBN 2.1 Alloy is our entry-level road bike – but that’s not to say that it’s a basic machine. With an internal weld aluminium frame, a full carbon fork, and the slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance. The 6061 alloy frame is triple-butted which ensures a lighter weight and smoother ride. And it’s comfortable with dropped seat stays and the carbon fork. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires balance grip, rolling friction and puncture protection when coasting down the other side. " + }, + { + "model": "WattBike", + "brand": "ScramBikes", + "price": 2300, + "type": "eBikes", + "specs": { + "material": "alloy", + "weight": "15" + }, + "description": "The WattBike is the best e-bike for people who still feel young at heart. It has a Bafang 500 watt geared hub motor that can reach 20 miles per hour on both steep inclines and city streets. The lithium-ion battery, which gets nearly 40 miles per charge, has a lightweight form factor, making it easier for seniors to use. It comes fully assembled (no convoluted instructions!) and includes a sturdy helmet at no cost. The Plush saddle softens over time with use. The included Seatpost, however, is easily adjustable and adds to this bike’s fantastic rating for seniors, as do the hydraulic disc brakes from Tektro. " + }, + { + "model": "Soothe Electric bike", + "brand": "Peaknetic", + "price": 1950, + "type": "eBikes", + "specs": { + "material": "alloy", + "weight": "14.7" + }, + "description": "The Soothe is an everyday electric bike, from the makers of Exercycle bikes, that conveys style while you get around the city. The Soothe lives up to its name by keeping your posture upright and relaxed for the ride ahead, keeping those aches and pains from riding at bay. It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. " + }, + { + "model": "Secto", + "brand": "Peaknetic", + "price": 430, + "type": "Commuter bikes", + "specs": { + "material": "aluminium", + "weight": "10.0" + }, + "description": "If you struggle with stiff fingers or a kinked neck or back after a few minutes on the road, this lightweight, aluminum bike alleviates those issues and allows you to enjoy the ride. From the ergonomic grips to the lumbar-supporting seat position, the Roll Low-Entry offers incredible comfort. The rear-inclined seat tube facilitates stability by allowing you to put a foot on the ground to balance at a stop, and the low step-over frame makes it accessible for all ability and mobility levels. The saddle is very soft, with a wide back to support your hip joints and a cutout in the center to redistribute that pressure. Rim brakes deliver satisfactory braking control, and the wide tires provide a smooth, stable ride on paved roads and gravel. Rack and fender mounts facilitate setting up the Roll Low-Entry as your preferred commuter, and the BMX-like handlebar offers space for mounting a flashlight, bell, or phone holder." + }, + { + "model": "Summit", + "brand": "nHill", + "price": 1200, + "type": "Mountain Bike", + "specs": { + "material": "alloy", + "weight": "11.3" + }, + "description": "This budget mountain bike from nHill performs well both on bike paths and on the trail. The fork with 100mm of travel absorbs rough terrain. Fat Kenda Booster tires give you grip in corners and on wet trails. The Shimano Tourney drivetrain offered enough gears for finding a comfortable pace to ride uphill, and the Tektro hydraulic disc brakes break smoothly. Whether you want an affordable bike that you can take to work, but also take trail riding on the weekends or you’re just after a stable, comfortable ride for the bike path, the Summit gives a good value for money." + }, + { + "model": "ThrillCycle", + "brand": "BikeShind", + "price": 815, + "type": "Commuter Bikes", + "specs": { + "material": "alloy", + "weight": "12.7" + }, + "description": "An artsy, retro-inspired bicycle that’s as functional as it is pretty: The ThrillCycle steel frame offers a smooth ride. A 9-speed drivetrain has enough gears for coasting in the city, but we wouldn’t suggest taking it to the mountains. Fenders protect you from mud, and a rear basket lets you transport groceries, flowers and books. The ThrillCycle comes with a limited lifetime warranty, so this little guy will last you long past graduation." + } + + + + +] diff --git a/docs/getting-started/faq.md b/docs/get-started/faq.md similarity index 96% rename from docs/getting-started/faq.md rename to docs/get-started/faq.md index 9ee1d55c83..0c8531ac97 100644 --- a/docs/getting-started/faq.md +++ b/docs/get-started/faq.md @@ -63,10 +63,9 @@ and not refreshed on cache misses. ## How can I reduce Redis' overall memory usage? -If you can, use Redis 32 bit instances. Also make good use of small hashes, -lists, sorted sets, and sets of integers, since Redis is able to represent -those data types in the special case of a few elements in a much more compact -way. There is more info in the [Memory Optimization page](/topics/memory-optimization). +A good practice is to consider memory consumption when mapping your logical data model to the physical data model within Redis. These considerations include using specific data types, key patterns, and normalization. + +Beyond data modeling, there is more info in the [Memory Optimization page](/topics/memory-optimization). ## What happens if Redis runs out of memory? diff --git a/docs/get-started/img/free-cloud-db.png b/docs/get-started/img/free-cloud-db.png new file mode 100644 index 0000000000..3336f3353a Binary files /dev/null and b/docs/get-started/img/free-cloud-db.png differ diff --git a/docs/getting-started/_index.md b/docs/getting-started/_index.md deleted file mode 100644 index 8a97629bcc..0000000000 --- a/docs/getting-started/_index.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: "Get started with Redis" -linkTitle: "Get started" - -weight: 20 - -description: > - How to get up and running with Redis -aliases: - - /docs/getting-started/tutorial ---- - -This is a guide to getting started with Redis. You'll learn how to install, run, and experiment with the Redis server process. - -## Install Redis - -How you install Redis depends on your operating system and whether you'd like to install it bundled with Redis Stack and Redis UI. See the guide below that best fits your needs: - -* [Install Redis from Source](/docs/getting-started/installation/install-redis-from-source) -* [Install Redis on Linux](/docs/getting-started/installation/install-redis-on-linux) -* [Install Redis on macOS](/docs/getting-started/installation/install-redis-on-mac-os) -* [Install Redis on Windows](/docs/getting-started/installation/install-redis-on-windows) -* [Install Redis with Redis Stack and RedisInsight](/docs/getting-started/install-stack/) - -Once you have Redis up and running, and can connect using `redis-cli`, you can continue with the steps below. - -## Explore Redis using the CLI - -External programs talk to Redis using a TCP socket and a Redis specific protocol. This protocol is implemented in the Redis client libraries for the different programming languages. However to make hacking with Redis simpler Redis provides a command line utility that can be used to send commands to Redis. This program is called **redis-cli**. - -The first thing to do in order to check if Redis is working properly is sending a **PING** command using redis-cli: - - $ redis-cli ping - PONG - -Running **redis-cli** followed by a command name and its arguments will send this command to the Redis instance running on localhost at port 6379. You can change the host and port used by `redis-cli` - just try the `--help` option to check the usage information. - -Another interesting way to run `redis-cli` is without arguments: the program will start in interactive mode. You can type different commands and see their replies. - - $ redis-cli - redis 127.0.0.1:6379> ping - PONG - redis 127.0.0.1:6379> set mykey somevalue - OK - redis 127.0.0.1:6379> get mykey - "somevalue" - -At this point you are able to talk with Redis. It is the right time to pause a bit with this tutorial and start the [fifteen minutes introduction to Redis data types](https://redis.io/topics/data-types-intro) in order to learn a few Redis commands. Otherwise if you already know a few basic Redis commands you can keep reading. - -## Securing Redis - -By default Redis binds to **all the interfaces** and has no authentication at -all. If you use Redis in a very controlled environment, separated from the -external internet and in general from attackers, that's fine. However if an unhardened Redis -is exposed to the internet, it is a big security concern. If you are not 100% sure your environment is secured properly, please check the following steps in order to make Redis more secure, which are enlisted in order of increased security. - -1. Make sure the port Redis uses to listen for connections (by default 6379 and additionally 16379 if you run Redis in cluster mode, plus 26379 for Sentinel) is firewalled, so that it is not possible to contact Redis from the outside world. -2. Use a configuration file where the `bind` directive is set in order to guarantee that Redis listens on only the network interfaces you are using. For example only the loopback interface (127.0.0.1) if you are accessing Redis just locally from the same computer, and so forth. -3. Use the `requirepass` option in order to add an additional layer of security so that clients will require to authenticate using the `AUTH` command. -4. Use [spiped](http://www.tarsnap.com/spiped.html) or another SSL tunneling software in order to encrypt traffic between Redis servers and Redis clients if your environment requires encryption. - -Note that a Redis instance exposed to the internet without any security [is very simple to exploit](http://antirez.com/news/96), so make sure you understand the above and apply **at least** a firewall layer. After the firewall is in place, try to connect with `redis-cli` from an external host in order to prove yourself the instance is actually not reachable. - -## Use Redis from your application - -Of course using Redis just from the command line interface is not enough as -the goal is to use it from your application. In order to do so you need to -download and install a Redis client library for your programming language. -You'll find a [full list of clients for different languages in this page](https://redis.io/clients). - - -## Redis persistence - -You can learn [how Redis persistence works on this page](https://redis.io/topics/persistence), however what is important to understand for a quick start is that by default, if you start Redis with the default configuration, Redis will spontaneously save the dataset only from time to time (for instance after at least five minutes if you have at least 100 changes in your data), so if you want your database to persist and be reloaded after a restart make sure to call the **SAVE** command manually every time you want to force a data set snapshot. Otherwise make sure to shutdown the database using the **SHUTDOWN** command: - - $ redis-cli shutdown - -This way Redis will make sure to save the data on disk before quitting. -Reading the [persistence page](https://redis.io/topics/persistence) is strongly suggested in order to better understand how Redis persistence works. - -## Install Redis more properly - -Running Redis from the command line is fine just to hack a bit or for development. However, at some point you'll have some actual application to run on a real server. For this kind of usage you have two different choices: - -* Run Redis using screen. -* Install Redis in your Linux box in a proper way using an init script, so that after a restart everything will start again properly. - -A proper install using an init script is strongly suggested. -The following instructions can be used to perform a proper installation using the init script shipped with Redis version 2.4 or higher in a Debian or Ubuntu based distribution. - -We assume you already copied **redis-server** and **redis-cli** executables under /usr/local/bin. - -* Create a directory in which to store your Redis config files and your data: - - sudo mkdir /etc/redis - sudo mkdir /var/redis - -* Copy the init script that you'll find in the Redis distribution under the **utils** directory into `/etc/init.d`. We suggest calling it with the name of the port where you are running this instance of Redis. For example: - - sudo cp utils/redis_init_script /etc/init.d/redis_6379 - -* Edit the init script. - - sudo vi /etc/init.d/redis_6379 - -Make sure to modify **REDISPORT** accordingly to the port you are using. -Both the pid file path and the configuration file name depend on the port number. - -* Copy the template configuration file you'll find in the root directory of the Redis distribution into `/etc/redis/` using the port number as name, for instance: - - sudo cp redis.conf /etc/redis/6379.conf - -* Create a directory inside `/var/redis` that will work as data and working directory for this Redis instance: - - sudo mkdir /var/redis/6379 - -* Edit the configuration file, making sure to perform the following changes: - * Set **daemonize** to yes (by default it is set to no). - * Set the **pidfile** to `/var/run/redis_6379.pid` (modify the port if needed). - * Change the **port** accordingly. In our example it is not needed as the default port is already 6379. - * Set your preferred **loglevel**. - * Set the **logfile** to `/var/log/redis_6379.log` - * Set the **dir** to `/var/redis/6379` (very important step!) -* Finally add the new Redis init script to all the default runlevels using the following command: - - sudo update-rc.d redis_6379 defaults - -You are done! Now you can try running your instance with: - - sudo /etc/init.d/redis_6379 start - -Make sure that everything is working as expected: - -* Try pinging your instance with redis-cli. -* Do a test save with `redis-cli save` and check that the dump file is correctly stored into `/var/redis/6379/` (you should find a file called `dump.rdb`). -* Check that your Redis instance is correctly logging in the log file. -* If it's a new machine where you can try it without problems make sure that after a reboot everything is still working. - -Note: The above instructions don't include all of the Redis configuration parameters that you could change, for instance, to use AOF persistence instead of RDB persistence, or to set up replication, and so forth. -Make sure to read the example [`redis.conf`](https://github.com/redis/redis/blob/6.2/redis.conf) file (that is heavily commented). - -
\ No newline at end of file diff --git a/docs/getting-started/installation/_index.md b/docs/getting-started/installation/_index.md deleted file mode 100644 index 4a8845d356..0000000000 --- a/docs/getting-started/installation/_index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: "Installing Redis" -linkTitle: "Install Redis" -weight: 1 -description: > - Install Redis on Linux, macOS, and Windows ---- diff --git a/docs/install/_index.md b/docs/install/_index.md new file mode 100644 index 0000000000..4685cefe7e --- /dev/null +++ b/docs/install/_index.md @@ -0,0 +1,18 @@ +--- +title: "Install Redis or Redis Stack" +linkTitle: "Install" +weight: 30 +hideListLinks: true +description: How to install your preferred Redis flavor on your target platform +aliases: + - /docs/getting-started +--- + +You can install [Redis](https://redis.io/docs/about/) or [Redis Stack](/docs/about/about-stack) locally on your machine. Redis and Redis Stack are available on Linux, macOS, and Windows. + +Here are the installation instructions: + +* [Install Redis](/docs/install/install-redis) +* [Install Redis Stack](/docs/install/install-stack) + +While you can install Redis (Stack) locally, you might also consider using Redis Cloud by creating a [free account](https://redis.com/try-free/?utm_source=redisio&utm_medium=referral&utm_campaign=2023-09-try_free&utm_content=cu-redis_cloud_users). diff --git a/docs/install/install-redis/_index.md b/docs/install/install-redis/_index.md new file mode 100644 index 0000000000..e316a5565b --- /dev/null +++ b/docs/install/install-redis/_index.md @@ -0,0 +1,166 @@ +--- +title: "Install Redis" +linkTitle: "Install Redis" +weight: 1 +description: > + Install Redis on Linux, macOS, and Windows +aliases: +- /docs/getting-started/installation +- /docs/getting-started/tutorial +--- + +This is a an installation guide. You'll learn how to install, run, and experiment with the Redis server process. + +While you can install Redis on any of the platforms listed below, you might also consider using Redis Cloud by creating a [free account](https://redis.com/try-free?utm_source=redisio&utm_medium=referral&utm_campaign=2023-09-try_free&utm_content=cu-redis_cloud_users). + +## Install Redis + +How you install Redis depends on your operating system and whether you'd like to install it bundled with Redis Stack and Redis UI. See the guide below that best fits your needs: + +* [Install Redis from Source](/docs/install/install-redis/install-redis-from-source) +* [Install Redis on Linux](/docs/install/install-redis/install-redis-on-linux) +* [Install Redis on macOS](/docs/install/install-redis/install-redis-on-mac-os) +* [Install Redis on Windows](/docs/install/install-redis/install-redis-on-windows) +* [Install Redis with Redis Stack and RedisInsight](/docs/install/install-stack/) + +Refer to [Redis Administration](/docs/management/admin/) for detailed setup tips. + +## Test if you can connect using the CLI + +After you have Redis up and running, you can connect using `redis-cli`. + +External programs talk to Redis using a TCP socket and a Redis specific protocol. This protocol is implemented in the Redis client libraries for the different programming languages. However, to make hacking with Redis simpler, Redis provides a command line utility that can be used to send commands to Redis. This program is called **redis-cli**. + +The first thing to do to check if Redis is working properly is sending a **PING** command using redis-cli: + +``` +$ redis-cli ping +PONG +``` + +Running **redis-cli** followed by a command name and its arguments will send this command to the Redis instance running on localhost at port 6379. You can change the host and port used by `redis-cli` - just try the `--help` option to check the usage information. + +Another interesting way to run `redis-cli` is without arguments: the program will start in interactive mode. You can type different commands and see their replies. + +``` +$ redis-cli +redis 127.0.0.1:6379> ping +PONG +``` + +## Securing Redis + +By default Redis binds to **all the interfaces** and has no authentication at all. If you use Redis in a very controlled environment, separated from the external internet and in general from attackers, that's fine. However, if an unhardened Redis is exposed to the internet, it is a big security concern. If you are not 100% sure your environment is secured properly, please check the following steps in order to make Redis more secure: + +1. Make sure the port Redis uses to listen for connections (by default 6379 and additionally 16379 if you run Redis in cluster mode, plus 26379 for Sentinel) is firewalled, so that it is not possible to contact Redis from the outside world. +2. Use a configuration file where the `bind` directive is set in order to guarantee that Redis listens on only the network interfaces you are using. For example, only the loopback interface (127.0.0.1) if you are accessing Redis locally from the same computer. +3. Use the `requirepass` option to add an additional layer of security so that clients will be required to authenticate using the `AUTH` command. +4. Use [spiped](http://www.tarsnap.com/spiped.html) or another SSL tunneling software to encrypt traffic between Redis servers and Redis clients if your environment requires encryption. + +Note that a Redis instance exposed to the internet without any security [is very simple to exploit](http://antirez.com/news/96), so make sure you understand the above and apply **at least** a firewall layer. After the firewall is in place, try to connect with `redis-cli` from an external host to confirm that the instance is not reachable. + +## Use Redis from your application + +Of course using Redis just from the command line interface is not enough as the goal is to use it from your application. To do so, you need to download and install a Redis client library for your programming language. + +You'll find a [full list of clients for different languages in this page](/clients). + + +## Redis persistence + +You can learn [how Redis persistence works on this page](/docs/management/persistence/). It is important to understand that, if you start Redis with the default configuration, Redis will spontaneously save the dataset only from time to time. For example, after at least five minutes if you have at least 100 changes in your data. If you want your database to persist and be reloaded after a restart make sure to call the **SAVE** command manually every time you want to force a data set snapshot. Alternatively, you can save the data on disk before quitting by using the **SHUTDOWN** command: + +``` +$ redis-cli shutdown +``` + +This way, Redis will save the data on disk before quitting. Reading the [persistence page](/docs/management/persistence/) is strongly suggested to better understand how Redis persistence works. + +## Install Redis properly + +Running Redis from the command line is fine just to hack a bit or for development. However, at some point you'll have some actual application to run on a real server. For this kind of usage you have two different choices: + +* Run Redis using screen. +* Install Redis in your Linux box in a proper way using an init script, so that after a restart everything will start again properly. + +A proper install using an init script is strongly recommended. + +{{% alert title="Note" color="warning" %}} +The available packages for supported Linux distributions already include the capability of starting the Redis server from `/etc/init`. +{{% /alert %}} + +{{% alert title="Note" color="warning" %}} +The remainder of this section assumes you've [installed Redis from its source code](/docs/install/install-redis/install-redis-from-source). If instead you have installed Redis Stack, you will need to download a [basic init script](https://raw.githubusercontent.com/redis/redis/7.2/utils/redis_init_script) and then modify both it and the following instructions to conform to the way Redis Stack was installed on your platform. For example, on Ubuntu 20.04 LTS, Redis Stack is installed in `/opt/redis-stack`, not `/usr/local`, so you'll need to adjust accordingly. +{{% /alert %}} + +The following instructions can be used to perform a proper installation using the init script shipped with the Redis source code, `/path/to/redis-stable/utils/redis_init_script`. + +If you have not yet run `make install` after building the Redis source, you will need to do so before continuing. By default, `make install` will copy the `redis-server` and `redis-cli` binaries to `/usr/local/bin`. + +* Create a directory in which to store your Redis config files and your data: + + ``` + sudo mkdir /etc/redis + sudo mkdir /var/redis + ``` + +* Copy the init script that you'll find in the Redis distribution under the **utils** directory into `/etc/init.d`. We suggest calling it with the name of the port where you are running this instance of Redis. Make sure the resulting file has `0755` permissions. + + ``` + sudo cp utils/redis_init_script /etc/init.d/redis_6379 + ``` + +* Edit the init script. + + ``` + sudo vi /etc/init.d/redis_6379 + ``` + +Make sure to set the **REDISPORT** variable to the port you are using. +Both the pid file path and the configuration file name depend on the port number. + +* Copy the template configuration file you'll find in the root directory of the Redis distribution into `/etc/redis/` using the port number as the name, for instance: + + ``` + sudo cp redis.conf /etc/redis/6379.conf + ``` + +* Create a directory inside `/var/redis` that will work as both data and working directory for this Redis instance: + + ``` + sudo mkdir /var/redis/6379 + ``` + +* Edit the configuration file, making sure to perform the following changes: + * Set **daemonize** to yes (by default it is set to no). + * Set the **pidfile** to `/var/run/redis_6379.pid`, modifying the port as necessary. + * Change the **port** accordingly. In our example it is not needed as the default port is already `6379`. + * Set your preferred **loglevel**. + * Set the **logfile** to `/var/log/redis_6379.log`. + * Set the **dir** to `/var/redis/6379` (very important step!). +* Finally, add the new Redis init script to all the default runlevels using the following command: + + ``` + sudo update-rc.d redis_6379 defaults + ``` + +You are done! Now you can try running your instance with: + +``` +sudo /etc/init.d/redis_6379 start +``` + +Make sure that everything is working as expected: + +1. Try pinging your instance within a `redis-cli` session using the `PING` command. +2. Do a test save with `redis-cli save` and check that a dump file is correctly saved to `/var/redis/6379/dump.rdb`. +3. Check that your Redis instance is logging to the `/var/log/redis_6379.log` file. +4. If it's a new machine where you can try it without problems, make sure that after a reboot everything is still working. + +{{% alert title="Note" color="warning" %}} +The above instructions don't include all of the Redis configuration parameters that you could change. For example, to use AOF persistence instead of RDB persistence, or to set up replication, and so forth. +{{% /alert %}} + +You should also read the example [redis.conf](/docs/management/config-file/) file, which is heavily annotated to help guide you on making changes. Further details can also be found in the [configuration article on this site](/docs/management/config/). + +
diff --git a/docs/getting-started/installation/install-redis-from-source.md b/docs/install/install-redis/install-redis-from-source.md similarity index 73% rename from docs/getting-started/installation/install-redis-from-source.md rename to docs/install/install-redis/install-redis-from-source.md index d885bca190..f910965350 100644 --- a/docs/getting-started/installation/install-redis-from-source.md +++ b/docs/install/install-redis/install-redis-from-source.md @@ -1,9 +1,11 @@ --- title: "Install Redis from Source" -linkTitle: "Install from Source" +linkTitle: "Source code" weight: 5 description: > Compile and install Redis from source +aliases: +- /docs/getting-started/installation/install-redis-from-source --- You can compile and install Redis from source on variety of platforms and operating systems including Linux and macOS. Redis has no dependencies other than a C compiler and `libc`. @@ -20,7 +22,7 @@ wget https://download.redis.io/redis-stable.tar.gz ## Compiling Redis -To compile Redis, first the tarball, change to the root directory, and then run `make`: +To compile Redis, first extract the tarball, change to the root directory, and then run `make`: {{< highlight bash >}} tar -xzvf redis-stable.tar.gz @@ -28,6 +30,12 @@ cd redis-stable make {{< / highlight >}} +To build with TLS support, you'll need to install OpenSSL development libraries (e.g., libssl-dev on Debian/Ubuntu) and then run: + +{{< highlight bash >}} +make BUILD_TLS=yes +{{< / highlight >}} + If the compile succeeds, you'll find several Redis binaries in the `src` directory, including: * **redis-server**: the Redis Server itself @@ -36,7 +44,7 @@ If the compile succeeds, you'll find several Redis binaries in the `src` directo To install these binaries in `/usr/local/bin`, run: {{< highlight bash >}} -make install +sudo make install {{< / highlight >}} ### Starting and stopping Redis in the foreground @@ -50,3 +58,5 @@ redis-server If successful, you'll see the startup logs for Redis, and Redis will be running in the foreground. To stop Redis, enter `Ctrl-C`. + +For a more complete installation, continue with [these instructions](/docs/install/#install-redis-more-properly). diff --git a/docs/getting-started/installation/install-redis-on-linux.md b/docs/install/install-redis/install-redis-on-linux.md similarity index 94% rename from docs/getting-started/installation/install-redis-on-linux.md rename to docs/install/install-redis/install-redis-on-linux.md index 41b0041351..2e47efe945 100644 --- a/docs/getting-started/installation/install-redis-on-linux.md +++ b/docs/install/install-redis/install-redis-on-linux.md @@ -1,9 +1,11 @@ --- title: "Install Redis on Linux" -linkTitle: "Install on Linux" +linkTitle: "Linux" weight: 1 description: > How to install Redis on Linux +aliases: +- /docs/getting-started/installation/install-redis-on-linux --- Most major Linux distributions provide packages for Redis. diff --git a/docs/getting-started/installation/install-redis-on-mac-os.md b/docs/install/install-redis/install-redis-on-mac-os.md similarity index 92% rename from docs/getting-started/installation/install-redis-on-mac-os.md rename to docs/install/install-redis/install-redis-on-mac-os.md index cb838e5ae2..f2bd70cfab 100644 --- a/docs/getting-started/installation/install-redis-on-mac-os.md +++ b/docs/install/install-redis/install-redis-on-mac-os.md @@ -1,11 +1,13 @@ --- title: "Install Redis on macOS" -linkTitle: "Install on macOS" +linkTitle: "MacOS" weight: 1 description: Use Homebrew to install and start Redis on macOS +aliases: +- /docs/getting-started/installation/install-redis-on-mac-os --- -This guide shows you how to install Redis on macOS using Homebrew. Homebrew is the easiest way to install Redis on macOS. If you'd prefer to build Redis from the source files on macOS, see [Installing Redis from Source](../install-redis-from-source). +This guide shows you how to install Redis on macOS using Homebrew. Homebrew is the easiest way to install Redis on macOS. If you'd prefer to build Redis from the source files on macOS, see [Installing Redis from Source](/docs/install/install-redis/install-redis-from-source). ## Prerequisites diff --git a/docs/getting-started/installation/install-redis-on-windows.md b/docs/install/install-redis/install-redis-on-windows.md similarity index 84% rename from docs/getting-started/installation/install-redis-on-windows.md rename to docs/install/install-redis/install-redis-on-windows.md index 3ce2d367d0..087f3ba119 100644 --- a/docs/getting-started/installation/install-redis-on-windows.md +++ b/docs/install/install-redis/install-redis-on-windows.md @@ -1,8 +1,10 @@ --- title: "Install Redis on Windows" -linkTitle: "Install on Windows" +linkTitle: "Windows" weight: 1 description: Use Redis on Windows for development +aliases: +- /docs/getting-started/installation/install-redis-on-windows/ --- Redis is not officially supported on Windows. However, you can install Redis on Windows for development by following the instructions below. @@ -15,7 +17,7 @@ Microsoft provides [detailed instructions for installing WSL](https://docs.micro ## Install Redis -Once you're running Ubuntu on Windows, you can follow the steps detailed at [Install on Ubuntu/Debian](../install-redis-on-linux#install-on-ubuntu-debian) to install recent stable versions of Redis from the official `packages.redis.io` APT repository. +Once you're running Ubuntu on Windows, you can follow the steps detailed at [Install on Ubuntu/Debian](/docs/install/install-redis/install-redis-on-linux#install-on-ubuntu-debian) to install recent stable versions of Redis from the official `packages.redis.io` APT repository. Add the repository to the apt index, update it, and then install: {{< highlight bash >}} diff --git a/docs/install/install-redisinsight/_index.md b/docs/install/install-redisinsight/_index.md new file mode 100644 index 0000000000..a45a4defcf --- /dev/null +++ b/docs/install/install-redisinsight/_index.md @@ -0,0 +1,9 @@ +--- +title: "Install RedisInsight" +linkTitle: "Install RedisInsight" +weight: 3 +description: > + Install RedisInsite on AWS, Docker, and Kubernetes +--- + +This is a an installation guide. You'll learn how to install RedisInsight on Amazon Web Services (AWS), Docker, and Kubernetes. \ No newline at end of file diff --git a/docs/install/install-redisinsight/env-variables.md b/docs/install/install-redisinsight/env-variables.md new file mode 100644 index 0000000000..dbf115bcff --- /dev/null +++ b/docs/install/install-redisinsight/env-variables.md @@ -0,0 +1,19 @@ +--- +title: "Environment variables" +linkTitle: "Environment variables" +weight: 1 +description: > + RedisInsight supported environment variables +--- +You can configure RedisInsight with the following environment variables. + +| Variable | Purpose | Default | Additional info | +| --- | --- | --- | --- | +| RI_APP_PORT | The port that RedisInsight listens on |
  • Docker: 5540
  • desktop: 5530
| See [Express Documentation](https://expressjs.com/en/api.html#app.listen)| +| RI_APP_HOST | The host that RedisInsight connects to |
  • Docker: 0.0.0.0
  • desktop: 127.0.0.1
| See [Express Documentation](https://expressjs.com/en/api.html#app.listen)| +| RI_SERVER_TLS_KEY | Private key for HTTPS | n/a | Private key in [PEM format](https://www.ssl.com/guide/pem-der-crt-and-cer-x-509-encodings-and-conversions/#ftoc-heading-3). Can be a path to a file or a string in PEM format.| +| RI_SERVER_TLS_CERT | Certificate for supplied private key | n/a | Public certificate in [PEM format](https://www.ssl.com/guide/pem-der-crt-and-cer-x-509-encodings-and-conversions/#ftoc-heading-3). Can be a path to a file or a string in PEM format.| +| RI_ENCRYPTION_KEY | Key to encrypt data with | n/a | Available only for Docker.
Redisinsight stores sensitive information (database passwords, Workbench history, etc.) locally (using [sqlite3](https://github.com/TryGhost/node-sqlite3)). This variable allows you to store sensitive information encrypted using the specified encryption key.
Note: The same encryption key should be provided for subsequent `docker run` commands with the same volume attached to decrypt the information. | +| RI_LOG_LEVEL | Configures the log level of the application. | `info` | Supported logging levels are prioritized from highest to lowest:
  • error
  • warn
  • info
  • http
  • verbose
  • debug
  • silly
| +| RI_FILES_LOGGER | Log to file | `true` | By default, you can find log files in the following folders:
  • Docker: `/data/logs`
  • desktop: `/.refisinsight-app/logs`
| +| RI_STDOUT_LOGGER | Log to STDOUT | `true` | | diff --git a/docs/install/install-redisinsight/install-on-aws.md b/docs/install/install-redisinsight/install-on-aws.md new file mode 100644 index 0000000000..93fe59299e --- /dev/null +++ b/docs/install/install-redisinsight/install-on-aws.md @@ -0,0 +1,92 @@ +--- +title: "Install on AWS EC2" +linkTitle: "Install on AWS EC2" +weight: 3 +description: > + How to install RedisInsight on AWS EC2 +--- +This tutorial shows you how to install RedisInsight on an AWS EC2 instance and manage ElastiCache Redis instances using RedisInsight. To complete this tutorial you must have access to the AWS Console and permissions to launch EC2 instances. + +Step 1: Create a new IAM Role (optional) +-------------- + +RedisInsight needs read-only access to S3 and ElastiCache APIs. This is an optional step. + +1. Log in to the AWS Console and navigate to the IAM screen. +1. Create a new IAM Role. +1. Under *Select type of trusted entity*, choose EC2. The role is used by an EC2 instance. +1. Assign the following permissions: + * AmazonS3ReadOnlyAccess + * AmazonElastiCacheReadOnlyAccess + +Step 2: Launch EC2 Instance +-------------- + +Next, launch an EC2 instance. + +1. Navigate to EC2 under AWS Console. +1. Click Launch Instance. +1. Choose 64-bit Amazon Linux AMI. +1. Choose at least a t2.medium instance. The size of the instance depends on the memory used by your ElastiCache instance that you want to analyze. +1. Under Configure Instance: + * Choose the VPC that has your ElastiCache instances. + * Choose a subnet that has network access to your ElastiCache instances. + * Ensure that your EC2 instance has a public IP Address. + * Assign the IAM role that you created in Step 1. +1. Under the storage section, allocate at least 100 GiB storage. +1. Under security group, ensure that: + * Incoming traffic is allowed on port 5540 + * Incoming traffic is allowed on port 22 only during installation +1. Review and launch the ec2 instance. + +Step 3: Verify permissions and connectivity +---------- + +Next, verify that the EC2 instance has the required IAM permissions and can connect to ElastiCache Redis instances. + +1. SSH into the newly launched EC2 instance. +1. Open a command prompt. +1. Run the command `aws s3 ls`. This should list all S3 buckets. + 1. If the `aws` command cannot be found, make sure your EC2 instance is based of Amazon Linux. +1. Next, find the hostname of the ElastiCache instance you want to analyze and run the command `echo info | nc 6379`. +1. If you see some details about the ElastiCache Redis instance, you can proceed to the next step. +1. If you cannot connect to redis, you should review your VPC, subnet, and security group settings. + +Step 4: Install Docker on EC2 +------- + +Next, install Docker on the EC2 instance. Run the following commands: + +1. `sudo yum update -y` +1. `sudo yum install -y docker` +1. `sudo service docker start` +1. `sudo usermod -a -G docker ec2-user` +1. Log out and log back in again to pick up the new docker group permissions. +1. To verify, run `docker ps`. You should see some output without having to run `sudo`. + +Step 5: Run RedisInsight in the Docker container +------- + +Finally, install RedisInsight using one of the options described below. + +1. If you do not want to persist your RedisInsight data: + +```bash +docker run -d --name redisinsight -p 5540:5540 redis/redisinsight:latest +``` +2. If you want to persist your RedisInsight data, first attach the Docker volume to the `/data` path and then run the following command: + +```bash +docker run -d --name redisinsight -p 5540:5540 redis/redisinsight:latest -v redisinsight:/data +``` + +If the previous command returns a permission error, ensure that the user with `ID = 1000` has the necessary permission to access the volume provided (`redisinsight` in the command above). + +Find the IP Address of your EC2 instances and launch your browser at `http://:5540`. Accept the EULA and start using RedisInsight. + +RedisInsight also provides a health check endpoint at `http://:5540/api/health/` to monitor the health of the running container. + +Summary +------ + +In this guide, we installed RedisInsight on an AWS EC2 instance running Docker. As a next step, you should add an ElastiCache Redis Instance and then run the memory analysis. diff --git a/docs/install/install-redisinsight/install-on-docker.md b/docs/install/install-redisinsight/install-on-docker.md new file mode 100644 index 0000000000..c73a15ea97 --- /dev/null +++ b/docs/install/install-redisinsight/install-on-docker.md @@ -0,0 +1,34 @@ +--- +title: "Install on Docker" +linkTitle: "Install on Docker" +weight: 2 +description: > + How to install RedisInsight on Docker +--- +This tutorial shows how to install RedisInsight on [Docker](https://www.docker.com/) so you can use RedisInsight in development. +See a separate guide for installing [RedisInsight on AWS](/docs/install/install-redisinsight/install-on-aws/). + +## Install Docker + +The first step is to [install Docker for your operating system](https://docs.docker.com/install/). + +## Run RedisInsight Docker image + +You can install RedisInsight using one of the options described below. + +1. If you do not want to persist your RedisInsight data: + +```bash +docker run -d --name redisinsight -p 5540:5540 redis/redisinsight:latest +``` +2. If you want to persist your RedisInsight data, first attach the Docker volume to the `/data` path and then run the following command: + +```bash +docker run -d --name redisinsight -p 5540:5540 redis/redisinsight:latest -v redisinsight:/data +``` + +If the previous command returns a permission error, ensure that the user with `ID = 1000` has the necessary permissions to access the volume provided (`redisinsight` in the command above). + +Next, point your browser to `http://localhost:5540`. + +RedisInsight also provides a health check endpoint at `http://localhost:5540/api/health/` to monitor the health of the running container. diff --git a/docs/install/install-redisinsight/install-on-k8s.md b/docs/install/install-redisinsight/install-on-k8s.md new file mode 100644 index 0000000000..8a42865fec --- /dev/null +++ b/docs/install/install-redisinsight/install-on-k8s.md @@ -0,0 +1,267 @@ +--- +title: "Install on Kubernetes" +linkTitle: "Install on Kubernetes" +weight: 4 +description: > + How to install RedisInsight on Kubernetes +--- +This tutorial shows how to install RedisInsight on [Kubernetes](https://kubernetes.io/) (K8s). +This is an easy way to use RedisInsight with a [Redis Enterprise K8s deployment](https://redis.io/docs/about/redis-enterprise/#:~:text=and%20Multi%2Dcloud-,Redis%20Enterprise%20Software,-Redis%20Enterprise%20Software). + +## Create the RedisInsight deployment and service + +Below is an annotated YAML file that will create a RedisInsight +deployment and a service in a K8s cluster. + +1. Create a new file named `redisinsight.yaml` with the content below. + +```yaml +# RedisInsight service with name 'redisinsight-service' +apiVersion: v1 +kind: Service +metadata: + name: redisinsight-service # name should not be 'redisinsight' + # since the service creates + # environment variables that + # conflicts with redisinsight + # application's environment + # variables `RI_APP_HOST` and + # `RI_APP_PORT` +spec: + type: LoadBalancer + ports: + - port: 80 + targetPort: 5540 + selector: + app: redisinsight +--- +# RedisInsight deployment with name 'redisinsight' +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redisinsight #deployment name + labels: + app: redisinsight #deployment label +spec: + replicas: 1 #a single replica pod + selector: + matchLabels: + app: redisinsight #which pods is the deployment managing, as defined by the pod template + template: #pod template + metadata: + labels: + app: redisinsight #label for pod/s + spec: + containers: + + - name: redisinsight #Container name (DNS_LABEL, unique) + image: redis/redisinsight:latest #repo/image + imagePullPolicy: IfNotPresent #Installs the latest RedisInsight version + volumeMounts: + - name: redisinsight #Pod volumes to mount into the container's filesystem. Cannot be updated. + mountPath: /data + ports: + - containerPort: 5540 #exposed container port and protocol + protocol: TCP + volumes: + - name: redisinsight + emptyDir: {} # node-ephemeral volume https://kubernetes.io/docs/concepts/storage/volumes/#emptydir +``` + +2. Create the RedisInsight deployment and service: + +```sh +kubectl apply -f redisinsight.yaml +``` + +3. Once the deployment and service are successfully applied and complete, access RedisInsight. This can be accomplished by using the `` of the service we created to reach RedisInsight. + +```sh +$ kubectl get svc redisinsight-service +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +redisinsight-service 80:32143/TCP 1m +``` + +4. If you are using minikube, run `minikube list` to list the service and access RedisInsight at `http://:`. +``` +$ minikube list +|-------------|----------------------|--------------|---------------------------------------------| +| NAMESPACE | NAME | TARGET PORT | URL | +|-------------|----------------------|--------------|---------------------------------------------| +| default | kubernetes | No node port | | +| default | redisinsight-service | 80 | http://: | +| kube-system | kube-dns | No node port | | +|-------------|----------------------|--------------|---------------------------------------------| +``` + +## Create the RedisInsight deployment with persistant storage + +Below is an annotated YAML file that will create a RedisInsight +deployment in a K8s cluster. It will assign a peristent volume created from a volume claim template. +Write access to the container is configured in an init container. When using deployments +with persistent writeable volumes, it's best to set the strategy to `Recreate`. Otherwise you may find yourself +with two pods trying to use the same volume. + +1. Create a new file `redisinsight.yaml` with the content below. + +```yaml +# RedisInsight service with name 'redisinsight-service' +apiVersion: v1 +kind: Service +metadata: + name: redisinsight-service # name should not be 'redisinsight' + # since the service creates + # environment variables that + # conflicts with redisinsight + # application's environment + # variables `RI_APP_HOST` and + # `RI_APP_PORT` +spec: + type: LoadBalancer + ports: + - port: 80 + targetPort: 5540 + selector: + app: redisinsight +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: redisinsight-pv-claim + labels: + app: redisinsight +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + storageClassName: default +--- +# RedisInsight deployment with name 'redisinsight' +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redisinsight #deployment name + labels: + app: redisinsight #deployment label +spec: + replicas: 1 #a single replica pod + strategy: + type: Recreate + selector: + matchLabels: + app: redisinsight #which pods is the deployment managing, as defined by the pod template + template: #pod template + metadata: + labels: + app: redisinsight #label for pod/s + spec: + volumes: + - name: redisinsight + persistentVolumeClaim: + claimName: redisinsight-pv-claim + initContainers: + - name: init + image: busybox + command: + - /bin/sh + - '-c' + - | + chown -R 1001 /data + resources: {} + volumeMounts: + - name: redisinsight + mountPath: /data + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + containers: + - name: redisinsight #Container name (DNS_LABEL, unique) + image: redis/redisinsight:latest #repo/image + imagePullPolicy: IfNotPresent #Always pull image + volumeMounts: + - name: redisinsight #Pod volumes to mount into the container's filesystem. Cannot be updated. + mountPath: /data + ports: + - containerPort: 5540 #exposed container port and protocol + protocol: TCP +``` + +2. Create the RedisInsight deployment and service. + +```sh +kubectl apply -f redisinsight.yaml +``` + +## Create the RedisInsight deployment without a service. + +Below is an annotated YAML file that will create a RedisInsight +deployment in a K8s cluster. + +1. Create a new file redisinsight.yaml with the content below + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redisinsight #deployment name + labels: + app: redisinsight #deployment label +spec: + replicas: 1 #a single replica pod + selector: + matchLabels: + app: redisinsight #which pods is the deployment managing, as defined by the pod template + template: #pod template + metadata: + labels: + app: redisinsight #label for pod/s + spec: + containers: + - name: redisinsight #Container name (DNS_LABEL, unique) + image: redis/redisinsight:latest #repo/image + imagePullPolicy: IfNotPresent #Always pull image + env: + # If there's a service named 'redisinsight' that exposes the + # deployment, we manually set `RI_APP_HOST` and + # `RI_APP_PORT` to override the service environment + # variables. + - name: RI_APP_HOST + value: "0.0.0.0" + - name: RI_APP_PORT + value: "5540" + volumeMounts: + - name: redisinsight #Pod volumes to mount into the container's filesystem. Cannot be updated. + mountPath: /data + ports: + - containerPort: 5540 #exposed container port and protocol + protocol: TCP + livenessProbe: + httpGet: + path : /healthcheck/ # exposed RI endpoint for healthcheck + port: 5540 # exposed container port + initialDelaySeconds: 5 # number of seconds to wait after the container starts to perform liveness probe + periodSeconds: 5 # period in seconds after which liveness probe is performed + failureThreshold: 1 # number of liveness probe failures after which container restarts + volumes: + - name: redisinsight + emptyDir: {} # node-ephemeral volume https://kubernetes.io/docs/concepts/storage/volumes/#emptydir +``` + +2. Create the RedisInsight deployment + +```sh +kubectl apply -f redisinsight.yaml +``` + +{{< alert title="Note" >}} +If the deployment will be exposed by a service whose name is 'redisinsight', set `RI_APP_HOST` and `RI_APP_PORT` environment variables to override the environment variables created by the service. +{{< /alert >}} + +3. Once the deployment has been successfully applied and the deployment is complete, access RedisInsight. This can be accomplished by exposing the deployment as a K8s Service or by using port forwarding, as in the example below: + +```sh +kubectl port-forward deployment/redisinsight 5540 +``` + +Open your browser and point to diff --git a/docs/interact/programmability/functions-intro.md b/docs/interact/programmability/functions-intro.md index b4dc77033c..7d7d8e2543 100644 --- a/docs/interact/programmability/functions-intro.md +++ b/docs/interact/programmability/functions-intro.md @@ -272,14 +272,20 @@ redis> FUNCTION LIST 2) "my_hset" 3) "description" 4) (nil) + 5) "flags" + 6) (empty array) 2) 1) "name" 2) "my_hgetall" 3) "description" 4) (nil) + 5) "flags" + 6) (empty array) 3) 1) "name" 2) "my_hlastmodified" 3) "description" 4) (nil) + 5) "flags" + 6) (empty array) ``` You can see that it is easy to update our library with new capabilities. diff --git a/docs/interact/programmability/lua-api.md b/docs/interact/programmability/lua-api.md index f5d6e3e505..3fa62f10c9 100644 --- a/docs/interact/programmability/lua-api.md +++ b/docs/interact/programmability/lua-api.md @@ -670,6 +670,7 @@ The following [standard Lua libraries](https://www.lua.org/manual/5.1/manual.htm * The [_String Manipulation (string)_ library](https://www.lua.org/manual/5.1/manual.html#5.4) * The [_Table Manipulation (table)_ library](https://www.lua.org/manual/5.1/manual.html#5.5) * The [_Mathematical Functions (math)_ library](https://www.lua.org/manual/5.1/manual.html#5.6) +* The [_Operating System Facilities (os)_ library](#os-library) In addition, the following external libraries are loaded and accessible to scripts: @@ -678,6 +679,18 @@ In addition, the following external libraries are loaded and accessible to scrip * The [_cmsgpack_ library](#cmsgpack-library) * The [_bitop_ library](#bitop-library) +### _os_ library + +* Since version: 8.0.0 +* Available in scripts: yes +* Available in functions: yes + +_os_ provides a set of functions for dealing with date, time, and system commands. +More details can be found in the [Operating System Facilities](https://www.lua.org/manual/5.1/manual.html#5.8). +Note that for sandbox security, currently only the following os functions is exposed: + +* `os.clock()` + ### _struct_ library * Since version: 2.6.0 diff --git a/docs/management/admin.md b/docs/management/admin.md index 8d31b9a14d..116b3aca21 100644 --- a/docs/management/admin.md +++ b/docs/management/admin.md @@ -17,7 +17,7 @@ aliases: [ * Deploy Redis using the Linux operating system. Redis is also tested on OS X, and from time to time on FreeBSD and OpenBSD systems. However, Linux is where most of the stress testing is performed, and where most production deployments are run. -* Set the Linux kernel overcommit memory setting to 1. Add `vm.overcommit_memory = 1` to `/etc/sysctl.conf`. Then, reboot or run the command `sysctl vm.overcommit_memory=1` to activate the setting. See [FAQ: Background saving fails with a fork() error on Linux?](https://redis.io/docs/getting-started/faq/#background-saving-fails-with-a-fork-error-on-linux) for details. +* Set the Linux kernel overcommit memory setting to 1. Add `vm.overcommit_memory = 1` to `/etc/sysctl.conf`. Then, reboot or run the command `sysctl vm.overcommit_memory=1` to activate the setting. See [FAQ: Background saving fails with a fork() error on Linux?](https://redis.io/docs/get-started/faq/#background-saving-fails-with-a-fork-error-on-linux) for details. * To ensure the Linux kernel feature Transparent Huge Pages does not impact Redis memory usage and latency, run the command: `echo never > /sys/kernel/mm/transparent_hugepage/enabled` to disable it. See [Latency Diagnosis - Latency induced by transparent huge pages](https://redis.io/docs/management/optimization/latency/#latency-induced-by-transparent-huge-pages) for additional context. diff --git a/docs/management/persistence.md b/docs/management/persistence.md index e2e4be102b..4328c1b849 100644 --- a/docs/management/persistence.md +++ b/docs/management/persistence.md @@ -259,26 +259,30 @@ and starts appending new data into the new file. ### How I can switch to AOF, if I'm currently using dump.rdb snapshots? -There is a different procedure to do this in version 2.0 and later versions, as you -can guess it's simpler since Redis 2.2 and does not require a restart at all. +If you want to enable AOF in a server that is currently using RDB snapshots, you need to convert the data by enabling AOF via CONFIG command on the live server first. + +**IMPORTANT:** not following this procedure (e.g. just changing the config and restarting the server) can result in data loss! **Redis >= 2.2** +Preparations: + * Make a backup of your latest dump.rdb file. * Transfer this backup to a safe place. -* Issue the following two commands: -* `redis-cli config set appendonly yes` -* `redis-cli config set save ""` -* Make sure your database contains the same number of keys it contained. -* Make sure writes are appended to the append only file correctly. -The first CONFIG command enables the Append Only File persistence. +Switch to AOF on live database: -The second CONFIG command is used to turn off snapshotting persistence. This is optional, if you wish you can take both the persistence methods enabled. +* Enable AOF: `redis-cli config set appendonly yes` +* Optionally disable RDB: `redis-cli config set save ""` +* Make sure writes are appended to the append only file correctly. +* **IMPORTANT:** Update your `redis.conf` (potentially through `CONFIG REWRITE`) and ensure that it matches the configuration above. + If you forget this step, when you restart the server, the configuration changes will be lost and the server will start again with the old configuration, resulting in a loss of your data. + +Next time you restart the server: -**IMPORTANT:** remember to edit your redis.conf to turn on the AOF, otherwise -when you restart the server the configuration changes will be lost and the -server will start again with the old configuration. +* Before restarting the server, wait for AOF rewrite to finish persisting the data. + You can do that by watching `INFO persistence`, waiting for `aof_rewrite_in_progress` and `aof_rewrite_scheduled` to be `0`, and validating that `aof_last_bgrewrite_status` is `ok`. +* After restarting the server, check that your database contains the same number of keys it contained previously. **Redis 2.0** @@ -294,7 +298,6 @@ server will start again with the old configuration. ## Interactions between AOF and RDB persistence - Redis >= 2.4 makes sure to avoid triggering an AOF rewrite when an RDB snapshotting operation is already in progress, or allowing a `BGSAVE` while the AOF rewrite is in progress. This prevents two Redis background processes diff --git a/docs/management/scaling.md b/docs/management/scaling.md index bb47574241..11de8eaafe 100644 --- a/docs/management/scaling.md +++ b/docs/management/scaling.md @@ -1,6 +1,6 @@ --- -title: Scaling with Redis Cluster -linkTitle: Scaling +title: Scale with Redis Cluster +linkTitle: Scale with Redis Cluster weight: 6 description: Horizontal scaling with Redis Cluster aliases: [ @@ -875,6 +875,14 @@ over one of its replicas and remove the node after it turned into a replica of t new master. Obviously this does not help when you want to reduce the actual number of masters in your cluster, in that case, a resharding is needed. +There is a special scenario where you want to remove a failed node. +You should not use the `del-node` command because it tries to connect to all nodes and you will encounter a "connection refused" error. +Instead, you can use the `call` command: + + redis-cli --cluster call 127.0.0.1:7000 cluster forget `` + +This command will execute `CLUSTER FORGET` command on every node. + #### Replica migration In Redis Cluster, you can reconfigure a replica to replicate with a diff --git a/docs/manual/keyspace.md b/docs/manual/keyspace.md index 5e37c2bf1f..f6f443f64d 100644 --- a/docs/manual/keyspace.md +++ b/docs/manual/keyspace.md @@ -114,190 +114,8 @@ To incrementally iterate over the keys in a Redis database in an efficient mann Since `SCAN` allows for incremental iteration, returning only a small number of elements per call, it can be used in production without the downside of commands like `KEYS` or `SMEMBERS` that may block the server for a long time (even several seconds) when called against big collections of keys or elements. -However while blocking commands like `SMEMBERS` are able to provide all the elements that are part of a Set in a given moment, The SCAN family of commands only offer limited guarantees about the returned elements since the collection that we incrementally iterate can change during the iteration process. - -#### SCAN basic usage - -SCAN is a cursor based iterator. This means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. - -An iteration starts when the cursor is set to 0, and terminates when the cursor returned by the server is 0. The following is an example of SCAN iteration: - -``` -redis 127.0.0.1:6379> scan 0 -1) "17" -2) 1) "key:12" - 2) "key:8" - 3) "key:4" - 4) "key:14" - 5) "key:16" - 6) "key:17" - 7) "key:15" - 8) "key:10" - 9) "key:3" - 10) "key:7" - 11) "key:1" -redis 127.0.0.1:6379> scan 17 -1) "0" -2) 1) "key:5" - 2) "key:18" - 3) "key:0" - 4) "key:2" - 5) "key:19" - 6) "key:13" - 7) "key:6" - 8) "key:9" - 9) "key:11" -``` - -In the example above, the first call uses zero as a cursor, to start the iteration. The second call uses the cursor returned by the previous call as the first element of the reply, that is, 17. - -As you can see the **SCAN return value** is an array of two values: the first value is the new cursor to use in the next call, the second value is an array of elements. - -Since in the second call the returned cursor is 0, the server signaled to the caller that the iteration finished, and the collection was completely explored. Starting an iteration with a cursor value of 0, and calling `SCAN` until the returned cursor is 0 again is called a **full iteration**. - -#### Scan guarantees - -The `SCAN` command, and the other commands in the `SCAN` family, are able to provide to the user a set of guarantees associated to full iterations. - -* A full iteration always retrieves all the elements that were present in the collection from the start to the end of a full iteration. This means that if a given element is inside the collection when an iteration is started, and is still there when an iteration terminates, then at some point `SCAN` returned it to the user. -* A full iteration never returns any element that was NOT present in the collection from the start to the end of a full iteration. So if an element was removed before the start of an iteration, and is never added back to the collection for all the time an iteration lasts, `SCAN` ensures that this element will never be returned. - -However because `SCAN` has very little state associated (just the cursor) it has the following drawbacks: - -* A given element may be returned multiple times. It is up to the application to handle the case of duplicated elements, for example only using the returned elements in order to perform operations that are safe when re-applied multiple times. -* Elements that were not constantly present in the collection during a full iteration, may be returned or not: it is undefined. - -#### Number of elements returned at every SCAN call - -`SCAN` family functions do not guarantee that the number of elements returned per call are in a given range. The commands are also allowed to return zero elements, and the client should not consider the iteration complete as long as the returned cursor is not zero. - -However the number of returned elements is reasonable, that is, in practical terms SCAN may return a maximum number of elements in the order of a few tens of elements when iterating a large collection, or may return all the elements of the collection in a single call when the iterated collection is small enough to be internally represented as an encoded data structure (this happens for small sets, hashes and sorted sets). - -However there is a way for the user to tune the order of magnitude of the number of returned elements per call using the **COUNT** option. - -#### The COUNT option - -While `SCAN` does not provide guarantees about the number of elements returned at every iteration, it is possible to empirically adjust the behavior of `SCAN` using the **COUNT** option. Basically with COUNT the user specified the *amount of work that should be done at every call in order to retrieve elements from the collection*. This is **just a hint** for the implementation, however generally speaking this is what you could expect most of the times from the implementation. - -* The default COUNT value is 10. -* When iterating the key space, or a Set, Hash or Sorted Set that is big enough to be represented by a hash table, assuming no **MATCH** option is used, the server will usually return *count* or a bit more than *count* elements per call. Please check the *why SCAN may return all the elements at once* section later in this document. -* When iterating Sets encoded as intsets (small sets composed of just integers), or Hashes and Sorted Sets encoded as ziplists (small hashes and sets composed of small individual values), usually all the elements are returned in the first `SCAN` call regardless of the COUNT value. - -Important: **there is no need to use the same COUNT value** for every iteration. The caller is free to change the count from one iteration to the other as required, as long as the cursor passed in the next call is the one obtained in the previous call to the command. - -#### The MATCH option - -It is possible to only iterate elements matching a given glob-style pattern, similarly to the behavior of the `KEYS` command that takes a pattern as its only argument. - -To do so, just append the `MATCH ` arguments at the end of the `SCAN` command (it works with all the SCAN family commands). - -This is an example of iteration using **MATCH**: - -``` -redis 127.0.0.1:6379> sadd myset 1 2 3 foo foobar feelsgood -(integer) 6 -redis 127.0.0.1:6379> sscan myset 0 match f* -1) "0" -2) 1) "foo" - 2) "feelsgood" - 3) "foobar" -redis 127.0.0.1:6379> -``` - -It is important to note that the **MATCH** filter is applied after elements are retrieved from the collection, just before returning data to the client. This means that if the pattern matches very little elements inside the collection, `SCAN` will likely return no elements in most iterations. An example is shown below: - -``` -redis 127.0.0.1:6379> scan 0 MATCH *11* -1) "288" -2) 1) "key:911" -redis 127.0.0.1:6379> scan 288 MATCH *11* -1) "224" -2) (empty list or set) -redis 127.0.0.1:6379> scan 224 MATCH *11* -1) "80" -2) (empty list or set) -redis 127.0.0.1:6379> scan 80 MATCH *11* -1) "176" -2) (empty list or set) -redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000 -1) "0" -2) 1) "key:611" - 2) "key:711" - 3) "key:118" - 4) "key:117" - 5) "key:311" - 6) "key:112" - 7) "key:111" - 8) "key:110" - 9) "key:113" - 10) "key:211" - 11) "key:411" - 12) "key:115" - 13) "key:116" - 14) "key:114" - 15) "key:119" - 16) "key:811" - 17) "key:511" - 18) "key:11" -redis 127.0.0.1:6379> -``` - -As you can see most of the calls returned zero elements, but the last call where a COUNT of 1000 was used in order to force the command to do more scanning for that iteration. - - -#### The TYPE option - -You can use the `!TYPE` option to ask `SCAN` to only return objects that match a given `type`, allowing you to iterate through the database looking for keys of a specific type. The **TYPE** option is only available on the whole-database `SCAN`, not `HSCAN` or `ZSCAN` etc. - -The `type` argument is the same string name that the `TYPE` command returns. Note a quirk where some Redis types, such as GeoHashes, HyperLogLogs, Bitmaps, and Bitfields, may internally be implemented using other Redis types, such as a string or zset, so can't be distinguished from other keys of that same type by `SCAN`. For example, a ZSET and GEOHASH: - -``` -redis 127.0.0.1:6379> GEOADD geokey 0 0 value -(integer) 1 -redis 127.0.0.1:6379> ZADD zkey 1000 value -(integer) 1 -redis 127.0.0.1:6379> TYPE geokey -zset -redis 127.0.0.1:6379> TYPE zkey -zset -redis 127.0.0.1:6379> SCAN 0 TYPE zset -1) "0" -2) 1) "geokey" - 2) "zkey" -``` - -It is important to note that the **TYPE** filter is also applied after elements are retrieved from the database, so the option does not reduce the amount of work the server has to do to complete a full iteration, and for rare types you may receive no elements in many iterations. - -#### Multiple parallel iterations - -It is possible for an infinite number of clients to iterate the same collection at the same time, as the full state of the iterator is in the cursor, that is obtained and returned to the client at every call. No server side state is taken at all. - -#### Terminating iterations in the middle - -Since there is no state server side, but the full state is captured by the cursor, the caller is free to terminate an iteration half-way without signaling this to the server in any way. An infinite number of iterations can be started and never terminated without any issue. - -#### Calling SCAN with a corrupted cursor - -Calling `SCAN` with a broken, negative, out of range, or otherwise invalid cursor, will result in undefined behavior but never in a crash. What will be undefined is that the guarantees about the returned elements can no longer be ensured by the `SCAN` implementation. - -The only valid cursors to use are: - -* The cursor value of 0 when starting an iteration. -* The cursor returned by the previous call to SCAN in order to continue the iteration. - -#### Guarantee of termination - -The `SCAN` algorithm is guaranteed to terminate only if the size of the iterated collection remains bounded to a given maximum size, otherwise iterating a collection that always grows may result into `SCAN` to never terminate a full iteration. - -This is easy to see intuitively: if the collection grows there is more and more work to do in order to visit all the possible elements, and the ability to terminate the iteration depends on the number of calls to `SCAN` and its COUNT option value compared with the rate at which the collection grows. - -#### Why SCAN may return all the items of an aggregate data type in a single call? - -In the `COUNT` option documentation, we state that sometimes this family of commands may return all the elements of a Set, Hash or Sorted Set at once in a single call, regardless of the `COUNT` option value. The reason why this happens is that the cursor-based iterator can be implemented, and is useful, only when the aggregate data type that we are scanning is represented as a hash table. However Redis uses a [memory optimization](/topics/memory-optimization) where small aggregate data types, until they reach a given amount of items or a given max size of single elements, are represented using a compact single-allocation packed encoding. When this is the case, `SCAN` has no meaningful cursor to return, and must iterate the whole data structure at once, so the only sane behavior it has is to return everything in a call. - -However once the data structures are bigger and are promoted to use real hash tables, the `SCAN` family of commands will resort to the normal behavior. Note that since this special behavior of returning all the elements is true only for small aggregates, it has no effects on the command complexity or latency. However the exact limits to get converted into real hash tables are [user configurable](/topics/memory-optimization), so the maximum number of elements you can see returned in a single call depends on how big an aggregate data type could be and still use the packed representation. - -Also note that this behavior is specific of `SSCAN`, `HSCAN` and `ZSCAN`. `SCAN` itself never shows this behavior because the key space is always represented by hash tables. +However while blocking commands like `SMEMBERS` are able to provide all the elements that are part of a Set in a given moment. +The `SCAN` family of commands only offer limited guarantees about the returned elements since the collection that we incrementally iterate can change during the iteration process. ### Keys diff --git a/docs/manual/patterns/distributed-locks.md b/docs/manual/patterns/distributed-locks.md index 603e0e91fc..e4169f8970 100644 --- a/docs/manual/patterns/distributed-locks.md +++ b/docs/manual/patterns/distributed-locks.md @@ -46,7 +46,6 @@ already available that can be used for reference. * [Redis-plus-plus](https://github.com/sewenew/redis-plus-plus/#redlock) (C++ implementation). * [Redlock-cs](https://github.com/kidfashion/redlock-cs) (C#/.NET implementation). * [RedLock.net](https://github.com/samcook/RedLock.net) (C#/.NET implementation). Includes async and lock extension support. -* [ScarletLock](https://github.com/psibernetic/scarletlock) (C# .NET implementation with configurable datastore). * [Redlock4Net](https://github.com/LiZhenNet/Redlock4Net) (C# .NET implementation). * [node-redlock](https://github.com/mike-marcacci/node-redlock) (NodeJS implementation). Includes support for lock extension. * [Deno DLM](https://github.com/oslabs-beta/Deno-Redlock) (Deno implementation) diff --git a/docs/reference/clients.md b/docs/reference/clients.md index b71007c3f2..45dbcb1608 100644 --- a/docs/reference/clients.md +++ b/docs/reference/clients.md @@ -47,8 +47,7 @@ However, Redis does the following two things when serving clients: In Redis 2.4 there was a hard-coded limit for the maximum number of clients that could be handled simultaneously. -In Redis 2.6 and newer, this limit is dynamic: by default it is set to 10000 clients, unless -otherwise stated by the `maxclients` directive in `redis.conf`. +In Redis 2.6 and newer, this limit is configurable using the `maxclients` directive in `redis.conf`. The default is 10,000 clients. However, Redis checks with the kernel what the maximum number of file descriptors that we are able to open is (the *soft limit* is checked). If the diff --git a/docs/reference/cluster-spec.md b/docs/reference/cluster-spec.md index 64c8016980..6a1eb47cc4 100644 --- a/docs/reference/cluster-spec.md +++ b/docs/reference/cluster-spec.md @@ -199,6 +199,23 @@ Examples: * For the key `foo{bar}{zap}` the substring `bar` will be hashed, since the algorithm stops at the first valid or invalid (without bytes inside) match of `{` and `}`. * What follows from the algorithm is that if the key starts with `{}`, it is guaranteed to be hashed as a whole. This is useful when using binary data as key names. +#### Glob-style patterns + +Commands accepting a glob-style pattern, including `KEYS`, `SCAN` and `SORT`, are optimized for patterns that imply a single slot. +This means that if all keys that can match a pattern must belong to a specific slot, only this slot is searched for keys matching the pattern. +The pattern slot optimization is introduced in Redis 8.0. + +The optimization kicks in when the pattern meets the following conditions: + +* the pattern contains a hashtag, +* there are no wildcards or escape characters before the hashtag, and +* the hashtag within curly braces doesn't contain any wildcards or escape characters. + +For example, `SCAN 0 MATCH {abc}*` can successfully recognize the hashtag and scans only the slot corresponding to `abc`. +However, the patterns `*{abc}`, `{a*c}`, or `{a\*bc}` cannot recognize the hashtag, so all slots need to be scanned. + +#### Hash slot example code + Adding the hash tags exception, the following is an implementation of the `HASH_SLOT` function in Ruby and C language. Ruby example code: diff --git a/docs/reference/command-tips.md b/docs/reference/command-tips.md index 090c1e7e0b..5a373624d7 100644 --- a/docs/reference/command-tips.md +++ b/docs/reference/command-tips.md @@ -50,7 +50,9 @@ In cases where the client should adopt a behavior different than the default, th This tip is in-use by commands that don't accept key name arguments. The command operates atomically per shard. - **multi_shard:** the client should execute the command on several shards. - The shards that execute the command are determined by the hash slots of its input key name arguments. + The client should split the inputs according to the hash slots of its input key name arguments. + For example, the command `DEL {foo} {foo}1 bar` should be split to `DEL {foo} {foo}1` and `DEL bar`. + If the keys are hashed to more than a single slot, the command must be split even if all the slots are managed by the same shard. Examples for such commands include `MSET`, `MGET` and `DEL`. However, note that `SUNIONSTORE` isn't considered as _multi_shard_ because all of its keys must belong to the same hash slot. - **special:** indicates a non-trivial form of the client's request policy, such as the `SCAN` command. diff --git a/docs/reference/eviction/index.md b/docs/reference/eviction/index.md index 4874a82bb2..0cf1b5be97 100644 --- a/docs/reference/eviction/index.md +++ b/docs/reference/eviction/index.md @@ -158,7 +158,7 @@ By default Redis is configured to: * Saturate the counter at, around, one million requests. * Decay the counter every one minute. -Those should be reasonable values and were tested experimental, but the user may want to play with these configuration settings to pick optimal values. +Those should be reasonable values and were tested experimentally, but the user may want to play with these configuration settings to pick optimal values. Instructions about how to tune these parameters can be found inside the example `redis.conf` file in the source distribution. Briefly, they are: diff --git a/docs/reference/protocol-spec.md b/docs/reference/protocol-spec.md index bbb9f331cc..c5ace66fd8 100644 --- a/docs/reference/protocol-spec.md +++ b/docs/reference/protocol-spec.md @@ -67,7 +67,7 @@ This is the simplest model possible; however, there are some exceptions: The protocol of this mode is not specified but is obvious to parse. * [Protected mode](/docs/management/security/#protected-mode). Connections opened from a non-loopback address to a Redis while in protected mode are denied and terminated by the server. - Before terminating the connection, Redis unconditionally sends `-DENIED` reply, irregardless of whether the client writes to the socket. + Before terminating the connection, Redis unconditionally sends a `-DENIED` reply, regardless of whether the client writes to the socket. * The [RESP3 Push type](#resp3-pushes). As the name suggests, a push type allows the server to send out-of-band data to the connection. The server may push data at any time, and the data isn't necessarily related to specific commands executed by the client. @@ -298,7 +298,7 @@ For example, a nested array of two arrays is encoded as follows: (The raw RESP encoding is split into multiple lines for readability). -The above encodes a two-elements array. +The above encodes a two-element array. The first element is an array that, in turn, contains three integers (1, 2, 3). The second element is another array containing a simple string and an error. @@ -356,7 +356,7 @@ Due to historical reasons, RESP2 features two specially crafted values for repre This duality has always been a redundancy that added zero semantical value to the protocol itself. The null type, introduced in RESP3, aims to fix this wrong. -{{% /alert %}}}} +{{% /alert %}} @@ -516,8 +516,9 @@ However, low-level programming languages (such as C, for example) will likely re {{% alert title="Map pattern in RESP2" color="info" %}} RESP2 doesn't have a map type. -Maps in RESP2 are represented by arrays, in which each element is a key-value tuple. -Each tuple is an array with two elements, these being the key and the value. +A map in RESP2 is represented by a flat array containing the keys and the values. +The first element is a key, followed by the corresponding value, then the next key and so on, like this: +`key1, value1, key2, value2, ...`. {{% /alert %}} diff --git a/docs/ui/_index.md b/docs/ui/_index.md deleted file mode 100644 index a7e27b13f5..0000000000 --- a/docs/ui/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: User interfaces -linkTitle: User interfaces -description: Learn how to use Redis interfaces -weight: 30 ---- -The Redis command line interface (redis-cli) is a terminal program used to send commands to and read replies from the Redis server. It has two main modes: an interactive Read Eval Print Loop (REPL) mode where the user types Redis commands and receives replies, and a command mode where redis-cli is executed with additional arguments and the reply is printed to the standard output. - -RedisInsight combines a graphical user interface with Redis CLI to let you work with any Redis deployment. You can visually browse and interact with data, take advantage of diagnostic tools, learn by example, and much more. Best of all, RedisInsight is free. diff --git a/languages.json b/languages.json index b201a3bbca..45bf6c212d 100644 --- a/languages.json +++ b/languages.json @@ -1,6 +1,7 @@ { "ActionScript": "actionscript", "ActiveX/COM+": "activex-com", + "Ballerina": "ballerina", "Bash": "bash", "Boomi": "boomi", "C": "c", @@ -18,6 +19,7 @@ "Erlang": "erlang", "Fancy": "fancy", "gawk": "gawk", + "Gleam": "gleam", "GNU Prolog": "gnu-prolog", "Go": "go", "Haskell": "haskell", diff --git a/libraries/c/github.com/redis/librdb.json b/libraries/c/github.com/redis/librdb.json new file mode 100644 index 0000000000..23818714d8 --- /dev/null +++ b/libraries/c/github.com/redis/librdb.json @@ -0,0 +1,5 @@ +{ + "name": "librdb", + "description": "Redis RDB file parser, with JSON, RESP and RDB-loader extensions", + "recommended": true +} diff --git a/modules/community/github.com/FalkorDB/FalkorDB.json b/modules/community/github.com/FalkorDB/FalkorDB.json new file mode 100644 index 0000000000..dac23f5ead --- /dev/null +++ b/modules/community/github.com/FalkorDB/FalkorDB.json @@ -0,0 +1,8 @@ +{ + "name": "FalkorDB", + "license": "SSPL", + "description": "A graph database with a Cypher-based querying language using sparse adjacency matrices", + "github": [ + "FalkorDB" + ] +} diff --git a/resp2_replies.json b/resp2_replies.json new file mode 100644 index 0000000000..33abc6c5cb --- /dev/null +++ b/resp2_replies.json @@ -0,0 +1,1320 @@ +{ + "ACL": [], + "ACL CAT": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array of [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) elements representing ACL categories or commands in a given category.", + "* [Simple error reply](/docs/reference/protocol-spec#simple-errors): the command returns an error if an invalid category name is given." + ], + "ACL DELUSER": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of users that were deleted. This number will not always match the number of arguments since certain users may not exist." + ], + "ACL DRYRUN": [ + "Any of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` on success.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): an error describing why the user can't execute the command." + ], + "ACL GENPASS": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): pseudorandom data. By default it contains 64 bytes, representing 256 bits of data. If `bits` was given, the output string length is the number of specified bits (rounded to the next multiple of 4) divided by 4." + ], + "ACL GETUSER": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of ACL rule definitions for the user.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if user does not exist." + ], + "ACL HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of subcommands and their descriptions." + ], + "ACL LIST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array of [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) elements." + ], + "ACL LOG": [ + "When called to show security events:", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array of [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) elements representing ACL security events.", + "When called with `RESET`:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the security log was cleared." + ], + "ACL SAVE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`.", + "The command may fail with an error for several reasons: if the file cannot be written or if the server is not configured to use an external ACL file." + ], + "ACL SETUSER": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`.", + "If the rules contain errors, the error is returned." + ], + "ACL USERS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): list of existing ACL users." + ], + "ACL WHOAMI": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the username of the current connection." + ], + "ACL-LOAD": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` on success.", + "", + "The command may fail with an error for several reasons: if the file is not readable, if there is an error inside the file, and in such cases, the error will be reported to the user in the error.", + "Finally, the command will fail if the server is not configured to use an external ACL file." + ], + "APPEND": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the string after the append operation." + ], + "ASKING": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "AUTH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`, or an error if the password, or username/password pair, is invalid." + ], + "BGREWRITEAOF": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): a simple string reply indicating that the rewriting started or is about to start ASAP when the call is executed with success.", + "", + "The command may reply with an error in certain cases, as documented above." + ], + "BGSAVE": [ + "One of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `Background saving started`.", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `Background saving scheduled`." + ], + "BITCOUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of bits set to 1." + ], + "BITFIELD": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): each entry being the corresponding result of the sub-command given at the same position.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if OVERFLOW FAIL was given and overflows or underflows are detected." + ], + "BITFIELD_RO": [ + "[Array reply](/docs/reference/protocol-spec#arrays): each entry being the corresponding result of the sub-command given at the same position." + ], + "BITOP": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the size of the string stored in the destination key is equal to the size of the longest input string." + ], + "BITPOS": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): the position of the first bit set to 1 or 0 according to the request", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1`. In case the `bit` argument is 1 and the string is empty or composed of just zero bytes", + "", + "If we look for set bits (the bit argument is 1) and the string is empty or composed of just zero bytes, -1 is returned.", + "", + "If we look for clear bits (the bit argument is 0) and the string only contains bits set to 1, the function returns the first bit not part of the string on the right. So if the string is three bytes set to the value `0xff` the command `BITPOS key 0` will return 24, since up to bit 23 all the bits are 1.", + "", + "The function considers the right of the string as padded with zeros if you look for clear bits and specify no range or the _start_ argument **only**.", + "", + "However, this behavior changes if you are looking for clear bits and specify a range with both _start_ and _end_.", + "If a clear bit isn't found in the specified range, the function returns -1 as the user specified a clear range and there are no 0 bits in that range." + ], + "BLMOVE": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the element being popped from the _source_ and pushed to the _destination_.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): the operation timed-out" + ], + "BLMPOP": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): when no element could be popped and the _timeout_ is reached.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a two-element array with the first element being the name of the key from which elements were popped, and the second element being an array of the popped elements." + ], + "BLPOP": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): no element could be popped and the timeout expired", + "* [Array reply](/docs/reference/protocol-spec#arrays): the key from which the element was popped and the value of the popped element." + ], + "BRPOP": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): no element could be popped and the timeout expired.", + "* [Array reply](/docs/reference/protocol-spec#arrays): the key from which the element was popped and the value of the popped element" + ], + "BRPOPLPUSH": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the element being popped from _source_ and pushed to _destination_.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): the timeout is reached." + ], + "BZMPOP": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): when no element could be popped.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a two-element array with the first element being the name of the key from which elements were popped, and the second element is an array of the popped elements. Every entry in the elements array is also an array that contains the member and its score." + ], + "BZPOPMAX": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): when no element could be popped and the _timeout_ expired.", + "* [Array reply](/docs/reference/protocol-spec#arrays): the keyname, popped member, and its score." + ], + "BZPOPMIN": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): when no element could be popped and the _timeout_ expired.", + "* [Array reply](/docs/reference/protocol-spec#arrays): the keyname, popped member, and its score." + ], + "CLIENT": [], + "CLIENT CACHING": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` or an error if the argument is not \"yes\" or \"no\"." + ], + "CLIENT GETNAME": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the connection name of the current connection.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): the connection name was not set." + ], + "CLIENT GETREDIR": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` when not redirecting notifications to any client.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if client tracking is not enabled.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the ID of the client to which notification are being redirected." + ], + "CLIENT HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of subcommands and their descriptions." + ], + "CLIENT ID": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the ID of the client." + ], + "CLIENT INFO": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a unique string for the current client, as described at the `CLIENT LIST` page." + ], + "CLIENT KILL": [ + "One of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` when called in 3 argument format and the connection has been closed.", + "* [Integer reply](/docs/reference/protocol-spec#integers): when called in filter/value format, the number of clients killed." + ], + "CLIENT LIST": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): information and statistics about client connections." + ], + "CLIENT NO-EVICT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "CLIENT NO-TOUCH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "CLIENT PAUSE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` or an error if the timeout is invalid." + ], + "CLIENT REPLY": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` when called with `ON`. When called with either `OFF` or `SKIP` sub-commands, no reply is made." + ], + "CLIENT SETINFO": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the attribute name was successfully set." + ], + "CLIENT SETNAME": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the connection name was successfully set." + ], + "CLIENT TRACKING": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the connection was successfully put in tracking mode or if the tracking mode was successfully disabled. Otherwise, an error is returned." + ], + "CLIENT TRACKINGINFO": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of tracking information sections and their respective values." + ], + "CLIENT UNBLOCK": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the client was unblocked successfully.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the client wasn't unblocked." + ], + "CLIENT UNPAUSE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "CLUSTER": [], + "CLUSTER ADDSLOTS": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER ADDSLOTSRANGE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER BUMPEPOCH": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): `BUMPED` if the epoch was incremented.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): `STILL` if the node already has the greatest configured epoch in the cluster." + ], + "CLUSTER COUNT-FAILURE-REPORTS": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of active failure reports for the node." + ], + "CLUSTER COUNTKEYSINSLOT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The number of keys in the specified hash slot, or an error if the hash slot is invalid." + ], + "CLUSTER DELSLOTS": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER DELSLOTSRANGE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER FAILOVER": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was accepted and a manual failover is going to be attempted. An error if the operation cannot be executed, for example if the client is connected to a node that is already a master." + ], + "CLUSTER FLUSHSLOTS": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`" + ], + "CLUSTER FORGET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was executed successfully. Otherwise an error is returned." + ], + "CLUSTER GETKEYSINSLOT": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array with up to count elements." + ], + "CLUSTER HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of subcommands and their descriptions." + ], + "CLUSTER INFO": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): A map between named fields and values in the form of `:` lines separated by newlines composed by the two bytes `CRLF`." + ], + "CLUSTER KEYSLOT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The hash slot number for the specified key" + ], + "CLUSTER LINKS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array of maps where each map contains various attributes and their values of a cluster link." + ], + "CLUSTER MEET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. If the address or port specified are invalid an error is returned." + ], + "CLUSTER MYID": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the node ID." + ], + "CLUSTER MYSHARDID": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the node's shard ID." + ], + "CLUSTER NODES": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the serialized cluster configuration." + ], + "CLUSTER REPLICAS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of replica nodes replicating from the specified master node provided in the same format used by `CLUSTER NODES`." + ], + "CLUSTER REPLICATE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER RESET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER SAVECONFIG": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER SET-CONFIG-EPOCH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER SETSLOT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): all the sub-commands return `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER SHARDS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a nested list of a map of hash ranges and shard nodes describing individual shards." + ], + "CLUSTER SLAVES": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of replica nodes replicating from the specified master node provided in the same format used by `CLUSTER NODES`." + ], + "CLUSTER SLOTS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): nested list of slot ranges with networking information." + ], + "COMMAND": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a nested list of command details. The order of the commands in the array is random." + ], + "COMMAND COUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of commands returned by `COMMAND`." + ], + "COMMAND DOCS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a map, as a flattened array, where each key is a command name, and each value is the documentary information." + ], + "COMMAND GETKEYS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): list of keys from the given command." + ], + "COMMAND GETKEYSANDFLAGS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of keys from the given command and their usage flags." + ], + "COMMAND HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "COMMAND INFO": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a nested list of command details." + ], + "COMMAND LIST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of command names." + ], + "CONFIG": [], + "CONFIG GET": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of configuration parameters matching the provided arguments." + ], + "CONFIG HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "CONFIG RESETSTAT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "CONFIG REWRITE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` when the configuration was rewritten properly. Otherwise an error is returned." + ], + "CONFIG SET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` when the configuration was set properly. Otherwise an error is returned." + ], + "COPY": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if _source_ was copied.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if _source_ was not copied." + ], + "DBSIZE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of keys in the currently-selected database." + ], + "DEBUG": [], + "DECR": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the key after decrementing it." + ], + "DECRBY": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the key after decrementing it." + ], + "DEL": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of keys that were removed." + ], + "DISCARD": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "DUMP": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): The serialized value of the key.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): the key does not exist." + ], + "ECHO": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the given string." + ], + "EVAL": [ + "The return value depends on the script that was executed." + ], + "EVALSHA": [ + "The return value depends on the script that was executed." + ], + "EVALSHA_RO": [ + "The return value depends on the script that was executed." + ], + "EVAL_RO": [ + "The return value depends on the script that was executed." + ], + "EXEC": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): each element being the reply to each of the commands in the atomic transaction.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): the transaction was aborted because a `WATCH`ed key was touched." + ], + "EXISTS": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of keys that exist from those specified as arguments." + ], + "EXPIRE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the timeout was not set; for example, the key doesn't exist, or the operation was skipped because of the provided arguments.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout was set." + ], + "EXPIREAT": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the timeout was not set; for example, the key doesn't exist, or the operation was skipped because of the provided arguments.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout was set." + ], + "EXPIRETIME": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): the expiration Unix timestamp in seconds.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if the key exists but has no associated expiration time.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-2` if the key does not exist." + ], + "FAILOVER": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was accepted and a coordinated failover is in progress. An error if the operation cannot be executed." + ], + "FCALL": [ + "The return value depends on the function that was executed." + ], + "FCALL_RO": [ + "The return value depends on the function that was executed." + ], + "FLUSHALL": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FLUSHDB": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION": [], + "FUNCTION DELETE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION DUMP": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the serialized payload" + ], + "FUNCTION FLUSH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions" + ], + "FUNCTION KILL": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION LIST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): information about functions and libraries." + ], + "FUNCTION LOAD": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the library name that was loaded." + ], + "FUNCTION RESTORE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION STATS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): information about the function that's currently running and information about the available execution engines." + ], + "GEOADD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): When used without optional arguments, the number of elements added to the sorted set (excluding score updates). If the CH option is specified, the number of elements that were changed (added or updated)." + ], + "GEODIST": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): one or both of the elements are missing.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): distance as a double (represented as a string) in the specified units." + ], + "GEOHASH": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array where each element is the Geohash corresponding to each member name passed as an argument to the command." + ], + "GEOPOS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): An array where each element is a two elements array representing longitude and latitude (x,y) of each member name passed as argument to the command. Non-existing elements are reported as [Nil reply](/docs/reference/protocol-spec#bulk-strings) elements of the array." + ], + "GEORADIUS": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " 1. The distance from the center as a floating point number, in the same unit specified in the radius.", + " 1. The Geohash integer.", + " 1. The coordinates as a two items x,y array (longitude,latitude).", + "", + "For example, the command `GEORADIUS Sicily 15 37 200 km WITHCOORD WITHDIST` will return each item in the following way:", + "", + "`[\"Palermo\",\"190.4424\",[\"13.361389338970184\",\"38.115556395496299\"]]`" + ], + "GEORADIUSBYMEMBER": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " * The distance from the center as a floating point number, in the same unit specified in the radius.", + " * The Geohash integer.", + " * The coordinates as a two items x,y array (longitude,latitude)." + ], + "GEORADIUSBYMEMBER_RO": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " * The distance from the center as a floating point number, in the same unit specified in the radius.", + " * The Geohash integer.", + " * The coordinates as a two items x,y array (longitude,latitude)." + ], + "GEORADIUS_RO": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " * The distance from the center as a floating point number, in the same unit specified in the radius.", + " * The Geohash integer.", + " * The coordinates as a two items x,y array (longitude,latitude)." + ], + "GEOSEARCH": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " * The distance from the center as a floating point number, in the same unit specified in the radius.", + " * The Geohash integer.", + " * The coordinates as a two items x,y array (longitude,latitude)." + ], + "GEOSEARCHSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting set" + ], + "GET": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the value of the key.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key does not exist." + ], + "GETBIT": [ + "The bit value stored at _offset_, one of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0`.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1`." + ], + "GETDEL": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the value of the key.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key does not exist or if the key's value type is not a string." + ], + "GETEX": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the value of `key`", + "[Nil reply](/docs/reference/protocol-spec#bulk-strings): if `key` does not exist." + ], + "GETRANGE": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): The substring of the string value stored at key, determined by the offsets start and end (both are inclusive)." + ], + "GETSET": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the old value stored at the key.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key does not exist." + ], + "HDEL": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of fields that were removed from the hash, excluding any specified but non-existing fields." + ], + "HELLO": [ + "[Map reply](/docs/reference/protocol-spec#maps): a list of server properties.", + "[Simple error reply](/docs/reference/protocol-spec#simple-errors): if the `protover` requested does not exist." + ], + "HEXISTS": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the hash does not contain the field, or the key does not exist.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the hash contains the field." + ], + "HGET": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): The value associated with the field.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): If the field is not present in the hash or key does not exist." + ], + "HGETALL": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of fields and their values stored in the hash, or an empty list when key does not exist." + ], + "HINCRBY": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the field after the increment operation." + ], + "HINCRBYFLOAT": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the value of the field after the increment operation." + ], + "HKEYS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of fields in the hash, or an empty list when the key does not exist" + ], + "HLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of fields in the hash, or 0 when the key does not exist." + ], + "HMGET": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of values associated with the given fields, in the same order as they are requested." + ], + "HMSET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "HRANDFIELD": [ + "Any of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key doesn't exist", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a single, randomly selected field when the `count` option is not used", + "* [Array reply](/docs/reference/protocol-spec#arrays): a list containing `count` fields when the `count` option is used, or an empty array if the key does not exists.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of fields and their values when `count` and `WITHVALUES` were both used." + ], + "HSCAN": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a two-element array.", + "* The first element is a [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) that represents an unsigned 64-bit number, the cursor.", + "* The second element is an [Array reply](/docs/reference/protocol-spec#arrays) of field/value pairs that were scanned." + ], + "HSET": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of fields that were added." + ], + "HSETNX": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the field already exists in the hash and no operation was performed.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the field is a new field in the hash and the value was set." + ], + "HSTRLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the string length of the value associated with the _field_, or zero when the _field_ isn't present in the hash or the _key_ doesn't exist at all." + ], + "HVALS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of values in the hash, or an empty list when the key does not exist" + ], + "INCR": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the key after the increment." + ], + "INCRBY": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the key after the increment." + ], + "INCRBYFLOAT": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the value of the key after the increment." + ], + "INFO": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a map of info fields, one field per line in the form of `:` where the value can be a comma separated map like `=`. Also contains section header lines starting with `#` and blank lines.", + "", + "Lines can contain a section name (starting with a `#` character) or a property. All the properties are in the form of `field:value` terminated by `\\r\\n`." + ], + "KEYS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of keys matching _pattern_." + ], + "LASTSAVE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): UNIX TIME of the last DB save executed with success." + ], + "LATENCY": [], + "LATENCY DOCTOR": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a human readable latency analysis report." + ], + "LATENCY GRAPH": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): Latency graph" + ], + "LATENCY HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "LATENCY HISTOGRAM": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a map where each key is a command name, and each value is a map with the total calls, and an inner map of the histogram time buckets." + ], + "LATENCY HISTORY": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array where each element is a two elements array representing the timestamp and the latency of the event." + ], + "LATENCY LATEST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array where each element is a four elements array representing the event's name, timestamp, latest and all-time latency measurements." + ], + "LATENCY RESET": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of event time series that were reset." + ], + "LCS": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the longest common subsequence.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the length of the longest common subsequence when _LEN_ is given.", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array with the LCS length and all the ranges in both the strings when _IDX_ is given." + ], + "LINDEX": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): when _index_ is out of range.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the requested element." + ], + "LINSERT": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): the list length after a successful insert operation.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` when the key doesn't exist.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` when the pivot wasn't found." + ], + "LLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list." + ], + "LMOVE": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the element being popped and pushed." + ], + "LMPOP": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if no element could be popped.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a two-element array with the first element being the name of the key from which elements were popped and the second element being an array of elements." + ], + "LOLWUT": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a string containing generative computer art and the Redis version." + ], + "LPOP": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key does not exist.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): when called without the _count_ argument, the value of the first element.", + "* [Array reply](/docs/reference/protocol-spec#arrays): when called with the _count_ argument, a list of popped elements." + ], + "LPOS": [ + "Any of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if there is no matching element.", + "* [Integer reply](/docs/reference/protocol-spec#integers): an integer representing the matching element.", + "* [Array reply](/docs/reference/protocol-spec#arrays): If the COUNT option is given, an array of integers representing the matching elements (or an empty array if there are no matches)." + ], + "LPUSH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list after the push operation." + ], + "LPUSHX": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list after the push operation." + ], + "LRANGE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of elements in the specified range, or an empty array if the key doesn't exist." + ], + "LREM": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of removed elements." + ], + "LSET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "LTRIM": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "MEMORY": [], + "MEMORY DOCTOR": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a memory problems report." + ], + "MEMORY HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions" + ], + "MEMORY MALLOC-STATS": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the memory allocator's internal statistics report" + ], + "MEMORY PURGE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "MEMORY STATS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a nested list of memory usage metrics and their values." + ], + "MEMORY USAGE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): the memory usage in bytes.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key does not exist." + ], + "MGET": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of values at the specified keys." + ], + "MIGRATE": [ + "One of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` on success.", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `NOKEY` when no keys were found in the source instance." + ], + "MODULE": [], + "MODULE HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "MODULE LIST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): list of loaded modules. Each element in the list represents a represents a module, and is in itself a list of property names and their values. The following properties is reported for each loaded module:", + "* name: the name of the module.", + "* ver: the version of the module." + ], + "MODULE LOAD": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the module was loaded." + ], + "MODULE LOADEX": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the module was loaded." + ], + "MODULE UNLOAD": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the module was unloaded." + ], + "MONITOR": [ + "**Non-standard return value**. Dumps the received commands in an infinite flow." + ], + "MOVE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if _key_ was moved.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if _key_ wasn't moved." + ], + "MSET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): always `OK` because `MSET` can't fail." + ], + "MSETNX": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if no key was set (at least one key already existed).", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if all the keys were set." + ], + "MULTI": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "OBJECT": [], + "OBJECT ENCODING": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key doesn't exist.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the encoding of the object." + ], + "OBJECT FREQ": [ + "One of the following:", + "[Integer reply](/docs/reference/protocol-spec#integers): the counter's value.", + "[Nil reply](/docs/reference/protocol-spec#bulk-strings): if _key_ doesn't exist." + ], + "OBJECT HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions" + ], + "OBJECT IDLETIME": [ + "One of the following:", + "[Integer reply](/docs/reference/protocol-spec#integers): the idle time in seconds.", + "[Nil reply](/docs/reference/protocol-spec#bulk-strings): if _key_ doesn't exist." + ], + "OBJECT REFCOUNT": [ + "One of the following:", + "[Integer reply](/docs/reference/protocol-spec#integers): the number of references.", + "[Nil reply](/docs/reference/protocol-spec#bulk-strings): if _key_ doesn't exist." + ], + "PERSIST": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if _key_ does not exist or does not have an associated timeout.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout has been removed." + ], + "PEXPIRE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0`if the timeout was not set. For example, if the key doesn't exist, or the operation skipped because of the provided arguments.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout was set." + ], + "PEXPIREAT": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout was set.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the timeout was not set. For example, if the key doesn't exist, or the operation was skipped due to the provided arguments." + ], + "PEXPIRETIME": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): Expiration Unix timestamp in milliseconds.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if the key exists but has no associated expiration time.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-2` if the key does not exist." + ], + "PFADD": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if at least one HyperLogLog internal register was altered.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if no HyperLogLog internal registers were altered." + ], + "PFCOUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the approximated number of unique elements observed via `PFADD`." + ], + "PFDEBUG": [], + "PFMERGE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "PFSELFTEST": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "PING": [ + "Any of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `PONG` when no argument is provided.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the provided argument." + ], + "PSETEX": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "PSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each pattern, one message with the first element being the string `psubscribe` is pushed as a confirmation that the command succeeded." + ], + "PSYNC": [ + "**Non-standard return value**, a bulk transfer of the data followed by `PING` and write requests from the master." + ], + "PTTL": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): TTL in milliseconds.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if the key exists but has no associated expiration.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-2` if the key does not exist." + ], + "PUBLISH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of clients that received the message. Note that in a Redis Cluster, only clients that are connected to the same node as the publishing client are included in the count." + ], + "PUBSUB": [], + "PUBSUB CHANNELS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of active channels, optionally matching the specified pattern." + ], + "PUBSUB HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "PUBSUB NUMPAT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of patterns all the clients are subscribed to." + ], + "PUBSUB NUMSUB": [ + "[Array reply](/docs/reference/protocol-spec#arrays): the number of subscribers per channel, each even element (including the 0th) is channel name, each odd element is the number of subscribers" + ], + "PUBSUB SHARDCHANNELS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of active channels, optionally matching the specified pattern." + ], + "PUBSUB SHARDNUMSUB": [ + "[Array reply](/docs/reference/protocol-spec#arrays): the number of subscribers per shard channel, each even element (including the 0th) is channel name, each odd element is the number of subscribers." + ], + "PUNSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each pattern, one message with the first element being the string `punsubscribe` is pushed as a confirmation that the command succeeded." + ], + "QUIT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): OK." + ], + "RANDOMKEY": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): when the database is empty.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a random key in database." + ], + "READONLY": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "READWRITE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "RENAME": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "RENAMENX": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if _key_ was renamed to _newkey_.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if _newkey_ already exists." + ], + "REPLCONF": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "REPLICAOF": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "RESET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `RESET`." + ], + "RESTORE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "RESTORE-ASKING": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "ROLE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): where the first element is one of `master`, `slave`, or `sentinel`, and the additional elements are role-specific as illustrated above." + ], + "RPOP": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key does not exist.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): when called without the _count_ argument, the value of the last element.", + "* [Array reply](/docs/reference/protocol-spec#arrays): when called with the _count_ argument, a list of popped elements." + ], + "RPOPLPUSH": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the element being popped and pushed.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the source list is empty." + ], + "RPUSH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list after the push operation." + ], + "RPUSHX": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list after the push operation." + ], + "SADD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements that were added to the set, not including all the elements already present in the set." + ], + "SAVE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SCAN": [ + "[Array reply](/docs/reference/protocol-spec#arrays): specifically, an array with two elements.", + "* The first element is a [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) that represents an unsigned 64-bit number, the cursor.", + "* The second element is an [Array reply](/docs/reference/protocol-spec#arrays) with the names of scanned keys." + ], + "SCARD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the cardinality (number of elements) of the set, or `0` if the key does not exist." + ], + "SCRIPT": [], + "SCRIPT DEBUG": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SCRIPT EXISTS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array of integers that correspond to the specified SHA1 digest arguments." + ], + "SCRIPT FLUSH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SCRIPT HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "SCRIPT KILL": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SCRIPT LOAD": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the SHA1 digest of the script added into the script cache." + ], + "SDIFF": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list with members of the resulting set." + ], + "SDIFFSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting set." + ], + "SELECT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SET": [ + "Any of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): `GET` not given: Operation was aborted (conflict with one of the `XX`/`NX` options).", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`. `GET` not given: The key was set.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): `GET` given: The key didn't exist before the `SET`.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): `GET` given: The previous value of the key." + ], + "SETBIT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the original bit value stored at _offset_." + ], + "SETEX": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SETNX": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the key was not set.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the key was set." + ], + "SETRANGE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the string after it was modified by the command." + ], + "SHUTDOWN": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if _ABORT_ was specified and shutdown was aborted. On successful shutdown, nothing is returned because the server quits and the connection is closed. On failure, an error is returned." + ], + "SINTER": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list with the members of the resulting set." + ], + "SINTERCARD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting intersection." + ], + "SINTERSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting set." + ], + "SISMEMBER": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the element is not a member of the set, or when the key does not exist.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the element is a member of the set." + ], + "SLAVEOF": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SLOWLOG": [], + "SLOWLOG GET": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of slow log entries per the above format." + ], + "SLOWLOG HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "SLOWLOG LEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of entries in the slow log." + ], + "SLOWLOG RESET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SMEMBERS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): all members of the set." + ], + "SMISMEMBER": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list representing the membership of the given elements, in the same order as they are requested." + ], + "SMOVE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the element is moved.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the element is not a member of _source_ and no operation was performed." + ], + "SORT": [ + "[Array reply](/docs/reference/protocol-spec#arrays): without passing the _STORE_ option, the command returns a list of sorted elements.", + "[Integer reply](/docs/reference/protocol-spec#integers): when the _STORE_ option is specified, the command returns the number of sorted elements in the destination list." + ], + "SORT_RO": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sorted elements." + ], + "SPOP": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key does not exist.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): when called without the _count_ argument, the removed member.", + "* [Array reply](/docs/reference/protocol-spec#arrays): when called with the _count_ argument, a list of the removed members." + ], + "SPUBLISH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of clients that received the message. Note that in a Redis Cluster, only clients that are connected to the same node as the publishing client are included in the count" + ], + "SRANDMEMBER": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): without the additional _count_ argument, the command returns a randomly selected member, or a [Nil reply](/docs/reference/protocol-spec#bulk-strings) when _key_ doesn't exist.", + "* [Array reply](/docs/reference/protocol-spec#arrays): when the optional _count_ argument is passed, the command returns an array of members, or an empty array when _key_ doesn't exist." + ], + "SREM": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members that were removed from the set, not including non existing members." + ], + "SSCAN": [ + "[Array reply](/docs/reference/protocol-spec#arrays): specifically, an array with two elements:", + "* The first element is a [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) that represents an unsigned 64-bit number, the cursor.", + "* The second element is an [Array reply](/docs/reference/protocol-spec#arrays) with the names of scanned members." + ], + "SSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each shard channel, one message with the first element being the string `ssubscribe` is pushed as a confirmation that the command succeeded. Note that this command can also return a -MOVED redirect." + ], + "STRLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the string stored at key, or 0 when the key does not exist." + ], + "SUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each channel, one message with the first element being the string `subscribe` is pushed as a confirmation that the command succeeded." + ], + "SUBSTR": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the substring of the string value stored at key, determined by the offsets start and end (both are inclusive)." + ], + "SUNION": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list with members of the resulting set." + ], + "SUNIONSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting set." + ], + "SUNSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each shard channel, one message with the first element being the string `sunsubscribe` is pushed as a confirmation that the command succeeded." + ], + "SWAPDB": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SYNC": [ + "**Non-standard return value**, a bulk transfer of the data followed by `PING` and write requests from the master." + ], + "TIME": [ + "[Array reply](/docs/reference/protocol-spec#arrays): specifically, a two-element array consisting of the Unix timestamp in seconds and the microseconds' count." + ], + "TOUCH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of touched keys." + ], + "TTL": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): TTL in seconds.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if the key exists but has no associated expiration.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-2` if the key does not exist." + ], + "TYPE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): the type of _key_, or `none` when _key_ doesn't exist." + ], + "UNLINK": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of keys that were unlinked." + ], + "UNSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each channel, one message with the first element being the string `unsubscribe` is pushed as a confirmation that the command succeeded." + ], + "UNWATCH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "WAIT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the command returns the number of replicas reached by all the writes performed in the context of the current connection." + ], + "WAITAOF": [ + "[Array reply](/docs/reference/protocol-spec#arrays): The command returns an array of two integers:", + "1. The first is the number of local Redises (0 or 1) that have fsynced to AOF all writes performed in the context of the current connection", + "2. The second is the number of replicas that have acknowledged doing the same." + ], + "WATCH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "XACK": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The command returns the number of messages successfully acknowledged. Certain message IDs may no longer be part of the PEL (for example because they have already been acknowledged), and XACK will not count them as successfully acknowledged." + ], + "XADD": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): The ID of the added entry. The ID is the one automatically generated if an asterisk (`*`) is passed as the _id_ argument, otherwise the command just returns the same ID specified by the user during insertion.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the NOMKSTREAM option is given and the key doesn't exist." + ], + "XAUTOCLAIM": [ + "[Array reply](/docs/reference/protocol-spec#arrays), specifically, an array with three elements:", + "1. A stream ID to be used as the _start_ argument for the next call to XAUTOCLAIM.", + "2. An [Array reply](/docs/reference/protocol-spec#arrays) containing all the successfully claimed messages in the same format as `XRANGE`.", + "3. An [Array reply](/docs/reference/protocol-spec#arrays) containing message IDs that no longer exist in the stream, and were deleted from the PEL in which they were found." + ], + "XCLAIM": [ + "Any of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): when the _JUSTID_ option is specified, an array of IDs of messages successfully claimed.", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array of stream entries, each of which contains an array of two elements, the entry ID and the entry data itself." + ], + "XDEL": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of entries that were deleted." + ], + "XGROUP": [], + "XGROUP CREATE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "XGROUP CREATECONSUMER": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of created consumers, either 0 or 1." + ], + "XGROUP DELCONSUMER": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of pending messages the consumer had before it was deleted." + ], + "XGROUP DESTROY": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of destroyed consumer groups, either 0 or 1." + ], + "XGROUP HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "XGROUP SETID": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "XINFO": [], + "XINFO CONSUMERS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of consumers and their attributes." + ], + "XINFO GROUPS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of consumer groups." + ], + "XINFO HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "XINFO STREAM": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): when the _FULL_ argument is used, a list of information about a stream in summary form.", + "* [Array reply](/docs/reference/protocol-spec#arrays): when the _FULL_ argument is used, a list of information about a stream in extended form." + ], + "XLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of entries of the stream at _key_." + ], + "XPENDING": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): different data depending on the way XPENDING is called, as explained on this page." + ], + "XRANGE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of stream entries with IDs matching the specified range." + ], + "XREAD": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array where each element is an array composed of a two elements containing the key name and the entries reported for that key. The entries reported are full stream entries, having IDs and the list of all the fields and values. Field and values are guaranteed to be reported in the same order they were added by `XADD`.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the _BLOCK_ option is given and a timeout occurs, or if there is no stream that can be served." + ], + "XREADGROUP": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array where each element is an array composed of a two elements containing the key name and the entries reported for that key. The entries reported are full stream entries, having IDs and the list of all the fields and values. Field and values are guaranteed to be reported in the same order they were added by `XADD`.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the _BLOCK_ option is given and a timeout occurs, or if there is no stream that can be served." + ], + "XREVRANGE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): The command returns the entries with IDs matching the specified range. The returned entries are complete, which means that the ID and all the fields they are composed of are returned. Moreover, the entries are returned with their fields and values in the same order as `XADD` added them." + ], + "XSETID": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "XTRIM": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The number of entries deleted from the stream." + ], + "ZADD": [ + "Any of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the operation was aborted because of a conflict with one of the _XX/NX/LT/GT_ options.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the number of new members when the _CH_ option is not used.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the number of new or updated members when the _CH_ option is used.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the updated score of the member when the _INCR_ option is used." + ], + "ZCARD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the cardinality (number of members) of the sorted set, or 0 if the key doesn't exist." + ], + "ZCOUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the specified score range." + ], + "ZDIFF": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): the result of the difference including, optionally, scores when the _WITHSCORES_ option is used." + ], + "ZDIFFSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the resulting sorted set at _destination_." + ], + "ZINCRBY": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the new score of _member_ as a double precision floating point number." + ], + "ZINTER": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): the result of the intersection including, optionally, scores when the _WITHSCORES_ option is used." + ], + "ZINTERCARD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the resulting intersection." + ], + "ZINTERSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the resulting sorted set at the _destination_." + ], + "ZLEXCOUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the specified score range." + ], + "ZMPOP": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): when no element could be popped.", + "* [Array reply](/docs/reference/protocol-spec#arrays): A two-element array with the first element being the name of the key from which elements were popped, and the second element is an array of the popped elements. Every entry in the elements array is also an array that contains the member and its score." + ], + "ZMSCORE": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the member does not exist in the sorted set.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) _member_ scores as double-precision floating point numbers." + ], + "ZPOPMAX": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of popped elements and scores." + ], + "ZPOPMIN": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of popped elements and scores." + ], + "ZRANDMEMBER": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): without the additional _count_ argument, the command returns a randomly selected member, or [Nil reply](/docs/reference/protocol-spec#bulk-strings) when _key_ doesn't exist.", + "[Array reply](/docs/reference/protocol-spec#arrays): when the additional _count_ argument is passed, the command returns an array of members, or an empty array when _key_ doesn't exist. If the _WITHSCORES_ modifier is used, the reply is a list of members and their scores from the sorted set." + ], + "ZRANGE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of members in the specified range with, optionally, their scores when the _WITHSCORES_ option is given." + ], + "ZRANGEBYLEX": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of elements in the specified score range." + ], + "ZRANGEBYSCORE": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of the members with, optionally, their scores in the specified score range." + ], + "ZRANGESTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting sorted set." + ], + "ZRANK": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key does not exist or the member does not exist in the sorted set.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the rank of the member when _WITHSCORE_ is not used.", + "* [Array reply](/docs/reference/protocol-spec#arrays): the rank and score of the member when _WITHSCORE_ is used." + ], + "ZREM": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members removed from the sorted set, not including non-existing members." + ], + "ZREMRANGEBYLEX": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members removed." + ], + "ZREMRANGEBYRANK": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members removed." + ], + "ZREMRANGEBYSCORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members removed." + ], + "ZREVRANGE": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of members in the specified range, optionally with their scores if _WITHSCORE_ was used." + ], + "ZREVRANGEBYLEX": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of members in the specified score range." + ], + "ZREVRANGEBYSCORE": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of the members and, optionally, their scores in the specified score range." + ], + "ZREVRANK": [ + "One of the following:", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if the key does not exist or the member does not exist in the sorted set.", + "* [Integer reply](/docs/reference/protocol-spec#integers): The rank of the member when _WITHSCORE_ is not used.", + "* [Array reply](/docs/reference/protocol-spec#arrays): The rank and score of the member when _WITHSCORE_ is used." + ], + "ZSCAN": [ + "[Array reply](/docs/reference/protocol-spec#arrays): cursor and scan response in array form." + ], + "ZSCORE": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the score of the member (a double-precision floating point number), represented as a string.", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if _member_ does not exist in the sorted set, or the key does not exist." + ], + "ZUNION": [ + "[Array reply](/docs/reference/protocol-spec#arrays): the result of the union with, optionally, their scores when _WITHSCORES_ is used." + ], + "ZUNIONSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting sorted set." + ] +} diff --git a/resp3_replies.json b/resp3_replies.json new file mode 100644 index 0000000000..fa7da38383 --- /dev/null +++ b/resp3_replies.json @@ -0,0 +1,1385 @@ +{ + "ACL": [], + "ACL CAT": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array of [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) elements representing ACL categories or commands in a given category.", + "* [Simple error reply](/docs/reference/protocol-spec#simple-errors): the command returns an error if an invalid category name is given." + ], + "ACL DELUSER": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of users that were deleted. This number will not always match the number of arguments since certain users may not exist." + ], + "ACL DRYRUN": [ + "Any of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` on success.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): an error describing why the user can't execute the command." + ], + "ACL GENPASS": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): pseudorandom data. By default it contains 64 bytes, representing 256 bits of data. If `bits` was given, the output string length is the number of specified bits (rounded to the next multiple of 4) divided by 4." + ], + "ACL GETUSER": [ + "One of the following:", + "* [Map reply](/docs/reference/protocol-spec#maps): a set of ACL rule definitions for the user", + "* [Null reply](/docs/reference/protocol-spec#nulls): if user does not exist." + ], + "ACL HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of subcommands and their descriptions." + ], + "ACL LIST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array of [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) elements." + ], + "ACL LOAD": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` on success.", + "", + "The command may fail with an error for several reasons: if the file is not readable, if there is an error inside the file, and in such cases, the error will be reported to the user in the error.", + "Finally, the command will fail if the server is not configured to use an external ACL file." + ], + "ACL LOG": [ + "When called to show security events:", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array of [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) elements representing ACL security events.", + "When called with `RESET`:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the security log was cleared." + ], + "ACL SAVE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`.", + "The command may fail with an error for several reasons: if the file cannot be written or if the server is not configured to use an external ACL file." + ], + "ACL SETUSER": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`.", + "If the rules contain errors, the error is returned." + ], + "ACL USERS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): list of existing ACL users." + ], + "ACL WHOAMI": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the username of the current connection." + ], + "APPEND": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the string after the append operation." + ], + "ASKING": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "AUTH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`, or an error if the password, or username/password pair, is invalid." + ], + "BGREWRITEAOF": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a simple string reply indicating that the rewriting started or is about to start ASAP when the call is executed with success.", + "", + "The command may reply with an error in certain cases, as documented above." + ], + "BGSAVE": [ + "One of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `Background saving started`.", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `Background saving scheduled`." + ], + "BITCOUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of bits set to 1." + ], + "BITFIELD": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): each entry being the corresponding result of the sub-command given at the same position.", + "* [Null reply](/docs/reference/protocol-spec#nulls): if OVERFLOW FAIL was given and overflows or underflows are detected." + ], + "BITFIELD_RO": [ + "[Array reply](/docs/reference/protocol-spec#arrays): each entry being the corresponding result of the sub-command given at the same position." + ], + "BITOP": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the size of the string stored in the destination key is equal to the size of the longest input string." + ], + "BITPOS": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): the position of the first bit set to 1 or 0 according to the request", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1`. In case the `bit` argument is 1 and the string is empty or composed of just zero bytes", + "", + "If we look for set bits (the bit argument is 1) and the string is empty or composed of just zero bytes, -1 is returned.", + "", + "If we look for clear bits (the bit argument is 0) and the string only contains bits set to 1, the function returns the first bit not part of the string on the right. So if the string is three bytes set to the value `0xff` the command `BITPOS key 0` will return 24, since up to bit 23 all the bits are 1.", + "", + "The function considers the right of the string as padded with zeros if you look for clear bits and specify no range or the _start_ argument **only**.", + "", + "However, this behavior changes if you are looking for clear bits and specify a range with both _start_ and _end_.", + "If a clear bit isn't found in the specified range, the function returns -1 as the user specified a clear range and there are no 0 bits in that range." + ], + "BLMOVE": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the element being popped from the _source_ and pushed to the _destination_.", + "* [Null reply](/docs/reference/protocol-spec#nulls): the operation timed-out" + ], + "BLMPOP": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): when no element could be popped and the _timeout_ is reached.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a two-element array with the first element being the name of the key from which elements were popped, and the second element being an array of the popped elements." + ], + "BLPOP": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): no element could be popped and the timeout expired", + "* [Array reply](/docs/reference/protocol-spec#arrays): the key from which the element was popped and the value of the popped element." + ], + "BRPOP": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): no element could be popped and the timeout expired.", + "* [Array reply](/docs/reference/protocol-spec#arrays): the key from which the element was popped and the value of the popped element" + ], + "BRPOPLPUSH": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the element being popped from _source_ and pushed to _destination_.", + "* [Null reply](/docs/reference/protocol-spec#nulls): the timeout is reached." + ], + "BZMPOP": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): when no element could be popped.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a two-element array with the first element being the name of the key from which elements were popped, and the second element is an array of the popped elements. Every entry in the elements array is also an array that contains the member and its score." + ], + "BZPOPMAX": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): when no element could be popped and the _timeout_ expired.", + "* [Array reply](/docs/reference/protocol-spec#arrays): the keyname, popped member, and its score." + ], + "BZPOPMIN": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): when no element could be popped and the _timeout_ expired.", + "* [Array reply](/docs/reference/protocol-spec#arrays): the keyname, popped member, and its score." + ], + "CLIENT": [], + "CLIENT CACHING": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` or an error if the argument is not \"yes\" or \"no\"." + ], + "CLIENT GETNAME": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the connection name of the current connection.", + "* [Null reply](/docs/reference/protocol-spec#nulls): the connection name was not set." + ], + "CLIENT GETREDIR": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` when not redirecting notifications to any client.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if client tracking is not enabled.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the ID of the client to which notification are being redirected." + ], + "CLIENT HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of subcommands and their descriptions." + ], + "CLIENT ID": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the ID of the client." + ], + "CLIENT INFO": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a unique string for the current client, as described at the `CLIENT LIST` page." + ], + "CLIENT KILL": [ + "One of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` when called in 3 argument format and the connection has been closed.", + "* [Integer reply](/docs/reference/protocol-spec#integers): when called in filter/value format, the number of clients killed." + ], + "CLIENT LIST": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): information and statistics about client connections." + ], + "CLIENT NO-EVICT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "CLIENT NO-TOUCH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "CLIENT PAUSE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` or an error if the timeout is invalid." + ], + "CLIENT REPLY": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` when called with `ON`. When called with either `OFF` or `SKIP` sub-commands, no reply is made." + ], + "CLIENT SETINFO": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the attribute name was successfully set." + ], + "CLIENT SETNAME": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the connection name was successfully set." + ], + "CLIENT TRACKING": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the connection was successfully put in tracking mode or if the tracking mode was successfully disabled. Otherwise, an error is returned." + ], + "CLIENT TRACKINGINFO": [ + "[Map reply](/docs/reference/protocol-spec#maps): a list of tracking information sections and their respective values." + ], + "CLIENT UNBLOCK": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the client was unblocked successfully.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the client wasn't unblocked." + ], + "CLIENT UNPAUSE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "CLUSTER": [], + "CLUSTER ADDSLOTS": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER ADDSLOTSRANGE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER BUMPEPOCH": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): `BUMPED` if the epoch was incremented.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): `STILL` if the node already has the greatest configured epoch in the cluster." + ], + "CLUSTER COUNT-FAILURE-REPORTS": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of active failure reports for the node." + ], + "CLUSTER COUNTKEYSINSLOT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The number of keys in the specified hash slot, or an error if the hash slot is invalid." + ], + "CLUSTER DELSLOTS": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER DELSLOTSRANGE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER FAILOVER": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was accepted and a manual failover is going to be attempted. An error if the operation cannot be executed, for example if the client is connected to a node that is already a master." + ], + "CLUSTER FLUSHSLOTS": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "CLUSTER FORGET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was executed successfully. Otherwise an error is returned." + ], + "CLUSTER GETKEYSINSLOT": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array with up to count elements." + ], + "CLUSTER HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of subcommands and their descriptions." + ], + "CLUSTER INFO": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): A map between named fields and values in the form of : lines separated by newlines composed by the two bytes CRLF" + ], + "CLUSTER KEYSLOT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The hash slot number for the specified key" + ], + "CLUSTER LINKS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array of [Map reply](/docs/reference/protocol-spec#maps) where each map contains various attributes and their values of a cluster link." + ], + "CLUSTER MEET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. If the address or port specified are invalid an error is returned." + ], + "CLUSTER MYID": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the node ID." + ], + "CLUSTER MYSHARDID": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the node's shard ID." + ], + "CLUSTER NODES": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the serialized cluster configuration." + ], + "CLUSTER REPLICAS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of replica nodes replicating from the specified master node provided in the same format used by `CLUSTER NODES`." + ], + "CLUSTER REPLICATE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER RESET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER SAVECONFIG": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER SET-CONFIG-EPOCH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER SETSLOT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): all the sub-commands return `OK` if the command was successful. Otherwise an error is returned." + ], + "CLUSTER SHARDS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a nested list of [Map reply](/docs/reference/protocol-spec#maps) of hash ranges and shard nodes describing individual shards." + ], + "CLUSTER SLAVES": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of replica nodes replicating from the specified master node provided in the same format used by `CLUSTER NODES`." + ], + "CLUSTER SLOTS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): nested list of slot ranges with networking information." + ], + "COMMAND": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a nested list of command details. The order of the commands in the array is random." + ], + "COMMAND COUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of commands returned by `COMMAND`." + ], + "COMMAND DOCS": [ + "[Map reply](/docs/reference/protocol-spec#maps): a map where each key is a command name, and each value is the documentary information." + ], + "COMMAND GETKEYS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of keys from the given command." + ], + "COMMAND GETKEYSANDFLAGS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of keys from the given command and their usage flags." + ], + "COMMAND HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "COMMAND INFO": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a nested list of command details." + ], + "COMMAND LIST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of command names." + ], + "CONFIG": [], + "CONFIG GET": [ + "[Map reply](/docs/reference/protocol-spec#maps): a list of configuration parameters matching the provided arguments." + ], + "CONFIG HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "CONFIG RESETSTAT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "CONFIG REWRITE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` when the configuration was rewritten properly. Otherwise an error is returned." + ], + "CONFIG SET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` when the configuration was set properly. Otherwise an error is returned." + ], + "COPY": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if _source_ was copied.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if _source_ was not copied." + ], + "DBSIZE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of keys in the currently-selected database." + ], + "DEBUG": [], + "DECR": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the key after decrementing it." + ], + "DECRBY": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the key after decrementing it." + ], + "DEL": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of keys that were removed." + ], + "DISCARD": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "DUMP": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the serialized value of the key.", + "* [Null reply](/docs/reference/protocol-spec#nulls): the key does not exist." + ], + "ECHO": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the given string." + ], + "EVAL": [ + "The return value depends on the script that was executed." + ], + "EVALSHA": [ + "The return value depends on the script that was executed." + ], + "EVALSHA_RO": [ + "The return value depends on the script that was executed." + ], + "EVAL_RO": [ + "The return value depends on the script that was executed." + ], + "EXEC": [ + "One of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): each element being the reply to each of the commands in the atomic transaction.", + "* [Null reply](/docs/reference/protocol-spec#nulls): the transaction was aborted because a `WATCH`ed key was touched." + ], + "EXISTS": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of keys that exist from those specified as arguments." + ], + "EXPIRE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the timeout was not set; for example, the key doesn't exist, or the operation was skipped because of the provided arguments.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout was set." + ], + "EXPIREAT": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the timeout was not set; for example, the key doesn't exist, or the operation was skipped because of the provided arguments.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout was set." + ], + "EXPIRETIME": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): the expiration Unix timestamp in seconds.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if the key exists but has no associated expiration time.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-2` if the key does not exist." + ], + "FAILOVER": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the command was accepted and a coordinated failover is in progress. An error if the operation cannot be executed." + ], + "FCALL": [ + "The return value depends on the function that was executed." + ], + "FCALL_RO": [ + "The return value depends on the function that was executed." + ], + "FLUSHALL": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FLUSHDB": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION": [], + "FUNCTION DELETE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION DUMP": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the serialized payload" + ], + "FUNCTION FLUSH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "FUNCTION KILL": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION LIST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): information about functions and libraries." + ], + "FUNCTION LOAD": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the library name that was loaded." + ], + "FUNCTION RESTORE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "FUNCTION STATS": [ + "[Map reply](/docs/reference/protocol-spec#maps): information about the function that's currently running and information about the available execution engines." + ], + "GEOADD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): When used without optional arguments, the number of elements added to the sorted set (excluding score updates). If the CH option is specified, the number of elements that were changed (added or updated)." + ], + "GEODIST": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): one or both of the elements are missing.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): distance as a double (represented as a string) in the specified units." + ], + "GEOHASH": [ + "[Array reply](/docs/reference/protocol-spec#arrays): An array where each element is the Geohash corresponding to each member name passed as an argument to the command." + ], + "GEOPOS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): An array where each element is a two elements array representing longitude and latitude (x,y) of each member name passed as argument to the command. Non-existing elements are reported as [Null reply](/docs/reference/protocol-spec#nulls) elements of the array." + ], + "GEORADIUS": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " 1. The distance from the center as a floating point number, in the same unit specified in the radius.", + " 1. The Geohash integer.", + " 1. The coordinates as a two items x,y array (longitude,latitude).", + "", + "For example, the command `GEORADIUS Sicily 15 37 200 km WITHCOORD WITHDIST` will return each item in the following way:", + "", + "`[\"Palermo\",\"190.4424\",[\"13.361389338970184\",\"38.115556395496299\"]]`" + ], + "GEORADIUSBYMEMBER": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " * The distance from the center as a floating point number, in the same unit specified in the radius.", + " * The Geohash integer.", + " * The coordinates as a two items x,y array (longitude,latitude)." + ], + "GEORADIUSBYMEMBER_RO": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " * The distance from the center as a floating point number, in the same unit specified in the radius.", + " * The Geohash integer.", + " * The coordinates as a two items x,y array (longitude,latitude)." + ], + "GEORADIUS_RO": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " * The distance from the center as a floating point number, in the same unit specified in the radius.", + " * The Geohash integer.", + " * The coordinates as a two items x,y array (longitude,latitude)." + ], + "GEOSEARCH": [ + "One of the following:", + "* If no `WITH*` option is specified, an [Array reply](/docs/reference/protocol-spec#arrays) of matched member names", + "* If `WITHCOORD`, `WITHDIST`, or `WITHHASH` options are specified, the command returns an [Array reply](/docs/reference/protocol-spec#arrays) of arrays, where each sub-array represents a single item:", + " * The distance from the center as a floating point number, in the same unit specified in the radius.", + " * The Geohash integer.", + " * The coordinates as a two items x,y array (longitude,latitude)." + ], + "GEOSEARCHSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting set" + ], + "GET": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the value of the key.", + "* [Null reply](/docs/reference/protocol-spec#nulls): key does not exist." + ], + "GETBIT": [ + "The bit value stored at _offset_, one of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0`.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1`." + ], + "GETDEL": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the value of the key.", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key does not exist or if the key's value type is not a string." + ], + "GETEX": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the value of `key`", + "[Null reply](/docs/reference/protocol-spec#nulls): if `key` does not exist." + ], + "GETRANGE": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): The substring of the string value stored at key, determined by the offsets start and end (both are inclusive)." + ], + "GETSET": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the old value stored at the key.", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key does not exist." + ], + "HDEL": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The number of fields that were removed from the hash, excluding any specified but non-existing fields." + ], + "HELLO": [ + "[Map reply](/docs/reference/protocol-spec#maps): a list of server properties.", + "[Simple error reply](/docs/reference/protocol-spec#simple-errors): if the `protover` requested does not exist." + ], + "HEXISTS": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the hash does not contain the field, or the key does not exist.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the hash contains the field." + ], + "HGET": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): The value associated with the field.", + "* [Null reply](/docs/reference/protocol-spec#nulls): If the field is not present in the hash or key does not exist." + ], + "HGETALL": [ + "[Map reply](/docs/reference/protocol-spec#maps): a map of fields and their values stored in the hash, or an empty list when key does not exist." + ], + "HINCRBY": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the field after the increment operation." + ], + "HINCRBYFLOAT": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): The value of the field after the increment operation." + ], + "HKEYS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of fields in the hash, or an empty list when the key does not exist." + ], + "HLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of the fields in the hash, or 0 when the key does not exist." + ], + "HMGET": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of values associated with the given fields, in the same order as they are requested." + ], + "HMSET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "HRANDFIELD": [ + "Any of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key doesn't exist", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a single, randomly selected field when the `count` option is not used", + "* [Array reply](/docs/reference/protocol-spec#arrays): a list containing `count` fields when the `count` option is used, or an empty array if the key does not exists.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of fields and their values when `count` and `WITHVALUES` were both used." + ], + "HSCAN": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a two-element array.", + "* The first element is a [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) that represents an unsigned 64-bit number, the cursor.", + "* The second element is an [Array reply](/docs/reference/protocol-spec#arrays) of field/value pairs that were scanned." + ], + "HSET": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of fields that were added." + ], + "HSETNX": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the field already exists in the hash and no operation was performed.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the field is a new field in the hash and the value was set." + ], + "HSTRLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the string length of the value associated with the _field_, or zero when the _field_ isn't present in the hash or the _key_ doesn't exist at all." + ], + "HVALS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of values in the hash, or an empty list when the key does not exist." + ], + "INCR": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the key after the increment." + ], + "INCRBY": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the value of the key after the increment." + ], + "INCRBYFLOAT": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the value of the key after the increment." + ], + "INFO": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a map of info fields, one field per line in the form of `:` where the value can be a comma separated map like `=`. Also contains section header lines starting with `#` and blank lines.", + "", + "Lines can contain a section name (starting with a `#` character) or a property. All the properties are in the form of `field:value` terminated by `\\r\\n`." + ], + "KEYS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of keys matching _pattern_." + ], + "LASTSAVE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): UNIX TIME of the last DB save executed with success." + ], + "LATENCY": [], + "LATENCY DOCTOR": [ + "[Verbatim string reply](/docs/reference/protocol-spec#verbatim-strings): a human readable latency analysis report." + ], + "LATENCY GRAPH": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): Latency graph" + ], + "LATENCY HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "LATENCY HISTOGRAM": [ + "[Map reply](/docs/reference/protocol-spec#maps): a map where each key is a command name, and each value is a map with the total calls, and an inner map of the histogram time buckets." + ], + "LATENCY HISTORY": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array where each element is a two elements array representing the timestamp and the latency of the event." + ], + "LATENCY LATEST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array where each element is a four elements array representing the event's name, timestamp, latest and all-time latency measurements." + ], + "LATENCY RESET": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of event time series that were reset." + ], + "LCS": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the longest common subsequence.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the length of the longest common subsequence when _LEN_ is given.", + "* [Map reply](/docs/reference/protocol-spec#maps): a map with the LCS length and all the ranges in both the strings when _IDX_ is given." + ], + "LINDEX": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): when _index_ is out of range.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the requested element." + ], + "LINSERT": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): the list length after a successful insert operation.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` when the key doesn't exist.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` when the pivot wasn't found." + ], + "LLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list." + ], + "LMOVE": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the element being popped and pushed." + ], + "LMPOP": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if no element could be popped.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a two-element array with the first element being the name of the key from which elements were popped and the second element being an array of elements." + ], + "LOLWUT": [ + "[Verbatim string reply](/docs/reference/protocol-spec#verbatim-strings): a string containing generative computer art and the Redis version." + ], + "LPOP": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key does not exist.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): when called without the _count_ argument, the value of the first element.", + "* [Array reply](/docs/reference/protocol-spec#arrays): when called with the _count_ argument, a list of popped elements." + ], + "LPOS": [ + "Any of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if there is no matching element.", + "* [Integer reply](/docs/reference/protocol-spec#integers): an integer representing the matching element.", + "* [Array reply](/docs/reference/protocol-spec#arrays): If the COUNT option is given, an array of integers representing the matching elements (or an empty array if there are no matches)." + ], + "LPUSH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list after the push operation." + ], + "LPUSHX": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list after the push operation." + ], + "LRANGE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of elements in the specified range, or an empty array if the key doesn't exist." + ], + "LREM": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of removed elements." + ], + "LSET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "LTRIM": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "MEMORY": [], + "MEMORY DOCTOR": [ + "[Verbatim string reply](/docs/reference/protocol-spec#verbatim-strings): a memory problems report." + ], + "MEMORY HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "MEMORY MALLOC-STATS": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): The memory allocator's internal statistics report." + ], + "MEMORY PURGE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "MEMORY STATS": [ + "[Map reply](/docs/reference/protocol-spec#maps): memory usage metrics and their values." + ], + "MEMORY USAGE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): the memory usage in bytes.", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key does not exist." + ], + "MGET": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of values at the specified keys." + ], + "MIGRATE": [ + "One of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` on success.", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `NOKEY` when no keys were found in the source instance." + ], + "MODULE": [], + "MODULE HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions" + ], + "MODULE LIST": [ + "[Array reply](/docs/reference/protocol-spec#arrays): list of loaded modules. Each element in the list represents a represents a module, and is a [Map reply](/docs/reference/protocol-spec#maps) of property names and their values. The following properties is reported for each loaded module:", + "* name: the name of the module.", + "* ver: the version of the module." + ], + "MODULE LOAD": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the module was loaded." + ], + "MODULE LOADEX": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the module was loaded." + ], + "MODULE UNLOAD": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if the module was unloaded." + ], + "MONITOR": [ + "**Non-standard return value**. Dumps the received commands in an infinite flow." + ], + "MOVE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if _key_ was moved.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if _key_ wasn't moved." + ], + "MSET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): always `OK` because `MSET` can't fail." + ], + "MSETNX": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if no key was set (at least one key already existed).", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if all the keys were set." + ], + "MULTI": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "OBJECT": [], + "OBJECT ENCODING": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key doesn't exist.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the encoding of the object." + ], + "OBJECT FREQ": [ + "One of the following:", + "[Integer reply](/docs/reference/protocol-spec#integers): the counter's value.", + "[Null reply](/docs/reference/protocol-spec#nulls): if _key_ doesn't exist." + ], + "OBJECT HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "OBJECT IDLETIME": [ + "One of the following:", + "[Integer reply](/docs/reference/protocol-spec#integers): the idle time in seconds.", + "[Null reply](/docs/reference/protocol-spec#nulls): if _key_ doesn't exist." + ], + "OBJECT REFCOUNT": [ + "One of the following:", + "[Integer reply](/docs/reference/protocol-spec#integers): the number of references.", + "[Null reply](/docs/reference/protocol-spec#nulls): if _key_ doesn't exist." + ], + "PERSIST": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if _key_ does not exist or does not have an associated timeout.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout has been removed." + ], + "PEXPIRE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0`if the timeout was not set. For example, if the key doesn't exist, or the operation skipped because of the provided arguments.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout was set." + ], + "PEXPIREAT": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the timeout was set.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the timeout was not set. For example, if the key doesn't exist, or the operation was skipped due to the provided arguments." + ], + "PEXPIRETIME": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): Expiration Unix timestamp in milliseconds.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if the key exists but has no associated expiration time.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-2` if the key does not exist." + ], + "PFADD": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if at least one HyperLogLog internal register was altered.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if no HyperLogLog internal registers were altered." + ], + "PFCOUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the approximated number of unique elements observed via `PFADD`" + ], + "PFDEBUG": [], + "PFMERGE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "PFSELFTEST": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "PING": [ + "Any of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `PONG` when no argument is provided.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the provided argument." + ], + "PSETEX": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "PSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each pattern, one message with the first element being the string `psubscribe` is pushed as a confirmation that the command succeeded." + ], + "PSYNC": [ + "**Non-standard return value**, a bulk transfer of the data followed by `PING` and write requests from the master." + ], + "PTTL": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): TTL in milliseconds.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if the key exists but has no associated expiration.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-2` if the key does not exist." + ], + "PUBLISH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of clients that received the message. Note that in a Redis Cluster, only clients that are connected to the same node as the publishing client are included in the count." + ], + "PUBSUB": [], + "PUBSUB CHANNELS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of active channels, optionally matching the specified pattern." + ], + "PUBSUB HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "PUBSUB NUMPAT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of patterns all the clients are subscribed to." + ], + "PUBSUB NUMSUB": [ + "[Array reply](/docs/reference/protocol-spec#arrays): the number of subscribers per channel, each even element (including the 0th) is channel name, each odd element is the number of subscribers" + ], + "PUBSUB SHARDCHANNELS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of active channels, optionally matching the specified pattern." + ], + "PUBSUB SHARDNUMSUB": [ + "[Array reply](/docs/reference/protocol-spec#arrays): the number of subscribers per shard channel, each even element (including the 0th) is channel name, each odd element is the number of subscribers." + ], + "PUNSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each pattern, one message with the first element being the string `punsubscribe` is pushed as a confirmation that the command succeeded." + ], + "QUIT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "RANDOMKEY": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): when the database is empty.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): a random key in the database." + ], + "READONLY": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "READWRITE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "RENAME": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "RENAMENX": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if _key_ was renamed to _newkey_.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if _newkey_ already exists." + ], + "REPLCONF": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "REPLICAOF": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "RESET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `RESET`." + ], + "RESTORE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "RESTORE-ASKING": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "ROLE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): where the first element is one of `master`, `slave`, or `sentinel`, and the additional elements are role-specific as illustrated above." + ], + "RPOP": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key does not exist.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): when called without the _count_ argument, the value of the last element.", + "* [Array reply](/docs/reference/protocol-spec#arrays): when called with the _count_ argument, a list of popped elements." + ], + "RPOPLPUSH": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the element being popped and pushed.", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the source list is empty." + ], + "RPUSH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list after the push operation." + ], + "RPUSHX": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the list after the push operation." + ], + "SADD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements that were added to the set, not including all the elements already present in the set." + ], + "SAVE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SCAN": [ + "[Array reply](/docs/reference/protocol-spec#arrays): specifically, an array with two elements.", + "* The first element is a [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) that represents an unsigned 64-bit number, the cursor.", + "* The second element is an [Array reply](/docs/reference/protocol-spec#arrays) with the names of scanned keys." + ], + "SCARD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The cardinality (number of elements) of the set, or 0 if the key does not exist." + ], + "SCRIPT": [], + "SCRIPT DEBUG": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SCRIPT EXISTS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): an array of integers that correspond to the specified SHA1 digest arguments." + ], + "SCRIPT FLUSH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SCRIPT HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "SCRIPT KILL": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SCRIPT LOAD": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the SHA1 digest of the script added into the script cache." + ], + "SDIFF": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list with the members of the resulting set." + ], + "SDIFFSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting set." + ], + "SELECT": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SENTINEL CKQUORUM": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): Returns OK if the current Sentinel configuration is able to reach the quorum needed to failover a master, and the majority needed to authorize the failover." + ], + "SENTINEL CONFIG": [ + "One of the following:", + "* [Map reply](/docs/reference/protocol-spec#maps): When 'SENTINEL-CONFIG GET' is called, returns a map.", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`. When 'SENTINEL-CONFIG SET' is called, returns OK on success." + ], + "SENTINEL DEBUG": [ + "One of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`. The configuration update was successful.", + "* [Map reply](/docs/reference/protocol-spec#maps): List of configurable time parameters and their values (milliseconds)." + ], + "SENTINEL FAILOVER": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`. Force a fail over as if the master was not reachable, and without asking for agreement to other Sentinels." + ], + "SENTINEL FLUSHCONFIG": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`. Force Sentinel to rewrite its configuration on disk, including the current Sentinel state." + ], + "SENTINEL GET MASTER-ADDR-BY-NAME": [], + "SENTINEL HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): Helpful text about subcommands." + ], + "SENTINEL INFO CACHE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): This is actually a map, the odd entries are a master name, and the even entries are the last cached INFO output from that master and all its replicas." + ], + "SENTINEL IS MASTER-DOWN-BY-ADDR": [], + "SENTINEL MASTER": [ + "[Map reply](/docs/reference/protocol-spec#maps): The state and info of the specified master." + ], + "SENTINEL MASTERS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): List of monitored Redis masters, and their state." + ], + "SENTINEL MONITOR": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SENTINEL MYID": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): Node ID of the sentinel instance." + ], + "SENTINEL PENDING SCRIPTS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): List of pending scripts." + ], + "SENTINEL REMOVE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SENTINEL REPLICAS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): List of replicas for this master, and their state." + ], + "SENTINEL RESET": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The number of masters that were reset." + ], + "SENTINEL SENTINELS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): List of sentinel instances, and their state." + ], + "SENTINEL SET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SENTINEL SIMULATE FAILURE": [ + "One of the following:", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`. The simulated flag was set.", + "* [Array reply](/docs/reference/protocol-spec#arrays): Supported simulates flags. Returned in case `HELP` was used." + ], + "SENTINEL SLAVES": [ + "[Array reply](/docs/reference/protocol-spec#arrays): List of monitored replicas, and their state." + ], + "SET": [ + "Any of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): `GET` not given: Operation was aborted (conflict with one of the `XX`/`NX` options).", + "* [Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`. `GET` not given: The key was set.", + "* [Null reply](/docs/reference/protocol-spec#nulls): `GET` given: The key didn't exist before the `SET`.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): `GET` given: The previous value of the key." + ], + "SETBIT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the original bit value stored at _offset_." + ], + "SETEX": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SETNX": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the key was not set.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the key was set." + ], + "SETRANGE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the string after it was modified by the command." + ], + "SHUTDOWN": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK` if _ABORT_ was specified and shutdown was aborted. On successful shutdown, nothing is returned because the server quits and the connection is closed. On failure, an error is returned." + ], + "SINTER": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list with the members of the resulting set." + ], + "SINTERCARD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of the elements in the resulting intersection." + ], + "SINTERSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of the elements in the result set." + ], + "SISMEMBER": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the element is not a member of the set, or when the key does not exist.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the element is a member of the set." + ], + "SLAVEOF": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SLOWLOG": [], + "SLOWLOG GET": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of slow log entries per the above format." + ], + "SLOWLOG HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "SLOWLOG LEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of entries in the slow log." + ], + "SLOWLOG RESET": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SMEMBERS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): all members of the set." + ], + "SMISMEMBER": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list representing the membership of the given elements, in the same order as they are requested." + ], + "SMOVE": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): `1` if the element is moved.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `0` if the element is not a member of _source_ and no operation was performed." + ], + "SORT": [ + "[Array reply](/docs/reference/protocol-spec#arrays): without passing the _STORE_ option, the command returns a list of sorted elements.", + "[Integer reply](/docs/reference/protocol-spec#integers): when the _STORE_ option is specified, the command returns the number of sorted elements in the destination list." + ], + "SORT_RO": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sorted elements." + ], + "SPOP": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key does not exist.", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): when called without the _count_ argument, the removed member.", + "* [Array reply](/docs/reference/protocol-spec#arrays): when called with the _count_ argument, a list of the removed members." + ], + "SPUBLISH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of clients that received the message. Note that in a Redis Cluster, only clients that are connected to the same node as the publishing client are included in the count" + ], + "SRANDMEMBER": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): without the additional _count_ argument, the command returns a randomly selected member, or a [Null reply](/docs/reference/protocol-spec#nulls) when _key_ doesn't exist.", + "* [Array reply](/docs/reference/protocol-spec#arrays): when the optional _count_ argument is passed, the command returns an array of members, or an empty array when _key_ doesn't exist." + ], + "SREM": [ + "[Integer reply](/docs/reference/protocol-spec#integers): Number of members that were removed from the set, not including non existing members." + ], + "SSCAN": [ + "[Array reply](/docs/reference/protocol-spec#arrays): specifically, an array with two elements:", + "* The first element is a [Bulk string reply](/docs/reference/protocol-spec#bulk-strings) that represents an unsigned 64-bit number, the cursor.", + "* The second element is an [Array reply](/docs/reference/protocol-spec#arrays) with the names of scanned members." + ], + "SSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each shard channel, one message with the first element being the string 'ssubscribe' is pushed as a confirmation that the command succeeded. Note that this command can also return a -MOVED redirect." + ], + "STRLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the length of the string stored at key, or 0 when the key does not exist." + ], + "SUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each channel, one message with the first element being the string `subscribe` is pushed as a confirmation that the command succeeded." + ], + "SUBSTR": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): the substring of the string value stored at key, determined by the offsets start and end (both are inclusive)." + ], + "SUNION": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list with the members of the resulting set." + ], + "SUNIONSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): Number of the elements in the resulting set." + ], + "SUNSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each shard channel, one message with the first element being the string `sunsubscribe` is pushed as a confirmation that the command succeeded." + ], + "SWAPDB": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "SYNC": [ + "**Non-standard return value**, a bulk transfer of the data followed by `PING` and write requests from the master." + ], + "TIME": [ + "[Array reply](/docs/reference/protocol-spec#arrays): specifically, a two-element array consisting of the Unix timestamp in seconds and the microseconds' count." + ], + "TOUCH": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of touched keys." + ], + "TTL": [ + "One of the following:", + "* [Integer reply](/docs/reference/protocol-spec#integers): TTL in seconds.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-1` if the key exists but has no associated expiration.", + "* [Integer reply](/docs/reference/protocol-spec#integers): `-2` if the key does not exist." + ], + "TYPE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): the type of _key_, or `none` when _key_ doesn't exist." + ], + "UNLINK": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of keys that were unlinked." + ], + "UNSUBSCRIBE": [ + "When successful, this command doesn't return anything. Instead, for each channel, one message with the first element being the string `unsubscribe` is pushed as a confirmation that the command succeeded." + ], + "UNWATCH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "WAIT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of replicas reached by all the writes performed in the context of the current connection." + ], + "WAITAOF": [ + "[Array reply](/docs/reference/protocol-spec#arrays): The command returns an array of two integers:", + "1. The first is the number of local Redises (0 or 1) that have fsynced to AOF all writes performed in the context of the current connection", + "2. The second is the number of replicas that have acknowledged doing the same." + ], + "WATCH": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "XACK": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The command returns the number of messages successfully acknowledged. Certain message IDs may no longer be part of the PEL (for example because they have already been acknowledged), and XACK will not count them as successfully acknowledged." + ], + "XADD": [ + "One of the following:", + "* [Bulk string reply](/docs/reference/protocol-spec#bulk-strings): The ID of the added entry. The ID is the one automatically generated if an asterisk (`*`) is passed as the _id_ argument, otherwise the command just returns the same ID specified by the user during insertion.", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the NOMKSTREAM option is given and the key doesn't exist." + ], + "XAUTOCLAIM": [ + "[Array reply](/docs/reference/protocol-spec#arrays), specifically, an array with three elements:", + "1. A stream ID to be used as the _start_ argument for the next call to XAUTOCLAIM.", + "2. An [Array reply](/docs/reference/protocol-spec#arrays) containing all the successfully claimed messages in the same format as `XRANGE`.", + "3. An [Array reply](/docs/reference/protocol-spec#arrays) containing message IDs that no longer exist in the stream, and were deleted from the PEL in which they were found." + ], + "XCLAIM": [ + "Any of the following:", + "* [Array reply](/docs/reference/protocol-spec#arrays): when the _JUSTID_ option is specified, an array of IDs of messages successfully claimed.", + "* [Array reply](/docs/reference/protocol-spec#arrays): an array of stream entries, each of which contains an array of two elements, the entry ID and the entry data itself." + ], + "XDEL": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of entries that were deleted." + ], + "XGROUP": [], + "XGROUP CREATE": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "XGROUP CREATECONSUMER": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of created consumers, either 0 or 1." + ], + "XGROUP DELCONSUMER": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of pending messages the consumer had before it was deleted." + ], + "XGROUP DESTROY": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of destroyed consumer groups, either 0 or 1." + ], + "XGROUP HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "XGROUP SETID": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "XINFO": [], + "XINFO CONSUMERS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of consumers and their attributes." + ], + "XINFO GROUPS": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of consumer groups." + ], + "XINFO HELP": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of sub-commands and their descriptions." + ], + "XINFO STREAM": [ + "One of the following:", + "* [Map reply](/docs/reference/protocol-spec#maps): when the _FULL_ argument was not given, a list of information about a stream in summary form.", + "* [Map reply](/docs/reference/protocol-spec#maps): when the _FULL_ argument was given, a list of information about a stream in extended form." + ], + "XLEN": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of entries of the stream at _key_." + ], + "XPENDING": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): different data depending on the way XPENDING is called, as explained on this page." + ], + "XRANGE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of stream entries with IDs matching the specified range." + ], + "XREAD": [ + "One of the following:", + "* [Map reply](/docs/reference/protocol-spec#maps): A map of key-value elements where each element is composed of the key name and the entries reported for that key. The entries reported are full stream entries, having IDs and the list of all the fields and values. Field and values are guaranteed to be reported in the same order they were added by `XADD`.", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the _BLOCK_ option is given and a timeout occurs, or if there is no stream that can be served." + ], + "XREADGROUP": [ + "One of the following:", + "* [Map reply](/docs/reference/protocol-spec#maps): A map of key-value elements where each element is composed of the key name and the entries reported for that key. The entries reported are full stream entries, having IDs and the list of all the fields and values. Field and values are guaranteed to be reported in the same order they were added by `XADD`.", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the _BLOCK_ option is given and a timeout occurs, or if there is no stream that can be served." + ], + "XREVRANGE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): The command returns the entries with IDs matching the specified range. The returned entries are complete, which means that the ID and all the fields they are composed of are returned. Moreover, the entries are returned with their fields and values in the same order as `XADD` added them." + ], + "XSETID": [ + "[Simple string reply](/docs/reference/protocol-spec#simple-strings): `OK`." + ], + "XTRIM": [ + "[Integer reply](/docs/reference/protocol-spec#integers): The number of entries deleted from the stream." + ], + "ZADD": [ + "Any of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the operation was aborted because of a conflict with one of the _XX/NX/LT/GT_ options.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the number of new members when the _CH_ option is not used.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the number of new or updated members when the _CH_ option is used.", + "* [Double reply](/docs/reference/protocol-spec#doubles): the updated score of the member when the _INCR_ option is used." + ], + "ZCARD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the cardinality (number of members) of the sorted set, or 0 if the key doesn't exist." + ], + "ZCOUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the specified score range." + ], + "ZDIFF": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): the result of the difference including, optionally, scores when the _WITHSCORES_ option is used." + ], + "ZDIFFSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the resulting sorted set at _destination_." + ], + "ZINCRBY": [ + "[Double reply](/docs/reference/protocol-spec#doubles): the new score of _member_." + ], + "ZINTER": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): the result of the intersection including, optionally, scores when the _WITHSCORES_ option is used." + ], + "ZINTERCARD": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the resulting intersection." + ], + "ZINTERSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the resulting sorted set at the _destination_." + ], + "ZLEXCOUNT": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members in the specified score range." + ], + "ZMPOP": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): when no element could be popped.", + "* [Array reply](/docs/reference/protocol-spec#arrays): A two-element array with the first element being the name of the key from which elements were popped, and the second element is an array of the popped elements. Every entry in the elements array is also an array that contains the member and its score." + ], + "ZMSCORE": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the member does not exist in the sorted set.", + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of [Double reply](/docs/reference/protocol-spec#doubles) _member_ scores as double-precision floating point numbers." + ], + "ZPOPMAX": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of popped elements and scores." + ], + "ZPOPMIN": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of popped elements and scores." + ], + "ZRANDMEMBER": [ + "[Bulk string reply](/docs/reference/protocol-spec#bulk-strings): without the additional _count_ argument, the command returns a randomly selected member, or [Null reply](/docs/reference/protocol-spec#nulls) when _key_ doesn't exist.", + "[Array reply](/docs/reference/protocol-spec#arrays): when the additional _count_ argument is passed, the command returns an array of members, or an empty array when _key_ doesn't exist. If the _WITHSCORES_ modifier is used, the reply is a list of members and their scores from the sorted set." + ], + "ZRANGE": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of members in the specified range with, optionally, their scores when the _WITHSCORES_ option is given." + ], + "ZRANGEBYLEX": [ + "[Array reply](/docs/reference/protocol-spec#arrays): a list of elements in the specified score range." + ], + "ZRANGEBYSCORE": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of the members with, optionally, their scores in the specified score range." + ], + "ZRANGESTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting sorted set." + ], + "ZRANK": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key does not exist or the member does not exist in the sorted set.", + "* [Integer reply](/docs/reference/protocol-spec#integers): the rank of the member when _WITHSCORE_ is not used.", + "* [Array reply](/docs/reference/protocol-spec#arrays): the rank and score of the member when _WITHSCORE_ is used." + ], + "ZREM": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of members removed from the sorted set, not including non-existing members." + ], + "ZREMRANGEBYLEX": [ + "[Integer reply](/docs/reference/protocol-spec#integers): Number of members removed." + ], + "ZREMRANGEBYRANK": [ + "[Integer reply](/docs/reference/protocol-spec#integers): Number of members removed." + ], + "ZREMRANGEBYSCORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): Number of members removed." + ], + "ZREVRANGE": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of members in the specified range, optionally with their scores if _WITHSCORE_ was used." + ], + "ZREVRANGEBYLEX": [ + "[Array reply](/docs/reference/protocol-spec#arrays): List of the elements in the specified score range." + ], + "ZREVRANGEBYSCORE": [ + "* [Array reply](/docs/reference/protocol-spec#arrays): a list of the members and, optionally, their scores in the specified score range." + ], + "ZREVRANK": [ + "One of the following:", + "* [Null reply](/docs/reference/protocol-spec#nulls): if the key does not exist or the member does not exist in the sorted set.", + "* [Integer reply](/docs/reference/protocol-spec#integers): The rank of the member when _WITHSCORE_ is not used.", + "* [Array reply](/docs/reference/protocol-spec#arrays): The rank and score of the member when _WITHSCORE_ is used." + ], + "ZSCAN": [ + "[Array reply](/docs/reference/protocol-spec#arrays): cursor and scan response in array form." + ], + "ZSCORE": [ + "One of the following:", + "* [Double reply](/docs/reference/protocol-spec#doubles): the score of the member (a double-precision floating point number).", + "* [Nil reply](/docs/reference/protocol-spec#bulk-strings): if _member_ does not exist in the sorted set, or the key does not exist." + ], + "ZUNION": [ + "[Array reply](/docs/reference/protocol-spec#arrays): the result of the union with, optionally, their scores when _WITHSCORES_ is used." + ], + "ZUNIONSTORE": [ + "[Integer reply](/docs/reference/protocol-spec#integers): the number of elements in the resulting sorted set." + ] +} diff --git a/tools/other/github.com/redis/librdb.json b/tools/other/github.com/redis/librdb.json new file mode 100644 index 0000000000..23818714d8 --- /dev/null +++ b/tools/other/github.com/redis/librdb.json @@ -0,0 +1,5 @@ +{ + "name": "librdb", + "description": "Redis RDB file parser, with JSON, RESP and RDB-loader extensions", + "recommended": true +} diff --git a/wordlist b/wordlist index 60fe619c87..d222fcd152 100644 --- a/wordlist +++ b/wordlist @@ -1,483 +1,56 @@ - +3:00 AM +4:00 AM +5:00 AM +6:00 AM .rdb +ˈrɛd-ɪs 0s 0x00060007 0x00MMmmpp -100MB -100k -10GB -10k -128MB -12k -1GB -1s -1th -2GB -300ms -30ms -32MB -32bit -3GB -3MB -3am -3c3a0c -3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e -4GB -4am -4k -500MB -512MB -5GB -5am -60s -6am -6sync -80ms -85MB -8MB -8ms -90s -97a3a64667477371c4479320d683e4c8db5858b1 -A1 -ACKs -ACLs -AMD64 -AOF -AOFRW -AOF_START -APIs -ARGV -ASN -AUTOID -Aioredlock -Alibaba -Arity -Async -Asyncio -Atomicvar -Auth -B1 -B2 -B3 -BCC's -BDFL-style -birthyear -BPF -BPF's -BPF-optimized -Benchmarking -BigNumber -BitOp -Bitfields -Bitwise -Booleans -brpop -C1 -C2 -C3 -C4 -C5 -CAS -CAs -CFIELD -CKQUORUM -CLI -CLI's -CP -CPUs -CRC -CRC-16 -CRC16 -CRC64 -CRDTs -CRLF -CRLF-terminated -CSV -CallReply -CentOS -Changelog -Chemeris -Citrusbyte -CloseKey -Cn -Collina's -Config -ContextFlags -Costin -Craigslist -Ctrl-a -DBs -DLM -DMA -dnf -DNF -DNS -DSL -Deauthenticate -Deauthenticates -Defrag -Deno -Diskless -DistLock -Dynomite -EBADF -EBS -EC2 -EDOM -EEXIST -EFBIG -EINVAL -Enduro -Ergonom -ENOENT -ENOTSUP -EOF -EP -EPEL -EPSG:3785 -EPSG:900913 -ERANGE -Enum -Eval -EventLoop -EventMachine -FLUSHCONFIG -Failover -Failover-based -Failovers -FlameGraph -FreeBSD -FreeString -Fsyncing -GDB -GEODEL -GET-MASTER-ADDR-BY-NAME -go-redis -GPG -Gbit -GeoHashes -Geohash -Geohashes -Geospatial -Github -Gottlieb -Gradle -HashMap -HLL -HLLs -HMAC-SHA256 -HVM -HW -Hacktoberfest -Hardcoded -HashMaps -HashSets -Haversine -Hexastore -hget -hgetall -hincrby -hmget -Hitmeister -Homebrew -Hotspot -hset -HyperLogLog -HyperLogLog. -HyperLogLogs -Hyperloglogs -hyperloglogs -incr -incrby -IOPs -IPC -IPs -IPv4 -IPv6 -IS-MASTER-DOWN-BY-ADDR -Identinal -IoT -incrby_get_mget -Itamar -Jedis -JedisCluster -JedisPool -JedisPooled -JDK -JKS -JSON -JSON-encoded -Janowski -Javadocs -Jemalloc -js -KEYSPACE -Keyspace -KeyspaceNotification -Kleppman's -Kleppmann -L3 -LDB -LF -LFU -LHF -LLOOGG -lmove_lrange -LRU -LRU's -LRU. -LUA -Leaderboards -Leau -Lehmann -Levelgraph -licensor -licensor's -LibLZF -Linode -Liveness -llen -lmove_lrange -lpop -lpop_rpop -lpush_rpush -lrange -ltrim -ltrim_end_of_list -Lua -Lua's -lua-debugging -Lua-to-Redis -Lucraft -M1 -MASTERDOWN -MERCHANTABILITY -MacBook -Matteo -Maxmemory -Memcache -MessagePack -mget -Movablekeys -Mrkris -mset -multisets -NAS -NATted -NFS -NIC -NICs -NOOP -NTP -NUMA -NX -NaN -NaNs -Nehalem -node-redis -NoSQL -NodeJS -Noordhuis -NullArray -ODOWN -OOM -OR-ing -ORed -OSGEO:41001 -Ok -OpenBSD -OpenSSL -Opteron -ORM -PEL -PELs -PEM -PFAIL -PHPRedisMutex -PID -PMCs -PMU -POP3 -POSIX -POV -PRNG -PV -Parameterization -Pieter -Pipelining -Pool2 -Predis -Prev -Prioglio -Programm -Programmability -PubSub-related -Pubsub -Pubsub. -Pydantic -R1 -R2 -RC1 -RC3 -RC4 -RDB -RDB-saving -RedisInsight -REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD -REDISPORT -REPL -RESP2 -RESP2. -RESP3 -RESP3's -RESP3-typed -RESP3. -REdis -RHEL -RM_CreateCommand -RM_CreateStringFromString -RM_IsKeysPositionRequest -RM_KeyAtPosWithFlags -RM_SetCommandInfo -RM_.* -RPC -RSS -RTT -RU101 -RU102 -RU202 -RW -Rebranding -Reconfiguring -Reddit's -RediSearch -Redimension -Redis-rb -Redis-to-Lua -RedisCallReply -RedisConf -RedisHost. -RedisJSON -RedisModule.* -Redisson -Redistributions -Redlock -Redlock-cpp -Redlock-cs -Redlock-php -Redlock-py -Redlock-rb -Redlock4Net -Redsync -Reshard -Resharding -Resque -RetainString -Retwis -Retwis-J -Retwis-RB -Roshi -rpush -Rx/Tx -Rslock -S1 -S2 -S3 -S4 -SaaS -SCP -SDOWN -SHA-256 -SHA1 -SHA256 -SIGBUS -SIGFPE -SIGILL -SIGINT -SIGSEGV -SIGTERM -SSD -SSL -SVGs -SYNC_RDB_START -sadd -sadd_smembers -Sandboxed -Sanfilippo -Sanfilippo's -scard -ScarletLock -sdiff -Selectable -setnx_xx -Sharded -Shuttleworth -sinter -sismember -Slicehost -SmartOS -smismember -Snapchat -Snapcraft -Snapshotting -Solaris-derived -SomeOtherValue -Sonatype -SoundCloud -srem -StackOverflow -StringDMA -Subcommands -T1 -T2 -TCL -TCP -TLS -TLS-enabled -TTL -TTLs -Tthe -Twemproxy -UI -ULID -ULIds -ULIDs -URI -USD -UTF-8 -Unmodifiable -Unregister -Untrusted -Unwatches -VM -VMs -VMware -VPS -ValueN -Variadic -Virtualized -Vladev -WSL -WSL2 -Westmere -XMODEM -XSCAN -XYZ -Xen -Xen-specific -Xeon -YCSB -Yossi -Z1 -ZMODEM -ZPOP -ZSET -ZeroBrane -Zhao +100k +100MB +10GB +10k +128MB +12k +1GB +1s +1th +2GB +3am +300ms +30ms +32bit +32MB +3c3a0c +3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e +3GB +3MB +4am +4GB +4k +5am +500MB +512MB +5GB +6am +60s +6sync +80ms +85MB +8MB +8ms +90s +97a3a64667477371c4479320d683e4c8db5858b1 +A1 acknowledgement +ACKs acl acl-pubsub-default +ACLs ad-hoc +Aioredlock +Alibaba alice allchannels allkeys @@ -486,32 +59,48 @@ allkeys-random allocator allocator's allocators +AMD64 analytics antirez antirez's +AOF aof +AOF_START aof-1 aof-2 aof-N +AOFRW api apiname +APIs appendfsync appendonly applicative args +ARGV argv argvs +Arity arity +ASN +Async async +Asyncio atomicity +Atomicvar +Auth auth authenticateClientWithUser -autoloading -Autoloading -autoload -autoloader auto-reconnection autocomplete +AUTOID +autoload +autoloader +autoloading +Autoloading +B1 +B2 +B3 backend backported backslashed @@ -521,51 +110,104 @@ balancer bazzar bc bcc +BCC's bcc's +BDFL-style beforeSleep behaviour benchmarked +Benchmarking benchmarking big-endian +BigNumber +bikes:racing:france +bikes:racing:italy +bikes:racing:usa +bikes:rentable +birthyear bitfield bitfield +Bitfields bitfields +BitOp bitop +Bitwise bitwise bitwise bool +Booleans booleans +BPF +BPF-optimized +BPF's breakpoint broadcasted +brpop bt btree1-az +C1 +C2 +C3 +C4 +C5 +CallReply cancelled cardinalities cardinality +CAS +CAs casted +Castilla cd +CentOS +CFIELD +Changelog changelogs charset +Chemeris cheprasov +Citrusbyte cjson +CKQUORUM cleartext +CLI cli +CLI's +CloseKey cluster-config-file Cmd cmsgpack +Cn codename codenamed +Collina's commandstats commnad +CONFIG +Config config config-file configEpoch configs const +ContextFlags +Costin +CP cpu cpu-profiling +CPUs +Craigslist +CRC +CRC-16 +CRC16 +CRC64 +CRDTs +CRLF +CRLF-terminated cron cryptographic +CSV +Ctrl-a ctx daemonize daemonized @@ -573,14 +215,18 @@ daemontools dataset datastore dbid +DBs de de-serialization de-serialize deallocated dearmor +Deauthenticate deauthenticate deauthenticated +Deauthenticates deduplicated +Defrag defrag defragging defragment @@ -588,6 +234,7 @@ defragmentable defragmentation defragmented del +Deno deny-oom deserialize deserialized @@ -596,11 +243,27 @@ desync desynchronize dev dir +Diskless diskless +DistLock distlock +DLM +DMA +dnf +DNF +DNS +DSL dup-sentinel -eBPF +Dynomite earts +EBADF +eBPF +EBS +EC2 +EDOM +EEXIST +EFBIG +EINVAL ele emented enable-protected-configs @@ -613,20 +276,34 @@ end-slot2 end-slotN endian endianness +Enduro +ENOENT +ENOTSUP +Enum enum enum_val enum_vals enums +EOF +EP +EPEL epel-release epoll +EPSG:3785 +EPSG:900913 +ERANGE +Ergonom errno error1 error2 errorstats ethernet +Eval eval eval-intro +EventLoop eventloop +EventMachine everysec executables expiries @@ -634,7 +311,9 @@ explainer explainers facto factorializing +Failover failover +Failover-based failover-detected failover-end failover-end-for-timeout @@ -642,6 +321,7 @@ failover-state-reconf-slaves failover-state-select-slave failover-state-send-slaveof-noone failover. +Failovers failovers fanout faq @@ -653,46 +333,100 @@ firewalling first-arg first-args firstkey +FlameGraph +FLUSHCONFIG fmt foo0 foo1 foo2 formatter +france_location +FreeBSD +FreeString fractionals frequencyonly fsSL fsync +fsynced +Fsyncing fsyncing +fsyncs func +Gbit +GDB gdb geo +geo_tutorial +geoadd +GEODEL +Geohash geohash geohash-encoded +GeoHashes +Geohashes +geosearch +Geospatial geospatial +GET-MASTER-ADDR-BY-NAME getkeys-api +Github github globals +go-redis +Gottlieb +GPG gpg +Gradle +Hacktoberfest hacktoberfest handleClientsWithPendingWrites +Hardcoded hardcoded hardlinks +HashMap +HashMaps HashSet +HashSets +Haversine Healthcheck healthchecks +Henshaw +Hexastore hexastore +hget +hgetall +hincrby hiredis +Hitmeister +HLL +HLLs +HMAC-SHA256 +hmget holdApplicationUntilProxyStarts +Homebrew hostname hostnames +Hotspot hotspots +hset +HVM +HW +HyperLogLog hyperloglog +HyperLogLog. +HyperLogLogs +Hyperloglogs +hyperloglogs i8 iamonds IANA +Identinal idletime idx idx'-th +incr +incrby +incrby_get_mget indexable ing init @@ -704,51 +438,97 @@ internals-vm intsets invalidations iojob +IOPs iostat +IoT ip ip:port +IPC +IPs +IPv4 +IPv6 +IS-MASTER-DOWN-BY-ADDR Istio +italy_racers +Itamar iterable iteratively +ition +Janowski +Javadocs +JDK +Jedis jedis +JedisCluster jedisClusterNodes +JedisPool +JedisPooled +Jemalloc jemalloc +JKS jpeg +js +JSON +JSON-encoded +JUSTID kB keepalive -keyN keylen +keyN keyname keynum keynumidx keyrings +KEYSPACE +Keyspace keyspace keyspace-notifications +KeyspaceNotification keyspec keystep keytool +Kleppman's +Kleppmann knockknock kqueue +L3 last-failover-wins -lastVoteEpoch lastkey +lastVoteEpoch late-defrag latencies latencystats launchd lazyfree-lazy-user-flush +LDB ldb leaderboard +Leaderboards leaderboards +Leau +Lehmann len lenptr +Levelgraph lexicographically +LF +LFU +LHF libc +LibLZF libssl-dev +licensor +licensor's linenoise linkTitle +Linode little-endian +Liveness liveness +llen +LLOOGG +lmove_lrange +lmove_lrange ln LoadX509KeyPair localhost @@ -758,88 +538,164 @@ logics loglevel lookups loopback +lpop +lpop_rpop lpush +lpush_rpush +lrange +LRU lru_cache -lsb-release +LRU. +LRU's lsb_release +lsb-release +ltrim +ltrim_end_of_list +LUA +Lua lua-api +lua-debugging lua-replicate-commands +Lua-to-Redis +Lua's lubs +Lucraft +M1 +MacBook macOS macroscopically malloc +MASTERDOWN +Matteo matteocollina +maxlen +MAXLEN +Maxmemory maxmemory +Memcache memcached memset memtest86 memtier_benchmark +MERCHANTABILITY +MessagePack metatag +mget middleware +MINID miranda misconfiguration misconfigured -moduleType +MKSTREAM modules-api-ref +moduleType +Movablekeys movablekeys +Mrkris +mset +multisets mutex mylist mymaster +mystream myuser myzset namespace namespacing +NaN +NAS natively +NATted +Nehalem netcat newjobs +NFS +NIC +NICs nils no-appendfsync-on-rewrite +node-redis node-redlock +NodeJS noeviction +non-reachability non-TCP non-TLS non-loopback non-reachability non-virtualized nonprintable +NOOP +Noordhuis nopass +Norem +NoSQL notify-keyspace-events notifyKeyspaceEvent NRedisStack +NTP +NullArray +nullarray num-items +NUMA numactl numkeys -nullarray +NX nx observability +ODOWN octothorpe odown +Ok ok oldval oneof onwards +OOM +OpenBSD +OpenSSL openssl +Opteron optionals +OR-ing +ORed +ORM +OSGEO:41001 overcommit p50 p999 Packagist pades pageview +Parameterization parameterization parametrize params parsable +PEL +PELs +PEM perf perf_events performance-on-cpu +PFAIL php-redis-lock +PHPRedisMutex +PID pid pidfile +Pieter pipelined +Pipelining pipelining pkcs12 +PMCs pmessage +PMU +Pool2 +POP3 +POSIX +POV ppa:redislabs pre-conditions pre-configured @@ -848,28 +704,50 @@ pre-imported pre-loaded pre-populated pre-sharding +Predis prepend Prepend preprocessing prerequesits +Prev prev +Prickett printf printf-alike +Prioglio privdata +PRNG probabilistically proc +Programm +Programmability programmability programmatically programmatically-generated pseudorandom PSR-4 +Pubsub pubsub +PubSub-related +Pubsub. +PV +Pydantic qsort -quickstarts queueing +quickstarts +R1 +R2 +race:france +race:italy +race:usa radix rc +RC1 +RC3 +RC4 +RDB rdb-preamble +RDB-saving rdd rdd-1 rdd-2 @@ -884,12 +762,17 @@ realtime reauthenticate rebalance rebalancing +Rebranding reconfigurations reconfigures +Reconfiguring reconfiguring reconnection reconnections +Reddit's +Redimension redirections +REdis redis redis-benchmark redis-check-aof @@ -902,12 +785,35 @@ redis-macOS-demo redis-om-python redis-om-python. redis-py +Redis-rb redis-rb-cluster redis-server redis-stable +Redis-to-Lua +RedisCallReply +RedisConf +RediSearch +Redises +RedisHost. +RedisInsight +RedisJSON +REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD +RedisModule.* redisObjectVM +REDISPORT +Redisson +Redistributions +Redlock +Redlock-cpp +Redlock-cs +Redlock-php +Redlock-py +Redlock-rb +Redlock4Net +Redsync registerAPI reimplements +REPL repl-diskless-load repo representable @@ -919,53 +825,129 @@ rescanned reseek resends resetpass +Reshard reshard resharded +Resharding resharding reshardings +RESP2 +RESP2. +RESP3 +RESP3-typed +RESP3. +RESP3's +Resque resque resync resynchronization resynchronizations resyncs +RetainString retcode returing +Retwis +Retwis-J +Retwis-RB +RHEL +RM_.* +RM_CreateCommand +RM_CreateStringFromString +RM_IsKeysPositionRequest +RM_KeyAtPosWithFlags +RM_SetCommandInfo roadmap robj +Roshi roundtrips +RPC rpc-perf rpop +rpush +Rslock +RSS rss rtckit +RTT +RU101 +RU102 +RU202 runid runlevels +RW +Rx/Tx +S1 +S2 +S3 +S4 +SaaS +sadd +sadd_smembers +Sam-Bodden +Sandboxed sandboxed +Sanfilippo +Sanfilippo's scalable +scard +ScarletLock +SCP +sdiff +SDOWN sdown sds se seeked +Selectable semantical serverCron +setnx_xx +SHA-256 +SHA1 +SHA256 +Sharded sharded sharding +Shuttleworth si sidekiq +SIGBUS +SIGFPE +SIGILL +SIGINT signle +SIGSEGV +SIGTERM +sinter +sismember slave-reconf-done slave-reconf-inprog slave-reconf-sent +Slicehost slot1 slowlog smaps +SmartOS +smismember +Snapchat +Snapcraft snapd +Snapshotting snapshotting +Solaris-derived somekey +SomeOtherValue +Sonatype +SoundCloud spectrogram spellchecker-cli spiped spo sponsorships +srem +SSD +SSL +StackOverflow start-slot1 start-slot2 start-slotN @@ -975,14 +957,17 @@ status2 stdin storepass strace +stream_toturial +StringDMA struct -structs -struct's struct-encoded +struct's +structs stunnel subcommand -subcommand's subcommand. +subcommand's +Subcommands subcommands subevent subevents @@ -990,16 +975,24 @@ suboptimal subsequence substring sudo +SVGs superset swapdb swappability +SYNC_RDB_START syncd syscall systemctl +T1 +T2 taskset +TCL tcmalloc +TCP tcp the-redis-keyspace +TLS +TLS-enabled tls-port tmp tmux @@ -1010,9 +1003,17 @@ tradeoff tradeoffs transactional try-failover +Tthe +TTL +TTLs tty tunable +Twemproxy typemethods_ptr +UI +ULID +ULIds +ULIDs un-authenticated un-gated unclaimable @@ -1024,48 +1025,122 @@ unix unlink unlinked unlinks +Unmodifiable unmodifiable unpause unreachability +Unregister unregister unregisters +Untrusted untrusted untuned +Unwatches unwatches uppercased urandom +URI +USD used_memory_scripts_eval userSession usr +UTF-8 utf8 utils v9 value-ptr +ValueN +Variadic variadic venv virginia +Virtualized virtualized +Vladev +VM vm vm-max-memory -vmSwapOneObject +VMs vmstat +vmSwapOneObject +VMware volatile-lru volatile-ttl +VPS vtype +WAITAOF +Westmere wget wherefrom whitespace whitespaces whos-using-redis WRONGTYPE +WSL +WSL2 +xack +XACK +xadd +XADD +xadd_2 +xadd_7 +xadd_bad_id +xadd_id +xautoclaim +XAUTOCLAIM +xautoclaim_cursor +xclaim +XCLAIM +xdel +XDEL +Xen +Xen-specific +Xeon xff +XGROUP +xgroup_create +xgroup_create_mkstream +xgroup_read +xgroup_read_bob +xinfo +XINFO +xinfo_consumers +xinfo_groups +xlen +XLEN +XMODEM +xpending +XPENDING +xpending_plus_minus +xrange +XRANGE +xrange_all +xrange_empty +xrange_pending +xrange_step_1 +xrange_step_2 +xrange_time +xread +XREAD +XREADGROUP +xgroup_read_id +xread_block +xrevrange +XREVRANGE +XSCAN +xtrim +XTRIM +xtrim2 +XYZ xzvf +YCSB +Yossi +Z1 +ZeroBrane zeroed-ACLs +Zhao ziplists +ZMODEM +ZPOP +ZSET zset -ˈrɛd-ɪs -fsynced -fsyncs -WAITAOF -Redises -ition