HBASE-22735 list_regions show basic info for region currently in transition with error handling

Signed-off-by: Andrew Purtell <apurtell@apache.org>
Signed-off-by: Michael Stack <stack@apache.org>
This commit is contained in:
Viraj Jasani 2019-07-29 00:29:59 +05:30 committed by Andrew Purtell
parent 44f2d6e34f
commit ac807d7fe5
No known key found for this signature in database
GPG Key ID: 8597754DD5365CCD
1 changed files with 112 additions and 95 deletions

View File

@ -21,15 +21,13 @@ module Shell
module Commands
class ListRegions < Command
def help
return<<EOF
return <<EOF
List all regions for a particular table as an array and also filter them by server name (optional) as prefix
and maximum locality (optional). By default, it will return all the regions for the table with any locality.
The command displays server name, region name, start key, end key, size of the region in MB, number of requests
and the locality. The information can be projected out via an array as third parameter. By default all these information
is displayed. Possible array values are SERVER_NAME, REGION_NAME, START_KEY, END_KEY, SIZE, REQ and LOCALITY. Values
are not case sensitive. If you don't want to filter by server name, pass an empty hash / string as shown below.
Examples:
hbase> list_regions 'table_name'
hbase> list_regions 'table_name', 'server_name'
@ -37,39 +35,37 @@ module Shell
hbase> list_regions 'table_name', {SERVER_NAME => 'server_name', LOCALITY_THRESHOLD => 0.8}, ['SERVER_NAME']
hbase> list_regions 'table_name', {}, ['SERVER_NAME', 'start_key']
hbase> list_regions 'table_name', '', ['SERVER_NAME', 'start_key']
EOF
return
nil
end
def command(table_name, options = nil, cols = nil)
if options.nil?
options = {}
elsif not options.is_a? Hash
elsif !options.is_a? Hash
# When options isn't a hash, assume it's the server name
# and create the hash internally
options = {SERVER_NAME => options}
options = { SERVER_NAME => options }
end
size_hash = Hash.new
raise "Table #{table_name} must be enabled." unless admin.enabled?(table_name)
size_hash = {}
if cols.nil?
size_hash = { "SERVER_NAME" => 12, "REGION_NAME" => 12, "START_KEY" => 10, "END_KEY" => 10, "SIZE" => 5, "REQ" => 5, "LOCALITY" => 10 }
size_hash = { 'SERVER_NAME' => 12, 'REGION_NAME' => 12, 'START_KEY' => 10, 'END_KEY' => 10, 'SIZE' => 5, 'REQ' => 5, 'LOCALITY' => 10 }
elsif cols.is_a?(Array)
cols.each do |col|
if col.upcase.eql?("SERVER_NAME")
size_hash.store("SERVER_NAME", 12)
elsif col.upcase.eql?("REGION_NAME")
size_hash.store("REGION_NAME", 12)
elsif col.upcase.eql?("START_KEY")
size_hash.store("START_KEY", 10)
elsif col.upcase.eql?("END_KEY")
size_hash.store("END_KEY", 10)
elsif col.upcase.eql?("SIZE")
size_hash.store("SIZE", 5)
elsif col.upcase.eql?("REQ")
size_hash.store("REQ", 5)
elsif col.upcase.eql?("LOCALITY")
size_hash.store("LOCALITY", 10)
if col.casecmp('SERVER_NAME').zero?
size_hash.store('SERVER_NAME', 12)
elsif col.casecmp('REGION_NAME').zero?
size_hash.store('REGION_NAME', 12)
elsif col.casecmp('START_KEY').zero?
size_hash.store('START_KEY', 10)
elsif col.casecmp('END_KEY').zero?
size_hash.store('END_KEY', 10)
elsif col.casecmp('SIZE').zero?
size_hash.store('SIZE', 5)
elsif col.casecmp('REQ').zero?
size_hash.store('REQ', 5)
elsif col.casecmp('LOCALITY').zero?
size_hash.store('LOCALITY', 10)
else
raise "#{col} is not a valid column. Possible values are SERVER_NAME, REGION_NAME, START_KEY, END_KEY, SIZE, REQ, LOCALITY."
end
@ -77,22 +73,20 @@ EOF
else
raise "#{cols} must be an array of strings. Possible values are SERVER_NAME, REGION_NAME, START_KEY, END_KEY, SIZE, REQ, LOCALITY."
end
admin_instance = admin.instance_variable_get("@admin")
conn_instance = admin_instance.getConnection()
cluster_status = admin_instance.getClusterStatus()
admin_instance = admin.instance_variable_get('@admin')
conn_instance = admin_instance.getConnection
cluster_status = admin_instance.getClusterStatus
hregion_locator_instance = conn_instance.getRegionLocator(TableName.valueOf(table_name))
hregion_locator_list = hregion_locator_instance.getAllRegionLocations().to_a
results = Array.new
hregion_locator_list = hregion_locator_instance.getAllRegionLocations.to_a
results = []
desired_server_name = options[SERVER_NAME]
begin
# Filter out region servers which we don't want, default to all RS
regions = get_regions_for_table_and_server(table_name, conn_instance, desired_server_name)
# A locality threshold of "1.0" would be all regions (cannot have greater than 1 locality)
# Regions which have a `dataLocality` less-than-or-equal to this value are accepted
locality_threshold = 1.0
if options.has_key? LOCALITY_THRESHOLD
if options.key? LOCALITY_THRESHOLD
value = options[LOCALITY_THRESHOLD]
# Value validation. Must be a Float, and must be between [0, 1.0]
raise "#{LOCALITY_THRESHOLD} must be a float value" unless value.is_a? Float
@ -101,88 +95,111 @@ EOF
end
regions.each do |hregion|
hregion_info = hregion.getRegionInfo()
server_name = hregion.getServerName()
region_load_map = cluster_status.getLoad(server_name).getRegionsLoad()
region_load = region_load_map.get(hregion_info.getRegionName())
# Ignore regions which exceed our locality threshold
if accept_region_for_locality? region_load.getDataLocality(), locality_threshold
result_hash = Hash.new
if size_hash.key?("SERVER_NAME")
result_hash.store("SERVER_NAME", server_name.toString().strip)
size_hash["SERVER_NAME"] = [size_hash["SERVER_NAME"], server_name.toString().strip.length].max
end
if size_hash.key?("REGION_NAME")
result_hash.store("REGION_NAME", hregion_info.getRegionNameAsString().strip)
size_hash["REGION_NAME"] = [size_hash["REGION_NAME"], hregion_info.getRegionNameAsString().length].max
end
if size_hash.key?("START_KEY")
startKey = Bytes.toStringBinary(hregion_info.getStartKey()).strip
result_hash.store("START_KEY", startKey)
size_hash["START_KEY"] = [size_hash["START_KEY"], startKey.length].max
end
if size_hash.key?("END_KEY")
endKey = Bytes.toStringBinary(hregion_info.getEndKey()).strip
result_hash.store("END_KEY", endKey)
size_hash["END_KEY"] = [size_hash["END_KEY"], endKey.length].max
end
if size_hash.key?("SIZE")
region_store_file_size = region_load.getStorefileSizeMB().to_s.strip
result_hash.store("SIZE", region_store_file_size)
size_hash["SIZE"] = [size_hash["SIZE"], region_store_file_size.length].max
end
if size_hash.key?("REQ")
region_requests = region_load.getRequestsCount().to_s.strip
result_hash.store("REQ", region_requests)
size_hash["REQ"] = [size_hash["REQ"], region_requests.length].max
end
if size_hash.key?("LOCALITY")
locality = region_load.getDataLocality().to_s.strip
result_hash.store("LOCALITY", locality)
size_hash["LOCALITY"] = [size_hash["LOCALITY"], locality.length].max
end
results << result_hash
hregion_info = hregion.getRegionInfo
server_name = hregion.getServerName
server_load = cluster_status.getLoad(server_name)
if server_load.nil?
region_load_map = java.util.HashMap.new
else
region_load_map = server_load.getRegionsLoad
end
region_name = hregion_info.getRegionNameAsString
region_load = region_load_map.get(hregion_info.getRegionName)
if region_load.nil?
puts "Can not find all details for region: " \
"#{region_name.strip} ," \
" it may be disabled or in transition\n"
else
# Ignore regions which exceed our locality threshold
next unless accept_region_for_locality? region_load.getDataLocality,
locality_threshold
end
result_hash = {}
if size_hash.key?('SERVER_NAME')
result_hash.store('SERVER_NAME', server_name.toString.strip)
size_hash['SERVER_NAME'] = [size_hash['SERVER_NAME'], server_name.toString.strip.length].max
end
if size_hash.key?('REGION_NAME')
result_hash.store('REGION_NAME', region_name.strip)
size_hash['REGION_NAME'] = [size_hash['REGION_NAME'], region_name.length].max
end
if size_hash.key?('START_KEY')
start_key = Bytes.toStringBinary(hregion_info.getStartKey).strip
result_hash.store('START_KEY', start_key)
size_hash['START_KEY'] = [size_hash['START_KEY'], start_key.length].max
end
if size_hash.key?('END_KEY')
end_key = Bytes.toStringBinary(hregion_info.getEndKey).strip
result_hash.store('END_KEY', end_key)
size_hash['END_KEY'] = [size_hash['END_KEY'], end_key.length].max
end
if size_hash.key?('SIZE')
if region_load.nil?
region_store_file_size = ''
else
region_store_file_size = region_load.getStorefileSizeMB.to_s.strip
end
result_hash.store('SIZE', region_store_file_size)
size_hash['SIZE'] = [size_hash['SIZE'], region_store_file_size.length].max
end
if size_hash.key?('REQ')
if region_load.nil?
region_requests = ''
else
region_requests = region_load.getRequestsCount.to_s.strip
end
result_hash.store('REQ', region_requests)
size_hash['REQ'] = [size_hash['REQ'], region_requests.length].max
end
if size_hash.key?('LOCALITY')
if region_load.nil?
locality = ''
else
locality = region_load.getDataLocality.to_s.strip
end
result_hash.store('LOCALITY', locality)
size_hash['LOCALITY'] = [size_hash['LOCALITY'], locality.length].max
end
results << result_hash
end
ensure
hregion_locator_instance.close()
hregion_locator_instance.close
end
@end_time = Time.now
size_hash.each do | param, length |
size_hash.each do |param, length|
printf(" %#{length}s |", param)
end
printf("\n")
size_hash.each do | param, length |
str = "-" * length
size_hash.each_value do |length|
str = '-' * length
printf(" %#{length}s |", str)
end
printf("\n")
results.each do | result |
size_hash.each do | param, length |
results.each do |result|
size_hash.each do |param, length|
printf(" %#{length}s |", result[param])
end
printf("\n")
end
printf(" %d rows\n", results.size)
end
def valid_locality_threshold?(value)
value >= 0 and value <= 1.0
value >= 0 && value <= 1.0
end
def get_regions_for_table_and_server(table_name, conn, server_name)
@ -191,16 +208,16 @@ EOF
def get_regions_for_server(regions_for_table, server_name)
regions_for_table.select do |hregion|
accept_server_name? server_name, hregion.getServerName().toString()
accept_server_name? server_name, hregion.getServerName.toString
end
end
def get_regions_for_table(table_name, conn)
conn.getRegionLocator(TableName.valueOf(table_name)).getAllRegionLocations().to_a
conn.getRegionLocator(TableName.valueOf(table_name)).getAllRegionLocations.to_a
end
def accept_server_name?(desired_server_name, actual_server_name)
desired_server_name.nil? or actual_server_name.start_with? desired_server_name
desired_server_name.nil? || actual_server_name.start_with?(desired_server_name)
end
def accept_region_for_locality?(actual_locality, locality_threshold)
@ -208,4 +225,4 @@ EOF
end
end
end
end
end