Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
bdcb92f2
Commit
bdcb92f2
authored
Apr 09, 2010
by
antirez
Browse files
shareobjects feautres killed - no gains most of the time, but VM complexities
parent
78ebe4c8
Changes
3
Show whitespace changes
Inline
Side-by-side
redis.c
View file @
bdcb92f2
...
@@ -342,8 +342,6 @@ struct redisServer {
...
@@ -342,8 +342,6 @@ struct redisServer {
int port;
int port;
int fd;
int fd;
redisDb *db;
redisDb *db;
dict
*
sharingpool
;
/* Poll used for object sharing */
unsigned
int
sharingpoolsize
;
long long dirty; /* changes to DB from the last save */
long long dirty; /* changes to DB from the last save */
list *clients;
list *clients;
list *slaves, *monitors;
list *slaves, *monitors;
...
@@ -558,7 +556,6 @@ static robj *dupStringObject(robj *o);
...
@@ -558,7 +556,6 @@ static robj *dupStringObject(robj *o);
static void replicationFeedSlaves(list *slaves, int dictid, robj **argv, int argc);
static void replicationFeedSlaves(list *slaves, int dictid, robj **argv, int argc);
static void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int argc);
static void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int argc);
static int syncWithMaster(void);
static int syncWithMaster(void);
static
robj
*
tryObjectSharing
(
robj
*
o
);
static int tryObjectEncoding(robj *o);
static int tryObjectEncoding(robj *o);
static robj *getDecodedObject(robj *o);
static robj *getDecodedObject(robj *o);
static int removeExpire(redisDb *db, robj *key);
static int removeExpire(redisDb *db, robj *key);
...
@@ -1346,11 +1343,10 @@ static int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientD
...
@@ -1346,11 +1343,10 @@ static int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientD
/* Show information about connected clients */
/* Show information about connected clients */
if (!(loops % 50)) {
if (!(loops % 50)) {
redisLog
(
REDIS_VERBOSE
,
"%d clients connected (%d slaves), %zu bytes in use
, %d shared objects
"
,
redisLog(REDIS_VERBOSE,"%d clients connected (%d slaves), %zu bytes in use",
listLength(server.clients)-listLength(server.slaves),
listLength(server.clients)-listLength(server.slaves),
listLength(server.slaves),
listLength(server.slaves),
zmalloc_used_memory
(),
zmalloc_used_memory());
dictSize
(
server
.
sharingpool
));
}
}
/* Close connections of timedout clients */
/* Close connections of timedout clients */
...
@@ -1564,7 +1560,6 @@ static void initServerConfig() {
...
@@ -1564,7 +1560,6 @@ static void initServerConfig() {
server.requirepass = NULL;
server.requirepass = NULL;
server.shareobjects = 0;
server.shareobjects = 0;
server.rdbcompression = 1;
server.rdbcompression = 1;
server
.
sharingpoolsize
=
1024
;
server.maxclients = 0;
server.maxclients = 0;
server.blpop_blocked_clients = 0;
server.blpop_blocked_clients = 0;
server.maxmemory = 0;
server.maxmemory = 0;
...
@@ -1617,7 +1612,6 @@ static void initServer() {
...
@@ -1617,7 +1612,6 @@ static void initServer() {
createSharedObjects();
createSharedObjects();
server.el = aeCreateEventLoop();
server.el = aeCreateEventLoop();
server.db = zmalloc(sizeof(redisDb)*server.dbnum);
server.db = zmalloc(sizeof(redisDb)*server.dbnum);
server
.
sharingpool
=
dictCreate
(
&
setDictType
,
NULL
);
server.fd = anetTcpServer(server.neterr, server.port, server.bindaddr);
server.fd = anetTcpServer(server.neterr, server.port, server.bindaddr);
if (server.fd == -1) {
if (server.fd == -1) {
redisLog(REDIS_WARNING, "Opening TCP port: %s", server.neterr);
redisLog(REDIS_WARNING, "Opening TCP port: %s", server.neterr);
...
@@ -1802,11 +1796,6 @@ static void loadServerConfig(char *filename) {
...
@@ -1802,11 +1796,6 @@ static void loadServerConfig(char *filename) {
if ((server.rdbcompression = yesnotoi(argv[1])) == -1) {
if ((server.rdbcompression = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"shareobjectspoolsize"
)
&&
argc
==
2
)
{
server
.
sharingpoolsize
=
atoi
(
argv
[
1
]);
if
(
server
.
sharingpoolsize
<
1
)
{
err
=
"invalid object sharing pool size"
;
goto
loaderr
;
}
} else if (!strcasecmp(argv[0],"daemonize") && argc == 2) {
} else if (!strcasecmp(argv[0],"daemonize") && argc == 2) {
if ((server.daemonize = yesnotoi(argv[1])) == -1) {
if ((server.daemonize = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
err = "argument must be 'yes' or 'no'"; goto loaderr;
...
@@ -2286,12 +2275,6 @@ static int processCommand(redisClient *c) {
...
@@ -2286,12 +2275,6 @@ static int processCommand(redisClient *c) {
return 1;
return 1;
}
}
}
}
/* Let's try to share objects on the command arguments vector */
if
(
server
.
shareobjects
)
{
int
j
;
for
(
j
=
1
;
j
<
c
->
argc
;
j
++
)
c
->
argv
[
j
]
=
tryObjectSharing
(
c
->
argv
[
j
]);
}
/* Let's try to encode the bulk object to save space. */
/* Let's try to encode the bulk object to save space. */
if (cmd->flags & REDIS_CMD_BULK)
if (cmd->flags & REDIS_CMD_BULK)
tryObjectEncoding(c->argv[c->argc-1]);
tryObjectEncoding(c->argv[c->argc-1]);
...
@@ -2960,51 +2943,6 @@ static int deleteKey(redisDb *db, robj *key) {
...
@@ -2960,51 +2943,6 @@ static int deleteKey(redisDb *db, robj *key) {
return retval == DICT_OK;
return retval == DICT_OK;
}
}
/* Try to share an object against the shared objects pool */
static
robj
*
tryObjectSharing
(
robj
*
o
)
{
struct
dictEntry
*
de
;
unsigned
long
c
;
if
(
o
==
NULL
||
server
.
shareobjects
==
0
)
return
o
;
redisAssert
(
o
->
type
==
REDIS_STRING
);
de
=
dictFind
(
server
.
sharingpool
,
o
);
if
(
de
)
{
robj
*
shared
=
dictGetEntryKey
(
de
);
c
=
((
unsigned
long
)
dictGetEntryVal
(
de
))
+
1
;
dictGetEntryVal
(
de
)
=
(
void
*
)
c
;
incrRefCount
(
shared
);
decrRefCount
(
o
);
return
shared
;
}
else
{
/* Here we are using a stream algorihtm: Every time an object is
* shared we increment its count, everytime there is a miss we
* recrement the counter of a random object. If this object reaches
* zero we remove the object and put the current object instead. */
if
(
dictSize
(
server
.
sharingpool
)
>=
server
.
sharingpoolsize
)
{
de
=
dictGetRandomKey
(
server
.
sharingpool
);
redisAssert
(
de
!=
NULL
);
c
=
((
unsigned
long
)
dictGetEntryVal
(
de
))
-
1
;
dictGetEntryVal
(
de
)
=
(
void
*
)
c
;
if
(
c
==
0
)
{
dictDelete
(
server
.
sharingpool
,
de
->
key
);
}
}
else
{
c
=
0
;
/* If the pool is empty we want to add this object */
}
if
(
c
==
0
)
{
int
retval
;
retval
=
dictAdd
(
server
.
sharingpool
,
o
,(
void
*
)
1
);
redisAssert
(
retval
==
DICT_OK
);
incrRefCount
(
o
);
}
return
o
;
}
}
/* Check if the nul-terminated string 's' can be represented by a long
/* Check if the nul-terminated string 's' can be represented by a long
* (that is, is a number that fits into long without any other space or
* (that is, is a number that fits into long without any other space or
* character before or after the digits).
* character before or after the digits).
...
@@ -3624,9 +3562,9 @@ static robj *rdbLoadStringObject(FILE*fp) {
...
@@ -3624,9 +3562,9 @@ static robj *rdbLoadStringObject(FILE*fp) {
case REDIS_RDB_ENC_INT8:
case REDIS_RDB_ENC_INT8:
case REDIS_RDB_ENC_INT16:
case REDIS_RDB_ENC_INT16:
case REDIS_RDB_ENC_INT32:
case REDIS_RDB_ENC_INT32:
return
tryObjectSharing
(
rdbLoadIntegerObject
(
fp
,
len
)
)
;
return rdbLoadIntegerObject(fp,len);
case REDIS_RDB_ENC_LZF:
case REDIS_RDB_ENC_LZF:
return
tryObjectSharing
(
rdbLoadLzfStringObject
(
fp
)
)
;
return rdbLoadLzfStringObject(fp);
default:
default:
redisAssert(0);
redisAssert(0);
}
}
...
@@ -3638,7 +3576,7 @@ static robj *rdbLoadStringObject(FILE*fp) {
...
@@ -3638,7 +3576,7 @@ static robj *rdbLoadStringObject(FILE*fp) {
sdsfree(val);
sdsfree(val);
return NULL;
return NULL;
}
}
return
tryObjectSharing
(
createObject
(
REDIS_STRING
,
val
)
)
;
return createObject(REDIS_STRING,val);
}
}
/* For information about double serialization check rdbSaveDoubleValue() */
/* For information about double serialization check rdbSaveDoubleValue() */
...
@@ -7811,12 +7749,7 @@ int loadAppendOnlyFile(char *filename) {
...
@@ -7811,12 +7749,7 @@ int loadAppendOnlyFile(char *filename) {
redisLog(REDIS_WARNING,"Unknown command '%s' reading the append only file", argv[0]->ptr);
redisLog(REDIS_WARNING,"Unknown command '%s' reading the append only file", argv[0]->ptr);
exit(1);
exit(1);
}
}
/* Try object sharing and encoding */
/* Try object encoding */
if
(
server
.
shareobjects
)
{
int
j
;
for
(
j
=
1
;
j
<
argc
;
j
++
)
argv
[
j
]
=
tryObjectSharing
(
argv
[
j
]);
}
if (cmd->flags & REDIS_CMD_BULK)
if (cmd->flags & REDIS_CMD_BULK)
tryObjectEncoding(argv[argc-1]);
tryObjectEncoding(argv[argc-1]);
/* Run the command in the context of a fake client */
/* Run the command in the context of a fake client */
...
@@ -9689,7 +9622,7 @@ static void debugCommand(redisClient *c) {
...
@@ -9689,7 +9622,7 @@ static void debugCommand(redisClient *c) {
}
}
} else {
} else {
addReplySds(c,sdsnew(
addReplySds(c,sdsnew(
"-ERR Syntax error, try DEBUG [SEGFAULT|OBJECT <key>|SWAPIN <key
<
|SWAPOUT <key>|RELOAD]
\r\n
"
));
"-ERR Syntax error, try DEBUG [SEGFAULT|OBJECT <key>|SWAPIN <key
>
|SWAPOUT <key>|RELOAD]\r\n"));
}
}
}
}
...
...
redis.conf
View file @
bdcb92f2
...
@@ -255,23 +255,6 @@ vm-max-threads 4
...
@@ -255,23 +255,6 @@ vm-max-threads 4
# in terms of number of queries per second. Use 'yes' if unsure.
# in terms of number of queries per second. Use 'yes' if unsure.
glueoutputbuf
yes
glueoutputbuf
yes
# Use object sharing. Can save a lot of memory if you have many common
# string in your dataset, but performs lookups against the shared objects
# pool so it uses more CPU and can be a bit slower. Usually it's a good
# idea.
#
# When object sharing is enabled (shareobjects yes) you can use
# shareobjectspoolsize to control the size of the pool used in order to try
# object sharing. A bigger pool size will lead to better sharing capabilities.
# In general you want this value to be at least the double of the number of
# very common strings you have in your dataset.
#
# WARNING: object sharing is experimental, don't enable this feature
# in production before of Redis 1.0-stable. Still please try this feature in
# your development environment so that we can test it better.
shareobjects
no
shareobjectspoolsize
1024
# Hashes are encoded in a special way (much more memory efficient) when they
# Hashes are encoded in a special way (much more memory efficient) when they
# have at max a given numer of elements, and the biggest element does not
# have at max a given numer of elements, and the biggest element does not
# exceed a given threshold. You can configure this limits with the following
# exceed a given threshold. You can configure this limits with the following
...
...
staticsymbols.h
View file @
bdcb92f2
...
@@ -251,7 +251,6 @@ static struct redisFunctionSym symsTable[] = {
...
@@ -251,7 +251,6 @@ static struct redisFunctionSym symsTable[] = {
{
"syncWrite"
,(
unsigned
long
)
syncWrite
},
{
"syncWrite"
,(
unsigned
long
)
syncWrite
},
{
"tryFreeOneObjectFromFreelist"
,(
unsigned
long
)
tryFreeOneObjectFromFreelist
},
{
"tryFreeOneObjectFromFreelist"
,(
unsigned
long
)
tryFreeOneObjectFromFreelist
},
{
"tryObjectEncoding"
,(
unsigned
long
)
tryObjectEncoding
},
{
"tryObjectEncoding"
,(
unsigned
long
)
tryObjectEncoding
},
{
"tryObjectSharing"
,(
unsigned
long
)
tryObjectSharing
},
{
"tryResizeHashTables"
,(
unsigned
long
)
tryResizeHashTables
},
{
"tryResizeHashTables"
,(
unsigned
long
)
tryResizeHashTables
},
{
"ttlCommand"
,(
unsigned
long
)
ttlCommand
},
{
"ttlCommand"
,(
unsigned
long
)
ttlCommand
},
{
"typeCommand"
,(
unsigned
long
)
typeCommand
},
{
"typeCommand"
,(
unsigned
long
)
typeCommand
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment