Skip to content

Commit

Permalink
package with redis-doc data
Browse files Browse the repository at this point in the history
  • Loading branch information
laixintao committed Jan 15, 2020
1 parent a3f652c commit 83122b6
Show file tree
Hide file tree
Showing 235 changed files with 9,228 additions and 31 deletions.
42 changes: 21 additions & 21 deletions .circleci/config.yml
Expand Up @@ -14,7 +14,7 @@ jobs:
# Download and cache dependencies
- restore_cache:
keys:
- v5-dependencies-twine
- v6-dependencies-twine
- run:
name: install dependencies
command: |
Expand All @@ -24,7 +24,7 @@ jobs:
- save_cache:
paths:
- ./venv
key: v5-dependencies-poetry
key: v6-dependencies-twine
- run:
name: "upload files to pypi: https://pypi.org/project/iredis/#history"
command: |
Expand Down Expand Up @@ -67,19 +67,19 @@ jobs:
# Download and cache dependencies
- restore_cache:
keys:
- v5-dependencies-poetry
- v6-dependencies-poetry

- run:
name: install dependencies
command: |
python3 -m venv venv
. venv/bin/activate
pip install poetry pip==19
pip install poetry==1.0.0 pip==19
- save_cache:
paths:
- ./venv
key: v5-dependencies-poetry
key: v6-dependencies-poetry

- run:
name: build release
Expand All @@ -101,7 +101,7 @@ jobs:
# Download and cache dependencies
- restore_cache:
keys:
- v5-dependencies-black
- v6-dependencies-black

- run:
name: install dependencies
Expand All @@ -113,7 +113,7 @@ jobs:
- save_cache:
paths:
- ./venv
key: v5-dependencies-black
key: v6-dependencies-black

- run:
name: black format
Expand All @@ -131,7 +131,7 @@ jobs:
# Download and cache dependencies
- restore_cache:
keys:
- v5-dependencies-flake8
- v6-dependencies-flake8

- run:
name: install dependencies
Expand All @@ -143,7 +143,7 @@ jobs:
- save_cache:
paths:
- ./venv
key: v5-dependencies-flake8
key: v6-dependencies-flake8

- run:
name: run flake8
Expand All @@ -170,9 +170,9 @@ jobs:
# Download and cache dependencies
- restore_cache:
keys:
- v5-dependencies-{{ checksum "poetry.lock" }}
- v6-dependencies-{{ checksum "poetry.lock" }}
# fallback to using the latest cache if no exact match is found
- v5-dependencies-
- v6-dependencies-

- run:
name: install dependencies
Expand All @@ -185,7 +185,7 @@ jobs:
- save_cache:
paths:
- ./venv
key: v5-dependencies-{{ checksum "poetry.lock" }}
key: v6-dependencies-{{ checksum "poetry.lock" }}

- run:
name: run tests
Expand All @@ -211,9 +211,9 @@ jobs:
# Download and cache dependencies
- restore_cache:
keys:
- v5-dependencies-{{ checksum "poetry.lock" }}
- v6-dependencies-{{ checksum "poetry.lock" }}
# fallback to using the latest cache if no exact match is found
- v5-dependencies-
- v6-dependencies-

- run:
name: install dependencies
Expand All @@ -226,7 +226,7 @@ jobs:
- save_cache:
paths:
- ./venv
key: v5-dependencies-{{ checksum "poetry.lock" }}
key: v6-dependencies-{{ checksum "poetry.lock" }}

- run:
name: run tests
Expand All @@ -253,9 +253,9 @@ jobs:
# Download and cache dependencies
- restore_cache:
keys:
- v5-dependencies-{{ checksum "poetry.lock" }}
- v6-dependencies-{{ checksum "poetry.lock" }}
# fallback to using the latest cache if no exact match is found
- v5-dependencies-
- v6-dependencies-

