roma 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +21 -0
- data/Gemfile.lock +47 -0
- data/bin/check_tc_flag +39 -0
- data/bin/roma-adm +43 -0
- data/bin/ssroute +0 -3
- data/lib/roma/async_process.rb +203 -208
- data/lib/roma/command/sys_command_receiver.rb +52 -10
- data/lib/roma/config.rb +3 -0
- data/lib/roma/event/handler.rb +11 -4
- data/lib/roma/event/jaro_winkler.rb +23 -0
- data/lib/roma/event/levenshtein.rb +23 -0
- data/lib/roma/plugin/plugin_cmd_aliases.rb +1 -32
- data/lib/roma/romad.rb +23 -0
- data/lib/roma/routing/cb_rttable.rb +2 -0
- data/lib/roma/routing/random_partitioner.rb +43 -36
- data/lib/roma/routing/rttable.rb +5 -3
- data/lib/roma/stats.rb +4 -1
- data/lib/roma/tools/check_tc_flag.rb +25 -0
- data/lib/roma/tools/cpdb.rb +3 -2
- data/lib/roma/tools/mkconfig.rb +22 -13
- data/lib/roma/tools/roma-adm.rb +82 -0
- data/lib/roma/version.rb +1 -1
- data/test/config4mhash.rb +2 -0
- data/test/config4storage_error.rb +2 -0
- data/test/config4test.rb +2 -0
- data/test/cpdbtest/config4cpdb_base.rb +67 -0
- data/test/cpdbtest/config4cpdb_dbm.rb +9 -0
- data/test/cpdbtest/config4cpdb_groonga.rb +9 -0
- data/test/cpdbtest/config4cpdb_rh.rb +9 -0
- data/test/cpdbtest/config4cpdb_sqlite3.rb +9 -0
- data/test/cpdbtest/config4cpdb_tc.rb +9 -0
- data/test/cpdbtest/config4cpdb_tcmem.rb +9 -0
- data/test/roma-test-utils.rb +140 -40
- data/test/t_cpdata.rb +76 -80
- data/test/t_cpdb.rb +95 -0
- data/test/t_logshift.rb +86 -0
- data/test/t_mhash.rb +56 -54
- data/test/t_routing_logic.rb +121 -0
- data/test/t_writebehind.rb +202 -207
- metadata +25 -8
- data/bin/tc_data_restore.rb +0 -123
@@ -39,19 +39,58 @@ module Roma
|
|
39
39
|
@stop_event_loop = true
|
40
40
|
end
|
41
41
|
|
42
|
-
#
|
43
|
-
def
|
44
|
-
|
45
|
-
|
42
|
+
# shutdown [reason]
|
43
|
+
def ev_shutdown(s)
|
44
|
+
send_data("*** ARE YOU REALLY SURE TO SHUTDOWN? *** (yes/no)\r\n")
|
45
|
+
if gets != "yes\r\n"
|
46
|
+
close_connection_after_writing
|
47
|
+
return
|
48
|
+
end
|
49
|
+
|
50
|
+
if s.length == 2
|
51
|
+
@log.info("Receive a shutdown #{s[1]}")
|
52
|
+
else
|
53
|
+
@log.info("Receive a shutdown command.")
|
54
|
+
end
|
55
|
+
@rttable.enabled_failover = false
|
56
|
+
res = broadcast_cmd("rshutdown\r\n")
|
57
|
+
res[@stats.ap_str] = "BYE"
|
58
|
+
send_data("#{res.inspect}\r\n")
|
59
|
+
close_connection_after_writing
|
60
|
+
@stop_event_loop = true
|
61
|
+
end
|
62
|
+
|
63
|
+
# rshutdown [reason]
|
64
|
+
def ev_rshutdown(s)
|
65
|
+
if s.length == 2
|
66
|
+
@log.info("Receive a rshutdown #{s[1]}")
|
46
67
|
else
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
68
|
+
@log.info("Receive a rshutdown command.")
|
69
|
+
end
|
70
|
+
@rttable.enabled_failover = false
|
71
|
+
send_data("BYE\r\n")
|
72
|
+
close_connection_after_writing
|
73
|
+
@stop_event_loop = true
|
74
|
+
end
|
75
|
+
|
76
|
+
# shutdown_self
|
77
|
+
def ev_shutdown_self(s)
|
78
|
+
if s.length != 1
|
79
|
+
send_data("ERROR: shutdown_instance has irregular argument.\r\n")
|
80
|
+
else
|
81
|
+
send_data("\r\n=================================================================\r\n")
|
82
|
+
send_data("CAUTION!!: \r\n\tThis command kill the instance!\r\n\tThere is some possibility of occuring redundancy down!\r\n")
|
83
|
+
send_data("=================================================================\r\n")
|
84
|
+
send_data("\r\nAre you sure to shutdown this instance?(yes/no)\r\n")
|
85
|
+
if gets != "yes\r\n"
|
51
86
|
close_connection_after_writing
|
52
|
-
|
53
|
-
send_data("invalid [node-id]\r\n")
|
87
|
+
return
|
54
88
|
end
|
89
|
+
@log.info("Receive a shutdown_self command.")
|
90
|
+
@rttable.enabled_failover = false
|
91
|
+
send_data("BYE\r\n")
|
92
|
+
@stop_event_loop = true
|
93
|
+
close_connection_after_writing
|
55
94
|
end
|
56
95
|
end
|
57
96
|
|
@@ -243,6 +282,9 @@ module Roma
|
|
243
282
|
else
|
244
283
|
return send_data("CLIENT_ERROR no match log-level string\r\n")
|
245
284
|
end
|
285
|
+
|
286
|
+
@stats.log_level = s[1].downcase
|
287
|
+
|
246
288
|
send_data("STORED\r\n")
|
247
289
|
end
|
248
290
|
|
data/lib/roma/config.rb
CHANGED
data/lib/roma/event/handler.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
#
|
4
4
|
require 'eventmachine'
|
5
5
|
require 'roma/event/con_pool'
|
6
|
+
require 'roma/event/jaro_winkler'
|
7
|
+
#require 'roma/event/levenshtein'
|
6
8
|
require 'roma/logging/rlogger'
|
7
9
|
require 'roma/stats'
|
8
10
|
require 'roma/storage/basic_storage'
|
@@ -167,10 +169,15 @@ module Roma
|
|
167
169
|
send(@@ev_list[@lastcmd[0].downcase],@lastcmd)
|
168
170
|
next if @@system_commands.key?(@lastcmd[0].downcase)
|
169
171
|
else
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
172
|
+
distance, similar_cmd = Roma::Event::Distance.check_distance(s[0], @@ev_list)
|
173
|
+
if distance < 0.2
|
174
|
+
send_data("\r\nERROR: '#{s[0]}' is not roma command.\r\nDid you mean this?\r\n\t#{similar_cmd}\r\n")
|
175
|
+
next
|
176
|
+
else
|
177
|
+
@log.warn("command error:#{s}")
|
178
|
+
send_data("ERROR: '#{s[0]}' is not roma command. Please check command.\r\n(closing telnet connection command is 'quit')\r\n")
|
179
|
+
next
|
180
|
+
end
|
174
181
|
end
|
175
182
|
|
176
183
|
# hilatency check
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#
|
2
|
+
# File: jaro_winkler.rb
|
3
|
+
#
|
4
|
+
require "jaro_winkler"
|
5
|
+
|
6
|
+
module Roma
|
7
|
+
module Event
|
8
|
+
module Distance
|
9
|
+
def self.check_distance(cmd, ev_list)
|
10
|
+
jaro_winkler_distance = 0.0000 # initialize
|
11
|
+
similar_cmd = ''
|
12
|
+
ev_list.each_key{|ev|
|
13
|
+
distance = JaroWinkler.distance(cmd, ev)
|
14
|
+
if distance > jaro_winkler_distance
|
15
|
+
jaro_winkler_distance = distance
|
16
|
+
similar_cmd = ev
|
17
|
+
end
|
18
|
+
}
|
19
|
+
return (1-jaro_winkler_distance), similar_cmd
|
20
|
+
end
|
21
|
+
end # module Distance
|
22
|
+
end # module Event
|
23
|
+
end # module Roma
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#
|
2
|
+
# File: levenshtein.rb
|
3
|
+
#
|
4
|
+
require "levenshtein"
|
5
|
+
|
6
|
+
module Roma
|
7
|
+
module Event
|
8
|
+
module Distance
|
9
|
+
def self.check_distance(cmd, ev_list)
|
10
|
+
levenshtein_distance = 1.0 # initialize
|
11
|
+
similar_cmd = ''
|
12
|
+
ev_list.each_key{|ev|
|
13
|
+
distance = Levenshtein::normalized_distance(cmd, ev)
|
14
|
+
if distance < levenshtein_distance
|
15
|
+
levenshtein_distance = distance
|
16
|
+
similar_cmd = ev
|
17
|
+
end
|
18
|
+
}
|
19
|
+
return levenshtein_distance, similar_cmd
|
20
|
+
end
|
21
|
+
end # module Distance
|
22
|
+
end # module Event
|
23
|
+
end # module Roma
|
@@ -5,38 +5,7 @@ module Roma
|
|
5
5
|
module PluginCommandAliases
|
6
6
|
include ::Roma::CommandPlugin
|
7
7
|
|
8
|
-
#
|
9
|
-
def ev_shutdown(s)
|
10
|
-
send_data("*** ARE YOU REALLY SURE TO SHUTDOWN? *** (yes/no)\r\n")
|
11
|
-
if gets != "yes\r\n"
|
12
|
-
close_connection_after_writing
|
13
|
-
return
|
14
|
-
end
|
15
|
-
|
16
|
-
if s.length == 2
|
17
|
-
@log.info("Receive a shutdown #{s[1]}")
|
18
|
-
else
|
19
|
-
@log.info("Receive a shutdown command.")
|
20
|
-
end
|
21
|
-
@rttable.enabled_failover = false
|
22
|
-
res = broadcast_cmd("rshutdown\r\n")
|
23
|
-
send_data("#{res.inspect}\r\n")
|
24
|
-
close_connection_after_writing
|
25
|
-
@stop_event_loop = true
|
26
|
-
end
|
27
|
-
|
28
|
-
# rshutdown [reason]
|
29
|
-
def ev_rshutdown(s)
|
30
|
-
if s.length == 2
|
31
|
-
@log.info("Receive a rshutdown #{s[1]}")
|
32
|
-
else
|
33
|
-
@log.info("Receive a rshutdown command.")
|
34
|
-
end
|
35
|
-
@rttable.enabled_failover = false
|
36
|
-
send_data("BYE\r\n")
|
37
|
-
close_connection_after_writing
|
38
|
-
@stop_event_loop = true
|
39
|
-
end
|
8
|
+
# Please add your self if you want.
|
40
9
|
|
41
10
|
end
|
42
11
|
end
|
data/lib/roma/romad.rb
CHANGED
@@ -41,6 +41,26 @@ module Roma
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def start
|
44
|
+
# config version check
|
45
|
+
if !Config.const_defined?(:VERSION)
|
46
|
+
@log.error("ROMA FAIL TO BOOT! : config.rb's version is too old.")
|
47
|
+
exit
|
48
|
+
elsif Config::VERSION != Roma::VERSION
|
49
|
+
if /(\d+)\.(\d+)\.(\d+)/ =~ Config::VERSION
|
50
|
+
version_config = ($1.to_i << 16) + ($2.to_i << 8) + $3.to_i
|
51
|
+
end
|
52
|
+
if /(\d+)\.(\d+)\.(\d+)/ =~ Roma::VERSION
|
53
|
+
version_roma = ($1.to_i << 16) + ($2.to_i << 8) + $3.to_i
|
54
|
+
end
|
55
|
+
|
56
|
+
if version_config == version_roma
|
57
|
+
@log.info("This version is development version.")
|
58
|
+
else
|
59
|
+
@log.error("ROMA FAIL TO BOOT! : config.rb's version is differ from current ROMA version.")
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
44
64
|
if node_check(@stats.ap_str)
|
45
65
|
@log.error("#{@stats.ap_str} is already running.")
|
46
66
|
return
|
@@ -171,6 +191,9 @@ module Roma
|
|
171
191
|
if Config.const_defined?(:LOG_SHIFT_AGE)
|
172
192
|
@stats.log_shift_age = Config::LOG_SHIFT_AGE
|
173
193
|
end
|
194
|
+
if Config.const_defined?(:LOG_LEVEL)
|
195
|
+
@stats.log_level = Config::LOG_LEVEL
|
196
|
+
end
|
174
197
|
end
|
175
198
|
|
176
199
|
def initialize_connection
|
@@ -22,6 +22,7 @@ module Roma
|
|
22
22
|
attr_accessor :event
|
23
23
|
attr_accessor :event_limit_line
|
24
24
|
attr_accessor :logs
|
25
|
+
attr_accessor :enabled_failover
|
25
26
|
attr_reader :version_of_nodes
|
26
27
|
attr_reader :min_version
|
27
28
|
|
@@ -57,6 +58,7 @@ module Roma
|
|
57
58
|
ret['routing.event_limit_line'] = @event_limit_line
|
58
59
|
ret['routing.version_of_nodes'] = @version_of_nodes.inspect
|
59
60
|
ret['routing.min_version'] = @min_version
|
61
|
+
ret['routing.enabled_failover'] = @enabled_failover
|
60
62
|
ret
|
61
63
|
end
|
62
64
|
|
@@ -1,25 +1,23 @@
|
|
1
1
|
module Roma
|
2
2
|
module Routing
|
3
3
|
module RandomPartitioner
|
4
|
-
|
5
4
|
def exclude_nodes(ap_str, rep_host)
|
6
|
-
exclude_nodes =
|
5
|
+
exclude_nodes = nodes
|
7
6
|
if rep_host
|
8
7
|
exclude_nodes = [ap_str]
|
9
8
|
else
|
10
9
|
myhost = ap_str.split(/[:_]/)[0]
|
11
|
-
exclude_nodes.delete_if{|nid| nid.split(/[:_]/)[0] != myhost }
|
10
|
+
exclude_nodes.delete_if { |nid| nid.split(/[:_]/)[0] != myhost }
|
12
11
|
end
|
13
12
|
exclude_nodes
|
14
13
|
end
|
15
|
-
|
16
|
-
def exclude_nodes_for_join(ap_str,
|
14
|
+
|
15
|
+
def exclude_nodes_for_join(ap_str, _rep_host)
|
17
16
|
[ap_str]
|
18
17
|
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
alias :exclude_nodes_for_balance :exclude_nodes
|
19
|
+
alias_method :exclude_nodes_for_recover, :exclude_nodes
|
20
|
+
alias_method :exclude_nodes_for_balance, :exclude_nodes
|
23
21
|
|
24
22
|
def myhost_include?(nodes, myhost)
|
25
23
|
nodes.each do |nid|
|
@@ -30,44 +28,54 @@ module Roma
|
|
30
28
|
private :myhost_include?
|
31
29
|
|
32
30
|
# vnode sampling exclude +exclude_nodes+
|
33
|
-
def select_vn_for_join(exclude_nodes)
|
31
|
+
def select_vn_for_join(exclude_nodes, rep_host)
|
34
32
|
short_idx = {}
|
35
33
|
myhost_idx = {}
|
36
34
|
idx = {}
|
37
35
|
myhost = exclude_nodes[0].split(/[:_]/)[0]
|
36
|
+
|
38
37
|
@rd.v_idx.each_pair do |vn, nids|
|
39
38
|
unless list_include?(nids, exclude_nodes)
|
40
39
|
if myhost_include?(nids, myhost)
|
41
40
|
myhost_idx[vn] = nids
|
42
41
|
else
|
43
|
-
idx[vn] = nids # other
|
42
|
+
idx[vn] = nids # other hosts
|
44
43
|
end
|
45
44
|
short_idx[vn] = nids if nids.length < @rd.rn
|
46
45
|
end
|
47
46
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
|
48
|
+
# vnodes sampling priority:
|
49
|
+
# 1. Short vnodes
|
50
|
+
# 2. Other hosts vnodes
|
51
|
+
# 3. My host vnodes
|
52
|
+
if short_idx.length > 0
|
53
|
+
idx = short_idx
|
54
|
+
elsif idx.length == 0
|
52
55
|
idx = myhost_idx
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
56
|
+
end
|
57
|
+
|
58
|
+
return nil if idx.length == 0
|
59
|
+
|
60
|
+
ks = idx.keys
|
61
|
+
vn = ks[rand(ks.length)]
|
62
|
+
nids = idx[vn]
|
63
|
+
|
64
|
+
if !rep_host && nids[0].split(/[:_]/)[0] == myhost
|
65
|
+
is_primary = true
|
58
66
|
else
|
59
|
-
|
60
|
-
nids = idx[vn]
|
61
|
-
[vn, nids, rand(@rd.rn) == 0]
|
67
|
+
is_primary = rand(@rd.rn) == 0
|
62
68
|
end
|
69
|
+
|
70
|
+
[vn, nids, is_primary]
|
63
71
|
end
|
64
72
|
|
65
73
|
# select a vnodes where short of redundancy.
|
66
|
-
def select_vn_for_recover(exclude_nodes)
|
74
|
+
def select_vn_for_recover(exclude_nodes, _rep_host)
|
67
75
|
ret = []
|
68
76
|
@rd.v_idx.each_pair do |vn, nids|
|
69
|
-
if nids.length < @rd.rn && list_include?(nids,exclude_nodes) == false
|
70
|
-
ret << [vn,nids]
|
77
|
+
if nids.length < @rd.rn && list_include?(nids, exclude_nodes) == false
|
78
|
+
ret << [vn, nids]
|
71
79
|
end
|
72
80
|
end
|
73
81
|
if ret.length == 0
|
@@ -79,27 +87,27 @@ module Roma
|
|
79
87
|
end
|
80
88
|
|
81
89
|
def select_node_for_release(ap_str, rep_host, nids)
|
82
|
-
buf =
|
90
|
+
buf = nodes
|
83
91
|
|
84
92
|
unless rep_host
|
85
93
|
deny_hosts = []
|
86
|
-
nids.each
|
94
|
+
nids.each do |nid|
|
87
95
|
host = nid.split(/[:_]/)[0]
|
88
96
|
deny_hosts << host if host != ap_str.split(/[:_]/)[0]
|
89
|
-
|
90
|
-
buf.delete_if{|nid| deny_hosts.include?(nid.split(/[:_]/)[0])}
|
97
|
+
end
|
98
|
+
buf.delete_if { |nid| deny_hosts.include?(nid.split(/[:_]/)[0]) }
|
91
99
|
else
|
92
|
-
nids.each{|nid| buf.delete(nid) }
|
100
|
+
nids.each { |nid| buf.delete(nid) }
|
93
101
|
end
|
94
|
-
|
95
|
-
buf.delete_if{|instance| instance == ap_str}
|
102
|
+
|
103
|
+
buf.delete_if { |instance| instance == ap_str }
|
96
104
|
to_nid = buf.sample
|
97
|
-
new_nids = nids.map{|n| n == ap_str ? to_nid : n }
|
105
|
+
new_nids = nids.map { |n| n == ap_str ? to_nid : n }
|
98
106
|
[to_nid, new_nids]
|
99
107
|
end
|
100
108
|
|
101
109
|
# vnode sampling exclude +exclude_nodes+
|
102
|
-
def select_vn_for_balance(exclude_nodes)
|
110
|
+
def select_vn_for_balance(exclude_nodes, _rep_host)
|
103
111
|
short_idx = {}
|
104
112
|
idx = {}
|
105
113
|
@rd.v_idx.each_pair do |vn, nids|
|
@@ -109,14 +117,13 @@ module Roma
|
|
109
117
|
end
|
110
118
|
end
|
111
119
|
idx = short_idx if short_idx.length > 0
|
112
|
-
|
120
|
+
|
113
121
|
ks = idx.keys
|
114
122
|
return nil if ks.length == 0
|
115
123
|
vn = ks[rand(ks.length)]
|
116
124
|
nids = idx[vn]
|
117
125
|
[vn, nids, rand(@rd.rn) == 0]
|
118
126
|
end
|
119
|
-
|
120
127
|
end
|
121
128
|
end
|
122
129
|
end
|
data/lib/roma/routing/rttable.rb
CHANGED
@@ -36,7 +36,8 @@ module Roma
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def num_of_vn(ap)
|
39
|
-
pn =
|
39
|
+
pn = short = lost = 0
|
40
|
+
sn = Array.new(@rd.rn - 1, 0)
|
40
41
|
@rd.v_idx.each_pair do |vn, nids|
|
41
42
|
if nids == nil || nids.length == 0
|
42
43
|
lost += 1
|
@@ -44,7 +45,8 @@ module Roma
|
|
44
45
|
elsif nids[0] == ap
|
45
46
|
pn += 1
|
46
47
|
elsif nids.include?(ap)
|
47
|
-
|
48
|
+
i = nids.index(ap) - 1
|
49
|
+
sn[i] += 1
|
48
50
|
end
|
49
51
|
short += 1 if nids.length < @rd.rn
|
50
52
|
end
|
@@ -61,7 +63,7 @@ module Roma
|
|
61
63
|
ret['routing.div_bits'] = @div_bits
|
62
64
|
ret['routing.vnodes.length'] = vnodes.length
|
63
65
|
ret['routing.primary'] = pn
|
64
|
-
ret[
|
66
|
+
(@rn-1).times{|i| ret["routing.secondary#{i+1}"] = sn[i]}
|
65
67
|
ret['routing.short_vnodes'] = short
|
66
68
|
ret['routing.lost_vnodes'] = lost
|
67
69
|
ret['routing.fail_cnt_threshold'] = @fail_cnt_threshold
|
data/lib/roma/stats.rb
CHANGED
@@ -77,9 +77,10 @@ module Roma
|
|
77
77
|
attr_accessor :gui_run_gather_logs
|
78
78
|
attr_accessor :gui_last_snapshot
|
79
79
|
|
80
|
-
# for log
|
80
|
+
# for log
|
81
81
|
attr_accessor :log_shift_size
|
82
82
|
attr_accessor :log_shift_age
|
83
|
+
attr_accessor :log_level
|
83
84
|
|
84
85
|
def initialize
|
85
86
|
@config_path = nil
|
@@ -121,6 +122,7 @@ module Roma
|
|
121
122
|
@routing_trans_timeout = 3600 * 3 # 3hr
|
122
123
|
@log_shift_size = 1048576
|
123
124
|
@log_shift_age = 0
|
125
|
+
@log_level = :debug
|
124
126
|
end
|
125
127
|
|
126
128
|
def ap_str
|
@@ -171,6 +173,7 @@ module Roma
|
|
171
173
|
ret['stats.routing_trans_timeout'] = @routing_trans_timeout
|
172
174
|
ret['stats.log_shift_size'] = @log_shift_size
|
173
175
|
ret['stats.log_shift_age'] = @log_shift_age
|
176
|
+
ret['stats.log_level'] = @log_level
|
174
177
|
ret
|
175
178
|
end
|
176
179
|
|