roma 0.8.13 → 0.8.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,8 +21,6 @@ module Roma
21
21
  def incr(vn, k, d, v); end
22
22
  def decr(vn, k, d, v); end
23
23
  def true_length; 100; end
24
- def add_vnode(vn); end
25
- def del_vnode(vn); end
26
24
  def clean_up(t); end
27
25
 
28
26
  def load(dmp); 10 end
@@ -8,15 +8,18 @@ module Roma
8
8
  def get(k); self[k]; end
9
9
  def out(k); delete(k); end
10
10
  def rnum; length; end
11
+ def sync; true; end
11
12
  end
12
13
 
13
14
  class RubyHashStorage < BasicStorage
14
15
 
15
16
  def opendb
16
17
  create_div_hash
17
- @divnum.times{ |i|
18
+ @divnum.times do |i|
18
19
  @hdb[i] = open_db(nil)
19
- }
20
+ @hdbc[i] = nil
21
+ @dbs[i] = :normal
22
+ end
20
23
  end
21
24
 
22
25
  if RUBY_VERSION >= '1.9.2'
@@ -42,25 +45,23 @@ module Roma
42
45
  }
43
46
  end
44
47
 
45
- def each_vn_dump(target_vn)
48
+ def each_unpacked_db(target_vn, db)
46
49
  count = 0
47
50
  tn = Time.now.to_i
48
- keys = @hdb[@hdiv[target_vn]].keys
49
- keys.each{|k|
50
- v = @hdb[@hdiv[target_vn]][k]
51
+ keys = db[@hdiv[target_vn]].keys
52
+ keys.each do |k|
53
+ v = db[@hdiv[target_vn]][k]
51
54
  vn, last, clk, expt, val = unpack_data(v)
52
55
  if vn != target_vn || (expt != 0 && tn > expt)
53
56
  count += 1
54
57
  sleep @each_vn_dump_sleep if count % @each_vn_dump_sleep_count == 0
55
58
  next
56
59
  end
57
- if val
58
- yield [vn, last, clk, expt, k.length, k, val.length, val].pack("NNNNNa#{k.length}Na#{val.length}")
59
- else
60
- yield [vn, last, clk, expt, k.length, k, 0].pack("NNNNNa#{k.length}N")
61
- end
62
- }
60
+ yield vn, last, clk, expt, k, val
61
+ end
63
62
  end
63
+ private :each_unpacked_db
64
+
64
65
 
65
66
  def each_hdb_dump(i,except_vnh = nil)
66
67
  count = 0
@@ -56,6 +56,10 @@ module Roma
56
56
  "WHERE type='table' ORDER BY name;"
57
57
  self.execute( sql ).flatten
58
58
  end
59
+
60
+ def sync
61
+ true
62
+ end
59
63
  end
60
64
 
61
65
  class SQLite3Storage < BasicStorage
@@ -32,7 +32,7 @@ module Roma
32
32
  end
33
33
  ret
34
34
  end
35
- end
35
+ end # class TokyoCabinet::HDB
36
36
 
37
37
  def initialize
38
38
  super
@@ -51,33 +51,18 @@ module Roma
51
51
  end
52
52
 
53
53
  def opendb
54
- create_div_hash
55
- path = ''
56
- @storage_path.split('/').each{|p|
57
- if p.length==0
58
- path = '/'
59
- next
60
- end
61
- path << p
62
- Dir::mkdir(path) unless File.exist?(path)
63
- path << '/'
64
- }
65
-
66
54
  @fname_lock = "#{@storage_path}/lock"
67
55
  if File.exist?(@fname_lock)
68
56
  raise RuntimeError.new("Lock file already exists.")
69
57
  end
70
- open(@fname_lock,"w"){}
71
58
 
72
- @divnum.times{ |i|
73
- @hdb[i] = open_db("#{@storage_path}/#{i}.#{@ext_name}")
74
- }
59
+ super
60
+
61
+ open(@fname_lock,"w"){}
75
62
  end
76
63
 
77
64
  def closedb
78
- stop_clean_up
79
- buf = @hdb; @hdb = []
80
- buf.each{ |hdb| close_db(hdb) }
65
+ super
81
66
 
82
67
  File.unlink(@fname_lock) if @fname_lock
83
68
  @fname_lock = nil
@@ -202,6 +187,7 @@ module Roma
202
187
  opts += "#bnum=#{prop['bnum']}" if prop.key?('bnum')
