2009-03-22 05:30:00 -04:00
|
|
|
require 'redis'
|
|
|
|
require 'hash_ring'
|
|
|
|
class DistRedis
|
|
|
|
attr_reader :ring
|
2009-06-09 18:11:17 -04:00
|
|
|
def initialize(opts={})
|
|
|
|
hosts = []
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-06-09 18:11:17 -04:00
|
|
|
db = opts[:db] || nil
|
2009-09-02 04:37:32 -04:00
|
|
|
timeout = opts[:timeout] || nil
|
2009-06-09 18:11:17 -04:00
|
|
|
|
|
|
|
raise Error, "No hosts given" unless opts[:hosts]
|
|
|
|
|
|
|
|
opts[:hosts].each do |h|
|
|
|
|
host, port = h.split(':')
|
2009-09-02 04:37:32 -04:00
|
|
|
hosts << Redis.new(:host => host, :port => port, :db => db, :timeout => timeout)
|
2009-03-22 05:30:00 -04:00
|
|
|
end
|
2009-06-09 18:11:17 -04:00
|
|
|
|
2009-09-02 04:37:32 -04:00
|
|
|
@ring = HashRing.new hosts
|
2009-03-22 05:30:00 -04:00
|
|
|
end
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
def node_for_key(key)
|
2009-09-02 04:37:32 -04:00
|
|
|
key = $1 if key =~ /\{(.*)?\}/
|
2009-03-22 05:30:00 -04:00
|
|
|
@ring.get_node(key)
|
|
|
|
end
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
def add_server(server)
|
|
|
|
server, port = server.split(':')
|
|
|
|
@ring.add_node Redis.new(:host => server, :port => port)
|
|
|
|
end
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
def method_missing(sym, *args, &blk)
|
2009-03-27 07:14:35 -04:00
|
|
|
if redis = node_for_key(args.first.to_s)
|
2009-03-22 05:30:00 -04:00
|
|
|
redis.send sym, *args, &blk
|
|
|
|
else
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
def keys(glob)
|
2009-09-02 04:37:32 -04:00
|
|
|
@ring.nodes.map do |red|
|
|
|
|
red.keys(glob)
|
2009-03-22 05:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
def save
|
2009-09-02 04:37:32 -04:00
|
|
|
on_each_node :save
|
2009-03-22 05:30:00 -04:00
|
|
|
end
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
def bgsave
|
2009-09-02 04:37:32 -04:00
|
|
|
on_each_node :bgsave
|
2009-03-22 05:30:00 -04:00
|
|
|
end
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
def quit
|
2009-09-02 04:37:32 -04:00
|
|
|
on_each_node :quit
|
|
|
|
end
|
|
|
|
|
|
|
|
def flush_all
|
|
|
|
on_each_node :flush_all
|
|
|
|
end
|
|
|
|
alias_method :flushall, :flush_all
|
|
|
|
|
|
|
|
def flush_db
|
|
|
|
on_each_node :flush_db
|
2009-03-22 05:30:00 -04:00
|
|
|
end
|
2009-09-02 04:37:32 -04:00
|
|
|
alias_method :flushdb, :flush_db
|
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
def delete_cloud!
|
|
|
|
@ring.nodes.each do |red|
|
|
|
|
red.keys("*").each do |key|
|
|
|
|
red.delete key
|
2009-09-02 04:37:32 -04:00
|
|
|
end
|
2009-03-22 05:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
2009-09-02 04:37:32 -04:00
|
|
|
|
|
|
|
def on_each_node(command, *args)
|
|
|
|
@ring.nodes.each do |red|
|
|
|
|
red.send(command, *args)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
if __FILE__ == $0
|
|
|
|
|
|
|
|
r = DistRedis.new 'localhost:6379', 'localhost:6380', 'localhost:6381', 'localhost:6382'
|
|
|
|
r['urmom'] = 'urmom'
|
|
|
|
r['urdad'] = 'urdad'
|
|
|
|
r['urmom1'] = 'urmom1'
|
|
|
|
r['urdad1'] = 'urdad1'
|
|
|
|
r['urmom2'] = 'urmom2'
|
|
|
|
r['urdad2'] = 'urdad2'
|
|
|
|
r['urmom3'] = 'urmom3'
|
|
|
|
r['urdad3'] = 'urdad3'
|
|
|
|
p r['urmom']
|
|
|
|
p r['urdad']
|
|
|
|
p r['urmom1']
|
|
|
|
p r['urdad1']
|
|
|
|
p r['urmom2']
|
|
|
|
p r['urdad2']
|
|
|
|
p r['urmom3']
|
|
|
|
p r['urdad3']
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
r.push_tail 'listor', 'foo1'
|
|
|
|
r.push_tail 'listor', 'foo2'
|
|
|
|
r.push_tail 'listor', 'foo3'
|
|
|
|
r.push_tail 'listor', 'foo4'
|
|
|
|
r.push_tail 'listor', 'foo5'
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-27 07:14:35 -04:00
|
|
|
p r.pop_tail('listor')
|
|
|
|
p r.pop_tail('listor')
|
|
|
|
p r.pop_tail('listor')
|
|
|
|
p r.pop_tail('listor')
|
|
|
|
p r.pop_tail('listor')
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
puts "key distribution:"
|
2009-09-02 04:37:32 -04:00
|
|
|
|
2009-03-22 05:30:00 -04:00
|
|
|
r.ring.nodes.each do |red|
|
|
|
|
p [red.port, red.keys("*")]
|
|
|
|
end
|
|
|
|
r.delete_cloud!
|
|
|
|
p r.keys('*')
|
|
|
|
|
|
|
|
end
|