Hbase读比写数据要慢
数据读写不需要master参与
1、常见术语
同一个region中的store对应不同列族
region:table在行方向上分割为多个region,region是分布式存储和负载均衡的最小单元
store:每个region由一个或多个store组成,hbase会把一起访问的数据放在一个store中,即每个列族对应一个 store,一个store由一个memstore和多个storefile组成,hbase以store大小判断region是否需要切分
memstore:放在内存中的,到阈值时,进行flush
storefile:memstore flush后生成storefile,底层是Hfile格式保存
Hfile:是hbase中keyvalue数据的存储格式,是hadoop的二进制文件,一个storefile对应一个Hfile,Hfile是存储在 HDFS上的。Hfile是不定长的
每个memstore刷新到storefile后,是一组,合并也是组内合并,即同一个store中
2、HBASE写流程
1)Client-->从ZK上获取hbase:meta的regionserver位置,
2)client访问hbase:meta所在regionserver,查询需要的目标表所在的regionserver(client会缓存)
3)client连接目标表所在的regionserver,发起put
4)先写WAL(预写入日志),实现类是Hlog,写入memstore中,client结束
/hbase/meta-region-server 查看系统表所在region
1>写数据用了juc的锁
2>写数据用的时间戳运用了服务端的时间
3>构建wal,buile wal edit
......
3、hbase读数据流程
1、client--->访问ZK,找到meta表所在regionserver
2、client读取meta表,获取目标表的位置(并写入缓存)
3、client向目标表所在regionserver发起get
4、同时读取memstore和storefile(即内存和磁盘),做merge后返回最大的时间戳value
5、磁盘读出的数据缓存到block cache,便于下一次读取,即读取时候,先读取memstore和blockcache,没有的话再读取磁盘---使用LRU cache算法--最近最少使用方法
##4、 flush
1)regionserver级别的大小参数
hbase.regionserver.global.memstore.size ##全局memstore大小,超过会flush 大小是堆内存40%
hbase.regionserver.global.memstore.size.lower.limit ##40%的0.95,到这个值时候就开始flush,到40%时就会暂停写操作
flush时候会先对大的进行操作
2)regionserver级别的时间参数
hbase.regionserver.optionalcacheflushinterval ##内存中文件自动刷新之前最长memstore存在时间,默认3600000(即一个小时,最后一次编辑的时间)
3)region级别
hbase.hregion.memstore.flush.size ##单个region中的memstore到大小时候就会flush。默认134217728,即128M,我们环境配置256M
4、hbase StoreFile Compaction合并
两种方式
1、minor ,小范围,即将临近的若干个小Hfile合并成一个大Hfile,不会删除过期数据
2、major ,大的全局合并,会将一个store下的所有Hfile合并成一个,会删除过期数据
常用参数
hbase.hregion.majorcompaction ##一个region进行major合并的周期。默认7天,生产环境一般关闭(配置为0,Set to 0 to disable)
hbase.hregion.majorcompaction.jitter ##合并的抖动比例,生产一般也是关闭()
hbase.hstore.compactionThreshold ##storefile超过数量时候进行合并,代码中是>=3,默认是3
hbase.regionserver.compaction.enabled ##是否开启合并,默认是true
5、数据真正的删除过程
flush 'table'
compact 'table'
put过程时候
1、flush过程中,会删除同memstore中小版本的数据,保留大版本中的数据
2、compact(major)过程中,会删除同store中的小版本的数据
delete过程时候
1、major 过程中删除DeleteColum(删除标记),因为如果flush时候删除标记被删掉,flush后就又会出现,所以一直到major compaction时候再删除标记
2、保留数据版本数量根据建表version
6、 行键分区
1、预分区
预分区数数量
1)预计数据量有关,尽量保证预分区数量满足预计数据量,
2)机器规模有关(每台机器2-3个region,即30个的规模,最大90个region)
startKey和endkey称为分区键
每个region维护着StartRow和EndRow,如果加入的数据符合某个Region维护的RowKey范围,则数据给到这个 region维护,可以数据要投放的分区提前规划好
预分区之后,新数据进入,会rowkey和分区key(即每个region都会有startkey和endkey)作比较(要完全比较startkey和endkey的位数,有比没有大),是要按位进行比较
2、手工添加分区键
create ‘wanghaha01’,‘info1’,‘info2’,SPLITS => [‘1000’,‘2000’,‘3000’,‘4000’] ##建表,5个region
3、指定10个region,分区键十六进制自动取,一般不用
create ‘wanghaha02’,‘info1’,{NUMREGIONS =>10,SPLITALGO=>‘HexStringSplit’}
3、通过写文件的形式,在文件中写好分区键
vim linshi.txt
aa
bb
cc
dd
create ‘wanghaha03’,‘info1’,SPLITS_FILE=>’/opt/hbase_client/linshi.txt’
7、Rowkey的设计
设计原则
1、散列性,和多分区结合讨论
散列的几种方式
1)生成随机数。hash。散列值
2)字符串反转
3)字符串拼接
2、唯一性
3、长度原则,一般70-100位
8、常见参数调优
内存优化
Hbase操作椒需要大量内存开销的,table可以缓存在内存中,70%内存给hbase Java堆,但是不要过大,GC过程中持续太久会导致Regionserver长期处于不可用状态
基础优化
1、在hdfs-site.xml和hbase-site.xml中
dfs.support.append ##允许0HDFS追加同步,可以配合hbase数据同步持久化。默认true
2、在hdfs-site.xml中
dfs.datanode.max.transfer.threads ##DataNode间传输数据的线程的最大数,datanode打开的最大文件数
3、在hdfs-site.xml中,优化延迟高的数据操作等待时间
dfs.image.transfer.timeout ##默认600000毫秒,如果数据操作延时很高,可以适当调大,socket等待更长时间
4、RPC监听数量,读写请求大时候可以增大
hbase.regionserver.handler.count ##RegionServer上的RPC服务器实例数。HMaster上的RPC服务器实例数与此相等。
5、优化Hstore文件大小
hbase.hregion.max.filesize ##默认10G,我们目前业务调整为60G
6、客户端缓存,增大后可以增加写速度
hbase.client.write.buffer ###HBase客户端程序向HBase集群写入数据的缓存值,增大该值可以减少RPC调用次数,但是会消耗内存。默认是2M
7、读缓存(数据条数),增大该至可以提升读取数据速度
hbase.client.scanner.caching ##Scanner一次从服务端获取的数据条数,这部分数据会先缓存到客户端本地,每次next调用将从本地缓存返回数据直到缓存为空。高缓存值将加速scan但同时也将占用更大的内存
8、flush的memtore大小,默认128M
hbase.hregion.memstore.flush.size ##超过指定值,MemStore将被冲洗至磁盘
9、hbase shell 操作命令
DDL
create 'student'(表名),'info(列族)' ##建表
alter 'student',{NAME=>'info',VERSION=>'3'} ##修改表信息,此处修改保留3个版本
DML
put 'student(表名)','1001(rowkey)','info(列族):name(列)','wanghaha(value)' ##put数据
scan 'student(全表扫描)' ##全表扫描
get 'student','1001','info1:name' ##获取数据
scan 'student',{STARTROW => '1001',STOPKEY => '2002',LIMIT =>10} ##查看数据,标示起始终止rowkey,查10行(一个rowkey一行)
##修改
put 'student','1001','info:name','hahah(修改的值)'
##查看多个版本
scan 'student',{RAW=>true,VERSION=>10} 查看最近10个版本,
##删除
delete 'student','1001','info:name' ## 删除name列
truncate 是删表
deleteall 'student','1001' ##删除整个rowkey