flare-tools 0.1.4 → 0.4.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/.gemtest +0 -0
  2. data/Flare-tools.txt +0 -0
  3. data/History.txt +114 -2
  4. data/LICENSE +21 -0
  5. data/Manifest.txt +65 -8
  6. data/README.txt +356 -0
  7. data/Rakefile +90 -25
  8. data/Tutorial.txt +370 -0
  9. data/bin/flare-admin +6 -0
  10. data/bin/flare-argv0 +6 -0
  11. data/bin/flare-deploy +6 -0
  12. data/bin/flare-keychecker +6 -0
  13. data/bin/flare-part +6 -0
  14. data/bin/flare-ping +6 -0
  15. data/bin/flare-stats +4 -10
  16. data/bin/flare-zkadmin +6 -0
  17. data/lib/flare/net/connection.rb +98 -0
  18. data/lib/flare/test/cluster.rb +140 -0
  19. data/lib/flare/test/daemon.rb +144 -0
  20. data/lib/flare/test/node.rb +62 -0
  21. data/lib/flare/tools.rb +18 -16
  22. data/lib/flare/tools/cli.rb +32 -0
  23. data/lib/flare/tools/cli/activate.rb +106 -0
  24. data/lib/flare/tools/cli/balance.rb +83 -0
  25. data/lib/flare/tools/cli/cli_util.rb +77 -0
  26. data/lib/flare/tools/cli/deploy.rb +170 -0
  27. data/lib/flare/tools/cli/down.rb +85 -0
  28. data/lib/flare/tools/cli/dump.rb +219 -0
  29. data/lib/flare/tools/cli/dumpkey.rb +117 -0
  30. data/lib/flare/tools/cli/flare_admin.rb +81 -0
  31. data/lib/flare/tools/cli/flare_argv0.rb +60 -0
  32. data/lib/flare/tools/cli/flare_keychecker.rb +106 -0
  33. data/lib/flare/tools/cli/flare_zkadmin.rb +226 -0
  34. data/lib/flare/tools/cli/index.rb +54 -0
  35. data/lib/flare/tools/cli/list.rb +93 -0
  36. data/lib/flare/tools/cli/master.rb +143 -0
  37. data/lib/flare/tools/cli/part.rb +100 -0
  38. data/lib/flare/tools/cli/ping.rb +81 -0
  39. data/lib/flare/tools/cli/reconstruct.rb +164 -0
  40. data/lib/flare/tools/cli/remove.rb +119 -0
  41. data/lib/flare/tools/cli/restore.rb +180 -0
  42. data/lib/flare/tools/cli/slave.rb +125 -0
  43. data/lib/flare/tools/cli/stats.rb +229 -122
  44. data/lib/flare/tools/cli/sub_command.rb +73 -0
  45. data/lib/flare/tools/cli/summary.rb +97 -0
  46. data/lib/flare/tools/cli/threads.rb +78 -0
  47. data/lib/flare/tools/cli/verify.rb +202 -0
  48. data/lib/flare/tools/client.rb +267 -0
  49. data/lib/flare/tools/cluster.rb +319 -0
  50. data/lib/flare/tools/common.rb +196 -0
  51. data/lib/flare/tools/index_server.rb +51 -0
  52. data/lib/flare/tools/node.rb +162 -0
  53. data/lib/flare/tools/stats.rb +75 -0
  54. data/lib/flare/tools/zk_util.rb +28 -0
  55. data/lib/flare/util.rb +34 -0
  56. data/lib/flare/util/bwlimit.rb +132 -0
  57. data/lib/flare/util/command_line.rb +79 -0
  58. data/lib/flare/util/conf.rb +71 -0
  59. data/lib/flare/util/constant.rb +25 -0
  60. data/lib/flare/util/conversion.rb +26 -0
  61. data/lib/flare/util/default_logger.rb +52 -0
  62. data/lib/flare/util/exception.rb +19 -0
  63. data/lib/flare/util/filesystem.rb +30 -0
  64. data/lib/flare/util/flared_conf.rb +33 -0
  65. data/lib/flare/util/flarei_conf.rb +32 -0
  66. data/lib/flare/util/hash_function.rb +32 -0
  67. data/lib/flare/util/interruption.rb +70 -0
  68. data/lib/flare/util/key_resolver.rb +67 -0
  69. data/lib/flare/util/log4r_logger.rb +79 -0
  70. data/lib/flare/util/logger.rb +40 -0
  71. data/lib/flare/util/logging.rb +84 -0
  72. data/lib/flare/util/result.rb +53 -0
  73. data/test/test/experimental/cache_test.rb +113 -0
  74. data/test/test/experimental/key_distribution_test.rb +38 -0
  75. data/test/test/experimental/keychecker_test.rb +60 -0
  76. data/test/test/experimental/list_test.rb +108 -0
  77. data/test/test/extra/replication_test.rb +184 -0
  78. data/test/test/integration/cli_test.rb +348 -0
  79. data/test/test/integration/dump_expired_test.rb +103 -0
  80. data/test/test/integration/dump_test.rb +128 -0
  81. data/test/test/integration/index_server_test.rb +35 -0
  82. data/test/test/integration/node_test.rb +78 -0
  83. data/test/test/integration/partition_test.rb +235 -0
  84. data/test/test/integration/proxy_test.rb +54 -0
  85. data/test/test/integration/stats_test.rb +79 -0
  86. data/test/test/system/flare_admin_test.rb +191 -0
  87. data/test/test/unit/bwlimit_test.rb +52 -0
  88. data/test/test/unit/cluster_test.rb +96 -0
  89. data/test/test/unit/daemon_test.rb +30 -0
  90. data/test/test/unit/logger_test.rb +46 -0
  91. data/test/test/unit/tools_test.rb +25 -0
  92. data/test/test/unit/util_test.rb +70 -0
  93. metadata +239 -84
  94. data/README.rdoc +0 -83
  95. data/bin/flare-partition-setting +0 -12
  96. data/lib/flare/tools/cli/partition_setting.rb +0 -86
  97. data/lib/flare/tools/core.rb +0 -189
  98. data/lib/flare/tools/logger.rb +0 -31
  99. data/test/test_flare-tools.rb +0 -11
  100. data/test/test_helper.rb +0 -3
