博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TT/TC 遍历Key解决方案
阅读量:6860 次
发布时间:2019-06-26

本文共 5166 字,大约阅读时间需要 17 分钟。

  hot3.png

 

项目中要遍历,对Key进行处理,弄了N个方案,记录下,具体选哪个再说,呵呵

需求:TC服务中通过KEY-VALUE存储了准备删除的文件KEY和时间,需要定期全量遍历KEY,进行删除,然后清理TC对应的数据。由业务决定了删除数据的量不大,目前主要要求可靠。

 

1、给TT加个补丁,让其支持memcached协议访问,本人只会JAVA,困难(同时被鄙视了),网上的那个补丁说有问题...

代码:无

2、使用TC的JAVA-API直接访问TC数据问题,已测试通过,注意在TT启动的时候,打开文件时候,mode需要加HDB.ONOLCK,不然,是读取不到数据的,一直卡在哪儿(我的需要是读取KEY,所有mode使用的是:HDB.OREADER|HDB.ONOLCK),这需要部署程序到TC服务,有点不爽,而且JAVA打包也麻烦(有业务逻辑和功能基础包,都是maven依赖的,我靠,如果不人工清理,好多jar啊)。

代码:

 

import tokyocabinet.*;public class TCHDBEX {  public static void main(String[] args){    // create the object    HDB hdb = new HDB();    // open the database    if(!hdb.open("/mnt/ttserver/tt_11212.tch", HDB.OREADER | HDB.ONOLCK)){      int ecode = hdb.ecode();      System.err.println("open error: " + hdb.errmsg(ecode));    }    String key;    String value;    hdb.iterinit();    while((key = hdb.iternext2()) != null){        System.out.println(key);    }    // close the database    if(!hdb.close()){      int ecode = hdb.ecode();      System.err.println("close error: " + hdb.errmsg(ecode));    }  }}

 

3、使用程序在本地指定tchmgr的cli工具直接读取命令行范围的流,得到keys.比较不好的是需要部署程序到TC服务器了。问题同方案2

代码:

 

package com.feinno.storage.console.task.clean;import java.io.BufferedReader;import java.io.InputStreamReader;import java.nio.charset.Charset;import java.util.ArrayList;import java.util.List;public class LocalCliTCListKeys implements TCListKeys {	private String charset = "UTF-8";	@Override	public List
list(int top) { // TODO Auto-generated method stub return null; } @Override public List
list() { String shellCommand = "tchmgr list -nl /mnt/ttserver/tt_11211.tch"; String[] cmd = { "/bin/sh", "-c", shellCommand }; BufferedReader reader = null; List
keys = new ArrayList
(); try { Process process = Runtime.getRuntime().exec(cmd); reader = new BufferedReader(new InputStreamReader(process.getInputStream(), Charset.forName(charset))); String buf = null; while ((buf = reader.readLine()) != null) { keys.add(buf); } } catch (Exception e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (Exception e2) { // ig } } } return keys; }}

 

 

4、远端使用程序远程SSH执行命令,获取返回的流,得到Keys,但是,需要获得TC服务的账户,会有一定的安全问题,因为是内部系统,如果使用普通用户SUDO,其实也是可行的。

代码:

public class SSHCliTCListKeys implements TCListKeys {	private String charset = "UTF-8";	private String SSHUser = "root";	private String SSHPswd = "!QAZ2wsx";	private String SSHHost = "192.168.30.142";	private String dataFileLocalPath = "/mnt/ttserver/tt_11212.tch";	@Override	public List
list(int top) { String shellCommand = "tchmgr list -nl -m " + top + " " + dataFileLocalPath; return executeRemoteShellCommand(shellCommand); } @Override public List
list() { String shellCommand = "tchmgr list -nl " + dataFileLocalPath; return executeRemoteShellCommand(shellCommand); } private List
executeRemoteShellCommand(String shellCommand) { List
keys = new ArrayList
(); BufferedReader reader = null; Channel channel = null; Session session = null; JSch jsch = new JSch(); try { session = jsch.getSession(SSHUser, SSHHost, 22); session.setPassword(SSHPswd); java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(shellCommand); channel.setInputStream(null); ((ChannelExec) channel).setErrStream(System.err); channel.connect(); reader = new BufferedReader(new InputStreamReader(channel.getInputStream(), Charset.forName(charset))); String buf = null; while ((buf = reader.readLine()) != null) { keys.add(buf); } } catch (Exception e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (Exception e2) { // ig } } channel.disconnect(); session.disconnect(); } return keys; } public String getCharset() { return charset; } public void setCharset(String charset) { this.charset = charset; } public String getSSHUser() { return SSHUser; } public void setSSHUser(String sSHUser) { SSHUser = sSHUser; } public String getSSHPswd() { return SSHPswd; } public void setSSHPswd(String sSHPswd) { SSHPswd = sSHPswd; } public String getSSHHost() { return SSHHost; } public void setSSHHost(String sSHHost) { SSHHost = sSHHost; } public String getDataFileLocalPath() { return dataFileLocalPath; } public void setDataFileLocalPath(String dataFileLocalPath) { this.dataFileLocalPath = dataFileLocalPath; }}

 

5、在TC服务器上写个简单的Socket server,代理远端请求,在服务器上支持API或cli,返回给调用端。这个方法感觉最完美,没有安全问题,也实现了服务也业务解耦,只是,部署和维护麻烦了,多出来一个server,故障的可能性也稍微变大了些

 

6、另类方案,直接从业务本身出发,修改数据结,使用TT支持的memcached现有的API解决。

需要延迟删除的文件的数据结构:

key1:[{'deleteFileKey1':'yyyy-mm-dd'},..] //配置定义为:10-N个

key2:[....]

key3:[....]

key4:[....]

 

业务中,执行删除的时候,向使用循环遍历方式,找到空位或新插入keyN保存需要删除的fileKey

扫描遍历的逻辑(伪代码):

int i = 1;

while(memcacheClient.get("key"+i) != null){

    // do busi

    i++;

}

 

 

特点:程序逻辑实现和控制稍微复杂。好处是部署维护相当简单。

兄弟们,你们选哪个!?

 

 

 

转载于:https://my.oschina.net/acooly/blog/770233

你可能感兴趣的文章
试着写写Map/Reduce程序
查看>>
一种被忽视的攻击方式-padding oracle
查看>>
硬盘MBR常识和修复MBR的方法解析
查看>>
Lync 客户端功能对比之会议支持
查看>>
初步了解Docker容器(三)
查看>>
部署无需边缘提供外部访问的Lync Server前端
查看>>
安装、部署DPM 2012 R2服务器
查看>>
内核中的UDP socket流程(8)——udp_sendmsg
查看>>
大数据实战之环境搭建(三)
查看>>
Linux架设Jsp环境
查看>>
XenApp_XenDesktop_7.6实战篇之九:SQL Server数据库服务器规划及部署
查看>>
ExtJS样例总结 -1
查看>>
IT-标准化-系列-10.在VPC 2007中快速部署操作系统-下
查看>>
SCCM 2012 SP1升级
查看>>
.NET设计模式(5):工厂方法模式(Factory Method)
查看>>
民航业智能升级,安防巨头‘大华’如何利用 AI 保障机场安全
查看>>
支持向量机分类实战
查看>>
java-基础-JNI本地栈
查看>>
中国人工智能学会通讯——增强学习是人工智能的未来 1.3 增强学习的核心技术...
查看>>
2017全球SDNFV技术大会倒计时 大会完整日程曝光!
查看>>