Commit Graph

72 Commits

Author SHA1 Message Date
antirez
5b9d3ac6c6 Avoid changing setKey() API after #6679 fix. 2019-12-18 11:58:02 +01:00
zhaozhao.zz
58554396d6 incrbyfloat: fix issue #5256 ttl lost after propagate 2019-12-18 15:44:51 +08:00
zhaozhao.zz
24044f3356 add a new SET option KEEPTTL that doesn't remove expire time 2019-12-18 15:20:36 +08:00
antirez
317f8b9d38 RESP3: most null replies converted. 2019-01-09 17:00:29 +01:00
antirez
a577230a58 RESP3: Use new deferred len API in t_string.c. 2019-01-09 17:00:29 +01:00
antirez
c33ef454f0 Remove useless complexity from MSET implementation. 2018-10-22 12:24:02 +02:00
antirez
0ed0dc3c02 Fix incrDecrCommand() to create shared objects when needed.
See #5011.
2018-06-18 16:56:31 +02:00
antirez
04542cff92 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 10:59:54 +01:00
antirez
2d86995273 GETRANGE: return empty string with negative, inverted start/end. 2016-06-15 12:48:58 +02:00
antirez
32f80e2f1b RDMF: More consistent define names. 2015-07-27 14:37:58 +02:00
antirez
40eb548a80 RDMF: REDIS_OK REDIS_ERR -> C_OK C_ERR. 2015-07-26 23:17:55 +02:00
antirez
14ff572482 RDMF: OBJ_ macros for object related stuff. 2015-07-26 15:28:00 +02:00
antirez
554bd0e7bd RDMF: use client instead of redisClient, like Disque. 2015-07-26 15:20:52 +02:00
antirez
cef054e868 RDMF (Redis/Disque merge friendlyness) refactoring WIP 1. 2015-07-26 15:17:18 +02:00
Salvatore Sanfilippo
9454f7b3db Merge pull request #2050 from mattsta/bitops-no-overalloc
Bitops: Stop overallocating storage space on set
2015-02-25 10:18:07 +01:00
antirez
1dbd8e94a7 More obvious indentation in setCommand(). 2015-02-03 14:17:06 +01:00
antirez
51010007bc Merge branch 'unstable' of git://github.com/mihirvj/redis into set-pr 2015-02-03 14:13:30 +01:00
Mihir Joshi
352172a7ef Stricter options for SET command
- As per Antirez's suggestion, this commit raises an error when mutually
exclusive options are provided. Duplicate options are allowed.
2014-12-14 10:12:58 -05:00
Matt Stancliff
badf0f008b Bitops: Stop overallocating storage space on set
Previously the string was created empty then re-sized
to fit the offset, but sds resize causes the sds to
over-allocate by at least 1 MB (which is a lot when
you are operating at bit-level access).

This also improves the speed of initial sets by 2% to 6%
based on quick testing.

Patch logic provided by @oranagra

Fixes #1918
2014-12-11 10:54:21 -05:00
antirez
92c5ab4029 Use exp format and more precision output for ZSCAN.
Ref: issue #2175
2014-12-02 18:20:09 +01:00
Mihir Joshi
e9b014cfac stricter options for SET command
Issue: #2157
As the SET command is parsed, it remembers which options are already set
and if a duplicate option is found, raises an error because it is
essentially an invalid syntax.

It still allows mutually exclusive options like EX and PX because taking
an option over another (precedence) is not essentially a syntactic
error.
2014-11-21 22:35:42 -05:00
antirez
16559b4615 INCR: Modify incremented object in-place when possible.
However we don't try to do this if the integer is already inside a range
representable with a shared integer.

The performance gain appears to be around ~15% in micro benchmarks,
however in the long run this also helps to improve locality, so should
have more, hard to measure, benefits.
2014-10-03 12:11:13 +01:00
Matt Stancliff
b20df972ed Return empty string if GETRANGE of empty string
Previously, GETRANGE of a key containing nothing ("")
would allocate a large (size_t)-1 return value causing
crashes on 32bit builds when it tried to allocate the
4 GB return string.
2014-09-02 18:56:28 -04:00
Matt Stancliff
f0e306f4a0 Increase size of range request in getrange
32 bit builds don't have a big enough long to capture
the same range as a 64 bit build.  If we use "long long"
we get proper size limits everywhere.

