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
,
"
\n
I/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