Skip to content

Commit 6111f5a

Browse files
committed
HBAE-24408 Introduce a general 'local region' to store data on master
1 parent a8724e8 commit 6111f5a

38 files changed

+1597
-746
lines changed

hbase-common/src/main/resources/hbase-default.xml

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ possible configurations would overwhelm and obscure the important.
125125
</property>
126126
<property>
127127
<name>hbase.master.logcleaner.plugins</name>
128-
<value>org.apache.hadoop.hbase.master.cleaner.TimeToLiveLogCleaner,org.apache.hadoop.hbase.master.cleaner.TimeToLiveProcedureWALCleaner</value>
128+
<value>org.apache.hadoop.hbase.master.cleaner.TimeToLiveLogCleaner,org.apache.hadoop.hbase.master.cleaner.TimeToLiveProcedureWALCleaner,org.apache.hadoop.hbase.master.cleaner.TimeToLiveMasterLocalStoreWALCleaner</value>
129129
<description>A comma-separated list of BaseLogCleanerDelegate invoked by
130130
the LogsCleaner service. These WAL cleaners are called in order,
131131
so put the cleaner that prunes the most files in front. To
@@ -139,16 +139,9 @@ possible configurations would overwhelm and obscure the important.
139139
<description>How long a WAL remain in the archive ({hbase.rootdir}/oldWALs) directory,
140140
after which it will be cleaned by a Master thread. The value is in milliseconds.</description>
141141
</property>
142-
<property>
143-
<name>hbase.master.procedurewalcleaner.ttl</name>
144-
<value>604800000</value>
145-
<description>How long a Procedure WAL will remain in the
146-
archive directory, after which it will be cleaned
147-
by a Master thread. The value is in milliseconds.</description>
148-
</property>
149142
<property>
150143
<name>hbase.master.hfilecleaner.plugins</name>
151-
<value>org.apache.hadoop.hbase.master.cleaner.TimeToLiveHFileCleaner</value>
144+
<value>org.apache.hadoop.hbase.master.cleaner.TimeToLiveHFileCleaner,org.apache.hadoop.hbase.master.cleaner.TimeToLiveMasterLocalStoreHFileCleaner</value>
152145
<description>A comma-separated list of BaseHFileCleanerDelegate invoked by
153146
the HFileCleaner service. These HFiles cleaners are called in order,
154147
so put the cleaner that prunes the most files in front. To
@@ -157,17 +150,6 @@ possible configurations would overwhelm and obscure the important.
157150
default hfile cleaners in the list as they will be overwritten in
158151
hbase-site.xml.</description>
159152
</property>
160-
<property>
161-
<name>hbase.procedure.store.region.hfilecleaner.plugins</name>
162-
<value>org.apache.hadoop.hbase.master.cleaner.TimeToLiveHFileCleaner</value>
163-
<description>A comma-separated list of BaseHFileCleanerDelegate invoked by
164-
the RegionProcedureStore HFileCleaner service. These HFiles cleaners are
165-
called in order, so put the cleaner that prunes the most files in front. To
166-
implement your own BaseHFileCleanerDelegate, just put it in HBase's classpath
167-
and add the fully qualified class name here. Always add the above
168-
default hfile cleaners in the list as they will be overwritten in
169-
hbase-site.xml.</description>
170-
</property>
171153
<property>
172154
<name>hbase.master.infoserver.redirect</name>
173155
<value>true</value>

