mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
Reclaim space from the client querybuf if needed.
This commit is contained in:
parent
739803c064
commit
ae22bf1ef6
@ -287,6 +287,7 @@ struct redisClient *createFakeClient(void) {
|
|||||||
selectDb(c,0);
|
selectDb(c,0);
|
||||||
c->fd = -1;
|
c->fd = -1;
|
||||||
c->querybuf = sdsempty();
|
c->querybuf = sdsempty();
|
||||||
|
c->querybuf_peak = 0;
|
||||||
c->argc = 0;
|
c->argc = 0;
|
||||||
c->argv = NULL;
|
c->argv = NULL;
|
||||||
c->bufpos = 0;
|
c->bufpos = 0;
|
||||||
|
@ -43,6 +43,7 @@ redisClient *createClient(int fd) {
|
|||||||
c->fd = fd;
|
c->fd = fd;
|
||||||
c->bufpos = 0;
|
c->bufpos = 0;
|
||||||
c->querybuf = sdsempty();
|
c->querybuf = sdsempty();
|
||||||
|
c->querybuf_peak = 0;
|
||||||
c->reqtype = 0;
|
c->reqtype = 0;
|
||||||
c->argc = 0;
|
c->argc = 0;
|
||||||
c->argv = NULL;
|
c->argv = NULL;
|
||||||
@ -998,6 +999,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
qblen = sdslen(c->querybuf);
|
qblen = sdslen(c->querybuf);
|
||||||
|
if (c->querybuf_peak < qblen) c->querybuf_peak = qblen;
|
||||||
c->querybuf = sdsMakeRoomFor(c->querybuf, readlen);
|
c->querybuf = sdsMakeRoomFor(c->querybuf, readlen);
|
||||||
nread = read(fd, c->querybuf+qblen, readlen);
|
nread = read(fd, c->querybuf+qblen, readlen);
|
||||||
if (nread == -1) {
|
if (nread == -1) {
|
||||||
|
32
src/redis.c
32
src/redis.c
@ -642,7 +642,7 @@ long long getOperationsPerSecond(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clientsCronHandleTimeout(redisClient *c) {
|
void clientsCronHandleTimeout(redisClient *c) {
|
||||||
time_t now = time(NULL);
|
time_t now = server.unixtime;
|
||||||
|
|
||||||
if (server.maxidletime &&
|
if (server.maxidletime &&
|
||||||
!(c->flags & REDIS_SLAVE) && /* no timeout for slaves */
|
!(c->flags & REDIS_SLAVE) && /* no timeout for slaves */
|
||||||
@ -662,15 +662,40 @@ void clientsCronHandleTimeout(redisClient *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The client query buffer is an sds.c string that can end with a lot of
|
||||||
|
* free space not used, this function reclaims space if needed. */
|
||||||
|
void clientsCronResizeQueryBuffer(redisClient *c) {
|
||||||
|
size_t querybuf_size = sdsAllocSize(c->querybuf);
|
||||||
|
time_t idletime = server.unixtime - c->lastinteraction;
|
||||||
|
|
||||||
|
/* There are two conditions to resize the query buffer:
|
||||||
|
* 1) Query buffer is > BIG_ARG and too big for latest peak.
|
||||||
|
* 2) Client is inactive and the buffer is bigger than 1k. */
|
||||||
|
if (((querybuf_size > REDIS_MBULK_BIG_ARG) &&
|
||||||
|
(querybuf_size/(c->querybuf_peak+1)) > 2) ||
|
||||||
|
(querybuf_size > 1024 && idletime > 2))
|
||||||
|
{
|
||||||
|
/* Only resize the query buffer if it is actually wasting space. */
|
||||||
|
if (sdsavail(c->querybuf) > 1024) {
|
||||||
|
c->querybuf = sdsRemoveFreeSpace(c->querybuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Reset the peak again to capture the peak memory usage in the next
|
||||||
|
* cycle. */
|
||||||
|
c->querybuf_peak = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void clientsCron(void) {
|
void clientsCron(void) {
|
||||||
/* Make sure to process at least 1/100 of clients per call.
|
/* Make sure to process at least 1/100 of clients per call.
|
||||||
* Since this function is called 10 times per second we are sure that
|
* Since this function is called 10 times per second we are sure that
|
||||||
* in the worst case we process all the clients in 10 seconds.
|
* in the worst case we process all the clients in 10 seconds.
|
||||||
* In normal conditions (a reasonable number of clients) we process
|
* In normal conditions (a reasonable number of clients) we process
|
||||||
* all the clients in a shorter time. */
|
* all the clients in a shorter time. */
|
||||||
int iterations = listLength(server.clients)/100;
|
int numclients = listLength(server.clients);
|
||||||
if (iterations < 50) iterations = 50;
|
int iterations = numclients/100;
|
||||||
|
|
||||||
|
if (iterations < 50)
|
||||||
|
iterations = (numclients < 50) ? numclients : 50;
|
||||||
while(listLength(server.clients) && iterations--) {
|
while(listLength(server.clients) && iterations--) {
|
||||||
redisClient *c;
|
redisClient *c;
|
||||||
listNode *head;
|
listNode *head;
|
||||||
@ -682,6 +707,7 @@ void clientsCron(void) {
|
|||||||
head = listFirst(server.clients);
|
head = listFirst(server.clients);
|
||||||
c = listNodeValue(head);
|
c = listNodeValue(head);
|
||||||
clientsCronHandleTimeout(c);
|
clientsCronHandleTimeout(c);
|
||||||
|
clientsCronResizeQueryBuffer(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,6 +323,7 @@ typedef struct redisClient {
|
|||||||
redisDb *db;
|
redisDb *db;
|
||||||
int dictid;
|
int dictid;
|
||||||
sds querybuf;
|
sds querybuf;
|
||||||
|
size_t querybuf_peak; /* Recent (100ms or more) peak of querybuf size */
|
||||||
int argc;
|
int argc;
|
||||||
robj **argv;
|
robj **argv;
|
||||||
struct redisCommand *cmd, *lastcmd;
|
struct redisCommand *cmd, *lastcmd;
|
||||||
|
Loading…
Reference in New Issue
Block a user