①在
CompactingMemStore这个类中 默认使用BASIC
public
static
final
String COMPACTING_MEMSTORE_TYPE_DEFAULT =
String.valueOf(MemoryCompactionPolicy.BASIC);
②但是优先级别是 hbase-default.xml
<property>
<name>hbase.hregion.compacting.memstore.typename>
<value>NONEvalue>
<description>Determines the type of memstore to be used by user tables on
creation. By default it is NONE and so we use the default memstore. To enable
compacting memstore on creation of new user tables, set this property to
BASIC/EAGER/ADAPTIVE. All subsequent table creations will have the
new value of this attribute.
See http://hbase.apache.org/book.html#inmemory_compaction for more on
In-memory Compaction.
description>
property>
注: 默认不压缩memstore,可以配置成BASIC/EAGER/ADAPTIVE对memstore进行压缩
<property>
<name>hbase.systemtables.compacting.memstore.typename>
<value>NONEvalue>
<description>Determines the type of memstore to be used for system tables like
META, namespace tables etc., on creation. By default NONE is the type and hence
we use the default memstore for all the system tables. If we need to have compacting
memstore on creation of system tables then set this property to BASIC/EAGER
See http://hbase.apache.org/book.html#inmemory_compaction for more on
In-memory Compaction.
description>
property>
注:创建系统表的时候,默认是none,可以改成BASIC和EAGER
问题? 需要测试CompactingMemstore
和DefaultMemstore在代码中的调用顺序。
新的RpcThrottlingException不赞成ThrottlingException。新的RpcThrottlingException是一个可重试的异常,客户端将在超过Rpc限制配额时重试。弃用的ThrottlingException是一个不可修改的异常。
Quota 限额
1.quota的语句
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', TABLE => 't2', LIMIT => '10req/sec'
2.quota的介绍
(1)Quotas分别支持表级别以及用户级别资源限制,或者同时支持表级别和用户级别,如示例所示
(2)THROTTLE_TYPE可以取值READ / WRITE,分别对随机读和随机写进行限制
(3)LIMIT 可以从两个维度对资源进行限制,分别为req/time 和 size/time,前者限制单位时间内的请求数,后者限制单位时间内的请求数据量。需要指明的是time的单位可以是sec | min | hour | day,size的单位可以是B(bytes) | K | M | G | T | P,因此LIMIT可以表示为’1000req/min’或者’100G/day’,分别表示’限制1分钟的请求数在1000次以内’,’限制一台的数据量为100G’
总体来说,Quotas功能总体看来基本完成了资源限制的职能,达到了资源限制的目的。同时 支持用户级别和表级别,另外同时支持请求大小和请求数量两个维度,基本涵盖了常见的资源限制维度
目的:起到资源限制的作用,当客户端超过RPC限制时进行重试,直到成功或者资源耗尽
① sync、hflush、hsync的解释
hadoop2.0及以上版本的DFSOutputStream提供了sync ,hflush,hsync三个方法,三个方法的区别是
sync: client将数据刷到每个Datanode的缓存中,会有数据丢失的风险
hflush:与sync一样,会有数据丢失的风险
hsync:client客户端将数据刷到每个Datanode磁盘中,不会有数据丢失的风险。
②在哪里用的hsync和hflush
2.0.0版本在WALProcedureStore这个类中增加了些同步方法,防止当hadoop集群出现故障时,hbase访问WAL时无法访问之前预写入日志的所有数据,导致数据丢失的问题。
③hbase-2.0.0在WALProcedureStore改动的位置
protected
void
syncStream(
final
FSDataOutputStream
stream
)
throws
IOException {
if
(
useHsync
) {
stream
.hsync();
}
else
{
stream
.hflush();
}
}
①重现步骤如下:
1.创建一个包含多个列族的表格
CREATE TABLE TBL(
COL1 VARCHAR NOT NULL,
COL2 VARCHAR NOT NULL,
COL3 VARCHAR,
FAM.COL4 VARCHAR,
CONSTRAINT TRADE_EVENT_PK PRIMARY KEY(COL1,COL2)
)
2.插入一行
UPSERT INTO TBL(COL1,COL2)值(
'AAA'
,
'BBB'
)
3.使用DESC查询表格
SELECT * FROM TBL WHERE COL2 =
'
BBB'ORDER BY COL1 DESC
遵循上述步骤,我们会面临以下例外情况。
java.util.concurrent.ExecutionException:org.apache.phoenix.exception.PhoenixIOException:org.apache.hadoop.hbase.DoNotRetryIOException:TBL ,, 1521251842845.153781990c0fb4bc34e3f2c721a6f415 .: requestSeek无法在ReversedKeyValueHeap上调用
在org.apache.phoenix.util.ServerUtil.createIOException(ServerUtil.java:96)
在org.apache.phoenix.util.ServerUtil.throwIOException(ServerUtil.java:62)
在org.apache.phoenix.iterate.RegionScannerFactory $ 1.nextRaw(RegionScannerFactory.java:212)
在org.apache.phoenix.coprocessor.DelegateRegionScanner.nextRaw(DelegateRegionScanner.java:82)
在org.apache.phoenix.coprocessor.DelegateRegionScanner.nextRaw(DelegateRegionScanner.java:82)
在org.apache.phoenix.coprocessor.BaseScannerRegionObserver $ RegionScannerHolder.nextRaw(BaseScannerRegionObserver.java:294)
在org.apache.hadoop.hbase.regionserver.RSRpcServices.scan(RSRpcServices.java:2808)
在org.apache.hadoop.hbase.regionserver.RSRpcServices.scan(RSRpcServices.java:3045)
在org.apache.hadoop.hbase.protobuf.generated.ClientProtos $ ClientService $ 2.callBlockingMethod(ClientProtos.java:36613)
在org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:2352)
在org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:124)
在org.apache.hadoop.hbase.ipc.RpcExecutor $ Handler.run(RpcExecutor.java:297)
在org.apache.hadoop.hbase.ipc.RpcExecutor $ Handler.run(RpcExecutor.java:277)
导致:java.lang.IllegalStateException:无法在ReversedKeyValueHeap上调用requestSeek
在org.apache.hadoop.hbase.regionserver.ReversedKeyValueHeap.requestSeek(ReversedKeyValueHeap.java:65)
在org.apache.hadoop.hbase.regionserver.HRegion $ RegionScannerImpl.joinedHeapMayHaveData(HRegion.java:6485)
在org.apache.hadoop.hbase.regionserver.HRegion $ RegionScannerImpl.nextInternal(HRegion.java:6412)
在org.apache.hadoop.hbase.regionserver.HRegion $ RegionScannerImpl.nextRaw(HRegion.java:6126)
在org.apache.hadoop.hbase.regionserver.HRegion $ RegionScannerImpl.nextRaw(HRegion.java:6112)
在org.apache.phoenix.iterate.RegionScannerFactory $ 1.nextRaw(RegionScannerFactory.java:175)
... 10多
②以下是我自己测试的,果然报了问题
public
static
void
test()
throws
IOException {
final
byte
[]
FAM1
=
Bytes
.
toBytes
(
"fam1"
);
final
byte
[]
FAM2
=
Bytes
.
toBytes
(
"fam2"
);
final
byte
[]
COL1
=
Bytes
.
toBytes
(
"col1"
);
final
byte
[]
COL2
=
Bytes
.
toBytes
(
"col2"
);
final
byte
[]
VAL1
=
Bytes
.
toBytes
(
"val1"
);
final
byte
[]
VAL2
=
Bytes
.
toBytes
(
"val2"
);
Table
table
=
connection
.getTable(TableName.
valueOf
(
"C00119"
));
Put
put
=
new
Put(
Bytes
.
toBytes
(
"row1"
));
put
.addColumn(
FAM1
,
COL1
,
VAL1
);
put
.addColumn(
FAM2
,
COL2
,
VAL2
);
table
.put(
put
);
put
=
new
Put(
Bytes
.
toBytes
(
"row2"
));
put
.addColumn(
FAM2
,
COL2
,
Bytes
.
toBytes
(
"val"
));
table
.put(
put
);
SingleColumnValueFilter
filter
=
new
SingleColumnValueFilter(
FAM1
,
COL1
, CompareOperator.
EQUAL
,
VAL1
);
// 判断列值是否等于val1
filter
.setFilterIfMissing(
true
);
// 如果为true,当这一列不存在时,不会返回,如果为false,当这一列不存在时,会返回所有的列信息
Scan
scan
=
new
Scan();
scan
.addFamily(
FAM1
);
scan
.addFamily(
FAM2
);
scan
.setFilter(
filter
);
scan
.setReversed(
true
);
scan
.setLoadColumnFamiliesOnDemand(
true
);
ResultScanner
scanner
=
table
.getScanner(
scan
);
for
(Result
result
:
scanner
) {
String
row
=
Bytes
.
toString
(
result
.getRow());
for
(Cell
cell
:
result
.rawCells()) {
String
family
=
Bytes
.
toString
(CellUtil.
cloneFamily
(
cell
));
String
qualifier
=
Bytes
.
toString
(CellUtil.
cloneQualifier
(
cell
));
String
value
=
Bytes
.
toString
(CellUtil.
cloneValue
(
cell
));
System.
out
.println(
"rowkey:"
+
row
+
"列族为:"
+
family
+
"列名为:"
+
qualifier
+
"值为:"
+
value
);
}
}
}
报错:
Exception in thread "main" java.io.UncheckedIOException: org.apache.hadoop.hbase.DoNotRetryIOException: org.apache.hadoop.hbase.DoNotRetryIOException: Reverse scan with loading CFs on demand is not supported
at org.apache.hadoop.hbase.regionserver.ReversedRegionScannerImpl.initializeKVHeap(
ReversedRegionScannerImpl.java:56
)
at org.apache.hadoop.hbase.regionserver.HRegion$RegionScannerImpl.initializeScanners(
HRegion.java:6180
)
at org.apache.hadoop.hbase.regionserver.HRegion$RegionScannerImpl.(
HRegion.java:6151
)
at org.apache.hadoop.hbase.regionserver.HRegion$RegionScannerImpl.(
HRegion.java:6113
)
at org.apache.hadoop.hbase.regionserver.ReversedRegionScannerImpl.(
ReversedRegionScannerImpl.java:48
)
at org.apache.hadoop.hbase.regionserver.HRegion.instantiateRegionScanner(
HRegion.java:2797
)
at org.apache.hadoop.hbase.regionserver.HRegion.getScanner(
HRegion.java:2779
)
at org.apache.hadoop.hbase.regionserver.HRegion.getScanner(
HRegion.java:2761
)
at org.apache.hadoop.hbase.regionserver.HRegion.getScanner(
HRegion.java:2755
)
总结: 目前hbase-2.0.0
不支持按需加载CFs的反向扫描。
具体到底为什么会不支持,需要下来花时间再看一下。
hbase-2.0.0中如果我们定位某个区域时,碰到拆分父级,将跳到下一行进行重试。直到该区域不包含我们的行。(不会报错,RegionOfflineException),
如果split children还没有online,最后到达不包含这行的区域报IOException
原因是:在执行串行复制功能时,在分割某个Region时,不会删除parent region,而是将parent region标记为offline
HBASE-20046重新考虑串行复制的实现
说明:根据hbase官网顺序进行解读,作者微信:15559730752