内容简介:版权声明:本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,如有任何技术交流,可随时联系。网上的Hbase调优资料参差不齐,实在是不忍卒读,有些都是拼凑且版本过时的东西,我这里决定综合所有优质资源进行整合,写一份最全,最有深度,不过时的技术博客。辛苦成文,各自珍惜,谢谢!版权声明:禁止转载,欢迎学习,侵权必究!数据块编码主要是针对 Key/Valu
版权声明:本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,如有任何技术交流,可随时联系。
网上的Hbase调优资料参差不齐,实在是不忍卒读,有些都是拼凑且版本过时的东西,我这里决定综合所有优质资源进行整合,写一份最全,最有深度,不过时的技术博客。辛苦成文,各自珍惜,谢谢!版权声明:禁止转载,欢迎学习,侵权必究!
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)。 复制代码
版权声明:本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,如有任何技术交流,可随时联系。
1.3 快速差异编码(Fast Diff)
快速差异编码(Fast Diff)借鉴了 Diff 编码的思路,也考虑到了差异编码速度慢的致命缺陷。快速差异编码的 KeyValue 结构跟差异编码一模一样,只有 Flag 的存储规则不一样,并且优化了 Timestamp 的计算。Fast Diff 的实现比 Diff 更快,也是比较推荐的算法
不过这个“快速”只是相对本来的差异算法而言的,由于还是有很多计算过程存在,所以快速差异算法的速度依然属于比较慢的。
1.4 前缀树编码(Prefix Tree)
前缀树编码(Prefix Tree)是前缀算法的变体,它是 0.96 版本之后才加入的特性。前缀树编码最大的作用就是提高了随机读的能力,但是其复杂的算法相对地降低了写入的速度,消耗了更多的 CPU 资源,使用时需要在资源的消耗和随机读的性能之间进行取舍。
2 基于Value的压缩器启用
压缩器的作用是可以把 HBase 的数据按压缩的格式存储,这样可以更节省磁盘空间。当然这完全是可选的,不过推荐大家还是安装 Snappy 压缩器,这是 HBase 官方目前排名比较高的压缩器。
hbase> alter 'mytable',{NAME =>'mycf',COMPRESSION=>'snappy'} Snappy 是 Google 开发的压缩器,有以下特点: 快速:压缩速度达到 250MB/s; 稳定:已经用于 Google 多个产品长达数年; 健壮:Snappy 的解压器可以保证在数据被损坏的时候也不会太糟; 免费开源。 复制代码
3 客户端API 新版本最佳实践
3.1 Connection 连接实例出世
推荐将 Configuration 做为单例;Connection 随建随用,用完及时关闭。
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(); } } 复制代码
3.2 new HTable已废弃,新用法
// 已废弃,不推荐使用 // HTable table = new HTable(config, "mytable"); // 官方推荐 try (Connection connection = ConnectionFactory.createConnection(config)) { connection.getTable(TableName.valueOf("tb1")); } 复制代码
3.3 checkAndPut(数据一致性)方法
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) 复制代码
3.4 increment方法
保证原子性的情况下,把数据库中的某个列的数字进行数学运算
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); 复制代码
3.5 Mutation 方法
把添加一列的时候同时删除另一列的操作放在同一个原子操作中
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); 复制代码
3.6 BufferedMutator批量操作(batch)()
客户端写缓冲区就是一个在客户端 JVM 里面的缓存机制,可以把多个 Put 操作攒到一起通过单个 RPC 请求发送给客户端,目的是节省网络握手带来的 IO 消耗。这个缓冲区可以通过调用 HTable.setAutoFlush(false) 来开启。 最新版的 API 中 setAutoFlush 被废弃了,每个表自带的 writeBuffer 也被废弃了,但是客户端写缓冲区还是存在的,只是转而使用 BufferedMutator 对象。
最好不要把针对同一个单元格的 Put 和 Delete 放到同一个 actions 列表里面,因为 HBase 不一定是顺序地执行这些操作的,你可能会得到意想不到的结果。 connection.getTable(TableName.valueOf("tb1") Table table = connection.getBufferedMutator(TableName.valueOf("mytable")); bm.mutate(put); bm.flush(); bm.close(); 复制代码
3.7 批量 put 操作
HBase 提供了专门针对批量 put 的操作方法:void put(List puts);其实内部也是用 batch 来实现的。需要注意的是,当一部分数据插入成功,但是另一部分数据插入失败,比如某个 RegionServer 服务器出现了问题,这时会返回一个 IOException,操作会被放弃,不过插入成功的数据不会被回滚。
对于插入失败的数据,服务器会尝试着再次去插入或者换一个 RegionServer,当尝试的次数大于定义的最大次数会抛出 RetriesExhaustedWithDetailsException 异常,该异常包含了很多错误信息,包括有多少操作失败了,失败的原因以及服务器名和重试的次数。
3.8、Scan 缓存优化
现在的 HBase 在扫描的时候已经默认开启了缓存。
每一次的 next() 操作都会产生一次完整的 RPC 请求,而这次 RPC 请求可以获取多少数据是通过 hbase-site.xml 中的 hbase.client.scanner.caching 参数配置的。比如你如果配置该项为 1,那么当你遍历了 10 个结果就会发送 10 次请求,显而易见这是比较消耗性能的,尤其是当单条的数据量较小的时候。
hbase-site.xml参数调优:
<property> <name>hbase.client.scanner.caching</name> <value>100</value> </property> 复制代码
4 总结
本文解决了连个问题包括HBase数据块编码压缩机制调优以及客户端API 新版本最佳实践
版权声明:本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,如有任何技术交流,可随时联系。
参考文档及连接:Hbase不睡觉书 及官方文档资料 复制代码
秦凯新 于深圳 201801102252
以上所述就是小编给大家介绍的《HBase数据块编码压缩机制调优及客户端API 新版本最佳实践-OLAP商业环境实战》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Spring Cloud实战系列(二) - 客户端调用Rest + Ribbon
- Spring Cloud实战系列(三) - 声明式客户端调用Feign
- 《ElasticSearch6.x实战教程》之复杂搜索、Java客户端(下)
- 《ElasticSearch6.x实战教程》之简单搜索、Java客户端(上)
- 支付宝客户端架构解析:iOS 客户端启动性能优化初探
- 自己动手做数据库客户端: BashSQL开源数据库客户端
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深度探索C++对象模型
[美] Stanley B. Lippman / 侯捷 / 华中科技大学出版社 / 2001-5 / 54.00元
这本书探索“对象导向程序所支持的C++对象模型”下的程序行为。对于“对象导向性质之基础实现技术”以及“各种性质背后的隐含利益交换”提供一个清楚的认识。检验由程序变形所带来的效率冲击。提供丰富的程序范例、图片,以及对象导向观念和底层对象模型之间的效率测量。一起来看看 《深度探索C++对象模型》 这本书的介绍吧!