Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Issue #13 : Adds new command: redis-memory-for-key

This command prints the approximate memory used by a key

Logic :
1. Connect to a running Redis Server
2. Issue dump command and download binary dump of a key
3. Parse the dump using RdbParser
4. Display the memory usage
  • Loading branch information...
commit 08383ffcaa268b770fe11f38ba127fd400138da6 1 parent ef052ff
@sripathikrishnan authored
View
2  rdbtools/__init__.py
@@ -2,7 +2,7 @@
from rdbtools.callbacks import JSONCallback, DiffCallback
from rdbtools.memprofiler import MemoryCallback, PrintAllKeys, StatsAggregator
-__version__ = '0.1.2'
+__version__ = '0.1.3'
VERSION = tuple(map(int, __version__.split('.')))
__all__ = [
View
103 rdbtools/cli/redis_memory_for_key.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+import struct
+import os
+import sys
+
+try :
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+
+from optparse import OptionParser
+from rdbtools import RdbParser, JSONCallback, MemoryCallback
+from rdbtools.callbacks import encode_key
+
+from redis import StrictRedis
+from redis.exceptions import ConnectionError, ResponseError
+
+def main():
+ usage = """usage: %prog [options] redis-key
+Examples :
+%prog user:13423
+%prog -h localhost -p 6379 user:13423
+"""
+
+ parser = OptionParser(usage=usage)
+ parser.add_option("-s", "--server", dest="host", default="127.0.0.1",
+ help="Redis Server hostname. Defaults to 127.0.0.1")
+ parser.add_option("-p", "--port", dest="port", default=6379, type="int",
+ help="Redis Server port. Defaults to 6379")
+ parser.add_option("-a", "--password", dest="password",
+ help="Password to use when connecting to the server")
+ parser.add_option("-d", "--db", dest="db", default=0,
+ help="Database number, defaults to 0")
+
+ (options, args) = parser.parse_args()
+
+ if len(args) == 0:
+ parser.error("Key not specified")
+ redis_key = args[0]
+ print_memory_for_key(redis_key, host=options.host, port=options.port,
+ db=options.db, password=options.password)
+
+def print_memory_for_key(key, host='localhost', port=6379, db=0, password=None):
+ redis = connect_to_redis(host, port, db, password)
+ reporter = PrintMemoryUsage()
+ callback = MemoryCallback(reporter, 64)
+ parser = RdbParser(callback, filters={})
+ parser._key = key
+
+ raw_dump = redis.execute_command('dump', key)
+ if not raw_dump:
+ sys.stderr.write('Key %s does not exist\n' % key)
+ sys.exit(-1)
+
+ stream = StringIO(raw_dump)
+ data_type = read_unsigned_char(stream)
+ parser.read_object(stream, data_type)
+
+def connect_to_redis(host, port, db, password):
+ try:
+ redis = StrictRedis(host=host, port=port, db=db, password=password)
+ if not check_redis_version(redis):
+ sys.stderr.write('This script only works with Redis Server version 2.6.x or higher\n')
+ sys.exit(-1)
+ except ConnectionError as e:
+ sys.stderr.write('Could not connect to Redis Server : %s\n' % e)
+ sys.exit(-1)
+ except ResponseError as e:
+ sys.stderr.write('Could not connect to Redis Server : %s\n' % e)
+ sys.exit(-1)
+ return redis
+
+def check_redis_version(redis):
+ server_info = redis.info()
+ version_str = server_info['redis_version']
+ version = tuple(map(int, version_str.split('.')))
+
+ if version[0] > 2 or (version[0] == 2 and version[1] >= 6) :
+ return True
+ else:
+ return False
+
+def read_unsigned_char(f) :
+ return struct.unpack('B', f.read(1))[0]
+
+class PrintMemoryUsage():
+ def next_record(self, record) :
+ print("%s\t\t\t\t%s" % ("Key", encode_key(record.key)))
+ print("%s\t\t\t\t%s" % ("Bytes", record.bytes))
+ print("%s\t\t\t\t%s" % ("Type", record.type))
+ if record.type in ('set', 'list', 'sortedset', 'hash'):
+ print("%s\t\t\t%s" % ("Encoding", record.encoding))
+ print("%s\t\t%s" % ("Number of Elements", record.size))
+ print("%s\t%s" % ("Length of Largest Element", record.len_largest_element))
+
+ #print("%d,%s,%s,%d,%s,%d,%d\n" % (record.database, record.type, encode_key(record.key),
+ # record.bytes, record.encoding, record.size, record.len_largest_element))
+
+if __name__ == '__main__':
+ #print_memory_for_key('x')
+ main()
+
+
View
2  requirements.txt
@@ -0,0 +1,2 @@
+redis==2.4.12
+wsgiref==0.1.2
View
3  setup.py
@@ -17,7 +17,7 @@
'author_email' : 'Sripathi.Krishnan@gmail.com',
'maintainer' : 'Sripathi Krishnan',
'maintainer_email' : 'Sripathi.Krishnan@gmail.com',
- 'keywords' : ['Redis', 'RDB', 'Export', 'Dump'],
+ 'keywords' : ['Redis', 'RDB', 'Export', 'Dump', 'Memory Profiler'],
'license' : 'MIT',
'packages' : ['rdbtools', 'rdbtools.cli'],
'package_data' : {'rdbtools.cli': ['*.template']},
@@ -25,6 +25,7 @@
'entry_points' : {
'console_scripts' : [
'rdb = rdbtools.cli.rdb:main',
+ 'redis-memory-for-key = rdbtools.cli.redis_memory_for_key:main',
'redis-profiler = rdbtools.cli.redis_profiler:main'],
},
'classifiers' : [
Please sign in to comment.
Something went wrong with that request. Please try again.