505 Commits

Author SHA1 Message Date
antirez
aa32f92338 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
antirez
7f4fa85a62 addReplyDouble(): format infinite in a libc agnostic way.
There are systems that when printing +/- infinte with printf-family
functions will not use the usual "inf" "-inf", but different strings.
Handle that explicitly.

Fixes issue #930.
2013-07-17 15:05:25 +02:00
antirez
4c2998e8c4 getClientPeerId() refactored into two functions. 2013-07-09 15:46:34 +02:00
antirez
f309368ec2 getClientPeerId() now reports errors.
We now also use it in CLIENT KILL implementation.
2013-07-09 15:28:30 +02:00
antirez
800e918c7f getClientPeerID introduced.
The function returns an unique identifier for the client, as ip:port for
IPv4 and IPv6 clients, or as path:0 for Unix socket clients.

See the top comment in the function for more info.
2013-07-09 12:49:20 +02:00
antirez
e4d2e6fc9d All IP string repr buffers are now REDIS_IP_STR_LEN bytes. 2013-07-09 11:32:52 +02:00
Geoff Garside
5d702e012e Mark places that might want changing for IPv6.
Any places which I feel might want to be updated to work differently
with IPv6 have been marked with a comment starting "IPV6:".

Currently the only comments address places where an IP address is
combined with a port using the standard : separated form. These may want
to be changed when printing IPv6 addresses to wrap the address in []
such as

	[2001:db8::c0:ffee]:6379

instead of

	2001:db8::c0:ffee:6379

as the latter format is a technically valid IPv6 address and it is hard
to distinguish the IPv6 address component from the port unless you know
the port is supposed to be there.
2013-07-08 15:58:14 +02:00
Geoff Garside
0661cf0cf7 Expand ip char buffers which are too small for v6.
Increase the size of character buffers being used to store printable IP
addresses so that they can safely store IPv6 addresses.
2013-07-08 15:58:14 +02:00
Geoff Garside
15e37522ff Mark ip string buffers which could be reduced.
In two places buffers have been created with a size of 128 bytes which
could be reduced to INET6_ADDRSTRLEN to still hold a full IP address.
These places have been marked as they are presently big enough to handle
the needs of storing a printable IPv6 address.
2013-07-08 15:57:23 +02:00
Geoff Garside
8b2e90acec Update anetTcpAccept & anetPeerToString calls.
Add the additional ip buffer length argument to function calls of
anetTcpAccept and anetPeerToString in network.c and cluster.c
2013-07-08 15:51:37 +02:00
antirez
cb76f29230 min-slaves-to-write: don't accept writes with less than N replicas.
This feature allows the user to specify the minimum number of
connected replicas having a lag less or equal than the specified
amount of seconds for writes to be accepted.
2013-05-30 11:30:04 +02:00
antirez
84c7d48a80 Replication: send REPLCONF ACK to master. 2013-05-27 11:42:25 +02:00
antirez
6d2b8f5845 REPLCONF ACK command.
This special command is used by the slave to inform the master the
amount of replication stream it currently consumed.

it does not return anything so that we not need to consume additional
bandwidth needed by the master to reply something.

