docker hbase-shell 中文乱码问题排查
get 'student', '20230101', {FILTER => "ValueFilter(=, 'binary:张三')"}get 'student', '20230101', {FILTER => "ValueFilter(=, 'binary:男')"}put 'student', '20230101', 'info:gender', '男'put 'student', '2023
1.在进入 容器id的时候
进入容器里 首先(deepseek答案是正确的)
export LANG=en_US.UTF-8
2.进入容器里面的时候
create 表名称, 分组1_info, 分组2_grades
create 'student', 'info', 'grades'
put 'student', '20230101', 'info:name', '张三'
put 'student', '20230101', 'info:gender', '男'
--可以输入了 但是数据库 key_value 存放的还是16进制的中文
get 'student', '20230101', {FILTER => "ValueFilter(=, 'binary:张三')"}
get 'student', '20230101', {FILTER => "ValueFilter(=, 'binary:男')"}
3.排错过程
deepseek给出的相关的解决方案信息(没有效果)
import org.apache.hadoop.hbase.util.Bytes
get 'student', '20230101' do |k, v|
puts "Value: #{Bytes.toString(v.value)}"
end
但是没有效果截图如下:
3.2进入hbase环境后
hbase(main):001:0> ENV['HADOOP_OPTS']="-Dfile.encoding=UTF-8"
ENV['HADOOP_OPTS']="-Dfile.encoding=en_US.UTF-8"
参考:
https://blog.51cto.com/u_16175448/10696039
然后重启hbase服务也没有用
3.3步骤1
import org.apache.hadoop.hbase.client.Get
import org.apache.hadoop.hbase.util.Bytes
--ecode_get 'student', '20230101' 报错 No data found
--HBase Shell 的 @shell.hbase_table(table_name) 方法返回的 Table 对象 未正确绑定到当前连接,导致查询时无法获取数据。这是 JRuby 与 HBase Java API 交互时的常见作用域问题。
def decode_get(table_name, rowkey)
table = @shell.hbase_table(table_name)
get = Get.new(Bytes.toBytes(rowkey))
result = table.get(get)
result.list_cells.each do |cell|
family = Bytes.toString(cell.getFamilyArray, cell.getFamilyOffset, cell.getFamilyLength)
qualifier = Bytes.toString(cell.getQualifierArray, cell.getQualifierOffset, cell.getQualifierLength)
value = Bytes.toString(cell.getValueArray, cell.getValueOffset, cell.getValueLength)
puts "COLUMN: #{family}:#{qualifier}, VALUE: #{value}"
end
end
步骤2
在 decode_get 中添加调试语句:
def decode_get(table_name, rowkey)
table = @shell.hbase_table(table_name)
puts "Table object alive? #{!table.nil?}" # 检查 table 对象是否有效
get = Get.new(Bytes.toBytes(rowkey))
result = table.get(get)
puts "Result empty? #{result.isEmpty}" # 检查 result 是否为空
end
decode_get 'student', '20230101'
hbase:236:0> decode_get 'student', '20230101'
Table object alive? true
COLUMN CELL
0 row(s)
Took 0.0184 seconds Traceback (most recent call last):
NoMethodError (undefined method `isEmpty' for nil:NilClass)
hbase:237:0>
如果输出 Table object alive? true 但 Result empty? true,则证明 Table 对象未正确绑定连接
4.解决方案
!成功了
根本原因:@shell.hbase_table 返回的 Table 对象在 JRuby 中无法正常查询数据。
终极修复:绕过 Shell 的封装,直接通过 ConnectionFactory 创建连接。
验证方法:使用修正后的脚本,确保输出与原生 get 命令一致
修正后的脚本信息
def decode_get(table_name, rowkey)
import org.apache.hadoop.hbase.client.Get
import org.apache.hadoop.hbase.client.ConnectionFactory
import org.apache.hadoop.hbase.util.Bytes
# 使用 ConnectionFactory 创建新连接(绕过 Shell 的 Table 对象问题)
connection = ConnectionFactory.createConnection(@shell.hbase.configuration)
table = connection.getTable(org.apache.hadoop.hbase.TableName.valueOf(table_name))
begin
get = Get.new(Bytes.toBytes(rowkey))
result = table.get(get)
if result.isEmpty
puts "ERROR: No data found for rowkey '#{rowkey}'."
else
result.list_cells.each do |cell|
family = Bytes.toString(cell.getFamilyArray, cell.getFamilyOffset, cell.getFamilyLength)
qualifier = Bytes.toString(cell.getQualifierArray, cell.getQualifierOffset, cell.getQualifierLength)
value = Bytes.toString(cell.getValueArray, cell.getValueOffset, cell.getValueLength)
puts "COLUMN: #{family}:#{qualifier}, VALUE: #{value}"
end
end
ensure
table.close
connection.close
end
end
截图
上面这种方法 提供了一种hbase-shell 原生的学习环境
!注意!注意!注意
持久性:在 HBase Shell 中定义的函数仅在当前会话中有效。
如果你需要持久化这些函数,可以将它们写入一个 Ruby 脚本文件,并在每次启动 HBase Shell 时加载该脚本。
如果你有一个包含自定义函数的 Ruby 脚本文件(例如 custom_functions.rb)
load 'custom_functions.rb'
更多推荐
所有评论(0)