hbase-server/src/main/java/org/apache/hadoop/hbase/io/FileLink.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,12 +521,13 @@ public static String getBackReferenceFileName(final Path dirPath) {
521521

522522
/**
523523
* Checks if the specified directory path is a back reference links folder.
524-
*
525524
* @param dirPath Directory path to verify
526525
* @return True if the specified directory is a link references folder
527526
*/
528527
public static boolean isBackReferencesDir(final Path dirPath) {
529-
if (dirPath == null) return false;
528+
if (dirPath == null) {
529+
return false;
530+
}
530531
return dirPath.getName().startsWith(BACK_REFERENCES_DIRECTORY_PREFIX);
531532
}
532533

hbase-server/src/main/java/org/apache/hadoop/hbase/io/HFileLink.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,9 @@ public static boolean isHFileLink(final Path path) {
209209
*/
210210
public static boolean isHFileLink(String fileName) {
211211
Matcher m = LINK_NAME_PATTERN.matcher(fileName);
212-
if (!m.matches()) return false;
212+
if (!m.matches()) {
213+
return false;
214+
}
213215
return m.groupCount() > 2 && m.group(4) != null && m.group(3) != null && m.group(2) != null;
214216
}
215217

hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,6 +1447,8 @@ private void startServiceThreads() throws IOException {
14471447
this.executorService.startExecutorService(ExecutorType.MASTER_TABLE_OPERATIONS, 1);
14481448
startProcedureExecutor();
14491449

1450+
// Create cleaner thread pool
1451+
cleanerPool = new DirScanPool(conf);
14501452
// Start log cleaner thread
14511453
int cleanerInterval =
14521454
conf.getInt(HBASE_MASTER_CLEANER_INTERVAL, DEFAULT_HBASE_MASTER_CLEANER_INTERVAL);
@@ -1550,9 +1552,7 @@ protected void stopServiceThreads() {
15501552

15511553
private void createProcedureExecutor() throws IOException {
15521554
MasterProcedureEnv procEnv = new MasterProcedureEnv(this);
1553-
// Create cleaner thread pool
1554-
cleanerPool = new DirScanPool(conf);
1555-
procedureStore = new RegionProcedureStore(this, cleanerPool,
1555+
procedureStore = new RegionProcedureStore(this,
15561556
new MasterProcedureEnv.FsUtilsLeaseRecovery(this));
15571557
procedureStore.registerListener(new ProcedureStoreListener() {
15581558

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.hbase.master.cleaner;
19+
20+
import java.time.Instant;
21+
import java.time.ZoneOffset;
22+
import java.time.format.DateTimeFormatter;
23+
import org.apache.hadoop.conf.Configuration;
24+
import org.apache.hadoop.fs.FileStatus;
25+
import org.apache.hadoop.fs.Path;
26+
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
27+
import org.apache.yetus.audience.InterfaceAudience;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
31+
/**
32+
* Base class for time to live file cleaner.
33+
*/
34+
@InterfaceAudience.Private
35+
public abstract class BaseTimeToLiveFileCleaner extends BaseLogCleanerDelegate {
36+
37+
private static final Logger LOG =
38+
LoggerFactory.getLogger(BaseTimeToLiveFileCleaner.class.getName());
39+
40+
private static final DateTimeFormatter FORMATTER =
41+
DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneOffset.systemDefault());
42+
43+
// Configured time a log can be kept after it was closed
44+
private long ttlMs;
45+
46+
private boolean stopped = false;
47+
48+
@Override
49+
public final void setConf(Configuration conf) {
50+
super.setConf(conf);
51+
this.ttlMs = getTtlMs(conf);
52+
}
53+
54+
@Override
55+
public boolean isFileDeletable(FileStatus status) {
56+
// Files are validated for the second time here,
57+
// if it causes a bottleneck this logic needs refactored
58+
if (!valiateFilename(status.getPath())) {
59+
return true;
60+
}
61+
long currentTime = EnvironmentEdgeManager.currentTime();
62+
long time = status.getModificationTime();
63+
long life = currentTime - time;
64+
65+
if (LOG.isTraceEnabled()) {
66+
LOG.trace("File life:{}ms, ttl:{}ms, current:{}, from{}", life, ttlMs,
67+
FORMATTER.format(Instant.ofEpochMilli(currentTime)),
68+
FORMATTER.format(Instant.ofEpochMilli(time)));
69+
}
70+
if (life < 0) {
71+
LOG.warn("Found a file ({}) newer than current time ({} < {}), probably a clock skew",
72+
status.getPath(), FORMATTER.format(Instant.ofEpochMilli(currentTime)),
73+
FORMATTER.format(Instant.ofEpochMilli(time)));
74+
return false;
75+
}
76+
return life > ttlMs;
77+
}
78+
79+
@Override
80+
public void stop(String why) {
81+
this.stopped = true;
82+
}
83+
84+
@Override
85+
public boolean isStopped() {
86+
return this.stopped;
87+
}
88+
89+
protected abstract long getTtlMs(Configuration conf);
90+
91+
protected abstract boolean valiateFilename(Path file);
92+
}

hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/HFileCleaner.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.hadoop.hbase.Stoppable;
3333
import org.apache.hadoop.hbase.conf.ConfigurationObserver;
3434
import org.apache.hadoop.hbase.io.HFileLink;
35+
import org.apache.hadoop.hbase.master.store.LocalStore;
3536
import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
3637
import org.apache.hadoop.hbase.util.StealJobQueue;
3738
import org.apache.yetus.audience.InterfaceAudience;
@@ -158,10 +159,9 @@ public HFileCleaner(String name, int period, Stoppable stopper, Configuration co
158159

159160
@Override
160161
protected boolean validate(Path file) {
161-
if (HFileLink.isBackReferencesDir(file) || HFileLink.isBackReferencesDir(file.getParent())) {
162-
return true;
163-
}
164-
return StoreFileInfo.validateStoreFileName(file.getName());
162+
return HFileLink.isBackReferencesDir(file) || HFileLink.isBackReferencesDir(file.getParent()) ||
163+
StoreFileInfo.validateStoreFileName(file.getName()) ||
164+
file.getName().endsWith(LocalStore.ARCHIVED_HFILE_SUFFIX);
165165
}
166166

167167
/**

hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/LogCleaner.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.apache.hadoop.hbase.Stoppable;
3636
import org.apache.hadoop.hbase.conf.ConfigurationObserver;
3737
import org.apache.hadoop.hbase.master.procedure.MasterProcedureUtil;
38+
import org.apache.hadoop.hbase.master.store.LocalStore;
3839
import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;
3940
import org.apache.yetus.audience.InterfaceAudience;
4041
import org.slf4j.Logger;
@@ -86,8 +87,9 @@ public LogCleaner(final int period, final Stoppable stopper, Configuration conf,
8687

8788
@Override
8889
protected boolean validate(Path file) {
89-
return AbstractFSWALProvider.validateWALFilename(file.getName())
90-
|| MasterProcedureUtil.validateProcedureWALFilename(file.getName());
90+
return AbstractFSWALProvider.validateWALFilename(file.getName()) ||
91+
MasterProcedureUtil.validateProcedureWALFilename(file.getName()) ||
92+
file.getName().endsWith(LocalStore.ARCHIVED_WAL_SUFFIX);
9193
}
9294

9395
@Override

hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/TimeToLiveHFileCleaner.java

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,48 +17,33 @@
1717
*/
1818
package org.apache.hadoop.hbase.master.cleaner;
1919

20-
import org.apache.yetus.audience.InterfaceAudience;
21-
import org.slf4j.Logger;
22-
import org.slf4j.LoggerFactory;
2320
import org.apache.hadoop.conf.Configuration;
24-
import org.apache.hadoop.fs.FileStatus;
21+
import org.apache.hadoop.fs.Path;
2522
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
26-
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
23+
import org.apache.hadoop.hbase.io.HFileLink;
24+
import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
25+
import org.apache.yetus.audience.InterfaceAudience;
2726

2827
/**
2928
* HFile cleaner that uses the timestamp of the hfile to determine if it should be deleted. By
3029
* default they are allowed to live for {@value #DEFAULT_TTL}
3130
*/
3231
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
33-
public class TimeToLiveHFileCleaner extends BaseHFileCleanerDelegate {
32+
public class TimeToLiveHFileCleaner extends BaseTimeToLiveFileCleaner {
3433

35-
private static final Logger LOG = LoggerFactory.getLogger(TimeToLiveHFileCleaner.class.getName());
3634
public static final String TTL_CONF_KEY = "hbase.master.hfilecleaner.ttl";
35+
3736
// default ttl = 5 minutes
3837
public static final long DEFAULT_TTL = 60000 * 5;
39-
// Configured time a hfile can be kept after it was moved to the archive
40-
private long ttl;
4138

4239
@Override
43-
public void setConf(Configuration conf) {
44-
this.ttl = conf.getLong(TTL_CONF_KEY, DEFAULT_TTL);
45-
super.setConf(conf);
40+
protected long getTtlMs(Configuration conf) {
41+
return conf.getLong(TTL_CONF_KEY, DEFAULT_TTL);
4642
}
4743

4844
@Override
49-
public boolean isFileDeletable(FileStatus fStat) {
50-
long currentTime = EnvironmentEdgeManager.currentTime();
51-
long time = fStat.getModificationTime();
52-
long life = currentTime - time;
53-
if (LOG.isTraceEnabled()) {
54-
LOG.trace("HFile life:" + life + ", ttl:" + ttl + ", current:" + currentTime + ", from: "
55-
+ time);
56-
}
57-
if (life < 0) {
58-
LOG.warn("Found a hfile (" + fStat.getPath() + ") newer than current time (" + currentTime
59-
+ " < " + time + "), probably a clock skew");
60-
return false;
61-
}
62-
return life > ttl;
45+
protected boolean valiateFilename(Path file) {
46+
return HFileLink.isBackReferencesDir(file) || HFileLink.isBackReferencesDir(file.getParent()) ||
47+
StoreFileInfo.validateStoreFileName(file.getName());
6348
}
6449
}

hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/TimeToLiveLogCleaner.java

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,66 +17,31 @@
1717
*/
1818
package org.apache.hadoop.hbase.master.cleaner;
1919

20-
import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;
21-
import org.apache.yetus.audience.InterfaceAudience;
22-
import org.slf4j.Logger;
23-
import org.slf4j.LoggerFactory;
2420
import org.apache.hadoop.conf.Configuration;
25-
import org.apache.hadoop.fs.FileStatus;
21+
import org.apache.hadoop.fs.Path;
2622
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
27-
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
23+
import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;
24+
import org.apache.yetus.audience.InterfaceAudience;
2825

2926
/**
30-
* Log cleaner that uses the timestamp of the wal to determine if it should
31-
* be deleted. By default they are allowed to live for 10 minutes.
27+
* Log cleaner that uses the timestamp of the wal to determine if it should be deleted. By default
28+
* they are allowed to live for 10 minutes.
3229
*/
3330
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
34-
public class TimeToLiveLogCleaner extends BaseLogCleanerDelegate {
35-
private static final Logger LOG = LoggerFactory.getLogger(TimeToLiveLogCleaner.class.getName());
31+
public class TimeToLiveLogCleaner extends BaseTimeToLiveFileCleaner {
32+
3633
public static final String TTL_CONF_KEY = "hbase.master.logcleaner.ttl";
34+
3735
// default ttl = 10 minutes
3836
public static final long DEFAULT_TTL = 600_000L;
39-
// Configured time a log can be kept after it was closed
40-
private long ttl;
41-
private boolean stopped = false;
42-
43-
@Override
44-
public boolean isFileDeletable(FileStatus fStat) {
45-
// Files are validated for the second time here,
46-
// if it causes a bottleneck this logic needs refactored
47-
if (!AbstractFSWALProvider.validateWALFilename(fStat.getPath().getName())) {
48-
return true;
49-
}
50-
51-
long currentTime = EnvironmentEdgeManager.currentTime();
52-
long time = fStat.getModificationTime();
53-
long life = currentTime - time;
54-
55-
if (LOG.isTraceEnabled()) {
56-
LOG.trace("Log life:" + life + ", ttl:" + ttl + ", current:" + currentTime + ", from: "
57-
+ time);
58-
}
59-
if (life < 0) {
60-
LOG.warn("Found a log (" + fStat.getPath() + ") newer than current time (" + currentTime
61-
+ " < " + time + "), probably a clock skew");
62-
return false;
63-
}
64-
return life > ttl;
65-
}
66-
67-
@Override
68-
public void setConf(Configuration conf) {
69-
super.setConf(conf);
70-
this.ttl = conf.getLong(TTL_CONF_KEY, DEFAULT_TTL);
71-
}
7237

7338
@Override
74-
public void stop(String why) {
75-
this.stopped = true;
39+
protected long getTtlMs(Configuration conf) {
40+
return conf.getLong(TTL_CONF_KEY, DEFAULT_TTL);
7641
}
7742

7843
@Override
79-
public boolean isStopped() {
80-
return this.stopped;
44+
protected boolean valiateFilename(Path file) {
45+
return AbstractFSWALProvider.validateWALFilename(file.getName());
8146
}
8247
}

0 commit comments

Comments
 (0)