View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.namequeues;
21  
22  import java.util.ArrayList;
23  import java.util.List;
24  import java.util.concurrent.locks.ReentrantLock;
25  import org.apache.hadoop.conf.Configuration;
26  import org.apache.hadoop.hbase.classification.InterfaceAudience;
27  import org.apache.hadoop.hbase.namequeues.queue.EvictingQueue;
28  import org.apache.hadoop.hbase.protobuf.generated.TooSlowLog;
29  import org.apache.hadoop.hbase.slowlog.SlowLogTableAccessor;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  /**
34   * Persistent service provider for Slow/LargeLog events
35   */
36  @InterfaceAudience.Private
37  public class SlowLogPersistentService {
38  
39    private static final Logger LOG = LoggerFactory.getLogger(SlowLogPersistentService.class);
40  
41    private static final ReentrantLock LOCK = new ReentrantLock();
42    private static final String SYS_TABLE_QUEUE_SIZE =
43      "hbase.regionserver.slowlog.systable.queue.size";
44    private static final int DEFAULT_SYS_TABLE_QUEUE_SIZE = 1000;
45    private static final int SYSTABLE_PUT_BATCH_SIZE = 100;
46  
47    private final EvictingQueue<TooSlowLog.SlowLogPayload> queueForSysTable;
48  
49    private final Configuration configuration;
50  
51    public SlowLogPersistentService(final Configuration configuration) {
52      this.configuration = configuration;
53      int sysTableQueueSize =
54        configuration.getInt(SYS_TABLE_QUEUE_SIZE, DEFAULT_SYS_TABLE_QUEUE_SIZE);
55      queueForSysTable = EvictingQueue.create(sysTableQueueSize);
56    }
57  
58    public void addToQueueForSysTable(TooSlowLog.SlowLogPayload slowLogPayload) {
59      queueForSysTable.add(slowLogPayload);
60    }
61  
62    /**
63     * Poll from queueForSysTable and insert 100 records in hbase:slowlog table in single batch
64     */
65    public void addAllLogsToSysTable() {
66      if (queueForSysTable == null) {
67        LOG.trace("hbase.regionserver.slowlog.systable.enabled is turned off. Exiting.");
68        return;
69      }
70      if (LOCK.isLocked()) {
71        return;
72      }
73      LOCK.lock();
74      try {
75        List<TooSlowLog.SlowLogPayload> slowLogPayloads = new ArrayList<>();
76        int i = 0;
77        while (!queueForSysTable.isEmpty()) {
78          slowLogPayloads.add(queueForSysTable.poll());
79          i++;
80          if (i == SYSTABLE_PUT_BATCH_SIZE) {
81            SlowLogTableAccessor.addSlowLogRecords(slowLogPayloads, this.configuration);
82            slowLogPayloads.clear();
83            i = 0;
84          }
85        }
86        if (slowLogPayloads.size() > 0) {
87          SlowLogTableAccessor.addSlowLogRecords(slowLogPayloads, this.configuration);
88        }
89      } finally {
90        LOCK.unlock();
91      }
92    }
93  
94  }