Commit Graph

99 Commits

Author SHA1 Message Date
c65dfb436e Replication: fix the infamous key leakage of writable slaves + EXPIRE.
BACKGROUND AND USE CASEj

Redis slaves are normally write only, however the supprot a "writable"
mode which is very handy when scaling reads on slaves, that actually
need write operations in order to access data. For instance imagine
having slaves replicating certain Sets keys from the master. When
accessing the data on the slave, we want to peform intersections between
such Sets values. However we don't want to intersect each time: to cache
the intersection for some time often is a good idea.

To do so, it is possible to setup a slave as a writable slave, and
perform the intersection on the slave side, perhaps setting a TTL on the
resulting key so that it will expire after some time.

THE BUG

Problem: in order to have a consistent replication, expiring of keys in
Redis replication is up to the master, that synthesize DEL operations to
send in the replication stream. However slaves logically expire keys
by hiding them from read attempts from clients so that if the master did
not promptly sent a DEL, the client still see logically expired keys
as non existing.

Because slaves don't actively expire keys by actually evicting them but
just masking from the POV of read operations, if a key is created in a
writable slave, and an expire is set, the key will be leaked forever:

1. No DEL will be received from the master, which does not know about
such a key at all.

2. No eviction will be performed by the slave, since it needs to disable
eviction because it's up to masters, otherwise consistency of data is
lost.

THE FIX

In order to fix the problem, the slave should be able to tag keys that
were created in the slave side and have an expire set in some way.

My solution involved using an unique additional dictionary created by
the writable slave only if needed. The dictionary is obviously keyed by
the key name that we need to track: all the keys that are set with an
expire directly by a client writing to the slave are tracked.

The value in the dictionary is a bitmap of all the DBs where such a key
name need to be tracked, so that we can use a single dictionary to track
keys in all the DBs used by the slave (actually this limits the solution
to the first 64 DBs, but the default with Redis is to use 16 DBs).

This solution allows to pay both a small complexity and CPU penalty,
which is zero when the feature is not used, actually. The slave-side
eviction is encapsulated in code which is not coupled with the rest of
the Redis core, if not for the hook to track the keys.

TODO

I'm doing the first smoke tests to see if the feature works as expected:
so far so good. Unit tests should be added before merging into the
4.0 branch.
2016-12-13 18:34:04 +01:00
0fb9f341c9 fix memory corruption on RM_FreeCallReply 2016-12-05 14:40:59 +01:00
71e8d15e49 Modules: change type registration API to use a struct of methods. 2016-11-30 11:14:01 +01:00
1f55170b9c Modules: fix client blocking calls access to invalid struct field.
We already have reference to the client pointer, no need to access the
already freed structure.

Close #3634.
2016-11-24 11:05:19 +01:00
ec8fd6e5e4 fixed sizeof in allocating io RedisModuleCtx* 2016-10-31 18:48:16 +02:00
95c17c0cb2 Modules: AbortBlock() API implemented. 2016-10-13 16:57:40 +02:00
553aa0e259 module.c: trim comment to 80 cols. 2016-10-13 12:48:36 +02:00
34599691b3 Modules: fixes to the blocking commands API: examples now works. 2016-10-07 16:34:40 +02:00
f156038db8 Modules: RM_Milliseconds() API added. 2016-10-07 16:34:19 +02:00
ffb00fbcbe Modules: blocking commands WIP: API exported, a first example. 2016-10-07 13:48:14 +02:00
8fadfe52a2 Module: API to block clients with threading support.
Just a draft to align the main ideas, never executed code. Compiles.
2016-10-07 11:55:35 +02:00
152c1b6802 Module: Ability to get context from IO context.
It was noted by @dvirsky that it is not possible to use string functions
when writing the AOF file. This sometimes is critical since the command
rewriting may need to be built in the context of the AOF callback, and
without access to the context, and the limited types that the AOF
production functions will accept, this can be an issue.

Moreover there are other needs that we can't anticipate regarding the
ability to use Redis Modules APIs using the context in order to build
representations to emit AOF / RDB.

Because of this a new API was added that allows the user to get a
temporary context from the IO context. The context is auto released
if obtained when the RDB / AOF callback returns.

Calling multiple time the function to get the context, always returns
the same one, since it is invalid to have more than a single context.
2016-10-06 17:09:26 +02:00
72279e3ea4 Copyright notice added to module.c. 2016-10-06 08:48:21 +02:00
3dc84c5300 Modules: API to save/load single precision floating point numbers.
When double precision is not needed, to take 2x space in the
serialization is not good.
2016-10-03 00:08:35 +02:00
a1b1fd4f39 Modules: API to log from module I/O callbacks. 2016-10-02 16:51:37 +02:00
a91650fc57 added RM_CreateStringPrintf 2016-09-21 12:30:38 +03:00
afcbcc0e58 dict.c: introduce dictUnlink().
Notes by @antirez:

This patch was picked from a larger commit by Oran and adapted to change
the API a bit. The basic idea is to avoid double lookups when there is
to use the value of the deleted entry.

BEFORE:

    entry = dictFind( ... ); /* 1st lookup. */
    /* Do somethjing with the entry. */
    dictDelete(...);         /* 2nd lookup. */

AFTER:

    entry = dictUnlink( ... ); /* 1st lookup. */
    /* Do somethjing with the entry. */
    dictFreeUnlinkedEntry(entry); /* No lookups!. */
