roma 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|