Chaopeng Luo created HBASE-28866:
------------------------------------
Summary: Check and add logs for the configuration settings of log
cleaner to prevent runtime errors
Key: HBASE-28866
URL: https://issues.apache.org/jira/browse/HBASE-28866
Project: HBase
Issue Type: Bug
Components: master
Affects Versions: 3.0.0-beta-1, 2.4.2
Reporter: Chaopeng Luo
Fix For: 3.0.0-beta-1
Attachments: LogCleaner.patch
============================
Problem
-------------------------------------------------
HBase Master cannot be initialized with the following setting:
<property>
<name>hbase.oldwals.cleaner.thread.size</name>
<value>-1</value>
<description>Default is 2</description>
</property>
After running the start-hbase.sh, the Master node could not be started due to
an exception:
{code:java}
ERROR [master/localhost:16000:becomeActiveMaster] master.HMaster: Failed to
become active master
java.lang.IllegalArgumentException: Illegal Capacity: -1
at java.util.ArrayList.<init>(ArrayList.java:157)
at
org.apache.hadoop.hbase.master.cleaner.LogCleaner.createOldWalsCleaner(LogCleaner.java:149)
at
org.apache.hadoop.hbase.master.cleaner.LogCleaner.<init>(LogCleaner.java:80)
at
org.apache.hadoop.hbase.master.HMaster.startServiceThreads(HMaster.java:1329)
at
org.apache.hadoop.hbase.master.HMaster.finishActiveMasterInitialization(HMaster.java:917)
at
org.apache.hadoop.hbase.master.HMaster.startActiveMasterManager(HMaster.java:2081)
at org.apache.hadoop.hbase.master.HMaster.lambda$0(HMaster.java:505)
at java.lang.Thread.run(Thread.java:750){code}
We were really confused and misled by the error log as the 'Illegal Capacity'
of ArrayList seems like an internal code issue.
After we read the source code, we found that
"hbase.oldwals.cleaner.thread.size" is parsed and used in
createOldWalsCleaner() function without checking:
{code:java}
int size = conf.getInt(OLD_WALS_CLEANER_THREAD_SIZE,
DEFAULT_OLD_WALS_CLEANER_THREAD_SIZE); this.oldWALsCleaner =
createOldWalsCleaner(size); {code}
The value of "hbase.oldwals.cleaner.thread.size" will be served as the
initialCapacity of ArrayList. If the configuration value is negative, an
IllegalArgumentException will be thrown.:
{code:java}
private List<Thread> createOldWalsCleaner(int size) {
...
List<Thread> oldWALsCleaner = new ArrayList<>(size);
...
} {code}
============================
Solution (the attached patch)
-------------------------------------------------
The basic idea of the attached patch is to add a check and relevant logging for
this value during the initialization of the {{LogCleaner}} in the constructor.
This will help users better diagnose the issue. The detailed patch is shown
below.
{code:java}
@@ -78,6 +78,11 @@
public class LogCleaner extends CleanerChore<BaseLogCleanerDelegate>
pool, params, null);
this.pendingDelete = new LinkedBlockingQueue<>();
int size = conf.getInt(OLD_WALS_CLEANER_THREAD_SIZE,
DEFAULT_OLD_WALS_CLEANER_THREAD_SIZE);
+ if (size <= 0) {
+ LOG.warn("The size of old WALs cleaner thread is {}, which is invalid, "
+ + "the default value will be used.", size);
+ size = DEFAULT_OLD_WALS_CLEANER_THREAD_SIZE;
+ }
this.oldWALsCleaner = createOldWalsCleaner(size);
this.cleanerThreadTimeoutMsec =
conf.getLong(OLD_WALS_CLEANER_THREAD_TIMEOUT_MSEC,
DEFAULT_OLD_WALS_CLEANER_THREAD_TIMEOUT_MSEC);{code}
Thanks!
--
This message was sent by Atlassian Jira
(v8.20.10#820010)