Class: Redis::Dump

Inherits:
Object
  • Object
show all
Extended by:
ClassMethods
Defined in:
lib/redis/dump.rb

Defined Under Namespace

Modules: ClassMethods, VERSION Classes: Problem

Constant Summary collapse

VALID_TYPES =
['string', 'set', 'list', 'zset', 'hash', 'none'].freeze

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ClassMethods

dump_strings, set_value, set_value_hash, set_value_list, set_value_none, set_value_set, set_value_string, set_value_zset, stringify, stringify_hash, stringify_list, stringify_none, stringify_set, stringify_string, stringify_zset, type, value, value_hash, value_list, value_none, value_set, value_string, value_zset

Constructor Details

#initialize(dbs = nil, uri = "redis://#{Redis::Dump.host}:#{Redis::Dump.port}") ⇒ Dump

Returns a new instance of Dump.



33
34
35
36
37
38
39
40
41
# File 'lib/redis/dump.rb', line 33

def initialize(dbs=nil,uri="redis://#{Redis::Dump.host}:#{Redis::Dump.port}")
  @redis_connections = {}
  @uri = uri
  unless dbs.nil?
    @dbs = Range === dbs ? dbs : (dbs..dbs)
    @dbs = (@dbs.first.to_i..@dbs.last.to_i) # enforce integers
    @dbs.to_a.each { |db| redis(db) } # open_all_connections
  end
end

Class Attribute Details

.chunk_sizeObject

Returns the value of attribute chunk_size.



23
24
25
# File 'lib/redis/dump.rb', line 23

def chunk_size
  @chunk_size
end

.debugObject

Returns the value of attribute debug.



23
24
25
# File 'lib/redis/dump.rb', line 23

def debug
  @debug
end

.encoderObject

Returns the value of attribute encoder.



23
24
25
# File 'lib/redis/dump.rb', line 23

def encoder
  @encoder
end

.hostObject

Returns the value of attribute host.



23
24
25
# File 'lib/redis/dump.rb', line 23

def host
  @host
end

.parserObject

Returns the value of attribute parser.



23
24
25
# File 'lib/redis/dump.rb', line 23

def parser
  @parser
end

.portObject

Returns the value of attribute port.



23
24
25
# File 'lib/redis/dump.rb', line 23

def port
  @port
end

.safeObject

Returns the value of attribute safe.



23
24
25
# File 'lib/redis/dump.rb', line 23

def safe
  @safe
end

.with_optimizationsObject

Returns the value of attribute with_optimizations.



23
24
25
# File 'lib/redis/dump.rb', line 23

def with_optimizations
  @with_optimizations
end

Instance Attribute Details

#dbsObject

Returns the value of attribute dbs.



31
32
33
# File 'lib/redis/dump.rb', line 31

def dbs
  @dbs
end

#redis_connectionsObject (readonly)

Returns the value of attribute redis_connections.



32
33
34
# File 'lib/redis/dump.rb', line 32

def redis_connections
  @redis_connections
end

#uriObject

Returns the value of attribute uri.



31
32
33
# File 'lib/redis/dump.rb', line 31

def uri
  @uri
end

Class Method Details

.ld(msg) ⇒ Object



24
25
26
# File 'lib/redis/dump.rb', line 24

def ld(msg)
  STDERR.puts "#%.4f: %s" % [Time.now.utc.to_f, msg] if debug
end

.memory_usageObject



27
28
29
# File 'lib/redis/dump.rb', line 27

def memory_usage
  `ps -o rss= -p #{Process.pid}`.to_i # in kb
end

Instance Method Details

#connect(this_uri) ⇒ Object



45
46
47
48
# File 'lib/redis/dump.rb', line 45

def connect(this_uri)
  #self.class.ld 'CONNECT: ' << this_uri
  Redis.connect :url => this_uri
end

#dump(filter = nil) ⇒ Object