Also updates size of unsigned comparison to fit new size of `end`.

Fixes #1981
2014-09-02 18:56:01 -04:00
antirez
a6edfceaa8 Fix invalid expire error for SET family commands. 2014-08-18 11:15:50 +02:00
Jan-Erik Rediger
53fdfda9e3 Handle large getrange requests
Previously the end was casted to a smaller type
which resulted in a wrong check and failed
with values larger than handled by unsigned.

Closes #1847, #1844
2014-08-07 12:40:44 +02:00
antirez
543ede03f2 String value unsharing refactored into proper function.
All the Redis functions that need to modify the string value of a key in
a destructive way (APPEND, SETBIT, SETRANGE, ...) require to make the
object unshared (if refcount > 1) and encoded in raw format (if encoding
is not already REDIS_ENCODING_RAW).

This was cut & pasted many times in multiple places of the code. This
commit puts the small logic needed into a function called
dbUnshareStringValue().
2014-03-30 18:32:17 +02:00
antirez
894eba07c8 Introduction of a new string encoding: EMBSTR
Previously two string encodings were used for string objects:

1) REDIS_ENCODING_RAW: a string object with obj->ptr pointing to an sds
stirng.

2) REDIS_ENCODING_INT: a string object where the obj->ptr void pointer
is casted to a long.

This commit introduces a experimental new encoding called
REDIS_ENCODING_EMBSTR that implements an object represented by an sds
string that is not modifiable but allocated in the same memory chunk as
the robj structure itself.

The chunk looks like the following:

+--------------+-----------+------------+--------+----+
| robj data... | robj->ptr | sds header | string | \0 |
+--------------+-----+-----+------------+--------+----+
                     |                       ^
                     +-----------------------+

The robj->ptr points to the contiguous sds string data, so the object
can be manipulated with the same functions used to manipulate plan
string objects, however we need just on malloc and one free in order to
allocate or release this kind of objects. Moreover it has better cache
locality.

