Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acc894fe41 | ||
|
|
762396d997 | ||
|
|
aa6409f2e8 | ||
|
|
049b48ef79 | ||
|
|
0ba0a6ab0a | ||
|
|
7475ea1b0b | ||
|
|
d5f8df5997 |
No files matched your search
@@ -13,7 +13,9 @@ KeyDB maintains full compatibility with the Redis protocol, modules, and scripts
|
||||
|
||||
On the same hardware KeyDB can perform twice as many queries per second as Redis, with 60% lower latency. Active-Replication simplifies hot-spare failover allowing you to easily distribute writes over replicas and use simple TCP based load balancing/failover. KeyDB's higher performance allows you to do more on less hardware which reduces operation costs and complexity.
|
||||
|
||||
<img src=https://cdn-images-1.medium.com/max/1400/1*s7mTb7Qb0kxc951mz8bdgA.png width=420 height=300/><img src=https://cdn-images-1.medium.com/max/1400/1*R00A5U4AFGohGOYHMfT6fA.png height=300/>
|
||||
<img src="https://keydb.dev/assets/img/blog/5x_opspersecVSdatasize.PNG"/>
|
||||
|
||||
See the full benchmark results and setup information here: https://docs.keydb.dev/blog/2019/10/07/blog-post/
|
||||
|
||||
Why fork Redis?
|
||||
---------------
|
||||
|
||||
+3
-1
@@ -11,9 +11,11 @@ public:
|
||||
|
||||
void arm(client *c) // if a client is passed, then the client is already locked
|
||||
{
|
||||
if (m_fArmed)
|
||||
return;
|
||||
|
||||
if (c != nullptr)
|
||||
{
|
||||
serverAssert(!m_fArmed);
|
||||
serverAssert(c->lock.fOwnLock());
|
||||
|
||||
if (!aeTryAcquireLock(true /*fWeak*/)) // avoid locking the client if we can
|
||||
|
||||
+8
-4
@@ -165,10 +165,14 @@ void aofRewriteBufferAppend(unsigned char *s, unsigned long len) {
|
||||
|
||||
/* Install a file event to send data to the rewrite child if there is
|
||||
* not one already. */
|
||||
aePostFunction(g_pserver->rgthreadvar[IDX_EVENT_LOOP_MAIN].el, []{
|
||||
if (g_pserver->aof_pipe_write_data_to_child >= 0)
|
||||
aeCreateFileEvent(g_pserver->rgthreadvar[IDX_EVENT_LOOP_MAIN].el, g_pserver->aof_pipe_write_data_to_child, AE_WRITABLE, aofChildWriteDiffData, NULL);
|
||||
});
|
||||
if (!g_pserver->aof_rewrite_pending) {
|
||||
g_pserver->aof_rewrite_pending = true;
|
||||
aePostFunction(g_pserver->rgthreadvar[IDX_EVENT_LOOP_MAIN].el, [] {
|
||||
g_pserver->aof_rewrite_pending = false;
|
||||
if (g_pserver->aof_pipe_write_data_to_child >= 0)
|
||||
aeCreateFileEvent(g_pserver->rgthreadvar[IDX_EVENT_LOOP_MAIN].el, g_pserver->aof_pipe_write_data_to_child, AE_WRITABLE, aofChildWriteDiffData, NULL);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the buffer (possibly composed of multiple blocks) into the specified
|
||||
|
||||
@@ -804,6 +804,7 @@ void loadServerConfigFromString(char *config) {
|
||||
// NOP, handled in main
|
||||
} else if (!strcasecmp(argv[0],"enable-pro")) {
|
||||
cserver.fUsePro = true;
|
||||
break;
|
||||
} else {
|
||||
err = "Bad directive or wrong number of arguments"; goto loaderr;
|
||||
}
|
||||
|
||||
+58
-48
@@ -3585,9 +3585,6 @@ int processCommand(client *c, int callFlags) {
|
||||
}
|
||||
|
||||
incrementMvccTstamp();
|
||||
|
||||
if (!locker.isArmed())
|
||||
locker.arm(c);
|
||||
|
||||
/* Handle the maxmemory directive.
|
||||
*
|
||||
@@ -3596,6 +3593,7 @@ int processCommand(client *c, int callFlags) {
|
||||
* condition, to avoid mixing the propagation of scripts with the
|
||||
* propagation of DELs due to eviction. */
|
||||
if (g_pserver->maxmemory && !g_pserver->lua_timedout) {
|
||||
locker.arm(c);
|
||||
int out_of_memory = freeMemoryIfNeededAndSafe() == C_ERR;
|
||||
/* freeMemoryIfNeeded may flush replica output buffers. This may result
|
||||
* into a replica, that may be the active client, to be freed. */
|
||||
@@ -3615,44 +3613,48 @@ int processCommand(client *c, int callFlags) {
|
||||
|
||||
/* Don't accept write commands if there are problems persisting on disk
|
||||
* and if this is a master instance. */
|
||||
int deny_write_type = writeCommandsDeniedByDiskError();
|
||||
if (deny_write_type != DISK_ERROR_TYPE_NONE &&
|
||||
listLength(g_pserver->masters) == 0 &&
|
||||
(c->cmd->flags & CMD_WRITE ||
|
||||
c->cmd->proc == pingCommand))
|
||||
if (c->cmd->flags & CMD_WRITE || c->cmd->proc == pingCommand)
|
||||
{
|
||||
flagTransaction(c);
|
||||
if (deny_write_type == DISK_ERROR_TYPE_RDB)
|
||||
addReply(c, shared.bgsaveerr);
|
||||
else
|
||||
addReplySds(c,
|
||||
sdscatprintf(sdsempty(),
|
||||
"-MISCONF Errors writing to the AOF file: %s\r\n",
|
||||
strerror(g_pserver->aof_last_write_errno)));
|
||||
return C_OK;
|
||||
}
|
||||
locker.arm(c);
|
||||
int deny_write_type = writeCommandsDeniedByDiskError();
|
||||
if (deny_write_type != DISK_ERROR_TYPE_NONE &&
|
||||
listLength(g_pserver->masters) == 0 &&
|
||||
(c->cmd->flags & CMD_WRITE ||
|
||||
c->cmd->proc == pingCommand))
|
||||
{
|
||||
flagTransaction(c);
|
||||
if (deny_write_type == DISK_ERROR_TYPE_RDB)
|
||||
addReply(c, shared.bgsaveerr);
|
||||
else
|
||||
addReplySds(c,
|
||||
sdscatprintf(sdsempty(),
|
||||
"-MISCONF Errors writing to the AOF file: %s\r\n",
|
||||
strerror(g_pserver->aof_last_write_errno)));
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
/* Don't accept write commands if there are not enough good slaves and
|
||||
* user configured the min-slaves-to-write option. */
|
||||
if (listLength(g_pserver->masters) == 0 &&
|
||||
g_pserver->repl_min_slaves_to_write &&
|
||||
g_pserver->repl_min_slaves_max_lag &&
|
||||
c->cmd->flags & CMD_WRITE &&
|
||||
g_pserver->repl_good_slaves_count < g_pserver->repl_min_slaves_to_write)
|
||||
{
|
||||
flagTransaction(c);
|
||||
addReply(c, shared.noreplicaserr);
|
||||
return C_OK;
|
||||
}
|
||||
/* Don't accept write commands if there are not enough good slaves and
|
||||
* user configured the min-slaves-to-write option. */
|
||||
if (listLength(g_pserver->masters) == 0 &&
|
||||
g_pserver->repl_min_slaves_to_write &&
|
||||
g_pserver->repl_min_slaves_max_lag &&
|
||||
c->cmd->flags & CMD_WRITE &&
|
||||
g_pserver->repl_good_slaves_count < g_pserver->repl_min_slaves_to_write)
|
||||
{
|
||||
flagTransaction(c);
|
||||
addReply(c, shared.noreplicaserr);
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
/* Don't accept write commands if this is a read only replica. But
|
||||
* accept write commands if this is our master. */
|
||||
if (listLength(g_pserver->masters) && g_pserver->repl_slave_ro &&
|
||||
!(c->flags & CLIENT_MASTER) &&
|
||||
c->cmd->flags & CMD_WRITE)
|
||||
{
|
||||
addReply(c, shared.roslaveerr);
|
||||
return C_OK;
|
||||
/* Don't accept write commands if this is a read only replica. But
|
||||
* accept write commands if this is our master. */
|
||||
if (listLength(g_pserver->masters) && g_pserver->repl_slave_ro &&
|
||||
!(c->flags & CLIENT_MASTER) &&
|
||||
c->cmd->flags & CMD_WRITE)
|
||||
{
|
||||
addReply(c, shared.roslaveerr);
|
||||
return C_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only allow a subset of commands in the context of Pub/Sub if the
|
||||
@@ -3667,16 +3669,20 @@ int processCommand(client *c, int callFlags) {
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
/* Only allow commands with flag "t", such as INFO, SLAVEOF and so on,
|
||||
* when replica-serve-stale-data is no and we are a replica with a broken
|
||||
* link with master. */
|
||||
if (FBrokenLinkToMaster() &&
|
||||
g_pserver->repl_serve_stale_data == 0 &&
|
||||
!(c->cmd->flags & CMD_STALE))
|
||||
if (listLength(g_pserver->masters))
|
||||
{
|
||||
flagTransaction(c);
|
||||
addReply(c, shared.masterdownerr);
|
||||
return C_OK;
|
||||
locker.arm(c);
|
||||
/* Only allow commands with flag "t", such as INFO, SLAVEOF and so on,
|
||||
* when replica-serve-stale-data is no and we are a replica with a broken
|
||||
* link with master. */
|
||||
if (FBrokenLinkToMaster() &&
|
||||
g_pserver->repl_serve_stale_data == 0 &&
|
||||
!(c->cmd->flags & CMD_STALE))
|
||||
{
|
||||
flagTransaction(c);
|
||||
addReply(c, shared.masterdownerr);
|
||||
return C_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loading DB? Return an error if the command has not the
|
||||
@@ -3711,6 +3717,7 @@ int processCommand(client *c, int callFlags) {
|
||||
queueMultiCommand(c);
|
||||
addReply(c,shared.queued);
|
||||
} else {
|
||||
locker.arm(c);
|
||||
call(c,callFlags);
|
||||
c->woff = g_pserver->master_repl_offset;
|
||||
if (listLength(g_pserver->ready_keys))
|
||||
@@ -5199,7 +5206,10 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
if (cserver.fUsePro) {
|
||||
execv("keydb-pro-server", argv);
|
||||
const char *keydb_pro_dir = getenv("KEYDB_PRO_DIRECTORY");
|
||||
sds path = sdsnew(keydb_pro_dir);
|
||||
path = sdscat(path, "keydb-pro-server");
|
||||
execv(path, argv);
|
||||
perror("Failed launch the pro binary");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -1733,6 +1733,7 @@ struct redisServer {
|
||||
int aof_stop_sending_diff; /* If true stop sending accumulated diffs
|
||||
to child process. */
|
||||
sds aof_child_diff; /* AOF diff accumulator child side. */
|
||||
int aof_rewrite_pending = 0; /* is a call to aofChildWriteDiffData already queued? */
|
||||
/* RDB persistence */
|
||||
long long dirty; /* Changes to DB from the last save */
|
||||
long long dirty_before_bgsave; /* Used to restore dirty on failed BGSAVE */
|
||||
|
||||
Reference in new issue
Block a user