实现HBase序列号需要借用C++的序列号工具:protobuf
版本:protobuf-2.5.0.tar.gz
- 安装步骤
- 解压tar -zxvf
- 安装依赖环境
- 进入protobuf-2.5.0,运行./configure
- 报错,原因是没有对应C环境
报错没有对应环境 configure: error: in `/tmp/bigdata/protobuf-2.5.0': configure: error: no acceptable C compiler found in $PATH
- yum grouplist 查看需要的环境(通过这个命令来安装一批依赖环境)
- yum groupinstall "Development tools" 安装该环境
- ./configure(会生成一个Makefile文件,才能执行下面make命令)
- make && make install
- 编写序列化信息
package com.ke; message PhoneDetail { required string otherNumber = 1; required string length = 2; required string type = 3; required string date = 4; } // 要和自己项目的包名、字段 一致
- 创建.proto文件,将上面序列化信息保存到文件中,文件的名称就是后面生成序列化文件的类名
vi phoneInfo.proto - cd /usr/local/bin/ 有一个文件:protoc
protoc --help查询具体命令信息 - 执行命令:/usr/local/bin/protoc phoneInfo.proto --java_out=/root/
- root目录生成:com/xiaoke/PhoneInfo.java文件
- 将.java文件引入项目中,该文件可以直接序列化
- 使用序列化、反序列化进行插入、查询操作
1.进入刚才生成的序列化文件PhoneInfo.java 2.继续使用类:HBaseDemo,保持原来初始化、销毁方法 /** * 序列化数据: 可以减少内存、存储的数据量大小 * @throws Exception */ @Test public void insertMangerByProtoBufData() throws Exception{ List<Put> puts = new ArrayList<Put>(); for (int i = 0; i < 10; i++) { String myNumber = getNumber("177"); for (int j = 0; j < 10000; j++) { // 模拟数据 别人的手机号码、通话时长、通话时间、通话类型 String otherNumber = getNumber("177"); String length = String.valueOf(random.nextInt(100)); String date = getDate("2019"); String type = String.valueOf(random.nextInt(2)); // rowkey 设计为我的手机号码 + 时间戳反转(也可以将手机号码倒过来进行数据分散) String rowkey = myNumber+"_"+(Long.MAX_VALUE-sdf.parse(date).getTime()); PhoneInfo.PhoneDetail.Builder builder = PhoneInfo.PhoneDetail.newBuilder(); builder.setDate(date); builder.setLength(length); builder.setType(type); builder.setOtherNumber(otherNumber); Put put = new Put(Bytes.toBytes(rowkey)); // 序列化后就没有列名了,所以需要自定义列名 put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("phone"), builder.build().toByteArray()); puts.add(put); } } table.put(puts); /* HBase中序列化数据: 17786774306_9223370490639607807 column=cf:phone, timestamp=1605756025604, value=\x0A\x0B17714285591\x12\x0241\x1A\x010"\x0E20190100081248 17786774306_9223370490642379807 column=cf:phone, timestamp=1605756025604, value=\x0A\x0B17794212043\x12\x0274\x1A\x010"\x0E20190100072636 */ } /** * 查看数据,需要反序列化 * @throws Exception */ @Test public void getByProtoBuf() throws Exception { Get get = new Get("17786774306_9223370490639607807".getBytes()); Result result = table.get(get); byte[] info = CellUtil.cloneValue(result.getColumnLatestCell(Bytes.toBytes("cf"), Bytes.toBytes("phone"))); PhoneInfo.PhoneDetail phoneDetail = PhoneInfo.PhoneDetail.parseFrom(info); System.out.println(phoneDetail); /* 结果: otherNumber: "17714285591" length: "41" type: "0" date: "20190100081248" */ }
- HDFS目录:/hbase/data/default/phoneInfo/0b155055d15cc66d9f56067b72d9447d/cf, 文件大小节省空间、1/3
- 为什么linux文件名不加后缀、windows需要?
linux在执行的时候,你是先写了一个命令,在写文件名,意味着你已经知道那个应用程序执行了 - 代码:https://gitee.com/Xiaokeworksveryhard/big-data.git