1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver;
20
21 import java.io.IOException;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.Map;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.ScheduledChore;
29 import org.apache.hadoop.hbase.Stoppable;
30 import org.apache.hadoop.hbase.classification.InterfaceAudience;
31 import org.apache.hadoop.hbase.master.cleaner.TimeToLiveHFileCleaner;
32 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
33 import org.apache.hadoop.util.StringUtils;
34
35
36
37
38
39
40
41
42
43
44 @InterfaceAudience.Private
45 public class StorefileRefresherChore extends ScheduledChore {
46
47 private static final Log LOG = LogFactory.getLog(StorefileRefresherChore.class);
48
49
50
51
52 public static final String REGIONSERVER_STOREFILE_REFRESH_PERIOD
53 = "hbase.regionserver.storefile.refresh.period";
54 static final int DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD = 0;
55
56
57
58
59
60 public static final String REGIONSERVER_META_STOREFILE_REFRESH_PERIOD
61 = "hbase.regionserver.meta.storefile.refresh.period";
62 private HRegionServer regionServer;
63 private long hfileTtl;
64 private int period;
65 private boolean onlyMetaRefresh = true;
66
67
68 private Map<String, Long> lastRefreshTimes;
69
70 public StorefileRefresherChore(int period, boolean onlyMetaRefresh, HRegionServer regionServer,
71 Stoppable stoppable) {
72 super("StorefileRefresherChore", stoppable, period);
73 this.period = period;
74 this.regionServer = regionServer;
75 this.hfileTtl = this.regionServer.getConfiguration().getLong(
76 TimeToLiveHFileCleaner.TTL_CONF_KEY, TimeToLiveHFileCleaner.DEFAULT_TTL);
77 this.onlyMetaRefresh = onlyMetaRefresh;
78 if (period > hfileTtl / 2) {
79 throw new RuntimeException(REGIONSERVER_STOREFILE_REFRESH_PERIOD +
80 " should be set smaller than half of " + TimeToLiveHFileCleaner.TTL_CONF_KEY);
81 }
82 lastRefreshTimes = new HashMap<String, Long>();
83 }
84
85 @Override
86 protected void chore() {
87 for (Region r : regionServer.getOnlineRegionsLocalContext()) {
88 if (!r.isReadOnly()) {
89
90 continue;
91 }
92
93
94 if (onlyMetaRefresh && !r.getRegionInfo().isMetaTable()) continue;
95 String encodedName = r.getRegionInfo().getEncodedName();
96 long time = EnvironmentEdgeManager.currentTime();
97 if (!lastRefreshTimes.containsKey(encodedName)) {
98 lastRefreshTimes.put(encodedName, time);
99 }
100 try {
101 for (Store store : r.getStores()) {
102
103
104
105 store.refreshStoreFiles();
106 }
107 } catch (IOException ex) {
108 LOG.warn("Exception while trying to refresh store files for region:" + r.getRegionInfo()
109 + ", exception:" + StringUtils.stringifyException(ex));
110
111
112 if (isRegionStale(encodedName, time)) {
113 ((HRegion)r).setReadsEnabled(false);
114 }
115 continue;
116 }
117 lastRefreshTimes.put(encodedName, time);
118 ((HRegion)r).setReadsEnabled(true);
119 }
120
121
122 Iterator<String> lastRefreshTimesIter = lastRefreshTimes.keySet().iterator();
123 while (lastRefreshTimesIter.hasNext()) {
124 String encodedName = lastRefreshTimesIter.next();
125 if (regionServer.getFromOnlineRegions(encodedName) == null) {
126 lastRefreshTimesIter.remove();
127 }
128 }
129 }
130
131 protected boolean isRegionStale(String encodedName, long time) {
132 long lastRefreshTime = lastRefreshTimes.get(encodedName);
133 return time - lastRefreshTime > hfileTtl - period;
134 }
135 }