- run:
name: install dependencies
Expand All @@ -268,7 +268,7 @@ jobs:
- save_cache:
paths:
- ./venv
key: v5-dependencies-{{ checksum "poetry.lock" }}
key: v6-dependencies-{{ checksum "poetry.lock" }}

- run:
name: run tests
Expand All @@ -294,9 +294,9 @@ jobs:
# Download and cache dependencies
- restore_cache:
keys:
- v5-dependencies-3.8.0-{{ checksum "poetry.lock" }}
- v6-dependencies-3.8.0-{{ checksum "poetry.lock" }}
# fallback to using the latest cache if no exact match is found
- v5-dependencies-3.8.0-
- v6-dependencies-3.8.0-

- run:
name: install dependencies
Expand All @@ -309,7 +309,7 @@ jobs:
- save_cache:
paths:
- ./venv
key: v5-dependencies-3.8.0-{{ checksum "poetry.lock" }}
key: v6-dependencies-3.8.0-{{ checksum "poetry.lock" }}

- run:
name: run tests
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
@@ -1,3 +1,6 @@
[submodule "iredis/data/redis-doc"]
path = iredis/data/redis-doc
url = https://github.com/antirez/redis-doc.git
[submodule "redis-doc"]
path = redis-doc
url = https://github.com/antirez/redis-doc.git
4 changes: 1 addition & 3 deletions iredis/client.py
Expand Up @@ -350,9 +350,7 @@ def do_help(self, *args):
command_docs_name = "-".join(args).lower()
command_summary_name = " ".join(args).upper()
try:
doc_file = open(
project_data / "redis-doc" / "commands" / f"{command_docs_name}.md"
)
doc_file = open(project_data / "commands" / f"{command_docs_name}.md")
except FileNotFoundError:
raise NotRedisCommand(
f"{command_summary_name} is not a valide Redis command."
Expand Down
56 changes: 56 additions & 0 deletions iredis/data/commands/append.md
@@ -0,0 +1,56 @@
If `key` already exists and is a string, this command appends the `value` at the
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
EXISTS mykey
APPEND mykey "Hello"
APPEND mykey " World"
GET mykey
```

## Pattern: Time series

The `APPEND` command can be used to create a very compact representation of a
list of fixed-size samples, usually referred as _time series_.
Every time a new sample arrives we can store it using the command

```
APPEND timeseries "fixed-size sample"
```

Accessing individual elements in the time series is not hard:

* `STRLEN` can be used in order to obtain the number of samples.
* `GETRANGE` allows for random access of elements.
If our time series have associated time information we can easily implement
a binary search to get range combining `GETRANGE` with the Lua scripting
engine available in Redis 2.6.
* `SETRANGE` can be used to overwrite an existing time series.

The limitation of this pattern is that we are forced into an append-only mode
of operation, there is no way to cut the time series to a given size easily
because Redis currently lacks a command able to trim string objects.
However the space efficiency of time series stored in this way is remarkable.

Hint: it is possible to switch to a different key based on the current Unix
time, in this way it is possible to have just a relatively small amount of
samples per key, to avoid dealing with very big keys, and to make this pattern
more friendly to be distributed across many Redis instances.

An example sampling the temperature of a sensor using fixed-size strings (using
a binary format is better in real implementations).

```cli
APPEND ts "0043"
APPEND ts "0035"
GETRANGE ts 0 3
GETRANGE ts 4 7
```
16 changes: 16 additions & 0 deletions iredis/data/commands/auth.md
@@ -0,0 +1,16 @@
Request for authentication in a password-protected Redis server.
Redis can be instructed to require a password before allowing clients to execute
commands.
This is done using the `requirepass` directive in the configuration file.

If `password` matches the password in the configuration file, the server replies
with the `OK` status code and starts accepting commands.
Otherwise, an error is returned and the clients needs to try a new password.

**Note**: 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.

@return

@simple-string-reply
30 changes: 30 additions & 0 deletions iredis/data/commands/bgrewriteaof.md
@@ -0,0 +1,30 @@
Instruct Redis to start an [Append Only File][tpaof] rewrite process.
The rewrite will create a small optimized version of the current Append Only
File.

[tpaof]: /topics/persistence#append-only-file

If `BGREWRITEAOF` fails, no data gets lost as the old AOF will be untouched.

The rewrite will be only triggered by Redis if there is not already a background
process doing persistence.

Specifically:

* If a Redis child is creating a snapshot on disk, the AOF rewrite is _scheduled_ but not started until the saving child producing the RDB file terminates. In this case the `BGREWRITEAOF` will still return an positive status reply, but with an appropriate message. You can check if an AOF rewrite is scheduled looking at the `INFO` command as of Redis 2.6 or successive versions.
* If an AOF rewrite is already in progress the command returns an error and no
AOF rewrite will be scheduled for a later time.
* If the AOF rewrite could start, but the attempt at starting it fails (for instance because of an error in creating the child process), an error is returned to the caller.

Since Redis 2.4 the AOF rewrite is automatically triggered by Redis, however the
`BGREWRITEAOF` command can be used to trigger a rewrite at any time.

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.
14 changes: 14 additions & 0 deletions iredis/data/commands/bgsave.md
@@ -0,0 +1,14 @@
Save the DB in background.
The OK code is immediately returned.
Redis forks, the parent continues to serve the clients, the child saves the DB
on disk then exits.
A client may be able to check if the operation succeeded using the `LASTSAVE`
command.

Please refer to the [persistence documentation][tp] for detailed information.

[tp]: /topics/persistence

@return

@simple-string-reply
68 changes: 68 additions & 0 deletions iredis/data/commands/bitcount.md
@@ -0,0 +1,68 @@
Count the number of set bits (population counting) in a string.

By default all the bytes contained in the string are examined.
It is possible to specify the counting operation only in an interval passing the
additional arguments _start_ and _end_.

Like for the `GETRANGE` command start and end can contain negative values in
order to index bytes starting from the end of the string, where -1 is the last
byte, -2 is the penultimate, and so forth.

Non-existent keys are treated as empty strings, so the command will return zero.

@return

@integer-reply

The number of bits set to 1.

@examples

```cli
SET mykey "foobar"
BITCOUNT mykey
BITCOUNT mykey 0 0
BITCOUNT mykey 1 1
```

## Pattern: real-time metrics using bitmaps

Bitmaps are a very space-efficient representation of certain kinds of
information.
One example is a Web application that needs the history of user visits, so that
for instance it is possible to determine what users are good targets of beta
features.

Using the `SETBIT` command this is trivial to accomplish, identifying every day
with a small progressive integer.
For instance day 0 is the first day the application was put online, day 1 the
next day, and so forth.

Every time a user performs a page view, the application can register that in
the current day the user visited the web site using the `SETBIT` command setting
the bit corresponding to the current day.

Later it will be trivial to know the number of single days the user visited the
web site simply calling the `BITCOUNT` command against the bitmap.

A similar pattern where user IDs are used instead of days is described
in the article called "[Fast easy realtime metrics using Redis
bitmaps][hbgc212fermurb]".

[hbgc212fermurb]: http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps

## Performance considerations

In the above example of counting days, even after 10 years the application is
online we still have just `365*10` bits of data per user, that is just 456 bytes
per user.
With this amount of data `BITCOUNT` is still as fast as any other O(1) Redis
command like `GET` or `INCR`.

When the bitmap is big, there are two alternatives:

* Taking a separated key that is incremented every time the bitmap is modified.
This can be very efficient and atomic using a small Redis Lua script.
* Running the bitmap incrementally using the `BITCOUNT` _start_ and _end_
optional parameters, accumulating the results client-side, and optionally
caching the result into a key.

0 comments on commit 83122b6

Please sign in to comment.