This is an automated email from the ASF dual-hosted git repository.
sijie pushed a commit to branch branch-4.7
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git
The following commit(s) were added to refs/heads/branch-4.7 by this push:
new f32ea97 Add rest endpoint trigger_gc to trigger GC on Bookie
f32ea97 is described below
commit f32ea97906d7cfdf9cd19aa9af04c5196e9bd0b0
Author: Jia Zhai <[email protected]>
AuthorDate: Tue Nov 27 18:16:19 2018 +0800
Add rest endpoint trigger_gc to trigger GC on Bookie
Descriptions of the changes in this PR:
Add rest endpoint trigger_gc to trigger GC on Bookie
Some times user would like to trigger GC manually instead of waiting to the
timeout or disk full.
Reviewers: Enrico Olivelli <[email protected]>, Sijie Guo
<[email protected]>
This closes #1838 from jiazhai/rest_force_gc
(cherry picked from commit 641db3b4ff29d8e04216fee84625546707631e8e)
Signed-off-by: Sijie Guo <[email protected]>
---
.../org/apache/bookkeeper/http/HttpRouter.java | 2 +
.../org/apache/bookkeeper/http/HttpServer.java | 1 +
.../bookkeeper/bookie/GarbageCollectorThread.java | 7 +++
.../bookie/InterleavedLedgerStorage.java | 5 ++
.../apache/bookkeeper/bookie/LedgerStorage.java | 7 +++
.../bookie/storage/ldb/DbLedgerStorage.java | 4 ++
.../ldb/SingleDirectoryDbLedgerStorage.java | 5 ++
.../server/http/BKHttpServiceProvider.java | 3 +
.../server/http/service/TriggerGCService.java | 71 ++++++++++++++++++++++
.../bookkeeper/server/http/TestHttpService.java | 38 ++++++++++++
site/docs/latest/admin/http.md | 11 ++++
11 files changed, 154 insertions(+)
diff --git
a/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpRouter.java
b/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpRouter.java
index a856c72..5384df6 100644
---
a/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpRouter.java
+++
b/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpRouter.java
@@ -45,6 +45,7 @@ public abstract class HttpRouter<Handler> {
public static final String LAST_LOG_MARK =
"/api/v1/bookie/last_log_mark";
public static final String LIST_DISK_FILE =
"/api/v1/bookie/list_disk_file";
public static final String EXPAND_STORAGE =
"/api/v1/bookie/expand_storage";
+ public static final String GC =
"/api/v1/bookie/gc";
// autorecovery
public static final String RECOVERY_BOOKIE =
"/api/v1/autorecovery/bookie";
public static final String LIST_UNDER_REPLICATED_LEDGER =
"/api/v1/autorecovery/list_under_replicated_ledger";
@@ -73,6 +74,7 @@ public abstract class HttpRouter<Handler> {
this.endpointHandlers.put(LAST_LOG_MARK,
handlerFactory.newHandler(HttpServer.ApiType.LAST_LOG_MARK));
this.endpointHandlers.put(LIST_DISK_FILE,
handlerFactory.newHandler(HttpServer.ApiType.LIST_DISK_FILE));
this.endpointHandlers.put(EXPAND_STORAGE,
handlerFactory.newHandler(HttpServer.ApiType.EXPAND_STORAGE));
+ this.endpointHandlers.put(GC,
handlerFactory.newHandler(HttpServer.ApiType.GC));
// autorecovery
this.endpointHandlers.put(RECOVERY_BOOKIE,
handlerFactory.newHandler(HttpServer.ApiType.RECOVERY_BOOKIE));
diff --git
a/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpServer.java
b/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpServer.java
index 30e4d05..5e9f509 100644
---
a/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpServer.java
+++
b/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpServer.java
@@ -77,6 +77,7 @@ public interface HttpServer {
LAST_LOG_MARK,
LIST_DISK_FILE,
EXPAND_STORAGE,
+ GC,
// autorecovery
RECOVERY_BOOKIE,
LIST_UNDER_REPLICATED_LEDGER,
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
index ad752de..c4d9414 100644
---
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
@@ -382,6 +382,13 @@ public class GarbageCollectorThread extends SafeRunnable {
lastMinorCompactionTime = System.currentTimeMillis();
minorCompactionCounter.inc();
}
+
+ if (force) {
+ if (forceGarbageCollection.compareAndSet(true, false)) {
+ LOG.info("{} Set forceGarbageCollection to false after force
GC to make it forceGC-able again.", Thread
+ .currentThread().getName());
+ }
+ }
this.gcThreadRuntime.registerSuccessfulEvent(
MathUtils.nowInNano() - threadStart, TimeUnit.NANOSECONDS);
}
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/InterleavedLedgerStorage.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/InterleavedLedgerStorage.java
index 2c576d7..4f03670 100644
---
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/InterleavedLedgerStorage.java
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/InterleavedLedgerStorage.java
@@ -170,6 +170,11 @@ public class InterleavedLedgerStorage implements
CompactableLedgerStorage, Entry
}
@Override
+ public void forceGC() {
+ gcThread.enableForceGC();
+ }
+
+ @Override
public void start() {
gcThread.start();
}
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerStorage.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerStorage.java
index dcfac31..133c59d 100644
---
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerStorage.java
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerStorage.java
@@ -169,4 +169,11 @@ public interface LedgerStorage {
void setExplicitlac(long ledgerId, ByteBuf lac) throws IOException;
ByteBuf getExplicitLac(long ledgerId);
+
+ /**
+ * Force trigger Garbage Collection.
+ */
+ default void forceGC() {
+ return;
+ }
}
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/DbLedgerStorage.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/DbLedgerStorage.java
index 8753363..831de53 100644
---
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/DbLedgerStorage.java
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/DbLedgerStorage.java
@@ -348,4 +348,8 @@ public class DbLedgerStorage implements LedgerStorage {
}
}
+ @Override
+ public void forceGC() {
+
ledgerStorageList.stream().forEach(SingleDirectoryDbLedgerStorage::forceGC);
+ }
}
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java
index 7c54a7e..3203561 100644
---
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java
@@ -264,6 +264,11 @@ public class SingleDirectoryDbLedgerStorage implements
CompactableLedgerStorage
}
@Override
+ public void forceGC() {
+ gcThread.enableForceGC();
+ }
+
+ @Override
public void shutdown() throws InterruptedException {
try {
flush();
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/BKHttpServiceProvider.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/BKHttpServiceProvider.java
index 052b50e..102b0eb 100644
---
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/BKHttpServiceProvider.java
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/BKHttpServiceProvider.java
@@ -53,6 +53,7 @@ import
org.apache.bookkeeper.server.http.service.MetricsService;
import org.apache.bookkeeper.server.http.service.ReadLedgerEntryService;
import org.apache.bookkeeper.server.http.service.RecoveryBookieService;
import org.apache.bookkeeper.server.http.service.TriggerAuditService;
+import org.apache.bookkeeper.server.http.service.TriggerGCService;
import org.apache.bookkeeper.server.http.service.WhoIsAuditorService;
import org.apache.bookkeeper.stats.StatsProvider;
import org.apache.bookkeeper.zookeeper.ZooKeeperClient;
@@ -208,6 +209,8 @@ public class BKHttpServiceProvider implements
HttpServiceProvider {
return new ListDiskFilesService(configuration);
case EXPAND_STORAGE:
return new ExpandStorageService(configuration);
+ case GC:
+ return new TriggerGCService(configuration, bookieServer);
// autorecovery
case RECOVERY_BOOKIE:
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/TriggerGCService.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/TriggerGCService.java
new file mode 100644
index 0000000..a9a2b68
--- /dev/null
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/TriggerGCService.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bookkeeper.server.http.service;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.bookkeeper.conf.ServerConfiguration;
+import org.apache.bookkeeper.http.HttpServer;
+import org.apache.bookkeeper.http.service.HttpEndpointService;
+import org.apache.bookkeeper.http.service.HttpServiceRequest;
+import org.apache.bookkeeper.http.service.HttpServiceResponse;
+import org.apache.bookkeeper.proto.BookieServer;
+import org.apache.bookkeeper.util.JsonUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * HttpEndpointService that handle force trigger GC requests.
+ *
+ * <p>The PUT method will force trigger GC on current bookie, and make GC run
at backend.
+ */
+public class TriggerGCService implements HttpEndpointService {
+
+ static final Logger LOG = LoggerFactory.getLogger(TriggerGCService.class);
+
+ protected ServerConfiguration conf;
+ protected BookieServer bookieServer;
+
+ public TriggerGCService(ServerConfiguration conf, BookieServer
bookieServer) {
+ checkNotNull(conf);
+ checkNotNull(bookieServer);
+ this.conf = conf;
+ this.bookieServer = bookieServer;
+ }
+
+ @Override
+ public HttpServiceResponse handle(HttpServiceRequest request) throws
Exception {
+ HttpServiceResponse response = new HttpServiceResponse();
+ // PUT
+ if (HttpServer.Method.PUT == request.getMethod()) {
+ bookieServer.getBookie().getLedgerStorage().forceGC();
+
+ String output = "Triggered GC on BookieServer: " +
bookieServer.toString();
+ String jsonResponse = JsonUtil.toJson(output);
+ LOG.debug("output body:" + jsonResponse);
+ response.setBody(jsonResponse);
+ response.setCode(HttpServer.StatusCode.OK);
+ return response;
+ } else {
+ response.setCode(HttpServer.StatusCode.NOT_FOUND);
+ response.setBody("Not found method. Should be PUT method to
trigger GC.");
+ return response;
+ }
+ }
+}
diff --git
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
index 9f014e2..0754b6b 100644
---
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
+++
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
@@ -745,4 +745,42 @@ public class TestHttpService extends
BookKeeperClusterTestCase {
stopAuditorElector();
}
+ /**
+ * Create ledgers, then test Delete Ledger service.
+ */
+ @Test
+ public void testTriggerGCService() throws Exception {
+ baseConf.setMetadataServiceUri(zkUtil.getMetadataServiceUri());
+ BookKeeper.DigestType digestType = BookKeeper.DigestType.CRC32;
+ int numLedgers = 4;
+ int numMsgs = 100;
+ LedgerHandle[] lh = new LedgerHandle[numLedgers];
+ // create ledgers
+ for (int i = 0; i < numLedgers; i++) {
+ lh[i] = bkc.createLedger(digestType, "".getBytes());
+ }
+ String content = "Apache BookKeeper is cool!";
+ // add entries
+ for (int i = 0; i < numMsgs; i++) {
+ for (int j = 0; j < numLedgers; j++) {
+ lh[j].addEntry(content.getBytes());
+ }
+ }
+ // close ledgers
+ for (int i = 0; i < numLedgers; i++) {
+ lh[i].close();
+ }
+ HttpEndpointService triggerGCService = bkHttpServiceProvider
+ .provideHttpEndpointService(HttpServer.ApiType.GC);
+
+ //1, GET, should return NOT_FOUND
+ HttpServiceRequest request1 = new HttpServiceRequest(null,
HttpServer.Method.GET, null);
+ HttpServiceResponse response1 = triggerGCService.handle(request1);
+ assertEquals(HttpServer.StatusCode.NOT_FOUND.getValue(),
response1.getStatusCode());
+
+ //2, PUT, should return OK
+ HttpServiceRequest request2 = new HttpServiceRequest(null,
HttpServer.Method.PUT, null);
+ HttpServiceResponse response2 = triggerGCService.handle(request2);
+ assertEquals(HttpServer.StatusCode.OK.getValue(),
response2.getStatusCode());
+ }
}
diff --git a/site/docs/latest/admin/http.md b/site/docs/latest/admin/http.md
index dc64744..7c1abea 100644
--- a/site/docs/latest/admin/http.md
+++ b/site/docs/latest/admin/http.md
@@ -271,6 +271,17 @@ Currently all the HTTP endpoints could be divided into
these 4 components:
|403 | Permission denied |
|404 | Not found |
+### Endpoint: /api/v1/bookie/gc
+1. Method: PUT
+ * Description: trigger gc for this bookie.
+ * Response:
+
+ | Code | Description |
+ |:-------|:------------|
+ |200 | Successful operation |
+ |403 | Permission denied |
+ |404 | Not found |
+
## Auto recovery
### Endpoint: /api/v1/autorecovery/bookie/