HBase豆知识
关于Phoenix的使用
与Phoenix
带来的SQL on HBase
易用性相比,它带来的负面影响也是巨大的,
大表Join
大表,或者全表OrderBy
等消耗的资源随数据量呈至少线性增长,
并发直线下降,甚至低到只有百级别,扩容带来的收益下降很快。
另外,Phoenix表查询通过多个独立协调器(Query Server
),互相不管对方,
玩命占用HBase资源,在高并发的大查询下就会容易造成HBase整个集群过载。
而像Presto系统所有的请求都是走同一个协调器,可以总控资源使用,优雅的处理过载。
让现有HBase集群聚焦在线KV Store
,聚焦作为在线业务的温存储层。
Phoenix针对KV系统提供的 SaltBucket、SkipScan、Aggregation、列合并
等特性可以看做是对HBase的最佳实践。
云厂商今后可能从两个方面来改善Phoenix,一个是SQL的分离执行,Scale 无关的本地编译执行,Scale 相关的自动走DLA编译执行;另一个是像Presto那样资源调度的统一处理。
写入数据
HBase写入是先写WAL,然后写内存,如果宕机了,内存里的数据会丢失,需要回放log恢复数据之后,region才能上线,这个是需要时间的一般是3到5分钟。 而升级是不要这个过程的,region会先移走这个时间是百ms级别的。
phoniex 有自己的一套 编码格式, 列族、列名转化方式。 直接读phoenix原生的表, 需要自己去解析字段类型
连接数
hbase zk针对某个ip机器上连接有个上限:200,整体上HBase的连接数没有上限,据官方说是几十万级别的。
范围读
范围读说是的是 scan[startkey, endkey]
,在开始RK与结束RK顺之间按照字典顺序扫描数据。
一般一次扫描,不超过200为好,超过的话,可以设计为多次迭代的形式继续扫描。
删除表
执行删除表(disable->drop
操作),表并不是立即删除,而是先进archive目录
保留一小段时间,
所以,空间水位线不会立即下来。
Region Replica(HBASE-10070)特性
在HBase最初的架构中,一个Region
只能被部署在一个RegionServer
中,它的数据多副本交由HDFS
来保障。从1.0版本开始,HBase
有了Region Replica(HBASE-10070)
特性,该特性允许将一个Region
部署在多个RegionServer
中来提升读取的可用性,但多Region
副本之间的数据却不是实时同步的,因此不具备生产能力。
现存系统针对结构化数据存储与查询的一些痛点问题
结构化数据的存储,通常包含如下两种方式:
静态数据通常以Parquet/Carbon/Avro
形式直接存放在HDFS中,对于分析场景,这种存储通常是更加适合的。但无论以哪种方式存在于HDFS中,都难以支持单条记录级别的更新,随机读取也并不高效。
可变数据的存储通常选择HBase或者Cassandra
,因为它们能够支持记录级别的高效随机读写。但这种存储却并不适合离线分析场景,因为它们在大批量数据获取时的性能较差。
针对HBase
而言,有两方面的主要原因:
- 一、HFile本身的结构定义,它是按行组织数据的,这种格式针对大多数的分析场景,都会带来较大的IO消耗,因为可能会读取很多不必要的数据,相对而言
Parquet
格式针对分析场景就做了很多优化。 - 二、由于HBase本身的
LSM-Tree
架构决定的,HBase的读取路径中,不仅要考虑内存中的数据,同时要考虑HDFS中的一个或多个HFile
,较之于直接从HDFS
中读取文件而言,这种读取路径是过长的
如上两种存储方式,都存在明显的优缺点:
直接存放于HDFS
中,适合离线分析,却不利于记录级别的随机读写。
直接将数据存放于HBase/Cassandra
中,适合记录级别的随机读写,对离线分析却不友好。
ROWKEY设计
md5(car_Id).substring(0,4)_carid_timestamp md5的目的是打散,不是唯一
预分区
MD5Hash.getMD5AsHex hexString的假设数据范文是0000-fffff
建表时,指定分区算法,并且做了预分区
create 'prod:iov_passenger_location_history_5m','cf1',{NUMREGIONS => 30, SPLITALGO => 'HexStringSplit'}
NUMREGIONS
为 region的个数,一般按每个region 8~10GB
左右来计算region
数量,集群规模大,region
数量可以适当取大一些。
预分区
HBase可以支持100TB+的表,上万个分区, 建表时先估下数据量,然后指定好合适的分区数,分区数太多也不行,太少就会频繁的split,
SPLITALGO 为 rowkey分割的算法,HBase自带了三种pre-split的算法: HexStringSplit、DecimalStringSplit 和 UniformSplit
。
各种Split算法适用场景:
- HexStringSplit: rowkey是十六进制的字符串作为前缀的,这个配合md5前缀用的最多
- DecimalStringSplit: rowkey是10进制数字字符串作为前缀的
- UniformSplit: rowkey前缀完全随机
客户端的报错问题
Caused by: java.io.IOException: Call to press-001/10.30.93.78:16020 failed on local exception: org.apache.hadoop.hbase.ipc.FailedServerException: This server is in the failed servers list: press-001/10.30.93.78/10.30.93.78:16020
at org.apache.hadoop.hbase.ipc.IPCUtil.wrapException(IPCUtil.java:180)
at org.apache.hadoop.hbase.ipc.AbstractRpcClient.onCallFinished(AbstractRpcClient.java:390)
at org.apache.hadoop.hbase.ipc.AbstractRpcClient.access$100(AbstractRpcClient.java:95)
at org.apache.hadoop.hbase.ipc.AbstractRpcClient$3.run(AbstractRpcClient.java:410)
at org.apache.hadoop.hbase.ipc.AbstractRpcClient$3.run(AbstractRpcClient.java:406)
at org.apache.hadoop.hbase.ipc.Call.callComplete(Call.java:103)
at org.apache.hadoop.hbase.ipc.Call.setException(Call.java:118)
at org.apache.hadoop.hbase.ipc.AbstractRpcClient.callMethod(AbstractRpcClient.java:423)
hbase.regionserver.port:HBase RegionServer绑定的端口,默认16020
- WP、Win10开发或者WPF开发时绘制自定义窗体~例如:一个手机
- 【Java学习笔记之八】JavaBean中布尔类型使用注意事项
- BZOJ 1597: [Usaco2008 Mar]土地购买【斜率优化+凸包维护】
- BZOJ 1046: [HAOI2007]上升序列【贪心+二分状态+dp+递归】
- 【Java学习笔记之九】java二维数组及其多维数组的内存应用拓展延伸
- BZOJ 1293: [SCOI2009]生日礼物【单调队列】
- Javascript缓存投毒学习与实战
- 【Java学习笔记之十】Java中循环语句foreach使用总结及foreach写法失效的问题
- Codeforces 839B Game of the Rows【贪心】
- Codeforces 839A Arya and Bran【暴力】
- 【Java学习笔记之十一】Java中常用的8大排序算法详解总结
- 浅谈zip格式处理逻辑漏洞
- C/C++中peek函数的原理及应用
- 洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is He…【字符串+模拟】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法