]>
Commit | Line | Data |
---|---|---|
ed9b544e | 1 | require 'redis' |
2 | require 'hash_ring' | |
3 | class DistRedis | |
4 | attr_reader :ring | |
0df1ead7 | 5 | def initialize(opts={}) |
6 | hosts = [] | |
3113921a | 7 | |
0df1ead7 | 8 | db = opts[:db] || nil |
3113921a | 9 | timeout = opts[:timeout] || nil |
0df1ead7 | 10 | |
11 | raise Error, "No hosts given" unless opts[:hosts] | |
12 | ||
13 | opts[:hosts].each do |h| | |
14 | host, port = h.split(':') | |
3113921a | 15 | hosts << Redis.new(:host => host, :port => port, :db => db, :timeout => timeout) |
ed9b544e | 16 | end |
0df1ead7 | 17 | |
3113921a | 18 | @ring = HashRing.new hosts |
ed9b544e | 19 | end |
3113921a | 20 | |
ed9b544e | 21 | def node_for_key(key) |
3113921a | 22 | key = $1 if key =~ /\{(.*)?\}/ |
ed9b544e | 23 | @ring.get_node(key) |
24 | end | |
3113921a | 25 | |
ed9b544e | 26 | def add_server(server) |
27 | server, port = server.split(':') | |
28 | @ring.add_node Redis.new(:host => server, :port => port) | |
29 | end | |
3113921a | 30 | |
ed9b544e | 31 | def method_missing(sym, *args, &blk) |
29fac617 | 32 | if redis = node_for_key(args.first.to_s) |
ed9b544e | 33 | redis.send sym, *args, &blk |
34 | else | |
35 | super | |
36 | end | |
37 | end | |
3113921a | 38 | |
ed9b544e | 39 | def keys(glob) |
3113921a | 40 | @ring.nodes.map do |red| |
41 | red.keys(glob) | |
ed9b544e | 42 | end |
ed9b544e | 43 | end |
3113921a | 44 | |
ed9b544e | 45 | def save |
3113921a | 46 | on_each_node :save |
ed9b544e | 47 | end |
3113921a | 48 | |
ed9b544e | 49 | def bgsave |
3113921a | 50 | on_each_node :bgsave |
ed9b544e | 51 | end |
3113921a | 52 | |
ed9b544e | 53 | def quit |
3113921a | 54 | on_each_node :quit |
55 | end | |
56 | ||
57 | def flush_all | |
58 | on_each_node :flush_all | |
59 | end | |
60 | alias_method :flushall, :flush_all | |
61 | ||
62 | def flush_db | |
63 | on_each_node :flush_db | |
ed9b544e | 64 | end |
3113921a | 65 | alias_method :flushdb, :flush_db |
66 | ||
ed9b544e | 67 | def delete_cloud! |
68 | @ring.nodes.each do |red| | |
69 | red.keys("*").each do |key| | |
70 | red.delete key | |
3113921a | 71 | end |
ed9b544e | 72 | end |
73 | end | |
3113921a | 74 | |
75 | def on_each_node(command, *args) | |
76 | @ring.nodes.each do |red| | |
77 | red.send(command, *args) | |
78 | end | |
79 | end | |
80 | ||
ed9b544e | 81 | end |
82 | ||
83 | ||
84 | if __FILE__ == $0 | |
85 | ||
86 | r = DistRedis.new 'localhost:6379', 'localhost:6380', 'localhost:6381', 'localhost:6382' | |
87 | r['urmom'] = 'urmom' | |
88 | r['urdad'] = 'urdad' | |
89 | r['urmom1'] = 'urmom1' | |
90 | r['urdad1'] = 'urdad1' | |
91 | r['urmom2'] = 'urmom2' | |
92 | r['urdad2'] = 'urdad2' | |
93 | r['urmom3'] = 'urmom3' | |
94 | r['urdad3'] = 'urdad3' | |
95 | p r['urmom'] | |
96 | p r['urdad'] | |
97 | p r['urmom1'] | |
98 | p r['urdad1'] | |
99 | p r['urmom2'] | |
100 | p r['urdad2'] | |
101 | p r['urmom3'] | |
102 | p r['urdad3'] | |
3113921a | 103 | |
ed9b544e | 104 | r.push_tail 'listor', 'foo1' |
105 | r.push_tail 'listor', 'foo2' | |
106 | r.push_tail 'listor', 'foo3' | |
107 | r.push_tail 'listor', 'foo4' | |
108 | r.push_tail 'listor', 'foo5' | |
3113921a | 109 | |
29fac617 | 110 | p r.pop_tail('listor') |
111 | p r.pop_tail('listor') | |
112 | p r.pop_tail('listor') | |
113 | p r.pop_tail('listor') | |
114 | p r.pop_tail('listor') | |
3113921a | 115 | |
ed9b544e | 116 | puts "key distribution:" |
3113921a | 117 | |
ed9b544e | 118 | r.ring.nodes.each do |red| |
119 | p [red.port, red.keys("*")] | |
120 | end | |
121 | r.delete_cloud! | |
122 | p r.keys('*') | |
123 | ||
124 | end |