- 27 Sep, 2012 7 commits
-
-
antirez authored
-
antirez authored
We disconnect the Redis instances hiredis link in a more robust way now. Also we change the way we perform the redirection for the +switch-master event, that is not just an instance reset with an address change. Using the same system we now implement the +redirect-to-master event that is triggered by an instance that is configured to be master but found to be a slave at the first INFO reply. In that case we monitor the master instead, logging the incident as an event.
-
antirez authored
We can't be sure the instance object still exists when the reply callback is called.
-
antirez authored
Sentinel observers detect failover checking if a slave attached to the monitored master turns into its replication state from slave to master. However while this change may in theory only happen after a SLAVEOF NO ONE command, in practie it is very easy to reboot a slave instance with a wrong configuration that turns it into a master, especially if it was a past master before a successfull failover. This commit changes the detection policy so that if an instance goes from slave to master, but at the same time the runid has changed, we sense a reboot, and in that case we don't detect a failover at all. This commit also introduces the "reboot" sentinel event, that is logged at "warning" level (so this will trigger an admin notification). The commit also fixes a problem in the disconnect handler that assumed that the instance object always existed, that is not the case. Now we no longer assume that redisAsyncFree() will call the disconnection handler before returning.
-
antirez authored
-
antirez authored
-
antirez authored
This commit implements the first, beta quality implementation of Redis Sentinel, a distributed monitoring system for Redis with notification and automatic failover capabilities. More info at http://redis.io/topics/sentinel
-
- 21 Sep, 2012 3 commits
-
-
antirez authored
-
antirez authored
For "CASE 4" (see code) we need to free the element if it's already in the result dictionary and adding it failed.
-
antirez authored
SRANDMEMBER called with just the key argument can just return a single random element from a Redis Set. However many users need to return multiple unique elements from a Set, this is not a trivial problem to handle in the client side, and for truly good performance a C implementation was required. After many requests for this feature it was finally implemented. The problem implementing this command is the strategy to follow when the number of elements the user asks for is near to the number of elements that are already inside the set. In this case asking random elements to the dictionary API, and trying to add it to a temporary set, may result into an extremely poor performance, as most add operations will be wasted on duplicated elements. For this reason this implementation uses a different strategy in this case: the Set is copied, and random elements are returned to reach the specified count. The code actually uses 4 different algorithms optimized for the different cases. If the count is negative, the command changes behavior and allows for duplicated elements in the returned subset.
-
- 17 Sep, 2012 4 commits
-
-
antirez authored
-
antirez authored
-
antirez authored
-
antirez authored
Redis provides support for blocking operations such as BLPOP or BRPOP. This operations are identical to normal LPOP and RPOP operations as long as there are elements in the target list, but if the list is empty they block waiting for new data to arrive to the list. All the clients blocked waiting for th same list are served in a FIFO way, so the first that blocked is the first to be served when there is more data pushed by another client into the list. The previous implementation of blocking operations was conceived to serve clients in the context of push operations. For for instance: 1) There is a client "A" blocked on list "foo". 2) The client "B" performs `LPUSH foo somevalue`. 3) The client "A" is served in the context of the "B" LPUSH, synchronously. Processing things in a synchronous way was useful as if "A" pushes a value that is served by "B", from the point of view of the database is a NOP (no operation) thing, that is, nothing is replicated, nothing is written in the AOF file, and so forth. However later we implemented two things: 1) Variadic LPUSH that could add multiple values to a list in the context of a single call. 2) BRPOPLPUSH that was a version of BRPOP that also provided a "PUSH" side effect when receiving data. This forced us to make the synchronous implementation more complex. If client "B" is waiting for data, and "A" pushes three elemnents in a single call, we needed to propagate an LPUSH with a missing argument in the AOF and replication link. We also needed to make sure to replicate the LPUSH side of BRPOPLPUSH, but only if in turn did not happened to serve another blocking client into another list ;) This were complex but with a few of mutually recursive functions everything worked as expected... until one day we introduced scripting in Redis. Scripting + synchronous blocking operations = Issue #614. Basically you can't "rewrite" a script to have just a partial effect on the replicas and AOF file if the script happened to serve a few blocked clients. The solution to all this problems, implemented by this commit, is to change the way we serve blocked clients. Instead of serving the blocked clients synchronously, in the context of the command performing the PUSH operation, it is now an asynchronous and iterative process: 1) If a key that has clients blocked waiting for data is the subject of a list push operation, We simply mark keys as "ready" and put it into a queue. 2) Every command pushing stuff on lists, as a variadic LPUSH, a script, or whatever it is, is replicated verbatim without any rewriting. 3) Every time a Redis command, a MULTI/EXEC block, or a script, completed its execution, we run the list of keys ready to serve blocked clients (as more data arrived), and process this list serving the blocked clients. 4) As a result of "3" maybe more keys are ready again for other clients (as a result of BRPOPLPUSH we may have push operations), so we iterate back to step "3" if it's needed. The new code has a much simpler semantics, and a simpler to understand implementation, with the disadvantage of not being able to "optmize out" a PUSH+BPOP as a No OP. This commit will be tested with care before the final merge, more tests will be added likely.
-
- 11 Sep, 2012 1 commit
-
-
antirez authored
Unfortunately we had still the lame atoi() without any error checking in place, so "SELECT foo" would work as "SELECT 0". This was not an huge problem per se but some people expected that DB can be strings and not just numbers, and without errors you get the feeling that they can be numbers, but not the behavior. Now getLongFromObjectOrReply() is used as almost everybody else across the code, generating an error if the number is not an integer or overflows the long type. Thanks to @mipearson for reporting that on Twitter.
-
- 10 Sep, 2012 1 commit
-
-
antirez authored
-
- 05 Sep, 2012 3 commits
-
-
antirez authored
Bug #582 was not present in 32 bit builds of Redis as getObjectFromLong() will return an error for overflow. This commit makes sure that the test does not fail because of the error returned when running against 32 bit builds.
-
Haruto Otake authored
remove unsafe and unnecessary cast. until now, this cast may lead segmentation fault when end > UINT_MAX setbit foo 0 1 bitcount 0 4294967295 => ok bitcount 0 4294967296 => cause segmentation fault. Note by @antirez: the commit was modified a bit to also change the string length type to long, since it's guaranteed to be at max 512 MB in size, so we can work with the same type across all the code path. A regression test was also added.
-
Saj Goonatilleke authored
REDIS_REPL_PING_SLAVE_PERIOD controls how often the master should transmit a heartbeat (PING) to its slaves. This period, which defaults to 10, is measured in seconds. Redis 2.4 masters used to ping their slaves every ten seconds, just like it says on the tin. The Redis 2.6 masters I have been experimenting with, on the other hand, ping their slaves *every second*. (master_last_io_seconds_ago never approaches 10.) I think the ping period was inadvertently slashed to one-tenth of its nominal value around the time REDIS_HZ was introduced. This commit reintroduces correct ping schedule behaviour.
-
- 04 Sep, 2012 1 commit
-
-
antirez authored
SORT is able to return (faster than when ordering) unordered output if the "BY" clause is used with a constant value. However we try to play well with scripting requirements of determinism providing always sorted outputs when SORT (and other similar commands) are called by Lua scripts. However we used the general mechanism in place in scripting in order to reorder SORT output, that is, if the command has the "S" flag set, the Lua scripting engine will take an additional step when converting a multi bulk reply to Lua value, calling a Lua sorting function. This is suboptimal as we can do it faster inside SORT itself. This is also broken as issue #545 shows us: basically when SORT is used with a constant BY, and additionally also GET is used, the Lua scripting engine was trying to order the output as a flat array, while it was actually a list of key-value pairs. What we do know is to recognized if the caller of SORT is the Lua client (since we can check this using the REDIS_LUA_CLIENT flag). If so, and if a "don't sort" condition is triggered by the BY option with a constant string, we force the lexicographical sorting. This commit fixes this bug and improves the performance, and at the same time simplifies the implementation. This does not mean I'm smart today, it means I was stupid when I committed the original implementation ;)
-
- 03 Sep, 2012 1 commit
-
-
antirez authored
During the first synchronization step of the replication process, a Redis slave connects with the master in a non blocking way. However once the connection is established the replication continues sending the REPLCONF command, and sometimes the AUTH command if needed. Those commands are send in a partially blocking way (blocking with timeout in the order of seconds). Because it is common for a blocked master to accept connections even if it is actually not able to reply to the slave requests, it was easy for a slave to block if the master had serious issues, but was still able to accept connections in the listening socket. For this reason we now send an asynchronous PING request just after the non blocking connection ended in a successful way, and wait for the reply before to continue with the replication process. It is very unlikely that a master replying to PING can't reply to the other commands. This solution was proposed by Didier Spezia (Thanks!) so that we don't need to turn all the replication process into a non blocking affair, but still the probability of a slave blocked is minimal even in the event of a failing master. Also we now use getsockopt(SO_ERROR) in order to check errors ASAP in the event handler, instead of waiting for actual I/O to return an error. This commit fixes issue #632.
-
- 31 Aug, 2012 4 commits
-
-
antirez authored
Lua scripting uses a fake client in order to run commands in the context of a client, accumulate the reply, and convert it into a Lua object to return to the caller. This client is reused again and again, and is referenced by the server.lua_client globally accessible pointer. However after every call to redis.call() or redis.pcall(), that is handled by the luaRedisGenericCommand() function, the reply_bytes field of the client was not set back to zero. This filed is used to estimate the amount of memory currently used in the reply. Because of the lack of reset, script after script executed, this value used to get bigger and bigger, and in the end on 32 bit systems it triggered the following assert: redisAssert(c->reply_bytes < ULONG_MAX-(1024*64)); On 64 bit systems this does not happen because it takes too much time to reach values near to 2^64 for users to see the practical effect of the bug. Now in the cleanup stage of luaRedisGenericCommand() we reset the reply_bytes counter to zero, avoiding the issue. It is not practical to add a test for this bug, but the fix was manually tested using a debugger. This commit fixes issue #656.
-
antirez authored
-
antirez authored
A Redis slave can now be configured with a priority, that is an integer number that is shown in INFO output and can be get and set using the redis.conf file or the CONFIG GET/SET command. This field is used by Sentinel during slave election. A slave with lower priority is preferred. A slave with priority zero is never elected (and is considered to be impossible to elect even if it is the only slave available). A next commit will add support in the Sentinel side as well.
-
antirez authored
Redis used to crash with a call like the following: EVAL "redis.call()" 0 Now the explicit check for at least one argument prevents the problem. This commit fixes issue #655.
-
- 28 Aug, 2012 1 commit
-
-
antirez authored
This fixes issue #539. Basically if there is enough free memory the OS may buffer the RDB file that the slave transfers on disk from the master. The file may actually be flused on disk at once by the operating system when it gets closed by Redis, causing the close system call to block for a long time. This patch is a modified version of one provided by yoav-steinberg of @garantiadata (the original version was posted in the issue #539 comments), and tries to flush the OS buffers incrementally (every 8 MB of loaded data).
-
- 24 Aug, 2012 2 commits
-
-
antirez authored
-
antirez authored
The previous implementation of zmalloc.c was not able to handle out of memory in an application-specific way. It just logged an error on standard error, and aborted. The result was that in the case of an actual out of memory in Redis where malloc returned NULL (In Linux this actually happens under specific overcommit policy settings and/or with no or little swap configured) the error was not properly logged in the Redis log. This commit fixes this problem, fixing issue #509. Now the out of memory is properly reported in the Redis log and a stack trace is generated. The approach used is to provide a configurable out of memory handler to zmalloc (otherwise the default one logging the event on the standard output is used).
-
- 22 Aug, 2012 4 commits
-
-
antirez authored
This new hiredis features allows us to reuse a previous context reader buffer even if already very big in order to maximize performances with big payloads (Usually hiredis re-creates buffers when they are too big and unused in order to save memory).
-
antirez authored
This version of hiredis merges modifications of the Redis fork with latest changes in the hiredis repository. The same version was pushed on the hiredis repository and will probably merged into the master branch in short time.
-
Pieter Noordhuis authored
-
Pieter Noordhuis authored
-
- 02 Aug, 2012 1 commit
-
-
Tobias Schwab authored
-
- 01 Aug, 2012 1 commit
-
-
antirez authored
-
- 31 Jul, 2012 3 commits
-
-
Michael Parker authored
Note by @antirez: this code was never compiled because utils.c lacked the float.h include, so we never noticed this variable was mispelled in the past. This should provide a noticeable speed boost when saving certain types of databases with many sorted sets inside.
-
Saj Goonatilleke authored
If Redis only manages to write out a partial buffer, the AOF file won't load back into Redis the next time it starts up. It is better to discard the short write than waste time running redis-check-aof.
-
Saj Goonatilleke authored
Behaves like rdb_last_bgsave_status -- even down to reporting 'ok' when no rewrite has been done yet. (You might want to check that aof_last_rewrite_time_sec is not -1.)
-
- 22 Jul, 2012 2 commits
-
-
Steeve Lennmark authored
-
antirez authored
Redis loading data from disk, and a Redis slave disconnected from its master with serve-stale-data disabled, are two conditions where commands are normally refused by Redis, returning an error. However there is no reason to disable Pub/Sub commands as well, given that this layer does not interact with the dataset. To allow Pub/Sub in as many contexts as possible is especially interesting now that Redis Sentinel uses Pub/Sub of a Redis master as a communication channel between Sentinels. This commit allows Pub/Sub to be used in the above two contexts where it was previously denied.
-
- 18 Jul, 2012 1 commit
-
-
antirez authored
For the C standard char can be either signed or unsigned, it's up to the compiler, but Redis assumed that it was signed in a few places. The practical effect of this patch is that now Redis 2.6 will run correctly in every system where char is unsigned, notably the RaspBerry PI and other ARM systems with GCC. Thanks to Georgi Marinov (@eesn on twitter) that reported the problem and allowed me to use his RaspBerry via SSH to trace and fix the issue!
-