The master can do a number of things knowing the amount of stream
processed, such as understanding the "lag" in bytes of the slave, verify
if a given command was already processed by the slave, and so forth.
2013-05-27 11:42:17 +02:00
antirez
e29d536e17 Fixed a bug in no queueing replies to master. 2013-05-25 01:00:07 +02:00
antirez
f1a7fd7a95 Replication: don't even queue replies to master commands.
When master send commands, there is no need for the slave to reply.
Redis used to queue the reply in the output buffer and discard the reply
later, this is a waste of work and it is not clear why it was this way
(I sincerely don't remember).

This commit changes it in order to don't queue the reply at all.

All tests passing.
2013-05-24 18:58:57 +02:00
antirez
f06f9dacb7 Top comment for prepareClientToWrite() clarified.
We don't write the output buffer to the client socket for slaves only if
the slave is not online.
2013-05-24 18:41:43 +02:00
antirez
9076bf9d4b API to lookup commands with their original name.
A new server.orig_commands table was added to the server structure, this
contains a copy of the commant table unaffected by rename-command
statements in redis.conf.

A new API lookupCommandOrOriginal() was added that checks both tables,
new first, old later, so that rewriteClientCommandVector() and friends
can lookup commands with their new or original name in order to fix the
client->cmd pointer when the argument vector is renamed.

This fixes the segfault of issue #986, but does not fix a wider range of
problems resulting from renaming commands that actually operate on data
and are registered into the AOF file or propagated to slaves... That is
command renaming should be handled with care.
2013-03-06 16:28:26 +01:00
antirez
1de23b0795 Cluster: ASKING command fixed, state was not retained. 2013-02-20 17:07:52 +01:00
antirez
75512d94d9 PSYNC: work in progress, preview #2, rebased to unstable. 2013-02-12 12:52:21 +01:00
antirez
96ef42d768 Set SO_KEEPALIVE on client sockets if configured to do so. 2013-02-08 16:40:59 +01:00
antirez
d698a264d2 TCP_NODELAY after SYNC: changes to the implementation. 2013-02-05 12:04:30 +01:00
antirez
3394db6361 Fix decrRefCount() prototype from void to robj pointer.
decrRefCount used to get its argument as a void* pointer in order to be
used as destructor where a 'void free_object(void*)' prototype is
expected. However this made simpler to introduce bugs by freeing the
wrong pointer. This commit fixes the argument type and introduces a new
wrapper called decrRefCountVoid() that can be used when the void*
argument is needed.
2013-01-28 13:14:53 +01:00
antirez
45d02df764 Additionally two typos fixed thanks to @jodal 2013-01-19 13:46:14 +01:00
guiquanz
df7a5b7157 Fixed many typos. 2013-01-19 10:59:44 +01:00
bitterb
d5424943de Fix an error reply for CLIENT command 2013-01-19 14:11:33 +09:00
antirez
7d11268b51 Typo fixed, ASCI -> ASCII. 2013-01-15 13:34:13 +01:00
antirez
1472cae960 CLIENT GETNAME and CLIENT SETNAME introduced.
Sometimes it is much simpler to debug complex Redis installations if it
is possible to assign clients a name that is displayed in the CLIENT
LIST output.

This is the case, for example, for "leaked" connections. The ability to
provide a name to the client makes it quite trivial to understand what
is the part of the code implementing the client not releasing the
resources appropriately.

Behavior:

    CLIENT SETNAME: set a name for the client, or remove the current
                    name if an empty name is set.
    CLIENT GETNAME: get the current name, or a nil.
    CLIENT LIST: now displays the client name if any.

Thanks to Mark Gravell for pushing this idea forward.
2013-01-15 13:34:10 +01:00
antirez
0fc5457a7f Better error reporting when fd event creation fails. 2013-01-03 14:29:34 +01:00
antirez
0200e4f6ef Memory leak fixed: release client's bpop->keys dictionary.
Refactoring performed after issue #801 resolution (see commit
b775d5c3e9b4184c931fe2250a08ff1c3fb3b080) introduced a memory leak that
is fixed by this commit.

I simply forgot to free the new allocated dictionary in the client
structure trusting the output of "make test" on OSX.

However due to changes in the "leaks" utility the test was no longer
testing memory leaks. This problem was also fixed.

Fortunately the CI test running at ci.redis.io spotted the bug in the
valgrind run.

The leak never ended into a stable release.
2012-12-03 12:12:53 +01:00
antirez
b775d5c3e9 Blocking POP: use a dictionary to store keys clinet side.
To store the keys we block for during a blocking pop operation, in the
case the client is blocked for more data to arrive, we used a simple
linear array of redis objects, in the blockingState structure:

    robj **keys;
    int count;

However in order to fix issue #801 we also use a dictionary in order to
avoid to end in the blocked clients queue for the same key multiple
times with the same client.

The dictionary was only temporary, just to avoid duplicates, but since
we create / destroy it there is no point in doing this duplicated work,
so this commit simply use a dictionary as the main structure to store
the keys we are blocked for. So instead of the previous fields we now
just have:

    dict *keys;

This simplifies the code and reduces the work done by the server during
a blocking POP operation.
2012-12-02 20:43:15 +01:00
antirez
a32d1ddff6 BSD license added to every C source and header file. 2012-11-08 18:31:32 +01:00
Yecheng Fu
c9278122e0 fix typo in comments (redis.c, networking.c) 2012-11-01 22:26:46 +01:00
antirez
b754312cfe Unix socket clients properly displayed in MONITOR and CLIENT LIST.
This also fixes issue #745.
2012-11-01 22:10:45 +01:00
antirez
cee3bfd049 REPLCONF internal command introduced.
The REPLCONF command is an internal command (not designed to be directly
used by normal clients) that allows a slave to set some replication
related state in the master before issuing SYNC to start the
replication.

The initial motivation for this command, and the only reason currently
it is used by the implementation, is to let the slave instance
communicate its listening port to the slave, so that the master can
show all the slaves with their listening ports in the "replication"
section of the INFO output.