203
188
  opts += "#capnum=#{prop['capnum']}" if prop.key?('capnum')
204
189
  opts += "#capsiz=#{prop['capsiz']}" if prop.key?('capsiz')
190
+
205
191
  opts = nil unless opts.length > 0
206
192
  opts
207
193
  end
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'socket'
4
+
5
+ module Roma
6
+ class SafeCopy
7
+
8
+ attr_reader :storages
9
+
10
+ def initialize(addr, port)
11
+ @con = TCPSocket.open(addr, port)
12
+ get_storage_info
13
+ end
14
+
15
+ def backup_all
16
+ @storages.keys.each do |k|
17
+ backup(k)
18
+ end
19
+ end
20
+
21
+ def backup(hname)
22
+ stat = get_safecopy_stats(hname)
23
+ if stat.uniq != [:normal]
24
+ puts "storages[#{hname}].storage.safecopy_stats #{stat.to_s}"
25
+ puts "ERROR: Status except the :normal exists."
26
+ return
27
+ end
28
+ @storages[hname].each_with_index do |fname, num|
29
+ ret = set_storage_status(hname, num, "safecopy")
30
+ if ret != "PUSHED\r\n"
31
+ puts ret
32
+ puts "ERROR: Can't change storage status to safecopy."
33
+ return
34
+ end
35
+ wait(hname, num, :safecopy_flushed)
36
+ puts "copy file : #{fname}"
37
+ # file copy
38
+ `cp #{fname} #{fname}.#{Time.now.strftime("%Y%m%d%H%M%S")}`
39
+ ret = set_storage_status(hname, num, "normal")
40
+ if ret != "PUSHED\r\n"
41
+ puts ret
42
+ puts "ERROR: Can't change storage status to normal."
43
+ return
44
+ end
45
+ wait(hname, num, :normal)
46
+ end
47
+ end
48
+
49
+ def wait(hname, num, stat)
50
+ print "waiting for storages[#{hname}][#{num}] == #{stat} "
51
+ while get_safecopy_stats(hname)[num] != stat
52
+ print "."
53
+ sleep 5
54
+ end
55
+ puts
56
+ end
57
+
58
+ def get_storage_info
59
+ @storages = {}
60
+ stats do |line|
61
+ if /^storages\[(.+)\]\.storage\[(\d+)\]\.path\s(.+)/ =~ line
62
+ @storages[$1] = [] unless @storages.key? $1
63
+ @storages[$1][$2.to_i] = $3.chomp
64
+ # puts "#{$1} #{$2} #{$3}"
65
+ end
66
+ end
67
+ end
68
+
69
+ def get_safecopy_stats(hname)
70
+ ret = nil
71
+ stats do |line|
72
+ if /^storages\[#{hname}\]\.storage\.safecopy_stats\s(.+)/ =~ line
73
+ ret = $1.chomp
74
+ end
75
+ end
76
+ eval ret
77
+ end
78
+
79
+ def set_storage_status(hname, num, stat)
80
+ @con.puts "set_storage_status #{num} #{stat} #{hname}\r\n"
81
+ @con.gets
82
+ end
83
+
84
+ def stats
85
+ @con.puts "stat storage\r\n"
86
+ yield $_ while @con.gets != "END\r\n"
87
+ end
88
+
89
+ def close
90
+ @con.close if @con
91
+ end
92
+
93
+ end # SafeCopy
94
+ end # Roma
95
+
96
+ if ARGV.length < 1
97
+ puts File.basename(__FILE__) + " [port]"
98
+ exit
99
+ end
100
+
101
+ sc = Roma::SafeCopy.new("localhost", ARGV[0].to_i)
102
+ sc.backup_all
103
+ sc.close
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'date'
4
+ require 'roma/client/rclient'
5
+
6
+ @cnt = 0
7
+ @tmax = 0
8
+ @tmin = 100
9
+
10
+ @m = Mutex.new
11
+
12
+ Thread.new do
13
+ sleep_time=10
14
+ while(true)
15
+ sleep sleep_time
16
+ printf("\s\sqps=%d max=%f min=%f ave=%f\n",@cnt/sleep_time,@tmax,@tmin,sleep_time/@cnt.to_f)
17
+ @cnt=0
18
+ @tmax=0
19
+ @tmin=100
20
+ end
21
+ end
22
+
23
+ def random_rquest_sender(ini_nodes, n)
24
+ puts __method__
25
+ rc=Roma::Client::RomaClient.new(ini_nodes)
26
+
27
+ loop do
28
+ i=rand(n)
29
+ ts = DateTime.now
30
+ case rand(3)
31
+ when 0
32
+ res=rc.set(i.to_s,'hoge'+i.to_s)
33
+ puts "set k=#{i} #{res}" if res==nil || res.chomp != 'STORED'
34
+ when 1
35
+ res=rc.get(i.to_s)
36
+ puts "get k=#{i} #{res}" if res == :error
37
+ when 2
38
+ res=rc.delete(i.to_s)
39
+ puts "del k=#{i} #{res}" if res != 'DELETED' && res != 'NOT_FOUND'
40
+ end
41
+ t=(DateTime.now - ts).to_f * 86400.0
42
+ @tmax=t if t > @tmax
43
+ @tmin=t if t < @tmin
44
+ @cnt+=1
45
+ end
46
+ end
47
+
48
+ def set_counts(ini_nodes, range, key_prefix, value)
49
+ puts "\s\s#{__method__} #{range} #{value}"
50
+ rc=Roma::Client::RomaClient.new(ini_nodes)
51
+ @range_cnt = 0
52
+
53
+ range.each do |i|
54
+ ts = DateTime.now
55
+ @range_cnt = i
56
+ res=rc.set("#{key_prefix}_#{i}","#{value}")
57
+ puts "set #{key_prefix}_#{i}=#{value} #{res}" if res==nil || res.chomp != 'STORED'
58
+ t=(DateTime.now - ts).to_f * 86400.0
59
+ @tmax=t if t > @tmax
60
+ @tmin=t if t < @tmin
61
+ @cnt+=1
62
+ end
63
+ end
64
+
65
+ def check_count(ini_nodes, range, key_prefix, value)
66
+ puts "\s\s#{__method__} #{range} #{value}"
67
+ rc=Roma::Client::RomaClient.new(ini_nodes)
68
+
69
+ range.each do |i|
70
+ ts = DateTime.now
71
+ res = rc.get("#{key_prefix}_#{i}")
72
+ if res != value.to_s
73
+ puts "error k=#{key_prefix}_#{i} #{res}"
74
+ end
75
+
76
+ t=(DateTime.now - ts).to_f * 86400.0
77
+ @tmax=t if t > @tmax
78
+ @tmin=t if t < @tmin
79
+ @cnt+=1
80
+ end
81
+ end
82
+
83
+ def send_cmd(nid, cmd)
84
+ conn = Roma::Client::ConPool.instance.get_connection(nid)
85
+ conn.write "#{cmd}\r\n"
86
+ ret = conn.gets
87
+ Roma::Client::ConPool.instance.return_connection(nid, conn)
88
+ ret
89
+ rescue =>e
90
+ STDERR.puts "#{nid} #{cmd} #{e.inspect}"
91
+ nil
92
+ end
93
+
94
+ def stats(nid, regexp=nil)
95
+ conn = Roma::Client::ConPool.instance.get_connection(nid)
96
+ if regexp
97
+ conn.write "stats #{regexp}\r\n"
98
+ else
99
+ conn.write "stats\r\n"
100
+ end
101
+ ret = ""
102
+ while(conn.gets != "END\r\n")
103
+ ret << $_
104
+ end
105
+ Roma::Client::ConPool.instance.return_connection(nid, conn)
106
+ ret
107
+ rescue =>e
108
+ STDERR.puts "#{nid} #{e.inspect}"
109
+ nil
110
+ end
111
+
112
+ def safecopy_stats(nid)
113
+ ret = stats(nid, 'storage.safecopy_stats')
114
+ return eval $1 if ret =~ /^.+\s(\[.+\])/
115
+ nil
116
+ end
117
+
118
+ def set_storage_status(nid, fno, stat)
119
+ send_cmd(ARGV[0], "set_storage_status #{fno} #{stat}")
120
+ end
121
+
122
+ def wait_status(nid, fno, stat)
123
+ while safecopy_stats(nid)[fno] != stat
124
+ sleep 5
125
+ end
126
+ stat
127
+ end
128
+
129
+ def test_change_status
130
+
131
+ puts "write (0...10000) = 0"
132
+ set_counts(ARGV, 0...10000, "default_key",0)
133
+ Thread.new { random_rquest_sender(ARGV, 10000) }
134
+
135
+ set_counts(ARGV, 0...1000, "flushing_key", 0)
136
+ set_counts(ARGV, 0...1000, "caching_key", 0)
137
+
138
+ nid = ARGV[0]
139
+
140
+ sleep(5)
141
+
142
+ 10.times do |n|
143
+ puts "\n#{n+1}th loop(#{n}.tc)****************************************************************** "
144
+
145
+ #========================================================================================
146
+ #flushing(normal => safecopy_flushed)
147
+ flush_loop_count = 0
148
+ @range_cnt = 0
149
+ @flag = false
150
+
151
+ t = Thread.new {
152
+ loop{
153
+ flush_loop_count += 1
154
+ set_counts(ARGV, 0...1000, "flushing_key", flush_loop_count)
155
+ @flag = true
156
+ }
157
+ }
158
+ while !@flag do
159
+ puts "\s\s[debug]sleep flushing start"
160
+ sleep(1)
161
+ puts "\s\s[debug]sleep flushing end"
162
+ end
163
+ puts "\s\s#{set_storage_status(nid, n, 'safecopy')}"
164
+ puts "#{wait_status(nid, n, :safecopy_flushed)}"
165
+
166
+ #sleep(5)
167
+ t.kill
168
+
169
+ flushing_range_cnt = @range_cnt
170
+ puts "\s\s#{safecopy_stats(nid)}\n\n"
171
+
172
+ #========================================================================================
173
+ #Caching(safecopy_flushed => normal)
174
+ #sleep(30)
175
+ cache_loop_count = 0
176
+ @range_cnt = 0
177
+ @flag = false
178
+ t = Thread.new {
179
+ loop{
180
+ cache_loop_count += 1
181
+ set_counts(ARGV, 0...1000, "caching_key", cache_loop_count)
182
+ @flag = true
183
+ }
184
+ }
185
+ while !@flag do
186
+ puts "\s\s[debug]sleep caching start"
187
+ sleep(1)
188
+ puts "\s\s[debug]sleep caching end"
189
+ end
190
+
191
+ puts "\s\s#{set_storage_status(nid, n, 'normal')}"
192
+ puts "#{wait_status(nid, n, :normal)}"
193
+
194
+ #sleep(5)
195
+ t.kill
196
+
197
+ caching_range_cnt = @range_cnt
198
+ puts "\s\s#{safecopy_stats(nid)}"
199
+
200
+ #========================================================================================
201
+ #check
202
+ puts "\n[Check]"
203
+ puts "\s\sflushing key"
204
+ check_count(ARGV, 0..flushing_range_cnt, "flushing_key", flush_loop_count)
205
+ check_count(ARGV, flushing_range_cnt+1...1000, "flushing_key", flush_loop_count-1)
206
+
207
+ puts "\n\s\scaching key"
208
+ check_count(ARGV, 0..caching_range_cnt, "caching_key", cache_loop_count)
209
+ check_count(ARGV, caching_range_cnt+1...1000, "caching_key", cache_loop_count-1) if cache_loop_count != 1
210
+ end
211
+ end
212
+
213
+ def test_round
214
+ n = 0
215
+ 1000.times do |i|
216
+ set_counts(ARGV, 0...10000, i)
217
+ check_count(ARGV, 0...10000, i)
218
+ end
219
+ end
220
+
221
+ param = { :num=>10000, :th=>1 }
222
+
223
+ opts = OptionParser.new
224
+
225
+ opts.on("-r", "--round", "round request"){|v| param[:round] = v }
226
+ opts.on("-c", "--count [x]", "counts of the test times"){|v| param[:count] = v.to_i }
227
+
228
+ opts.banner = "usage:#{File.basename($0)} [options] addr:port"
229
+ opts.parse!(ARGV)
230
+
231
+ if ARGV.length == 0
232
+ STDERR.puts opts.help
233
+ exit
234
+ end
235
+
236
+ if param.key?(:round)
237
+ test_round
238
+ else
239
+ param[:count] = 1 if !param.key?(:count)
240
+
241
+ param[:count].times do |count|
242
+ puts "#{count+1}th test========================================================================================="
243
+ test_change_status
244
+ end
245
+ end
246
+
247
+ puts "#{File.basename($0)} has done."