39
39
import org .apache .bookkeeper .conf .ServerConfiguration ;
40
40
import org .apache .bookkeeper .meta .LedgerManager ;
41
41
import org .apache .bookkeeper .util .MathUtils ;
42
- import org .apache .bookkeeper .util .SnapshotMap ;
43
42
import org .slf4j .Logger ;
44
43
import org .slf4j .LoggerFactory ;
45
44
@@ -80,9 +79,7 @@ public class GarbageCollectorThread extends BookieThread {
80
79
// Entry Logger Handle
81
80
final EntryLogger entryLogger ;
82
81
83
- // Ledger Cache Handle
84
- final LedgerCache ledgerCache ;
85
- final SnapshotMap <Long , Boolean > activeLedgers ;
82
+ final CompactableLedgerStorage ledgerStorage ;
86
83
87
84
// flag to ensure gc thread will not be interrupted during compaction
88
85
// to reduce the risk getting entry log corrupted
@@ -103,35 +100,23 @@ public class GarbageCollectorThread extends BookieThread {
103
100
final GarbageCollector garbageCollector ;
104
101
final GarbageCleaner garbageCleaner ;
105
102
106
- private static class Offset {
107
- final long ledger ;
108
- final long entry ;
109
- final long offset ;
110
-
111
- Offset (long ledger , long entry , long offset ) {
112
- this .ledger = ledger ;
113
- this .entry = entry ;
114
- this .offset = offset ;
115
- }
116
- }
117
-
118
103
private static class Throttler {
119
104
final RateLimiter rateLimiter ;
120
105
final boolean isThrottleByBytes ;
121
106
final int compactionRateByBytes ;
122
107
final int compactionRateByEntries ;
123
108
124
- Throttler (boolean isThrottleByBytes ,
125
- int compactionRateByBytes ,
109
+ Throttler (boolean isThrottleByBytes ,
110
+ int compactionRateByBytes ,
126
111
int compactionRateByEntries ) {
127
112
this .isThrottleByBytes = isThrottleByBytes ;
128
113
this .compactionRateByBytes = compactionRateByBytes ;
129
114
this .compactionRateByEntries = compactionRateByEntries ;
130
- this .rateLimiter = RateLimiter .create (this .isThrottleByBytes ?
131
- this .compactionRateByBytes :
115
+ this .rateLimiter = RateLimiter .create (this .isThrottleByBytes ?
116
+ this .compactionRateByBytes :
132
117
this .compactionRateByEntries );
133
118
}
134
-
119
+
135
120
// acquire. if bybytes: bytes of this entry; if byentries: 1.
136
121
void acquire (int permits ) {
137
122
rateLimiter .acquire (this .isThrottleByBytes ? permits : 1 );
@@ -142,11 +127,11 @@ void acquire(int permits) {
142
127
* A scanner wrapper to check whether a ledger is alive in an entry log file
143
128
*/
144
129
class CompactionScannerFactory implements EntryLogger .EntryLogListener {
145
- List <Offset > offsets = new ArrayList <Offset >();
130
+ List <EntryLocation > offsets = new ArrayList <EntryLocation >();
146
131
147
132
EntryLogScanner newScanner (final EntryLogMetadata meta ) {
148
133
final Throttler throttler = new Throttler (isThrottleByBytes ,
149
- compactionRateByBytes ,
134
+ compactionRateByBytes ,
150
135
compactionRateByEntries );
151
136
152
137
return new EntryLogScanner () {
@@ -168,7 +153,7 @@ public void process(final long ledgerId, long offset, ByteBuffer entry)
168
153
entry .rewind ();
169
154
170
155
long newoffset = entryLogger .addEntry (ledgerId , entry );
171
- offsets .add (new Offset (ledgerId , entryId , newoffset ));
156
+ offsets .add (new EntryLocation (ledgerId , entryId , newoffset ));
172
157
}
173
158
}
174
159
};
@@ -190,15 +175,15 @@ synchronized private void waitEntrylogFlushed() throws IOException {
190
175
return ;
191
176
}
192
177
193
- Offset lastOffset = offsets .get (offsets .size ()-1 );
194
- long lastOffsetLogId = EntryLogger .logIdForOffset (lastOffset .offset );
178
+ EntryLocation lastOffset = offsets .get (offsets .size ()-1 );
179
+ long lastOffsetLogId = EntryLogger .logIdForOffset (lastOffset .location );
195
180
while (lastOffsetLogId < entryLogger .getLeastUnflushedLogId () && running ) {
196
181
synchronized (flushLock ) {
197
182
flushLock .wait (1000 );
198
183
}
199
184
200
185
lastOffset = offsets .get (offsets .size ()-1 );
201
- lastOffsetLogId = EntryLogger .logIdForOffset (lastOffset .offset );
186
+ lastOffsetLogId = EntryLogger .logIdForOffset (lastOffset .location );
202
187
}
203
188
if (lastOffsetLogId >= entryLogger .getLeastUnflushedLogId () && !running ) {
204
189
throw new IOException ("Shutdown before flushed" );
@@ -208,16 +193,14 @@ synchronized private void waitEntrylogFlushed() throws IOException {
208
193
throw new IOException ("Interrupted waiting for flush" , ie );
209
194
}
210
195
211
- for (Offset o : offsets ) {
212
- ledgerCache .putEntryOffset (o .ledger , o .entry , o .offset );
213
- }
196
+ ledgerStorage .updateEntriesLocations (offsets );
214
197
offsets .clear ();
215
198
}
216
199
217
200
synchronized void flush () throws IOException {
218
201
waitEntrylogFlushed ();
219
202
220
- ledgerCache . flushLedger ( true );
203
+ ledgerStorage . flushEntriesLocationsIndex ( );
221
204
}
222
205
}
223
206
@@ -230,16 +213,13 @@ synchronized void flush() throws IOException {
230
213
* @throws IOException
231
214
*/
232
215
public GarbageCollectorThread (ServerConfiguration conf ,
233
- final LedgerCache ledgerCache ,
234
- EntryLogger entryLogger ,
235
- SnapshotMap <Long , Boolean > activeLedgers ,
236
- LedgerManager ledgerManager )
216
+ LedgerManager ledgerManager ,
217
+ final CompactableLedgerStorage ledgerStorage )
237
218
throws IOException {
238
219
super ("GarbageCollectorThread" );
239
220
240
- this .ledgerCache = ledgerCache ;
241
- this .entryLogger = entryLogger ;
242
- this .activeLedgers = activeLedgers ;
221
+ this .entryLogger = ledgerStorage .getEntryLogger ();
222
+ this .ledgerStorage = ledgerStorage ;
243
223
244
224
this .gcWaitTime = conf .getGcWaitTime ();
245
225
this .isThrottleByBytes = conf .getIsThrottleByBytes ();
@@ -256,14 +236,15 @@ public void clean(long ledgerId) {
256
236
if (LOG .isDebugEnabled ()) {
257
237
LOG .debug ("delete ledger : " + ledgerId );
258
238
}
259
- ledgerCache .deleteLedger (ledgerId );
239
+
240
+ ledgerStorage .deleteLedger (ledgerId );
260
241
} catch (IOException e ) {
261
242
LOG .error ("Exception when deleting the ledger index file on the Bookie: " , e );
262
243
}
263
244
}
264
245
};
265
246
266
- this .garbageCollector = new ScanAndCompareGarbageCollector (ledgerManager , activeLedgers );
247
+ this .garbageCollector = new ScanAndCompareGarbageCollector (ledgerManager , ledgerStorage );
267
248
268
249
// compaction parameters
269
250
minorCompactionThreshold = conf .getMinorCompactionThreshold ();
@@ -333,7 +314,7 @@ public void suspendMajorGC() {
333
314
LOG .info ("Suspend Major Compaction triggered by thread: {}" , Thread .currentThread ().getName ());
334
315
}
335
316
}
336
-
317
+
337
318
public void resumeMajorGC () {
338
319
if (suspendMajorCompaction .compareAndSet (true , false )) {
339
320
LOG .info ("{} Major Compaction back to normal since bookie has enough space now." , Thread .currentThread ().getName ());
@@ -345,7 +326,7 @@ public void suspendMinorGC() {
345
326
LOG .info ("Suspend Minor Compaction triggered by thread: {}" , Thread .currentThread ().getName ());
346
327
}
347
328
}
348
-
329
+
349
330
public void resumeMinorGC () {
350
331
if (suspendMinorCompaction .compareAndSet (true , false )) {
351
332
LOG .info ("{} Minor Compaction back to normal since bookie has enough space now." , Thread .currentThread ().getName ());
@@ -389,7 +370,7 @@ public void run() {
389
370
}
390
371
391
372
long curTime = MathUtils .now ();
392
- if (enableMajorCompaction && (!suspendMajor ) &&
373
+ if (enableMajorCompaction && (!suspendMajor ) &&
393
374
(force || curTime - lastMajorCompactionTime > majorCompactionInterval )) {
394
375
// enter major compaction
395
376
LOG .info ("Enter major compaction, suspendMajor {}" , suspendMajor );
@@ -400,7 +381,7 @@ public void run() {
400
381
continue ;
401
382
}
402
383
403
- if (enableMinorCompaction && (!suspendMinor ) &&
384
+ if (enableMinorCompaction && (!suspendMinor ) &&
404
385
(force || curTime - lastMinorCompactionTime > minorCompactionInterval )) {
405
386
// enter minor compaction
406
387
LOG .info ("Enter minor compaction, suspendMinor {}" , suspendMinor );
@@ -428,8 +409,12 @@ private void doGcEntryLogs() {
428
409
EntryLogMetadata meta = entryLogMetaMap .get (entryLogId );
429
410
for (Long entryLogLedger : meta .ledgersMap .keySet ()) {
430
411
// Remove the entry log ledger from the set if it isn't active.
431
- if (!activeLedgers .containsKey (entryLogLedger )) {
432
- meta .removeLedger (entryLogLedger );
412
+ try {
413
+ if (!ledgerStorage .ledgerExists (entryLogLedger )) {
414
+ meta .removeLedger (entryLogLedger );
415
+ }
416
+ } catch (IOException e ) {
417
+ LOG .error ("Error reading from ledger storage" , e );
433
418
}
434
419
}
435
420
if (meta .isEmpty ()) {
0 commit comments