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
55e36e11
Commit
55e36e11
authored
Feb 25, 2014
by
antirez
Browse files
Merge branch 'bigkeys_scan' of
git://github.com/michael-grunder/redis
into unstable
parents
339322fe
013a4ce2
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/redis-cli.c
View file @
55e36e11
...
...
@@ -1335,81 +1335,105 @@ static void pipeMode(void) {
static
void
findBigKeys
(
void
)
{
unsigned
long
long
biggest
[
5
]
=
{
0
,
0
,
0
,
0
,
0
};
unsigned
long
long
samples
=
0
;
redisReply *reply1, *reply2, *reply3 = NULL;
char *sizecmd, *typename[] = {"string","list","set","hash","zset"};
redisReply
*
reply1
,
*
reply2
,
*
reply3
=
NULL
,
*
keys
;
char
*
key
,
*
sizecmd
,
*
typename
[]
=
{
"string"
,
"list"
,
"set"
,
"hash"
,
"zset"
};
char
*
typeunit
[]
=
{
"bytes"
,
"items"
,
"members"
,
"fields"
,
"members"
};
int type;
int
type
,
it
=
0
,
i
;
printf
(
"
\n
# Press ctrl+c when you have had enough of it... :)
\n
"
);
printf("# You can use -i 0.1 to sleep 0.1 sec
ev
er
y
100
sampled keys
\n");
printf
(
"# You can use -i 0.1 to sleep 0.1 sec
p
er 100
SCANS
\n
"
);
printf
(
"# in order to reduce server load (usually not needed).
\n\n
"
);
while(1) {
/* Sample with RANDOMKEY */
reply1 = redisCommand(context,"RANDOMKEY");
if (reply1 == NULL) {
fprintf(stderr,"\nI/O error\n");
do
{
/* Grab some keys with SCAN */
reply1
=
redisCommand
(
context
,
"SCAN %d"
,
it
);
if
(
reply1
==
NULL
)
{
fprintf
(
stderr
,
"
\n
I/O error
\n
"
);
exit
(
1
);
} else if (reply1->type == REDIS_REPLY_ERROR) {
fprintf(stderr, "RANDOMKEY error: %s\n",
reply1->str);
}
else
if
(
reply1
->
type
==
REDIS_REPLY_ERROR
)
{
fprintf
(
stderr
,
"SCAN error: %s
\n
"
,
reply1
->
str
);
exit
(
1
);
} else if
(reply1->type
=
= REDIS_REPLY_
NIL
) {
fprintf(stderr, "
It looks like the database is empty
!\n");
}
else
if
(
reply1
->
type
!
=
REDIS_REPLY_
ARRAY
)
{
fprintf
(
stderr
,
"
Non ARRAY response from SCAN
!
\n
"
);
exit
(
1
);
}
/* Get the key type */
reply2 = redisCommand(context,"TYPE %s",reply1->str);
assert(reply2 && reply2->type == REDIS_REPLY_STATUS);
samples++;
/* Get the key "size" */
if (!strcmp(reply2->str,"string")) {
sizecmd = "STRLEN";
type = TYPE_STRING;
} else if (!strcmp(reply2->str,"list")) {
sizecmd = "LLEN";
type = TYPE_LIST;
} else if (!strcmp(reply2->str,"set")) {
sizecmd = "SCARD";
type = TYPE_SET;
} else if (!strcmp(reply2->str,"hash")) {
sizecmd = "HLEN";
type = TYPE_HASH;
} else if (!strcmp(reply2->str,"zset")) {
sizecmd = "ZCARD";
type = TYPE_ZSET;
} else if (!strcmp(reply2->str,"none")) {
freeReplyObject(reply1);
freeReplyObject(reply2);
continue;
} else {
fprintf(stderr, "Unknown key type '%s' for key '%s'\n",
reply2->str, reply1->str);
}
else
if
(
reply1
->
elements
!=
2
)
{
fprintf
(
stderr
,
"Invalid SCAN result!
\n
"
);
exit
(
1
);
}
reply3 = redisCommand(context,"%s %s", sizecmd, reply1->str);
if (reply3 && reply3->type == REDIS_REPLY_INTEGER) {
if (biggest[type] < reply3->integer) {
printf("Biggest %-6s found so far '%s' with %llu %s.\n",
typename[type], reply1->str,
(unsigned long long) reply3->integer,
typeunit[type]);
biggest[type] = reply3->integer;
/* Validate the SCAN response */
assert
(
reply1
->
element
[
0
]
->
type
==
REDIS_REPLY_STRING
);
assert
(
reply1
->
element
[
1
]
->
type
==
REDIS_REPLY_ARRAY
);
/* Update iterator and grab pointer to keys */
it
=
atoi
(
reply1
->
element
[
0
]
->
str
);
keys
=
reply1
->
element
[
1
];
/* Iterate keys that SCAN returned */
for
(
i
=
0
;
i
<
keys
->
elements
;
i
++
)
{
/* Make sure we've got a string, grab it, and increment samples */
assert
(
keys
->
element
[
i
]
->
type
==
REDIS_REPLY_STRING
);
key
=
keys
->
element
[
i
]
->
str
;
samples
++
;
/* Get the key type */
reply2
=
redisCommand
(
context
,
"TYPE %s"
,
key
);
assert
(
reply2
&&
reply2
->
type
==
REDIS_REPLY_STATUS
);
/* Get the key "size" */
if
(
!
strcmp
(
reply2
->
str
,
"string"
))
{
sizecmd
=
"STRLEN"
;
type
=
TYPE_STRING
;
}
else
if
(
!
strcmp
(
reply2
->
str
,
"list"
))
{
sizecmd
=
"LLEN"
;
type
=
TYPE_LIST
;
}
else
if
(
!
strcmp
(
reply2
->
str
,
"set"
))
{
sizecmd
=
"SCARD"
;
type
=
TYPE_SET
;
}
else
if
(
!
strcmp
(
reply2
->
str
,
"hash"
))
{
sizecmd
=
"HLEN"
;
type
=
TYPE_HASH
;
}
else
if
(
!
strcmp
(
reply2
->
str
,
"zset"
))
{
sizecmd
=
"ZCARD"
;
type
=
TYPE_ZSET
;
}
else
if
(
!
strcmp
(
reply2
->
str
,
"none"
))
{
freeReplyObject
(
reply1
);
freeReplyObject
(
reply2
);
continue
;
}
else
{
fprintf
(
stderr
,
"Unknown key type '%s' for key '%s'
\n
"
,
reply2
->
str
,
key
);
exit
(
1
);
}
/* The size command */
reply3
=
redisCommand
(
context
,
"%s %s"
,
sizecmd
,
key
);
if
(
reply3
&&
reply3
->
type
==
REDIS_REPLY_INTEGER
)
{
if
(
biggest
[
type
]
<
reply3
->
integer
)
{
printf
(
"Biggest %-6s found so far '%s' with %llu %s.
\n
"
,
typename
[
type
],
key
,
(
unsigned
long
long
)
reply3
->
integer
,
typeunit
[
type
]);
biggest
[
type
]
=
reply3
->
integer
;
}
}
freeReplyObject
(
reply2
);
if
(
reply3
)
freeReplyObject
(
reply3
);
}
if ((samples % 1000000) == 0)
if
(
samples
&&
(
samples
%
1000000
)
==
0
)
printf
(
"(%llu keys sampled)
\n
"
,
samples
);
if ((samples % 100) == 0 && config.interval)
if
(
samples
&&
(
samples
%
100
)
==
0
&&
config
.
interval
)
usleep
(
config
.
interval
);
freeReplyObject
(
reply1
);
freeReplyObject(reply2);
if (reply3) freeReplyObject(reply3);
}
}
while
(
it
!=
0
);
/* We've finished scanning the keyspace */
printf
(
"
\n
# Scanned all %llu keys in the keyspace!
\n
"
,
samples
);
exit
(
0
);
}
/*------------------------------------------------------------------------------
...
...
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