@@ -0,0 +1,73 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
3
+ # Copyright:: Copyright (C) GREE, Inc. 2011.
4
+ # License:: MIT-style
5
+
6
+ require 'flare/util/logging'
7
+ require 'flare/util/interruption'
8
+
9
+ module Flare
10
+ module Tools
11
+ module Cli
12
+ class SubCommand
13
+ @@myname = {}
14
+ @@desc = {}
15
+ @@usage = {}
16
+
17
+ S_OK = 0
18
+ S_NG = 1
19
+
20
+ def self.to_sym
21
+ myname
22
+ end
23
+
24
+ def self.myname(myname = nil)
25
+ if myname.nil? then @@myname[name] else @@myname[name] = myname end
26
+ end
27
+
28
+ def self.usage(usage = nil)
29
+ if usage.nil?
30
+ @@usage[name] = "" unless @@usage.has_key?(name)
31
+ @@usage[name]
32
+ else
33
+ @@usage[name] = usage
34
+ end
35
+ end
36
+
37
+ def self.desc(desc = nil)
38
+ if desc.nil?
39
+ @@desc[name] = "" unless @@desc.has_key?(name)
40
+ @@desc[name]
41
+ else
42
+ @@desc[name] = desc
43
+ end
44
+ end
45
+
46
+ def myname
47
+ myname = @@myname[self.class.name]
48
+ if myname.nil? then "" else myname end
49
+ end
50
+
51
+ def self.to_s
52
+ self.to_sym.to_s
53
+ end
54
+
55
+ def initalize
56
+ end
57
+
58
+ def setup(opt)
59
+ raise "setup"
60
+ end
61
+
62
+ def execute(config, *args)
63
+ raise "execute"
64
+ end
65
+
66
+ include Flare::Util::Logging
67
+ include Flare::Util::Interruption
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+
@@ -0,0 +1,97 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
3
+ # Copyright:: Copyright (C) GREE, Inc. 2011.
4
+ # License:: MIT-style
5
+
6
+ require 'thread'
7
+ require 'flare/tools/index_server'
8
+ require 'flare/tools/cli/sub_command'
9
+ require 'flare/tools/common'
10
+ require 'flare/util/conversion'
11
+
12
+ #
13
+ module Flare
14
+ module Tools
15
+ module Cli
16
+
17
+ # == Description
18
+ #
19
+ class Summary < SubCommand
20
+ include Flare::Util::Conversion
21
+ include Flare::Util::Logging
22
+ include Flare::Tools::Common
23
+
24
+ myname :summary
25
+ desc "show the summary of a flare cluster."
26
+ usage "summary [hostname:port] ..."
27
+
28
+ HeaderConfig = [ ['%-30.30s', '#cluster'],
29
+ ['%6s', 'part'],
30
+ ['%6s', 'node'],
31
+ ['%7s', 'master'],
32
+ ['%6s', 'slave'],
33
+ ['%16s', 'size'],
34
+ ['%13s', 'items'] ]
35
+
36
+ def setup(opt)
37
+ end
38
+
39
+ def initialize
40
+ super
41
+ end
42
+
43
+ def execute(config, *args)
44
+ nodes = {}
45
+ threads = {}
46
+ header = HeaderConfig
47
+
48
+ Flare::Tools::IndexServer.open(config[:index_server_hostname], config[:index_server_port], config[:timeout]) do |s|
49
+ nodes = s.stats_nodes
50
+ unless nodes
51
+ error "Invalid index server."
52
+ return S_NG
53
+ end
54
+ nodes = nodes.sort_by{|key,val| [val['partition'].to_i, val['role'], key]}
55
+ end
56
+
57
+ name = if config[:cluster].nil? then
58
+ "#{config[:index_server_hostname]}:#{config[:index_server_port]}"
59
+ else
60
+ config[:cluster]
61
+ end
62
+
63
+ total_bytes = 0
64
+ total_parts = 0
65
+ total_nodes = 0
66
+ total_items = 0
67
+ total_masters = 0
68
+ total_slaves = 0
69
+
70
+ nodes.each do |hostname_port,data|
71
+ hostname, port = hostname_port.split(":", 2)
72
+ Flare::Tools::Stats.open(hostname, data['port'], config[:timeout]) do |s|
73
+ stats = s.stats
74
+ p = data['partition'].to_i
75
+ total_parts = p+1 if p+1 > total_parts if data['role'] == 'master'
76
+ total_nodes += 1
77
+ total_masters += 1 if data['role'] == 'master'
78
+ total_slaves += 1 if data['role'] == 'slave'
79
+ total_bytes += stats['bytes'].to_i if data['role'] == 'master'
80
+ total_items += stats['curr_items'].to_i if data['role'] == 'master'
81
+ end
82
+ end
83
+
84
+ format = header.map {|x| x[0]}.join(@delimiter)
85
+ label = format % header.map{|x| x[1]}.flatten
86
+ puts label
87
+ puts(format % [name, total_parts, total_nodes, total_masters, total_slaves, total_bytes, total_items])
88
+
89
+ S_OK
90
+ end
91
+
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+
@@ -0,0 +1,78 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
3
+ # Copyright:: Copyright (C) GREE, Inc. 2011.
4
+ # License:: MIT-style
5
+
6
+ require 'flare/tools/index_server'
7
+ require 'flare/util/conversion'
8
+ require 'flare/tools/common'
9
+ require 'flare/tools/cli/sub_command'
10
+
11
+ module Flare
12
+ module Tools
13
+ module Cli
14
+ class Threads < SubCommand
15
+ include Flare::Util::Conversion
16
+ include Flare::Tools::Common
17
+
18
+ myname :threads
19
+ desc "show the list of threads in a flare cluster."
20
+ usage "threads [hostname:port]"
21
+
22
+ def setup(opt)
23
+ end
24
+
25
+ def initialize
26
+ end
27
+
28
+ def execute(config, *args)
29
+ header = [
30
+ ['%5s', 'id'],
31
+ ['%-32s', 'peer'],
32
+ ['%-13s', 'operation'],
33
+ ['%4s', 'type'],
34
+ ['%8s', 'queue']
35
+ ]
36
+ format = header.map {|x| x[0]}.join(' ')
37
+
38
+ hostname = config[:index_server_hostname]
39
+ port = config[:index_server_port]
40
+
41
+ if args.size == 1
42
+ nodekey = nodekey_of args[0]
43
+ if nodekey.nil?
44
+ error "invalid nodekey: "+args[0]
45
+ return S_NG
46
+ end
47
+ hostname, port = nodekey.split(':')
48
+ elsif args.size > 1
49
+ error "invalid arguments: "+args.join(' ')
50
+ return S_NG
51
+ end
52
+
53
+ threads = []
54
+
55
+ Flare::Tools::Stats.open(hostname, port, config[:timeout]) do |s|
56
+ threads = s.stats_threads
57
+ threads = threads.sort_by{|key,val| [val['peer'], key]}
58
+ end
59
+
60
+ puts format % header.map{|x| x[1]}.flatten
61
+
62
+ threads.each do |thread_id, data|
63
+ puts format % [
64
+ thread_id,
65
+ data['peer'],
66
+ if data['op'].nil? then "-" else data['op'] end,
67
+ data['type'],
68
+ data['queue'],
69
+ ]
70
+ end
71
+
72
+ S_OK
73
+ end
74
+
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,202 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
3
+ # Copyright:: Copyright (C) GREE, Inc. 2011.
4
+ # License:: MIT-style
5
+
6
+ require 'flare/tools/index_server'
7
+ require 'flare/tools/node'
8
+ require 'flare/util/conversion'
9
+ require 'flare/util/key_resolver'
10
+ require 'flare/util/hash_function'
11
+ require 'flare/tools/cli/sub_command'
12
+ require 'digest/md5'
13
+
14
+
15
+ #
16
+ module Flare
17
+ module Tools
18
+ module Cli
19
+
20
+ # == Description
21
+ #
22
+ class Verify < SubCommand
23
+ include Flare::Util::Conversion
24
+ include Flare::Util::HashFunction
25
+
26
+ myname :verify
27
+ desc "verify the cluster. (experimental)"
28
+ usage "verify"
29
+
30
+ def setup(opt)
31
+ opt.on('--key-hash-algorithm=TYPE', "key hash algorithm") do |v|
32
+ case @key_hash_algorithm = v.to_sym
33
+ when :simple, :crc32
34
+ else
35
+ puts "unknown type: #{v}"
36
+ exit
37
+ end
38
+ end
39
+ opt.on('--use-test-data', "store test data") {|v| @use_test_data = true}
40
+ opt.on('--debug', "use debug mode") {|v| @debug = true}
41
+ opt.on('--64bit', "(experimental) 64bit mode") {|v| @word_size = 64}
42
+ opt.on('--verbose', "use verbose mode") {|v| @verbose = true}
43
+ opt.on('--meta', "use meta command") {|v| @meta = true}
44
+ opt.on('--quiet', "use quiet mode") {|v| @quiet = true}
45
+ end
46
+
47
+ def initialize
48
+ super
49
+ @numeric_hosts = false
50
+ @key_hash_algorithm = :simple
51
+ @use_test_data = false
52
+ @debug = false
53
+ @word_size = 32
54
+ @bwlimit = 0
55
+ @verbose = false
56
+ @meta = false
57
+ @quiet = false
58
+ end
59
+
60
+ def execute(config, *args)
61
+ keys = {}
62
+ cout = STDERR
63
+ status = S_OK
64
+ info "connecting to index ..."
65
+ Flare::Tools::IndexServer.open(config[:index_server_hostname], config[:index_server_port], config[:timeout]) do |s|
66
+ nodes = s.stats_nodes.sort_by{|key, val| [val['partition'].to_i, val['role'], key]}
67
+
68
+ # meta
69
+ info "setting up key resolver ..."
70
+ resolver = nil
71
+ if @meta
72
+ meta = s.meta
73
+ stats = s.stats
74
+ kha = meta['key-hash-algorithm']
75
+ if kha
76
+ @key_hash_algorithm = :crc32 if kha == 'crc32'
77
+ @key_hash_algorithm = :simple if kha == 'simple'
78
+ else
79
+ @key_hash_algorithm = :simple
80
+ end
81
+ pointer_size = stats['pointer_size']
82
+ option = {
83
+ :partition_size => meta['partition-size'].to_i,
84
+ :virtual => meta['partition-modular-virtual'].to_i,
85
+ :hint => meta['partition-modular-hint'].to_i
86
+ }
87
+ resolver = Util::KeyResolver.new(:modular, option)
88
+ else
89
+ resolver = Util::KeyResolver.new
90
+ end
91
+ info "key_hash_algorithm = #{@key_hash_algorithm.to_s}"
92
+
93
+ # check node list size
94
+ if nodes.size == 0
95
+ cout.puts "no nodes"
96
+ return S_NG
97
+ end
98
+ hostname0, port0 = nodes[0][0].split(":", 2)
99
+
100
+ # partition size
101
+ partition_size = 1+nodes.inject(-1) do |r,entry|
102
+ node, val = entry
103
+ i = val['partition'].to_i
104
+ if i >= r then i else r end
105
+ end
106
+ if partition_size <= 0
107
+ info "no need to verify."
108
+ return S_NG
109
+ end
110
+ info "partition_size: #{partition_size}"
111
+
112
+ if @use_test_data
113
+ info "storing test data ..."
114
+ Flare::Tools::Node.open(hostname0, port0.to_i, config[:timeout]) do |n|
115
+ (1..10000).each do |i|
116
+ key = ".test."+Digest::MD5.new.update(i.to_s).to_s
117
+ n.set(key, i.to_s)
118
+ keys[key] = :not_found
119
+ end
120
+ end
121
+ end
122
+
123
+ nodes.each do |nodekey,val|
124
+ hostname, port = nodekey.split(":", 2)
125
+ partition = val['partition'].to_i
126
+ Flare::Tools::Node.open(hostname, port.to_i, config[:timeout]) do |n|
127
+ cout.write "checking #{nodekey} ... "
128
+ msg = "OK"
129
+ interruptible do
130
+ count = 0
131
+ cout.write "keydump ... "
132
+ n.dumpkey(partition, partition_size) do |key|
133
+ next if key.nil?
134
+ type = @key_hash_algorithm
135
+ hash = get_key_hash_value(key, type, @word_size)
136
+ p = resolver.resolve(hash, partition_size)
137
+ count += 1
138
+ if p != partition then
139
+ cout.puts "keydump failed: the partition for #{key}(#{hash}) is #{p} but it was dumpped from #{partition}." if @debug
140
+ status = S_NG
141
+ msg = "NG"
142
+ else
143
+ keys[key] = :found
144
+ end
145
+ false
146
+ end
147
+ cout.write "#{count} entries. "
148
+ count = 0
149
+ cout.write "dump ... "
150
+ n.dump(0, partition, partition_size, @bwlimit) do |data, key, flag, len, version, expire|
151
+ next if key.nil?
152
+ type = @key_hash_algorithm
153
+ hash = get_key_hash_value(key, type, @word_size)
154
+ p = resolver.resolve(hash, partition_size)
155
+ count += 1
156
+ if p != partition then
157
+ cout.puts "dump failed: the partition for #{key}(#{hash}) is #{p} but it was dumpped from #{partition}." if @debug
158
+ status = S_NG
159
+ msg = "NG"
160
+ end
161
+ false
162
+ end
163
+ cout.write "#{count} entries. "
164
+ end # interruptible
165
+ cout.write "#{msg}\n"
166
+ end # Node.open
167
+ end # nodes.each
168
+
169
+ if @use_test_data && keys.size > 0
170
+ # check total result
171
+ remain = 0
172
+ keys.each do |k,state|
173
+ if state != :found
174
+ error "failed: not found '#{k}'" if @verbose
175
+ remain += 1
176
+ end
177
+ end
178
+ error "failed: not found #{remain} keys" if remain > 0
179
+
180
+ # delete
181
+ Flare::Tools::Node.open(hostname0, port0.to_i, config[:timeout]) do |n|
182
+ keys.each do |k,v|
183
+ n.delete(k)
184
+ end
185
+ end
186
+ end
187
+
188
+ # end of connection
189
+ end
190
+ if status == S_OK
191
+ cout.puts "OK"
192
+ else
193
+ cout.puts "NG"
194
+ end
195
+ status
196
+ end
197
+
198
+ end
199
+ end
200
+ end
201
+ end
202
+