See each_key



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/redis/dump.rb', line 57

def dump filter=nil
  filter ||= '*'
  entries = []
  each_database do |redis|
    chunk_entries = []
    dump_keys = redis.keys(filter)
    dump_keys_size = dump_keys.size
    Redis::Dump.ld "Memory after loading keys: #{Redis::Dump.memory_usage}kb"
    dump_keys.each_with_index do |key,idx|
      entry, idxplus = key, idx+1
      #self.class.ld " #{key} (#{key_dump['type']}): #{key_dump['size'].to_bytes}"
      #entry_enc = self.class.encoder.encode entry
      if block_given?
        chunk_entries << entry
        process_chunk idx, dump_keys_size do |count|
          Redis::Dump.ld " dumping #{chunk_entries.size} (#{count}) from #{redis.client.id}"
          output_buffer = []
          chunk_entries.select! do |key| 
            type = Redis::Dump.type(redis, key)
            if self.class.with_optimizations && type == 'string' 
              true
            else
              output_buffer.push self.class.encoder.encode(Redis::Dump.dump(redis, key, type))
              false
            end
          end
          unless output_buffer.empty?
            yield output_buffer 
          end
          unless chunk_entries.empty?
            yield Redis::Dump.dump_strings(redis, chunk_entries) { |obj| self.class.encoder.encode(obj) } 
          end
          output_buffer.clear
          chunk_entries.clear
        end
      else
        entries << self.class.encoder.encode(Redis::Dump.dump(redis, entry))
      end
    end
  end
  entries
end

#each_databaseObject



50
51
52
53
54
# File 'lib/redis/dump.rb', line 50

def each_database
  @redis_connections.keys.sort.each do |redis_uri|
    yield redis_connections[redis_uri]
  end
end

#load(string_or_stream, &each_record) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/redis/dump.rb', line 133

def load(string_or_stream, &each_record)
  count = 0
  Redis::Dump.ld " LOAD SOURCE: #{string_or_stream}"
  Redis::Dump.parser.parse string_or_stream do |obj|
    unless @dbs.member?(obj["db"].to_i)
      Redis::Dump.ld "db out of range: #{obj["db"]}"
      next
    end
    this_redis = redis(obj["db"])
    #Redis::Dump.ld "load[#{this_redis.hash}, #{obj}]"
    if each_record.nil? 
      if Redis::Dump.safe && this_redis.exists(obj['key'])
        #Redis::Dump.ld " record exists (no change)"
        next
      end
      Redis::Dump.set_value this_redis, obj['key'], obj['type'], obj['value'], obj['ttl']
    else
      each_record.call obj
    end
    count += 1
  end
  count
end

#redis(db) ⇒ Object



42
43
44
# File 'lib/redis/dump.rb', line 42

def redis(db)
  redis_connections["#{uri}/#{db}"] ||= connect("#{uri}/#{db}")
end

#report(filter = '*') ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/redis/dump.rb', line 106

def report filter='*'
  values = []
  total_size, dbs = 0, {}
  each_database do |redis|
    chunk_entries = []
    dump_keys = redis.keys(filter)
    dump_keys_size = dump_keys.size
    dump_keys.each_with_index do |key,idx|
      entry, idxplus = Redis::Dump.report(redis, key), idx+1
      chunk_entries << entry
      process_chunk idx, dump_keys_size do |count|
        Redis::Dump.ld " reporting on #{chunk_entries.size} (#{idxplus}) from #{redis.client.id}"
        chunk_entries.each do |e|
          #puts record if obj.global.verbose >= 1
          dbs[e['db']] ||= 0
          dbs[e['db']] += e['size']
          total_size += e['size']
        end
        chunk_entries.clear
      end
    end
  end
  puts dbs.keys.sort.collect { |db| "  db#{db}: #{dbs[db].to_bytes}" }
  puts "total: #{total_size.to_bytes}"
  values
end