This new allocation strategy should benefit both the memory usage and
the performances. A performance gain between 60 and 70% was observed
during micro-benchmarks, however there is more work to do to evaluate
the performance impact and the memory usage behavior.
2013-07-22 10:31:38 +02:00
charsyam
86d87e3554 Support for case unsensitive SET options. 2013-03-29 10:33:52 +01:00
antirez
30d5d416e6 Extended SET command implemented (issue #931). 2013-03-28 15:40:19 +01:00
antirez
fce016d31b Keyspace events: it is now possible to select subclasses of events.
When keyspace events are enabled, the overhead is not sever but
noticeable, so this commit introduces the ability to select subclasses
of events in order to avoid to generate events the user is not
interested in.

The events can be selected using redis.conf or CONFIG SET / GET.
2013-01-28 13:15:12 +01:00
antirez
da04e6ed44 Keyspace events added for more commands. 2013-01-28 13:14:56 +01:00
antirez
5b9357a6b3 Initial test events for the new keyspace notification API. 2013-01-28 13:14:46 +01:00
antirez
e50cdbe461 Additionally two typos fixed thanks to @jodal 2013-01-19 13:46:14 +01:00
guiquanz
9d09ce3981 Fixed many typos. 2013-01-19 10:59:44 +01:00
antirez
4365e5b2d3 BSD license added to every C source and header file. 2012-11-08 18:31:32 +01:00
antirez
973cb21a01 Invert two sides of if expression in SET to avoid a lookup.
Because of the short circuit behavior of && inverting the two sides of
the if expression avoids an hash table lookup if the non-EX variant of
SET is called.

Thanks to Weibin Yao (@yaoweibin on github) for spotting this.
2012-10-31 09:23:05 +01:00
antirez
760e776526 Bit-related string operations moved to bitop.c
All the general string operations are implemented in t_string.c, however
the bit operations, while targeting the string type, are better served
in a specific file where we have the implementations of the following
four commands and helper functions:

    GETBIT
    SETBIT
    BITOP
    BITCOUNT

In the future this file will probably contain more code related to
making the BITOP and BITCOUNT operations faster.
2012-05-24 15:19:51 +02:00
antirez
0bd6d68e34 New commands: BITOP and BITCOUNT.
The motivation for this new commands is to be search in the usage of
Redis for real time statistics. See the article "Fast real time metrics
using Redis".

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

In general Redis strings when used as bitmaps using the SETBIT/GETBIT
command provide a very space-efficient and fast way to store statistics.
For instance in a web application with users, every user can be
associated with a key that shows every day in which the user visited the
web service. This information can be really valuable to extract user
behaviour information.

With Redis bitmaps doing this is very simple just saying that a given
day is 0 (the data the service was put online) and all the next days are
1, 2, 3, and so forth. So with SETBIT it is possible to set the bit
corresponding to the current day every time the user visits the site.

It is possible to take the count of the bit sets on the run, this is
extremely easy using a Lua script. However a fast bit count native
operation can be useful, especially if it can operate on ranges, or when
the string is small like in the case of days (even if you consider many
years it is still extremely little data).

For this reason BITOP was introduced. The command counts the number of
bits set to 1 in a string, with optional range:

BITCOUNT key [start end]

The start/end parameters are similar to GETRANGE. If omitted the whole
string is tested.

Population counting is more useful when bit-level operations like AND,
OR and XOR are avaialble. For instance I can test multiple users to see
the number of days three users visited the site at the same time. To do
this we can take the AND of all the bitmaps, and then count the set bits.

For this reason the BITOP command was introduced:

BITOP [AND|OR|XOR|NOT] dest_key src_key1 src_key2 src_key3 ... src_keyN

In the special case of NOT (that inverts the bits) only one source key
can be passed.

The judicious use of BITCOUNT and BITOP combined can lead to interesting
use cases with very space efficient representation of data.

The implementation provided is still not tested and optimized for speed,
next commits will introduce unit tests. Later the implementation will be
profiled to see if it is possible to gain an important amount of speed
without making the code much more complex.
2012-05-24 15:19:43 +02:00
antirez
7c96b467c1 Fixed undefined behavior in *INCR style functions overflow detection. Sorry clang! 2012-02-21 18:26:11 +01:00
antirez
5244d6e54e rewrite INCRBYFLOAT as SETs for AOF/replication 2011-11-14 10:15:13 +01:00
antirez
5574b53eae INCRBYFLOAT implementation 2011-11-12 19:27:35 +01:00
antirez
12d293ca6e high resolution expires API modified to use separated commands. AOF transation to PEXPIREAT of all the expire-style commands fixed. 2011-11-10 17:52:02 +01:00
antirez
7dcc10b65e Initial support for key expire times with millisecond resolution. RDB version is now 3, new opcoded added for high resolution times. Redis is still able to correctly load RDB version 2. Tests passing but still a work in progress. API to specify milliseconds expires still missing, but the precision of normal expires is now already improved and working. 2011-11-09 16:51:19 +01:00
antirez
634bae94fb useless call removed, thanks to Pieter for spotting this 2011-06-20 16:42:37 +02:00
antirez
f85cd526c1 DB API refactoring. The changes were designed together with Pieter Noordhuis. 2011-06-20 16:42:16 +02:00
antirez
0b537972f4 Fixed return value of GETRANGE / SUBSTR 2011-03-04 16:22:50 +01:00
antirez
6eaad66373 Merge branch 'master' into unstable 2011-01-04 19:07:15 +01:00
antirez
cea8c5cd75 touched key for WATCH refactored into a more general thing that can be used also for the cache system. Some more changes towards diskstore working. 2010-12-29 19:39:42 +01:00
Pieter Noordhuis
89191613f1 limits.h is already included from redis.h 2010-12-23 11:14:05 +00:00