1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.mob.mapreduce;
20
21 import java.io.IOException;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.classification.InterfaceAudience;
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.fs.FileSystem;
28 import org.apache.hadoop.fs.Path;
29 import org.apache.hadoop.hbase.Cell;
30 import org.apache.hadoop.hbase.HColumnDescriptor;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.KeyValue;
33 import org.apache.hadoop.hbase.KeyValueUtil;
34 import org.apache.hadoop.hbase.Tag;
35 import org.apache.hadoop.hbase.TagType;
36 import org.apache.hadoop.hbase.client.HTable;
37 import org.apache.hadoop.hbase.client.Put;
38 import org.apache.hadoop.hbase.io.hfile.CacheConfig;
39 import org.apache.hadoop.hbase.mob.MobConstants;
40 import org.apache.hadoop.hbase.mob.MobUtils;
41 import org.apache.hadoop.hbase.mob.mapreduce.SweepJob.SweepCounter;
42 import org.apache.hadoop.hbase.mob.mapreduce.SweepReducer.SweepPartitionId;
43 import org.apache.hadoop.hbase.regionserver.KeyValueScanner;
44 import org.apache.hadoop.hbase.regionserver.MemStore;
45 import org.apache.hadoop.hbase.regionserver.MemStoreSnapshot;
46 import org.apache.hadoop.hbase.regionserver.StoreFile;
47 import org.apache.hadoop.hbase.util.Bytes;
48 import org.apache.hadoop.mapreduce.Reducer.Context;
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 @InterfaceAudience.Private
64 public class MemStoreWrapper {
65
66 private static final Log LOG = LogFactory.getLog(MemStoreWrapper.class);
67
68 private MemStore memstore;
69 private long flushSize;
70 private SweepPartitionId partitionId;
71 private Context context;
72 private Configuration conf;
73 private HTable table;
74 private HColumnDescriptor hcd;
75 private Path mobFamilyDir;
76 private FileSystem fs;
77 private CacheConfig cacheConfig;
78
79 public MemStoreWrapper(Context context, FileSystem fs, HTable table, HColumnDescriptor hcd,
80 MemStore memstore, CacheConfig cacheConfig) throws IOException {
81 this.memstore = memstore;
82 this.context = context;
83 this.fs = fs;
84 this.table = table;
85 this.hcd = hcd;
86 this.conf = context.getConfiguration();
87 this.cacheConfig = cacheConfig;
88 flushSize = this.conf.getLong(MobConstants.MOB_SWEEP_TOOL_COMPACTION_MEMSTORE_FLUSH_SIZE,
89 MobConstants.DEFAULT_MOB_SWEEP_TOOL_COMPACTION_MEMSTORE_FLUSH_SIZE);
90 mobFamilyDir = MobUtils.getMobFamilyPath(conf, table.getName(), hcd.getNameAsString());
91 }
92
93 public void setPartitionId(SweepPartitionId partitionId) {
94 this.partitionId = partitionId;
95 }
96
97
98
99
100
101 private void flushMemStoreIfNecessary() throws IOException {
102 if (memstore.heapSize() >= flushSize) {
103 flushMemStore();
104 }
105 }
106
107
108
109
110
111 public void flushMemStore() throws IOException {
112 MemStoreSnapshot snapshot = memstore.snapshot();
113 internalFlushCache(snapshot);
114 memstore.clearSnapshot(snapshot.getId());
115 }
116
117
118
119
120
121
122
123 private void internalFlushCache(final MemStoreSnapshot snapshot)
124 throws IOException {
125 if (snapshot.getCellsCount() == 0) {
126 return;
127 }
128
129 String tempPathString = context.getConfiguration().get(SweepJob.WORKING_FILES_DIR_KEY);
130 StoreFile.Writer mobFileWriter = MobUtils.createWriter(conf, fs, hcd,
131 partitionId.getDate(), new Path(tempPathString), snapshot.getCellsCount(),
132 hcd.getCompactionCompression(), partitionId.getStartKey(), cacheConfig);
133
134 String relativePath = mobFileWriter.getPath().getName();
135 LOG.info("Create files under a temp directory " + mobFileWriter.getPath().toString());
136
137 byte[] referenceValue = Bytes.toBytes(relativePath);
138 KeyValueScanner scanner = snapshot.getScanner();
139 Cell cell = null;
140 while (null != (cell = scanner.next())) {
141 KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
142 mobFileWriter.append(kv);
143 }
144 scanner.close();
145
146
147 mobFileWriter.appendMetadata(Long.MAX_VALUE, false, snapshot.getCellsCount());
148 mobFileWriter.close();
149
150 MobUtils.commitFile(conf, fs, mobFileWriter.getPath(), mobFamilyDir, cacheConfig);
151 context.getCounter(SweepCounter.FILE_AFTER_MERGE_OR_CLEAN).increment(1);
152
153 scanner = snapshot.getScanner();
154 scanner.seek(KeyValueUtil.createFirstOnRow(HConstants.EMPTY_START_ROW));
155 cell = null;
156 Tag tableNameTag = new Tag(TagType.MOB_TABLE_NAME_TAG_TYPE, this.table.getTableName());
157 while (null != (cell = scanner.next())) {
158 KeyValue reference = MobUtils.createMobRefKeyValue(cell, referenceValue, tableNameTag);
159 Put put =
160 new Put(reference.getRowArray(), reference.getRowOffset(), reference.getRowLength());
161 put.add(reference);
162 table.put(put);
163 context.getCounter(SweepCounter.RECORDS_UPDATED).increment(1);
164 }
165 table.flushCommits();
166 scanner.close();
167 }
168
169
170
171
172
173
174 public void addToMemstore(KeyValue kv) throws IOException {
175 memstore.add(kv);
176
177 flushMemStoreIfNecessary();
178 }
179
180 }