This allows clients to auto discover and query all the slaves attached
into a master.

Currently only a single option of the REPLCONF command is supported, and
it is called "listening-port", so the slave now starts the replication
process with something like the following chat:

    REPLCONF listening-prot 6380
    SYNC

Note that this works even if the master is an older version of Redis and
does not understand REPLCONF, because the slave ignores the REPLCONF
error.

In the future REPLCONF can be used for partial replication and other
replication related features where there is the need to exchange
information between master and slave.

NOTE: This commit also fixes a bug: the INFO outout already carried
information about slaves, but the port was broken, and was obtained
with getpeername(2), so it was actually just the ephemeral port used
by the slave to connect to the master as a client.
2012-06-27 09:43:57 +02:00
antirez
6b65fc77db Fix c->reply_bytes computation in setDeferredMultiBulkLength()
In order to implement reply buffer limits introduced in 2.6 and useful
to close the connection under user-selected circumastances of big output
buffers (for instance slow consumers in pub/sub, a blocked slave, and so
forth) Redis takes a counter with the amount of used memory in objects
inside the output list stored into c->reply.

The computation was broken in the function setDeferredMultiBulkLength(),
in the case the object was glued with the next one. This caused the
c->reply_bytes field to go out of sync, be subtracted more than needed,
and wrap back near to ULONG_MAX values.

This commit fixes this bug and adds an assertion that is able to trap
this class of problems.

This problem was discovered looking at the INFO output of an unrelated
issue (issue #547).
2012-06-15 10:03:25 +02:00
antirez
8f49d6f257 New client info field added to CLIENT LIST output: multi, containing the length of the current pipeline. Test modified accordingly. 2012-04-07 11:14:52 +02:00
antirez
b579d88337 Fixed typo in comment: "te" -> "the". 2012-03-29 09:33:29 +02:00
antirez
b72df2df2c Fix for slaves chains. Force resync of slaves (simply disconnecting them) when SLAVEOF turns a master into a slave. 2012-03-29 09:24:02 +02:00
Premysl Hruby
f3fa6655c6 use server.unixtime instead of time(NULL) where possible (cluster.c not checked though) 2012-03-27 17:39:58 +02:00
antirez
696c28fcf9 Reclaim space from the client querybuf if needed. 2012-03-14 15:32:30 +01:00
antirez
5bab1baf21 Process async client checks like client timeouts and BLPOP timeouts incrementally using a circular list. 2012-03-13 18:05:11 +01:00
antirez
ca9f6a5457 Added a qbuf-free field to CLIENT LIST output. 2012-03-13 13:26:33 +01:00
antirez
f171b199ca Client creation time in redisClient structure. New age field in CLIENT LIST output. 2012-03-13 13:05:08 +01:00
antirez
bad7813b70 c->bufpos initialization moved for aesthetics. 2012-03-13 12:59:27 +01:00
antirez
fcc81cb320 anetPeerToString() automatically populates ip/port with something that may be provided to the user as output in case of errors. 2012-03-07 11:30:30 +01:00
antirez
a82c3fcaf3 Return ASAP from checkClientOutputBufferLimits() if c->reply_bytes is zero. 2012-02-16 12:20:56 +01:00
antirez
97f45bad9b Fixes to c->reply_bytes computation, and debug messages to closely study the behavior of memory pressure + slaves + maxmemory + blocked slaves. 2012-02-07 17:41:31 +01:00
antirez
f57707f408 Precision of getClientOutputBufferMemoryUsage() greatily improved, see issue #327 for more information. 2012-02-07 13:05:36 +01:00
antirez
0de0faf4a0 freeMemoryIfNeeded() minor refactoring 2012-02-06 16:56:42 +01:00
antirez
ee273aa92c This fixes issue #327, is a very complex fix (unfortunately), details:
1) sendReplyToClient() now no longer stops transferring data to a single
client in the case we are out of memory (maxmemory-wise).

2) in processCommand() the idea of we being out of memory is no longer
the naive zmalloc_used_memory() > server.maxmemory. To say if we can
accept or not write queries is up to the return value of
freeMemoryIfNeeded(), that has full control about that.

3) freeMemoryIfNeeded() now does its math without considering output
buffers size. But at the same time it can't let the output buffers to
put us too much outside the max memory limit, so at the same time it
makes sure there is enough effort into delivering the output buffers to
the slaves, calling the write handler directly.

This three changes are the result of many tests, I found (partially
empirically) that is the best way to address the problem, but maybe
we'll find better solutions in the future.
2012-02-04 14:05:54 +01:00