2016-09-14 12:18:59 +02:00
wyx
f9c9b4bf4c fix memory error on module unload 2016-09-09 10:22:57 +08:00
13f18d2b17 Modules: handle NULL replies more gracefully.
After all crashing at every API misuse makes everybody's life more
complex.
2016-08-03 18:09:36 +02:00
04340e1ff1 Modules: initial draft for a testing module. 2016-08-03 10:23:03 +02:00
7829e4ed2c Modules: StringAppendBuffer() and ability to retain strings.
RedisModule_StringRetain() allows, when automatic memory management is
on, to keep string objects living after the callback returns. Can also
be used in order to use Redis reference counting of objects inside
modules.

The reason why this is useful is that sometimes when implementing new
data types we want to reference RedisModuleString objects inside the
module private data structures, so those string objects must be valid
after the callback returns even if not referenced inside the Redis key
space.
2016-08-02 15:29:04 +02:00
3a0b776b94 Merge pull request #3335 from dvirsky/rm_calloc
added RM_Calloc implementation
2016-06-23 16:19:14 +02:00
c026b5cd3e Merge branch 'unstable' of github.com:/antirez/redis into unstable 2016-06-23 16:18:57 +02:00
0f484d8312 Actually remove static from #3331.
I forgot -a when amending in the previous commit.
2016-06-23 16:18:30 +02:00
28ea585fce Merge pull request #3336 from yossigo/create_string_from_string
Add RedisModule_CreateStringFromString().
2016-06-23 16:16:28 +02:00
c0ca87dcc0 Minor change to conform PR #3331 to Redis code base style.
Also avoid "static" in order to have symbols during crashes.
2016-06-23 16:14:16 +02:00
a66dd43331 Merge pull request #3331 from yossigo/fix_openkey_crash
Fix occasional RM_OpenKey() crashes.
2016-06-23 16:12:07 +02:00
3d48c93122 Merge pull request #3330 from yossigo/fix_const
Use const in Redis Module API where possible.
2016-06-23 12:29:52 +02:00
4b12c6a360 Modules: changes to logging function.
This commit changes what provided by PR #3315 (merged) in order to
let the user specify the log level as a string.

The define could be also used, but when this happens, they must be
decoupled from the defines in the Redis core, like in the other part of
the Redis modules implementations, so that a switch statement (or a
function) remaps between the two, otherwise we are no longer free to
change the internal Redis defines.
2016-06-23 12:11:30 +02:00
715794b829 Add RedisModule_Log() logging API function. 2016-06-23 12:01:44 +02:00
b507289750 Commit change in autoMemoryFreed(): first -> last.
It's more natural to call the last entry added as "last", the original
commet got me confused until I actually read the code.
2016-06-23 09:38:30 +02:00
f2dbc02f65 Modules: implement zig-zag scanning in autoMemoryFreed().
Most of the time to check the last element is the way to go, however
there are patterns where the contrary is the best choice. Zig-zag
scanning implemented in this commmit always checks the obvious element
first (the last added -- think at a loop where the last element
allocated gets freed again and again), and continues checking one
element in the head and one in the tail.

Thanks to @dvisrky that fixed the original implementation of the
function and proposed zig zag scanning.
2016-06-23 09:09:51 +02:00
2fe9b79897 Merge pull request #3244 from dvirsky/optimize_autoMemoryFreed
Optimized autoMemoryFreed loop
2016-06-23 08:59:38 +02:00
61172ed01e Add RedisModule_CreateStringFromString(). 2016-06-22 21:02:40 +03:00
dc7f3fefad added RM_Calloc implementation 2016-06-22 17:32:41 +03:00
e22f3e40d5 Cleanup: remove zset reset function from RM_ZsetRangeStop(). 2016-06-22 07:34:14 +03:00
a8e2034548 Fix occasional RM_OpenKey() crashes. 2016-06-21 10:22:19 +03:00
8f3a4df775 Use const in Redis Module API where possible. 2016-06-20 23:08:06 +03:00
9a02dac2e8 Free module context after loading.
Now that modules receive RedisModuleString objects on loading, they are
allowed to call the String API, so the context must be released
correctly.

Related to #3293.
2016-06-13 09:45:53 +02:00
1ad5c22763 Minor changes to unifor C style to Redis code base for PR #3293. 2016-06-13 09:39:44 +02:00
e8d5387a44 Merge pull request #3293 from yossigo/module_config
Allow passing arguments to modules on load.
2016-06-13 09:31:59 +02:00
87312ff781 Fix MODULE UNLOAD crash and/or wrong error message. 2016-06-05 13:27:38 +03:00
cc58f11ccc Use RedisModuleString for OnLoad argv. 2016-06-05 13:18:24 +03:00
2bd13cf0eb Allow passing arguments to modules on load. 2016-06-05 11:37:24 +03:00
8ec28002be Modules: support for modules native data types. 2016-06-03 18:14:04 +02:00
137fd86a61 optimized amFree even further 2016-05-19 13:51:55 +03:00
46b07cbb5c Optimized autoMemoryFreed loop 2016-05-19 12:16:14 +03:00
e3edae957b Modules: RM_HashSet() SDS ownership business clarified in comments.
Related to #3239.
2016-05-18 16:30:20 +02:00
cfaef8d5d4 fixed bad transfer of ownership in HashSet causing a potential crash 2016-05-17 16:47:36 +03:00
9aff564045 Modules: initial pool allocator and a LEFTPAD usage example. 2016-05-14 19:42:31 +02:00