1 HBase 数据块编码 Key 优化
数据块编码主要是针对 Key/Value 中的 Key 进行编码, 减少 Key 存储所占用的空间, 因为很多 Key 的前缀都是重复的. 举例如下:
1.1 前缀编码(Prefix)
如果使用前缀编码作为数据块编码方式, 那么它只会存储第一个 Key 的完整字符串, 后面的 key 只存储跟第一个 key 的差异字符, 重新编码过的数据如下所示. 如下例所示:
最上面的 key 值为:
myrow001:mycf:col1
针对于 key 而言, 后续的可以之存储差异值:
myrow001:mycf:col2 就变为 2
myrow001:mycf:col3 就变为 3
myrow002:mycf:col3 就变为 2:mycf:col1 (变为最上面)
myrow003:mycf:col3 就变为 3
1.2 差异编码(Diff)
差异编码方式默认是不启用的. 为什么? 因为太慢了, 每条数据都要这样计算一下, 获取数据的速度很慢. 除非你要追求极致的压缩比, 但是不考虑读取性能的时候可以使用它, 比如你想要把这部分数据当作归档数据的时候, 可以考虑使用差异编码.
差异编码 (Diff) 比前缀编码更进一步, 差异编码甚至把以下字段也一起进行了差异化的编码.
键长度(KeyLen);
值长度(ValueLen);
时间戳(Timestamp), 也即是 Version;
类型(Type), 也即是键类型.
采用了差异编码后的 KeyValue 结构为:
1 byte: 标志位;
1-5 bytes:Key 长度(KeyLen);
1-5 bytes:Value 长度(ValLen);
1-5 bytes: 前缀长度(Prefix Len);
... bytes: 剩余的部分;
... bytes: 真正的 Key 或者只是有差异的 key 后缀部分;
1-8 bytes: 时间戳 (timestamp) 或者时间戳的差异部分;
1 byte:Key 类型(type);
... bytes: 值(value).
- public static void main(String[] args) throws URISyntaxException, IOException {
- // 获取配置文件
- Configuration config = HBaseConfiguration.create();
- config.addResource(new Path(ClassLoader.getSystemResource("hbase-site.xml").toURI()));
- config.addResource(new Path(ClassLoader.getSystemResource("core-site.xml").toURI()));
- // 创建连接
- try (Connection connection = ConnectionFactory.createConnection(config); Admin admin = connection.getAdmin()) {
- // 定义表名
- TableName tableName = TableName.valueOf("tb1");
- // 定义列族
- ColumnFamilyDescriptor myCf = ColumnFamilyDescriptorBuilder.of("cf1");
- // 定义表
- TableDescriptor table = TableDescriptorBuilder.newBuilder(tableName).setColumnFamily(myCf).build();
- // 执行创建表动作
- admin.createTable(table);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
- // 已废弃, 不推荐使用
- // HTable table = new HTable(config, "mytable");
- // 官方推荐
- try (Connection connection = ConnectionFactory.createConnection(config)) {
- connection.getTable(TableName.valueOf("tb1"));
- }
- Put put =new Put(Bytes.toBytes("qinkaixinRowkeys"))
- put.addColumn(Bytes.toBytes("mycf"),Bytes.toBytes("name"),Bytes.toBytes("ted"));
- boolean result = table.checkAndput(
- Bytes.toBytes("row3"),
- Bytes.toBytes("mycf"),
- Bytes.toBytes("name"),
- Bytes.toBytes("ted"),
- put)
- Table table = connection.getTable(TableName.valueOf("tb1"));
- Increment inc = new Increment(Bytes.toBytes("row1"));
- inc.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("age"), 1L);
- table.increment(inc);
- Delete delete =new Delete(Bytes.toBytes("qinkaixinRowkeys"))
- delete.addColumn(Bytes.toBytes("mycf"),Bytes.toBytes("name"),Bytes.toBytes("ted"));
- Put put =new Put(Bytes.toBytes("qinkaixinRowkeys"))
- put.addColumn(Bytes.toBytes("mycf"),Bytes.toBytes("name"),Bytes.toBytes("ted"));
- RowMutations rowMutations =new RowMutations(Bytes.toBytes("ted"));
- rowMutations.add(delete);
- rowMutations.add(put);
- table.mutateRow(rowMutations);
- connection.getTable(TableName.valueOf("tb1")
- Table table = connection.getBufferedMutator(TableName.valueOf("mytable"));
- bm.mutate(put);
- bm.flush();
- bm.close();
- <property>
- <name>hbase.client.scanner.caching</name>
- <value>100</value>
- </property>
来源: https://juejin.im/post/5c374eed518825255007ea88