项目中HBase在建表时设置了表中数据的超时时间(TTL值),这个超时时间是从项目配置文件中获取的。之后客户反馈说这个超时时间的配置可能会经常变动,当服务检测到该值有变动时自动去修改HBase中该表的TTL值。项目语言用的是Java,找了一圈发现Java的HBase API中似乎没有可以灵活修改表级TTL的方法。要想修改表的TTL值,只能重新建表,不可取。思来想去,只能通过在程序中调用hbase shell 进行动态修改TTL值了。具体做法是通过Java调用linux shell脚本,在该shell脚本中再调用hbase shell指令。
首先在hbase根目录下先新建一个名为hbase.sh的文件调用hbase shell指令,内容为:
$1hbase shell <<EOF
disable "t_test"
alter "t_test",NAME=>'i',TTL=>$2
enable "t_test"
echo "sussessful setTTL"
EOF
其中,t_test为要修改TTL值的表,$1为动态传入的hbase shell所在的路径,由于hbase部署到每台服务器的路径不一定相同,所以这里选择动态配置及获取该路径。$2为动态传入的该表的TTL值。接下来要做的就是在程序中调用该hbase.sh文件。
//每次初始化表时监测到指定的TTL值和现在表的TTL不一致,则调用shell修改TTL值
TableName onlineFeature = TableName.valueOf("t_test");
// 列族描述器构造器
TableDescriptor cdb = admin.getDescriptor(onlineFeature);
ColumnFamilyDescriptor cfd=cdb.getColumnFamily(Bytes.toBytes("i"));
//t_test表此时的TTL值
int ttl=cfd.getTimeToLive();
//t_test表新指定的TTL值(单位:秒)
int expireTime=60*60*24*2;
if(ttl != expireTime){
Process process1 = null;
Process process2 = null;
InputStreamReader insr = null;
try {
long sta = System.currentTimeMillis();
String hbasePath="/home/rad/hbase-2.1.3/";
char lastChar = hbasePath.charAt(hbasePath.length() - 1);
String hbshPath = hbasePath +"hbase.sh "+hbasePath+"bin/ "+ expireTime;
process1 = Runtime.getRuntime().exec("chmod -R 777 " + hbasePath+"hbase.sh");
System.out.println("hbshPath==" + hbshPath);
process2 = Runtime.getRuntime().exec(hbshPath);
process2.waitFor();
insr = new InputStreamReader(process2.getInputStream());
BufferedReader br = new BufferedReader(insr);
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
String result = sb.toString();
System.out.println("setTTL result==" + result);
System.out.println("setTTL Time===" + (System.currentTimeMillis() - sta) + "MS");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (insr != null) {
insr.close();
}
if (process1 != null) {
process1.destroy();
}
if (process2 != null) {
process2.destroy();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}