Skip to content

[improve][pip] PIP-362: Add admin APIs for batch updating and deleting bookie rack information #22922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 218 additions & 0 deletions pip/pip-362.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
# PIP-362: Add admin APIs for batch updating and deleting bookie rack information

# Background knowledge

Each time the rack information of a bookie is updated or deleted, the mapping information of the bookie rack
will be updated in `/bookies` on Zookeeper. At the same time, all bookies observing this path will be
notified to fetch the latest bookie rack mapping information from Zookeeper.

# Motivation

Currently, we only provide single update or delete admin APIs for bookie rack information (`updateBookieRackInfo`
and `deleteBookieRackInfo`). If we want to update the rack information for n bookies, we need to call
`updateBookieRackInfo` n times, which will result in a large number of write and read operations on Zookeeper,
thereby affecting Zookeeper's stability.

Therefore, we want to introduce admin APIs for batch updating and deleting bookie rack information to reduce
the number of times Zookeeper is accessed when batch setting bookie rack information.

# Goals

## In Scope

Add admin APIs for batch updating and deleting bookie rack information.

# High Level Design

Add admin APIs for batch updating and deleting bookie rack information.

# Detailed Design

## Design & Implementation Details

Add admin APIs for batch updating and deleting bookie rack information.

## Public-facing Changes

### Public API
org.apache.pulsar.common.policies.data.ExtBookieInfo
```java
public interface ExtBookieInfo {
String getAddress();
String getGroup();
String getRack();
String getHostname();

interface Builder {
Builder address(String address);
Builder group(String group);
Builder rack(String rack);
Builder hostname(String hostname);
ExtBookieInfo build();
}

static Builder builder() {
return ExtBookieInfoImpl.builder();
}
}
```

org.apache.pulsar.common.policies.data.impl.ExtBookieInfoImpl
```java
/**
* Ext Bookie information.
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public final class ExtBookieInfoImpl implements ExtBookieInfo {
private String address;
private String group;
private String rack;
private String hostname;

public static ExtBookieInfoImplBuilder builder() {
return new ExtBookieInfoImplBuilder();
}

public static class ExtBookieInfoImplBuilder implements ExtBookieInfo.Builder {
private String address;
private String group;
private String rack;
private String hostname;
private static final String PATH_SEPARATOR = "/";

public ExtBookieInfoImplBuilder address(String address) {
this.address = address;
return this;
}

public ExtBookieInfoImplBuilder group(String group) {
this.group = group;
return this;
}

public ExtBookieInfoImplBuilder rack(String rack) {
this.rack = rack;
return this;
}

public ExtBookieInfoImplBuilder hostname(String hostname) {
this.hostname = hostname;
return this;
}

public ExtBookieInfoImpl build() {
checkArgument(rack != null && !rack.isEmpty() && !rack.equals(PATH_SEPARATOR),
"rack name is invalid, it should not be null, empty or '/'");
return new ExtBookieInfoImpl(address, group, rack, hostname);
}

public static void checkArgument(boolean expression, @NonNull Object errorMessage) {
if (!expression) {
throw new IllegalArgumentException(String.valueOf(errorMessage));
}
}
}
}
```

V2/Namespaces.java
```java
@DELETE
@Path("/racks-info")
@ApiOperation(
value = "Removed the rack placement information for a batch of bookies in the cluster",
notes = "If the 'deleteAll' parameter is set to true, it will remove the rack placement "
+ "information for all bookies in the cluster, ignoring the 'bookieAddresses' parameter"
)
@ApiResponses(value = {
@ApiResponse(code = 204, message = "Operation successful"),
@ApiResponse(code = 403, message = "Don't have admin permission")
})
public void batchDeleteBookiesRackInfo(@Suspended final AsyncResponse asyncResponse,
@ApiParam(value = "List of bookie addresses")
@QueryParam("bookieAddresses") List<String> bookieAddresses,
@ApiParam(value = "Whether to delete all bookies rack info",
defaultValue = "false")
@QueryParam("deleteAll") @DefaultValue("false")
boolean deleteAll) throws Exception {
...
}

@POST
@Path("/racks-info")
@ApiOperation(value = "Updates the rack placement information for a batch of bookies in the cluster")
@ApiResponses(value = {
@ApiResponse(code = 204, message = "Operation successful"),
@ApiResponse(code = 403, message = "Don't have admin permission")}
)
public void batchUpdateBookiesRackInfo(@Suspended final AsyncResponse asyncResponse,
@ApiParam(value = "List of bookie info", required = true)
List<ExtBookieInfo> extBookieInfos) throws Exception {
...
}
```

Client
```java
/**
* Remove rack placement information for a batch of bookies in the cluster.
*/
void batchDeleteBookiesRackInfo(List<String> bookieAddresses) throws PulsarAdminException;

/**
* Remove rack placement information for a batch of bookies in the cluster asynchronously.
*/
CompletableFuture<Void> batchDeleteBookiesRackInfoAsync(List<String> bookieAddresses);

/**
* Clears the rack placement information for all bookies int the cluster.
*/
void clearAllBookiesRackInfo() throws PulsarAdminException;

/**
* Clears the rack placement information for all bookies int the cluster asynchronously.
*/
CompletableFuture<Void> clearAllBookiesRackInfoAsync();

/**
* Updates the rack placement information for a batch of bookies in the cluster.
*/
void batchUpdateBookiesRackInfo(List<ExtBookieInfo> extBookieInfos) throws PulsarAdminException;

/**
* Updates the rack placement information for a batch of bookies in the cluster asynchronously.
*/
CompletableFuture<Void> batchUpdateBookiesRackInfoAsync(List<ExtBookieInfo> extBookieInfos);
```

### Binary protocol

### Configuration

### CLI

### Metrics

# Monitoring

# Security Considerations

# Backward & Forward Compatibility

## Revert

## Upgrade

# Alternatives

# General Notes

# Links

<!--
Updated afterwards
-->
* Mailing List discussion thread:
* Mailing List voting thread:
Loading