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.classification.InterfaceAudience;
29 import org.apache.hadoop.hbase.Chore;
30 import org.apache.hadoop.hbase.Stoppable;
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 Chore {
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 private HRegionServer regionServer;
57 private long hfileTtl;
58 private int period;
59
60
61 private Map<String, Long> lastRefreshTimes;
62
63 public StorefileRefresherChore(int period, HRegionServer regionServer, Stoppable stoppable) {
64 super("StorefileRefresherChore", period, stoppable);
65 this.period = period;
66 this.regionServer = regionServer;
67 this.hfileTtl = this.regionServer.getConfiguration().getLong(
68 TimeToLiveHFileCleaner.TTL_CONF_KEY, TimeToLiveHFileCleaner.DEFAULT_TTL);
69 if (period > hfileTtl / 2) {
70 throw new RuntimeException(REGIONSERVER_STOREFILE_REFRESH_PERIOD +
71 " should be set smaller than half of " + TimeToLiveHFileCleaner.TTL_CONF_KEY);
72 }
73 lastRefreshTimes = new HashMap<String, Long>();
74 }
75
76 @Override
77 protected void chore() {
78 for (HRegion r : regionServer.getOnlineRegionsLocalContext()) {
79 if (!r.writestate.isReadOnly()) {
80
81 continue;
82 }
83 String encodedName = r.getRegionInfo().getEncodedName();
84 long time = EnvironmentEdgeManager.currentTime();
85 if (!lastRefreshTimes.containsKey(encodedName)) {
86 lastRefreshTimes.put(encodedName, time);
87 }
88 try {
89 for (Store store : r.getStores().values()) {
90
91
92
93 store.refreshStoreFiles();
94 }
95 } catch (IOException ex) {
96 LOG.warn("Exception while trying to refresh store files for region:" + r.getRegionInfo()
97 + ", exception:" + StringUtils.stringifyException(ex));
98
99
100 if (isRegionStale(encodedName, time)) {
101 r.setReadsEnabled(false);
102 }
103 continue;
104 }
105 lastRefreshTimes.put(encodedName, time);
106 r.setReadsEnabled(true);
107 }
108
109
110 Iterator<String> lastRefreshTimesIter = lastRefreshTimes.keySet().iterator();
111 while (lastRefreshTimesIter.hasNext()) {
112 String encodedName = lastRefreshTimesIter.next();
113 if (regionServer.getFromOnlineRegions(encodedName) == null) {
114 lastRefreshTimesIter.remove();
115 }
116 }
117 }
118
119 protected boolean isRegionStale(String encodedName, long time) {
120 long lastRefreshTime = lastRefreshTimes.get(encodedName);
121 return time - lastRefreshTime > hfileTtl - period;
122 }
123 }