roma 0.8.14 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +19 -0
- data/ruby/server/lib/roma/async_process.rb +130 -16
- data/ruby/server/lib/roma/command/command_definition.rb +19 -3
- data/ruby/server/lib/roma/command/rt_command_receiver.rb +28 -0
- data/ruby/server/lib/roma/command/sys_command_receiver.rb +64 -2
- data/ruby/server/lib/roma/config.rb +1 -0
- data/ruby/server/lib/roma/plugin/plugin_gui.rb +66 -0
- data/ruby/server/lib/roma/plugin/plugin_storage.rb +49 -6
- data/ruby/server/lib/roma/romad.rb +23 -18
- data/ruby/server/lib/roma/routing/cb_rttable.rb +28 -10
- data/ruby/server/lib/roma/routing/random_partitioner.rb +34 -7
- data/ruby/server/lib/roma/routing/rttable.rb +24 -7
- data/ruby/server/lib/roma/stats.rb +11 -1
- data/ruby/server/lib/roma/storage/basic_storage.rb +36 -31
- data/ruby/server/lib/roma/tools/cpdb.rb +20 -2
- data/ruby/server/lib/roma/tools/safecopy_integration_test.rb +37 -16
- data/ruby/server/lib/roma/version.rb +1 -1
- data/ruby/server/test/t_protocol.rb +1 -1
- data/ruby/server/test/t_storage.rb +28 -21
- data/ruby/server/test/t_writebehind.rb +120 -5
- metadata +19 -18
@@ -13,27 +13,53 @@ module Roma
|
|
13
13
|
exclude_nodes
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
def exclude_nodes_for_join(ap_str, rep_host)
|
17
|
+
[ap_str]
|
18
|
+
end
|
19
|
+
|
20
|
+
#alias :exclude_nodes_for_join :exclude_nodes
|
17
21
|
alias :exclude_nodes_for_recover :exclude_nodes
|
18
22
|
alias :exclude_nodes_for_balance :exclude_nodes
|
19
23
|
|
24
|
+
def myhost_include?(nodes, myhost)
|
25
|
+
nodes.each do |nid|
|
26
|
+
return true if nid.split(/[:_]/)[0] == myhost
|
27
|
+
end
|
28
|
+
false
|
29
|
+
end
|
30
|
+
private :myhost_include?
|
31
|
+
|
20
32
|
# vnode sampling exclude +exclude_nodes+
|
21
33
|
def select_vn_for_join(exclude_nodes)
|
22
34
|
short_idx = {}
|
35
|
+
myhost_idx = {}
|
23
36
|
idx = {}
|
37
|
+
myhost = exclude_nodes[0].split(/[:_]/)[0]
|
24
38
|
@rd.v_idx.each_pair do |vn, nids|
|
25
39
|
unless list_include?(nids, exclude_nodes)
|
26
|
-
|
40
|
+
if myhost_include?(nids, myhost)
|
41
|
+
myhost_idx[vn] = nids
|
42
|
+
else
|
43
|
+
idx[vn] = nids # other nodes
|
44
|
+
end
|
27
45
|
short_idx[vn] = nids if nids.length < @rd.rn
|
28
46
|
end
|
29
47
|
end
|
30
48
|
idx = short_idx if short_idx.length > 0
|
31
49
|
|
32
50
|
ks = idx.keys
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
51
|
+
if ks.length == 0
|
52
|
+
idx = myhost_idx
|
53
|
+
ks = idx.keys
|
54
|
+
return nil if ks.length == 0
|
55
|
+
vn = ks[rand(ks.length)]
|
56
|
+
nids = idx[vn]
|
57
|
+
[vn, nids, nids[0].split(/[:_]/)[0] == myhost]
|
58
|
+
else
|
59
|
+
vn = ks[rand(ks.length)]
|
60
|
+
nids = idx[vn]
|
61
|
+
[vn, nids, rand(@rd.rn) == 0]
|
62
|
+
end
|
37
63
|
end
|
38
64
|
|
39
65
|
# select a vnodes where short of redundancy.
|
@@ -66,7 +92,8 @@ module Roma
|
|
66
92
|
nids.each{|nid| buf.delete(nid) }
|
67
93
|
end
|
68
94
|
|
69
|
-
|
95
|
+
buf.delete_if{|instance| instance == ap_str}
|
96
|
+
to_nid = buf.sample
|
70
97
|
new_nids = nids.map{|n| n == ap_str ? to_nid : n }
|
71
98
|
[to_nid, new_nids]
|
72
99
|
end
|
@@ -35,10 +35,9 @@ module Roma
|
|
35
35
|
init_mtree
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
|
38
|
+
def num_of_vn(ap)
|
40
39
|
pn = sn = short = lost = 0
|
41
|
-
@rd.v_idx.each_pair
|
40
|
+
@rd.v_idx.each_pair do |vn, nids|
|
42
41
|
if nids == nil || nids.length == 0
|
43
42
|
lost += 1
|
44
43
|
next
|
@@ -48,8 +47,12 @@ module Roma
|
|
48
47
|
sn += 1
|
49
48
|
end
|
50
49
|
short += 1 if nids.length < @rd.rn
|
51
|
-
|
50
|
+
end
|
51
|
+
[pn, sn, short, lost]
|
52
|
+
end
|
52
53
|
|
54
|
+
def get_stat(ap)
|
55
|
+
pn, sn, short, lost = num_of_vn(ap)
|
53
56
|
ret = {}
|
54
57
|
ret['routing.redundant'] = @rn
|
55
58
|
ret['routing.nodes.length'] = nodes.length
|
@@ -128,6 +131,20 @@ module Roma
|
|
128
131
|
@rd.dump_binary
|
129
132
|
end
|
130
133
|
|
134
|
+
def check_repetition_in_routing
|
135
|
+
@rd.v_idx.each_value{|value|
|
136
|
+
host = []
|
137
|
+
value.each{|instance|
|
138
|
+
host << instance.split("_")[0]
|
139
|
+
}
|
140
|
+
if host.uniq!
|
141
|
+
return true
|
142
|
+
end
|
143
|
+
}
|
144
|
+
|
145
|
+
false
|
146
|
+
end
|
147
|
+
|
131
148
|
def proc_failed(nid)
|
132
149
|
t = Time.now
|
133
150
|
if t - @fail_time > @fail_cnt_gap
|
@@ -162,7 +179,7 @@ module Roma
|
|
162
179
|
|
163
180
|
def get_replaced_rd(regxp, replace)
|
164
181
|
rd = Marshal.load(dump)
|
165
|
-
|
182
|
+
|
166
183
|
rd.nodes.map! do |nid|
|
167
184
|
nid.sub(regxp, replace)
|
168
185
|
end
|
@@ -174,7 +191,7 @@ module Roma
|
|
174
191
|
end
|
175
192
|
rd
|
176
193
|
end
|
177
|
-
|
194
|
+
|
178
195
|
def check_netmask?(addr, mask)
|
179
196
|
if addr =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/
|
180
197
|
iaddr = ($1.to_i << 24) + ($2.to_i << 16) + ($3.to_i << 8) + $4.to_i
|
@@ -192,7 +209,7 @@ module Roma
|
|
192
209
|
end
|
193
210
|
(iaddr & imask) == (imask_addr & imask)
|
194
211
|
end
|
195
|
-
|
212
|
+
|
196
213
|
end # class RoutingTable
|
197
214
|
|
198
215
|
end # module Routing
|
@@ -71,6 +71,11 @@ module Roma
|
|
71
71
|
|
72
72
|
attr_accessor :routing_trans_timeout
|
73
73
|
|
74
|
+
# for GUI tool
|
75
|
+
attr_accessor :gui_run_snapshot
|
76
|
+
attr_accessor :gui_run_gather_logs
|
77
|
+
attr_accessor :gui_last_snapshot
|
78
|
+
|
74
79
|
def initialize
|
75
80
|
@config_path = nil
|
76
81
|
@run_recover = false
|
@@ -81,7 +86,10 @@ module Roma
|
|
81
86
|
@run_release = false
|
82
87
|
@run_join = false
|
83
88
|
@run_balance = false
|
89
|
+
@gui_run_snapshot = false
|
90
|
+
@gui_run_gather_logs = false
|
84
91
|
@last_clean_up = Time.now
|
92
|
+
@gui_last_snapshot = []
|
85
93
|
@spushv_protection = false
|
86
94
|
@stream_copy_wait_param = 0.0001
|
87
95
|
@dcnice = 3
|
@@ -94,7 +102,7 @@ module Roma
|
|
94
102
|
@out_message_count = 0
|
95
103
|
@redundant_count = 0
|
96
104
|
@size_of_zredundant = 0
|
97
|
-
@hilatency_warn_time = 5
|
105
|
+
@hilatency_warn_time = 5.0
|
98
106
|
@wb_command_map = {}
|
99
107
|
@latency_log = false
|
100
108
|
@latency_check_cmd =["get", "set", "delete"]
|
@@ -128,7 +136,9 @@ module Roma
|
|
128
136
|
ret['stats.run_release'] = @run_release
|
129
137
|
ret['stats.run_join'] = @run_join
|
130
138
|
ret['stats.run_balance'] = @run_balance
|
139
|
+
ret['stats.gui_run_snapshot'] = @gui_run_snapshot
|
131
140
|
ret['stats.last_clean_up'] = @last_clean_up
|
141
|
+
ret['stats.gui_last_snapshot'] = @gui_last_snapshot
|
132
142
|
ret['stats.spushv_protection'] = @spushv_protection
|
133
143
|
ret['stats.stream_copy_wait_param'] = @stream_copy_wait_param
|
134
144
|
ret['stats.dcnice'] = @dcnice
|
@@ -22,6 +22,7 @@ module Roma
|
|
22
22
|
attr_accessor :each_vn_dump_sleep
|
23
23
|
attr_accessor :each_vn_dump_sleep_count
|
24
24
|
attr_accessor :each_clean_up_sleep
|
25
|
+
attr_accessor :cleanup_regexp
|
25
26
|
attr_accessor :logic_clock_expire
|
26
27
|
|
27
28
|
attr_accessor :do_each_vn_dump
|
@@ -34,6 +35,8 @@ module Roma
|
|
34
35
|
# status of a database
|
35
36
|
@dbs = []
|
36
37
|
@log_fd = nil
|
38
|
+
# file number list of a each_vn_dump while
|
39
|
+
@each_vn_dump_vnodes = []
|
37
40
|
|
38
41
|
@hdiv = Hash.new(0)
|
39
42
|
|
@@ -44,6 +47,7 @@ module Roma
|
|
44
47
|
@each_vn_dump_sleep = 0.001
|
45
48
|
@each_vn_dump_sleep_count = 100
|
46
49
|
@each_clean_up_sleep = 0.01
|
50
|
+
@cleanup_regexp = nil
|
47
51
|
@logic_clock_expire = 300
|
48
52
|
|
49
53
|
@each_cache_lock = Mutex::new
|
@@ -58,7 +62,9 @@ module Roma
|
|
58
62
|
ret['storage.option'] = @option
|
59
63
|
ret['storage.each_vn_dump_sleep'] = @each_vn_dump_sleep
|
60
64
|
ret['storage.each_vn_dump_sleep_count'] = @each_vn_dump_sleep_count
|
65
|
+
ret['storage.each_vn_dump_files'] = @each_vn_dump_files.inspect
|
61
66
|
ret['storage.each_clean_up_sleep'] = @each_clean_up_sleep
|
67
|
+
ret['storage.cleanup_regexp'] = @cleanup_regexp
|
62
68
|
ret['storage.logic_clock_expire'] = @logic_clock_expire
|
63
69
|
ret['storage.safecopy_stats'] = @dbs.inspect
|
64
70
|
ret
|
@@ -414,6 +420,12 @@ module Roma
|
|
414
420
|
|
415
421
|
def each_clean_up(t, vnhash)
|
416
422
|
@do_clean_up = true
|
423
|
+
|
424
|
+
f = nil;
|
425
|
+
if @cleanup_regexp && File.exist?(@storage_path)
|
426
|
+
f = open(@storage_path + '/klist.txt','w')
|
427
|
+
end
|
428
|
+
|
417
429
|
return unless @each_clean_up_lock.try_lock
|
418
430
|
nt = Time.now.to_i
|
419
431
|
@divnum.times do |i|
|
@@ -423,6 +435,10 @@ module Roma
|
|
423
435
|
return unless @do_clean_up # 1st check
|
424
436
|
vn, last, clk, expt = unpack_header(v)
|
425
437
|
vn_stat = vnhash[vn]
|
438
|
+
if f && @cleanup_regexp && k =~ /#{@cleanup_regexp}/
|
439
|
+
# write klist
|
440
|
+
f.puts("#{k},#{last},#{clk}") if hdb.get(k) == v
|
441
|
+
end
|
426
442
|
if vn_stat == :primary && ( (expt != 0 && nt > expt) || (expt == 0 && t > last) )
|
427
443
|
if yield k, vn
|
428
444
|
hdb.out(k) if hdb.get(k) == v
|
@@ -437,7 +453,11 @@ module Roma
|
|
437
453
|
end
|
438
454
|
end
|
439
455
|
ensure
|
440
|
-
@each_clean_up_lock.unlock if @each_clean_up_lock.locked?
|
456
|
+
@each_clean_up_lock.unlock if @each_clean_up_lock.locked?
|
457
|
+
if f
|
458
|
+
@cleanup_regexp = nil
|
459
|
+
f.close
|
460
|
+
end
|
441
461
|
end
|
442
462
|
|
443
463
|
def stop_clean_up(&block)
|
@@ -524,42 +544,24 @@ module Roma
|
|
524
544
|
end
|
525
545
|
|
526
546
|
def each_vn_dump(target_vn)
|
527
|
-
@do_each_vn_dump = true
|
528
547
|
n = @hdiv[target_vn]
|
529
|
-
|
530
|
-
|
548
|
+
@stat_lock.synchronize do
|
549
|
+
return false if @dbs[n] != :normal
|
550
|
+
return false if @each_vn_dump_vnodes.include?(target_vn)
|
551
|
+
@each_vn_dump_vnodes << target_vn
|
552
|
+
end
|
553
|
+
|
554
|
+
begin
|
555
|
+
@do_each_vn_dump = true
|
531
556
|
each_unpacked_db(target_vn, @hdb) do |vn, last, clk, expt, k, val|
|
532
557
|
return unless @do_each_vn_dump
|
533
558
|
yield vn_dump_pack(vn, last, clk, expt, k, val)
|
534
559
|
end
|
535
|
-
|
536
|
-
|
537
|
-
@each_cache_lock.synchronize do
|
538
|
-
each_unpacked_db(target_vn, @hdbc) do |cvn, clast, cclk, cexpt, k, cval|
|
539
|
-
return unless @do_each_vn_dump
|
540
|
-
data = @hdb[n].get(k)
|
541
|
-
if data
|
542
|
-
vn, last, clk, expt, val = unpack_data(data)
|
543
|
-
#puts "#{k} #{clk} #{cclk} #{cmp_clk(clk, cclk)} #{val}"
|
544
|
-
if cmp_clk(clk, cclk) > 0
|
545
|
-
yield vn_dump_pack(vn, last, clk, expt, k, val)
|
546
|
-
else
|
547
|
-
yield vn_dump_pack(cvn, clast, cclk, cexpt, k, cval)
|
548
|
-
end
|
549
|
-
else
|
550
|
-
yield vn_dump_pack(cvn, clast, cclk, cexpt, k, cval)
|
551
|
-
end
|
552
|
-
end
|
553
|
-
end
|
554
|
-
each_unpacked_db(target_vn, @hdb) do |vn, last, clk, expt, k, val|
|
555
|
-
return unless @do_each_vn_dump
|
556
|
-
unless @hdbc[n].get(k)
|
557
|
-
yield vn_dump_pack(vn, last, clk, expt, k, val)
|
558
|
-
end
|
559
|
-
end
|
560
|
+
ensure
|
561
|
+
@each_vn_dump_vnodes.delete(target_vn)
|
560
562
|
end
|
561
|
-
|
562
|
-
|
563
|
+
|
564
|
+
true
|
563
565
|
end
|
564
566
|
|
565
567
|
def vn_dump_pack(vn, last, clk, expt, k, val)
|
@@ -674,6 +676,9 @@ module Roma
|
|
674
676
|
@stat_lock.synchronize do
|
675
677
|
case @dbs[dn]
|
676
678
|
when :normal
|
679
|
+
@each_vn_dump_vnodes.each do |vn|
|
680
|
+
return false if dn == @hdiv[vn]
|
681
|
+
end
|
677
682
|
if stat == :safecopy_flushing
|
678
683
|
# open cache
|
679
684
|
@hdbc[dn] = open_db(cache_file_name(dn))
|
@@ -9,6 +9,7 @@ module Roma
|
|
9
9
|
|
10
10
|
def initialize(addr, port)
|
11
11
|
@con = TCPSocket.open(addr, port)
|
12
|
+
set_gui_run_snapshot_status('true')
|
12
13
|
get_storage_info
|
13
14
|
end
|
14
15
|
|
@@ -81,12 +82,24 @@ module Roma
|
|
81
82
|
@con.gets
|
82
83
|
end
|
83
84
|
|
85
|
+
def set_gui_run_snapshot_status(status)
|
86
|
+
@con.puts "set_gui_run_snapshot #{status}\r\n"
|
87
|
+
@con.gets
|
88
|
+
end
|
89
|
+
|
90
|
+
def set_gui_last_snapshot
|
91
|
+
t = Time.now.strftime('%Y/%m/%dT%H:%M:%S')
|
92
|
+
@con.puts "set_gui_last_snapshot #{t}\r\n"
|
93
|
+
@con.gets
|
94
|
+
end
|
95
|
+
|
84
96
|
def stats
|
85
97
|
@con.puts "stat storage\r\n"
|
86
98
|
yield $_ while @con.gets != "END\r\n"
|
87
99
|
end
|
88
100
|
|
89
101
|
def close
|
102
|
+
set_gui_run_snapshot_status('false')
|
90
103
|
@con.close if @con
|
91
104
|
end
|
92
105
|
|
@@ -99,5 +112,10 @@ if ARGV.length < 1
|
|
99
112
|
end
|
100
113
|
|
101
114
|
sc = Roma::SafeCopy.new("localhost", ARGV[0].to_i)
|
102
|
-
|
103
|
-
|
115
|
+
|
116
|
+
begin
|
117
|
+
sc.backup_all
|
118
|
+
sc.set_gui_last_snapshot
|
119
|
+
ensure
|
120
|
+
sc.close
|
121
|
+
end
|
@@ -53,8 +53,16 @@ def set_counts(ini_nodes, range, key_prefix, value)
|
|
53
53
|
range.each do |i|
|
54
54
|
ts = DateTime.now
|
55
55
|
@range_cnt = i
|
56
|
-
res=
|
57
|
-
|
56
|
+
res = nil
|
57
|
+
begin
|
58
|
+
res=rc.set("#{key_prefix}_#{i}","#{value}")
|
59
|
+
raise "set #{key_prefix}_#{i}=#{value} #{res}" if res==nil || res.chomp != 'STORED'
|
60
|
+
rescue => e
|
61
|
+
puts "error:s#{__method__}: #{e}"
|
62
|
+
puts "retry"
|
63
|
+
sleep 0.1
|
64
|
+
retry
|
65
|
+
end
|
58
66
|
t=(DateTime.now - ts).to_f * 86400.0
|
59
67
|
@tmax=t if t > @tmax
|
60
68
|
@tmin=t if t < @tmin
|
@@ -68,7 +76,14 @@ def check_count(ini_nodes, range, key_prefix, value)
|
|
68
76
|
|
69
77
|
range.each do |i|
|
70
78
|
ts = DateTime.now
|
71
|
-
res =
|
79
|
+
res = nil
|
80
|
+
begin
|
81
|
+
res = rc.get("#{key_prefix}_#{i}")
|
82
|
+
rescue => e
|
83
|
+
puts "error: #{e}"
|
84
|
+
sleep 1
|
85
|
+
retry
|
86
|
+
end
|
72
87
|
if res != value.to_s
|
73
88
|
puts "error k=#{key_prefix}_#{i} #{res}"
|
74
89
|
end
|
@@ -116,7 +131,15 @@ def safecopy_stats(nid)
|
|
116
131
|
end
|
117
132
|
|
118
133
|
def set_storage_status(nid, fno, stat)
|
119
|
-
|
134
|
+
cnt = 0
|
135
|
+
begin
|
136
|
+
res = send_cmd(ARGV[0], "set_storage_status #{fno} #{stat}")
|
137
|
+
res.chomp! if res
|
138
|
+
puts res if cnt > 0
|
139
|
+
sleep 0.5
|
140
|
+
cnt += 1
|
141
|
+
end while res != 'PUSHED'
|
142
|
+
res
|
120
143
|
end
|
121
144
|
|
122
145
|
def wait_status(nid, fno, stat)
|
@@ -140,7 +163,7 @@ def test_change_status
|
|
140
163
|
sleep(5)
|
141
164
|
|
142
165
|
10.times do |n|
|
143
|
-
puts "\n#{n+1}th loop(#{n}.tc)
|
166
|
+
puts "\n#{n+1}th loop(#{n}.tc) " + "*" * 70
|
144
167
|
|
145
168
|
#========================================================================================
|
146
169
|
#flushing(normal => safecopy_flushed)
|
@@ -155,11 +178,9 @@ def test_change_status
|
|
155
178
|
@flag = true
|
156
179
|
}
|
157
180
|
}
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
puts "\s\s[debug]sleep flushing end"
|
162
|
-
end
|
181
|
+
puts "\s\s[debug]sleep flushing start"
|
182
|
+
sleep(1) while !@flag
|
183
|
+
puts "\s\s[debug]sleep flushing end"
|
163
184
|
puts "\s\s#{set_storage_status(nid, n, 'safecopy')}"
|
164
185
|
puts "#{wait_status(nid, n, :safecopy_flushed)}"
|
165
186
|
|
@@ -167,6 +188,7 @@ def test_change_status
|
|
167
188
|
t.kill
|
168
189
|
|
169
190
|
flushing_range_cnt = @range_cnt
|
191
|
+
puts "flushing_range_cnt = #{@range_cnt}"
|
170
192
|
puts "\s\s#{safecopy_stats(nid)}\n\n"
|
171
193
|
|
172
194
|
#========================================================================================
|
@@ -182,11 +204,9 @@ def test_change_status
|
|
182
204
|
@flag = true
|
183
205
|
}
|
184
206
|
}
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
puts "\s\s[debug]sleep caching end"
|
189
|
-
end
|
207
|
+
puts "\s\s[debug]sleep caching start"
|
208
|
+
sleep(1) while !@flag
|
209
|
+
puts "\s\s[debug]sleep caching end"
|
190
210
|
|
191
211
|
puts "\s\s#{set_storage_status(nid, n, 'normal')}"
|
192
212
|
puts "#{wait_status(nid, n, :normal)}"
|
@@ -195,6 +215,7 @@ def test_change_status
|
|
195
215
|
t.kill
|
196
216
|
|
197
217
|
caching_range_cnt = @range_cnt
|
218
|
+
puts "caching_range_cnt = #{@range_cnt}"
|
198
219
|
puts "\s\s#{safecopy_stats(nid)}"
|
199
220
|
|
200
221
|
#========================================================================================
|
@@ -239,7 +260,7 @@ else
|
|
239
260
|
param[:count] = 1 if !param.key?(:count)
|
240
261
|
|
241
262
|
param[:count].times do |count|
|
242
|
-
puts "#{count+1}th test
|
263
|
+
puts "#{count+1}th test " + "=" * 70
|
243
264
|
test_change_status
|
244
265
|
end
|
245
266
|
end
|