1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.util.compaction;
20
21 import com.google.common.base.Optional;
22 import com.google.common.collect.Sets;
23
24 import java.io.IOException;
25 import java.util.Arrays;
26 import java.util.Set;
27 import java.util.concurrent.Executors;
28
29 import org.apache.commons.cli.BasicParser;
30 import org.apache.commons.cli.CommandLine;
31 import org.apache.commons.cli.CommandLineParser;
32 import org.apache.commons.cli.Option;
33 import org.apache.commons.cli.Options;
34 import org.apache.commons.cli.ParseException;
35 import org.apache.hadoop.conf.Configuration;
36 import org.apache.hadoop.hbase.HBaseConfiguration;
37 import org.apache.hadoop.hbase.HBaseInterfaceAudience;
38 import org.apache.hadoop.hbase.HColumnDescriptor;
39 import org.apache.hadoop.hbase.HConstants;
40 import org.apache.hadoop.hbase.HRegionInfo;
41 import org.apache.hadoop.hbase.HTableDescriptor;
42 import org.apache.hadoop.hbase.TableName;
43 import org.apache.hadoop.hbase.classification.InterfaceAudience;
44 import org.apache.hadoop.hbase.client.Connection;
45 import org.apache.hadoop.hbase.client.ConnectionFactory;
46 import org.apache.hadoop.util.ToolRunner;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50
51
52
53
54 @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS)
55 public class MajorCompactorTTL extends MajorCompactor {
56
57 private static final Logger LOG = LoggerFactory.getLogger(MajorCompactorTTL .class);
58
59 private HTableDescriptor htd;
60
61 @InterfaceAudience.Private
62 public MajorCompactorTTL(Configuration conf, HTableDescriptor htd, int concurrency,
63 long sleepForMs) throws IOException {
64 this.connection = ConnectionFactory.createConnection(conf);
65 this.htd = htd;
66 this.tableName = htd.getTableName();
67 this.storesToCompact = Sets.newHashSet();
68 this.sleepForMs = sleepForMs;
69 this.executor = Executors.newFixedThreadPool(concurrency);
70 this.clusterCompactionQueues = new ClusterCompactionQueues(concurrency);
71 }
72
73 protected MajorCompactorTTL() {
74 super();
75 }
76
77 @Override
78 protected Optional<MajorCompactionRequest> getMajorCompactionRequest(HRegionInfo hri)
79 throws IOException {
80 return MajorCompactionTTLRequest.newRequest(connection.getConfiguration(), hri, htd);
81 }
82
83 @Override
84 protected Set<String> getStoresRequiringCompaction(MajorCompactionRequest request)
85 throws IOException {
86 return ((MajorCompactionTTLRequest)request).getStoresRequiringCompaction(htd).keySet();
87 }
88
89 public int compactRegionsTTLOnTable(Configuration conf, String table, int concurrency,
90 long sleep, int numServers, int numRegions, boolean dryRun, boolean skipWait)
91 throws Exception {
92
93 Connection conn = ConnectionFactory.createConnection(conf);
94 TableName tableName = TableName.valueOf(table);
95
96 HTableDescriptor htd = conn.getAdmin().getTableDescriptor(tableName);
97 if (!doesAnyColFamilyHaveTTL(htd)) {
98 LOG.info("No TTL present for CF of table: " + tableName + ", skipping compaction");
99 return 0;
100 }
101
102 LOG.info("Major compacting table " + tableName + " based on TTL");
103 MajorCompactor compactor = new MajorCompactorTTL(conf, htd, concurrency, sleep);
104 compactor.setNumServers(numServers);
105 compactor.setNumRegions(numRegions);
106 compactor.setSkipWait(skipWait);
107
108 compactor.initializeWorkQueues();
109 if (!dryRun) {
110 compactor.compactAllRegions();
111 }
112 compactor.shutdown();
113 return ERRORS.size();
114 }
115
116 private boolean doesAnyColFamilyHaveTTL(HTableDescriptor htd) {
117 for (HColumnDescriptor descriptor : htd.getColumnFamilies()) {
118 if (descriptor.getTimeToLive() != HConstants.FOREVER) {
119 return true;
120 }
121 }
122 return false;
123 }
124
125 private Options getOptions() {
126 Options options = getCommonOptions();
127
128 Option tableOption = new Option("table", true, "Table to be compacted");
129 tableOption.setRequired(true);
130 options.addOption(tableOption);
131
132 return options;
133 }
134
135 @Override
136 public int run(String[] args) throws Exception {
137 Options options = getOptions();
138
139 final CommandLineParser cmdLineParser = new BasicParser();
140 CommandLine commandLine;
141 try {
142 commandLine = cmdLineParser.parse(options, args);
143 } catch (ParseException parseException) {
144 System.err.println("ERROR: Unable to parse command-line arguments " + Arrays.toString(args)
145 + " due to: " + parseException);
146 printUsage(options);
147 throw parseException;
148 }
149
150 String table = commandLine.getOptionValue("table");
151 int numServers = Integer.parseInt(commandLine.getOptionValue("numservers", "-1"));
152 int numRegions = Integer.parseInt(commandLine.getOptionValue("numregions", "-1"));
153 int concurrency = Integer.parseInt(commandLine.getOptionValue("servers", "1"));
154 long sleep = Long.parseLong(commandLine.getOptionValue("sleep", "30000"));
155 boolean dryRun = commandLine.hasOption("dryRun");
156 boolean skipWait = commandLine.hasOption("skipWait");
157
158 return compactRegionsTTLOnTable(HBaseConfiguration.create(), table, concurrency, sleep,
159 numServers, numRegions, dryRun, skipWait);
160 }
161
162 public static void main(String[] args) throws Exception {
163 ToolRunner.run(HBaseConfiguration.create(), new MajorCompactorTTL(), args);
164 }
165 }