标签:线程 levels pre tar 加速 bms hdf 大小 合数
HBase构建在 HDFS 之上的分布式列式键值存储系统。
HBase内部管理的文件全部存储在HDFS中。
HDFS适合批处理场景
范式化和反范式化
事务(单行:多行ACID)
索引(RowKey: 健全索引)
列式存储的基础:对于特定的查询,不是所有值都是必需的。
(由于master只维护表和region的元数据,而不参与表数据IO的过程,master下线仅导致所有元数据的修改被冻结(无法创建删除表,无法修改表的schema,无法进行region的负载均衡,无法处理region上下线,无法进行region的合并,唯一例外的是region的split可以正常进行,因为只有region server参与),表的数据读写还可以正常进行。
因此master下线短时间内对整个hbase集群没有影响。)
HRegionServer:HRegion:HStore = Column Family
HStore:
- MemStore:用户数据首先写入MemStore。 (flush操作)
- StoreFile:Hfile (compact操作 split操作)
Hbase 只有增加数据,所有更新和删除都是在 compact 过程中进行的。
用户写操作只要写入内存就可以立即返回,保证I/O高性能。
这台rs上的所有region共享相同的HLog files。
知道到目前为止,哪些数据已经被持久化了。
每个 update(或者说edit)都会
被写到 log ,当通知客户端成功后, rs 把数据再加载到内存中。
行键,Table的主键,Table中的记录按照Row Key排序。类型为Byte array
列簇,Table在水平方向有一个或者多个Column Family组成,一个Column Family中可以由任意多个Column组成
列 格式为:familyName:columnName。
列名称是编码在cell中的。
不同的cell可以拥有不同的列。
版本号。默认值是系统时间戳。类型为long
具体的值。类型为Byte array
{HBASE_HMOE}/bin/hbase hfile -p -f /hbase/data/default/kks1/68639b7c80a31bf91448d26bb7af17b7/cf/74e43a51ebd14007870ac58658330aeb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<br />K: 1/cf:age/1445860350861/Put/vlen=2/mvcc=0 V: 20
K: 1/cf:city/1445860381005/Put/vlen=4/mvcc=0 V: xian
K: 1/cf:name/1445860341592/Put/vlen=10/mvcc=0 V: kangkaisen
K: 2/cf:age/1445860401501/Put/vlen=3/mvcc=0 V: 200
K: 2/cf:city/1445860411217/Put/vlen=7/mvcc=0 V: beijing
K: 2/cf:name/1445860390752/Put/vlen=4/mvcc=0 V: kang
K: 3/cf:age/1445860419363/Put/vlen=4/mvcc=0 V: 2000
K: 3/cf:name/1445860428949/Put/vlen=6/mvcc=0 V: llllll
K: 4/cf:age/1446016552833/Put/vlen=2/mvcc=0 V: 23
K: 4/cf:city/1446016565367/Put/vlen=4/mvcc=0 V: xian
K: 5/cf:city/1446016578471/Put/vlen=3/mvcc=0 V: xan
K: 6/cf:age/1446016593194/Put/vlen=2/mvcc=0 V: 24
K: 7/cf:name/1446016604500/Put/vlen=8/mvcc=0 V: xiaoming
|
{HBASE_HOME}/bin/hbase hfile -m -f /hbase/data/default/kks1/68639b7c80a31bf91448d26bb7af17b7/cf/74e43a51ebd14007870ac58658330aeb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
Block index size as per heapsize: 392
reader=/hbase/data/default/kks1/68639b7c80a31bf91448d26bb7af17b7/cf/74e43a51ebd14007870ac58658330aeb,
compression=none,
cacheConf=CacheConfig:disabled,
firstKey=1/cf:age/1445860350861/Put,
lastKey=3/cf:name/1445860428949/Put,
avgKeyLen=18,
avgValueLen=5,
entries=8,
length=1211
Trailer:
fileinfoOffset=448,
loadOnOpenDataOffset=343,
dataIndexCount=1,
metaIndexCount=0,
totalUncomressedBytes=1123,
entryCount=8,
compressionCodec=NONE,
uncompressedDataIndexSize=31,
numDataIndexLevels=1,
firstDataBlockOffset=0,
lastDataBlockOffset=0,
comparatorClassName=org.apache.hadoop.hbase.KeyValue$KeyComparator,
majorVersion=2,
minorVersion=3
Fileinfo:
BLOOM_FILTER_TYPE = ROW
DELETE_FAMILY_COUNT = \x00\x00\x00\x00\x00\x00\x00\x00
EARLIEST_PUT_TS = \x00\x00\x01P\xA3\xFD\xF7X
KEY_VALUE_VERSION = \x00\x00\x00\x01
LAST_BLOOM_KEY = 3
MAJOR_COMPACTION_KEY = \x00
MAX_MEMSTORE_TS_KEY = \x00\x00\x00\x00\x00\x00\x00\x00
MAX_SEQ_ID_KEY = 10
TIMERANGE = 1445860341592....1445860428949
hfile.AVG_KEY_LEN = 18
hfile.AVG_VALUE_LEN = 5
hfile.LASTKEY = \x00\x013\x02cfname\x00\x00\x01P\xA3\xFFL\x95\x04
Mid-key: \x00\x011\x02cfage\x00\x00\x01P\xA3\xFE\x1B\x8D\x04
Bloom filter:
BloomSize: 8
No of Keys in bloom: 3
Max Keys for bloom: 6
Percentage filled: 50%
Number of chunks: 1
Comparator: RawBytesComparator
Delete Family Bloom filter:
Not present
|
物理上,表是按列族分开存储的,每个 Column Family 存储在 HDFS 上的一个单独文件中(因此最好将具有共同I/O特性的列放在一个 Column Family中)
HBase 为每个值维护了多级索引,即: RowKey, column family, column name, timestamp
Table 中的所有行都按照 RowKey 的字典序排列
Table 在行的方向上分割为多个Region
Region 按大小分割的,每个表开始只有一个 region ,随着数据增多, region 不断增大,当增大到一个阀值的时候,region就会等分会两个新的region,之后会有越来越多的region
Region 实际上是rowkey 排序后的按规则分割的连续的存储空间
Region 是 HBase 中分布式存储和负载均衡的最小单元。不同Region分布到不同RegionServer上
Region 虽然是分布式存储的最小单元,但并不是存储的最小单元。
HBase 是强一致性的。
? 事务
? join、group by等关系查询不计算
? 不按rowkey查询数据
? 高并发随机读
? 低延迟随机读
重点是RowKey设计
Scan.setFilter
所有的过滤器都在服务端生效
数据仍然需要从硬盘读进RegionServer,过滤器在RegionServer里发挥作用
过滤器也可以自定义
如果没有计数器,用户需要针对一行加锁,读取一行的值,然后再加上特定的值,然后再写回并释放锁,尤其是当客户端进程崩溃之后,尚未释放的锁需要等待超时恢复,这样在一个高负载的系统中会引起灾难性后果。
计数器就是读取并修改(Read and modify),保证一次客户端操作的原子性。
将列作为计数器
通过Check-And-Save保证写操作原子性
便于给某些在线应用提供实时统计功能
允许用户在region服务器上运行自己的代码,也就是允许用户执行region级操作
RDBMS 通常是寻道型的
LSM树 属于传输型的
LSM树 会使用日志文件
为长期具有很高记录更新频率的文件提供低成本的索引机制
LSM 树 最适合 索引插入 比 查询操作 更常见的操作
主题思想是划分不同等级的树
LSM树和B+树相比,LSM树牺牲了部分读性能,用来大幅提高写性能。
LSM树的设计思想非常朴素:将对数据的修改增量保持在内存中,达到指定的大小限制后将这些修改操作顺序批量写入磁盘,不过读取的时候稍微麻烦,需要合并磁盘中历史数据和内存中最近修改操作,所以写入性能大大提升,读取时可能需要先看是否命中内存,否则需要访问较多的磁盘文件。(极端的说,基于LSM树实现的HBase的写性能比Mysql高了一个数量级,读性能低了一个数量级)
LSM树原理把一棵大树拆分成N棵小树,它首先写入内存中,随着小树越来越大,内存中的小树会flush到磁盘中,磁盘中的树定期可以做merge操作,合并成一棵大树,以优化读性能。
当store的store file集合中总文件长度太大时(超过配置的阈值),这个region会一分为二.
父 region 下线,新分裂的俩个子 region 会被Master 分配到相应的 RegionServer.
minor compaction 将部分小文件合并成大文件
majar compaction
合并所有文件为一个
操作的是此列族的全量数据,所以可以做物理删除。但是也由于是全量数据,执行起来耗费时间也会比价长
用空的新memstore 获取更新数据,将满的旧memstore写入磁盘。
第一次读取:
步骤1:读取ZooKeeper中META表的位置。
步骤2:读取META表中用户表的位置。
步骤3:读取数据。
如果已经读取过一次,则root表和.META都会缓存到本地,直接去用户表的位置读取数据。
当我们从客户端读取,写入数据的时候,我们需要知道数据的 Rowkey是在哪个Region以及我们需要的Region是在哪个RegionServer上。
而这正是HBase Meta表所记录的信息。
最小访问单元 是 HFile 中的 一个 Block.
1
2
3
4
5
6
7
8
9
10
|
Configuration conf = HBaseConfiguration.create();
HTable htable = new HTable(conf, "tablename");
Put put = new Put(Bytes.toBytes("rowkey"));
put.add(Bytes.toBytes("cf"), Bytes.toBytes("c1"), Bytes.toBytes("val1"));
put.add(Bytes.toBytes("cf"), Bytes.toBytes("c2"), Bytes.toBytes("val2"));
put.add(Bytes.toBytes("cf"), Bytes.toBytes("c3"), Bytes.toBytes("val3"));
htable.put(put);
htable.close();
}
|
当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。
它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难
Bloom Filter不适合那些“零错误”的应用场合。而在能容忍低错误率的应用场合下,Bloom Filter通过极少的错误换取了存储空间的极大节省。
None 默认
ROW 行级
ROWCOL 列标识符级
LZO SNAPPY GZIP
标签:线程 levels pre tar 加速 bms hdf 大小 合数
原文地址:https://www.cnblogs.com/SuKiWX/p/8861993.html