-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[controller] Add system store health check service in child controller (
#606) Add system store health check service in child controller, it is controlled by newly added configs: "controller.system.store.health.check.enabled" and "controller.system.store.health.check.interval" by default 1h. This PR is the first part of the change, the follow up change is to add parent controller support to query and repair system store.
- Loading branch information
1 parent
53e1ce6
commit b65db20
Showing
18 changed files
with
751 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
internal/venice-common/src/main/java/com/linkedin/venice/system/store/MetaStoreReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package com.linkedin.venice.system.store; | ||
|
||
import static com.linkedin.venice.system.store.MetaStoreWriter.KEY_STRING_STORE_NAME; | ||
|
||
import com.linkedin.d2.balancer.D2Client; | ||
import com.linkedin.venice.client.store.AvroSpecificStoreClient; | ||
import com.linkedin.venice.client.store.ClientConfig; | ||
import com.linkedin.venice.client.store.ClientFactory; | ||
import com.linkedin.venice.common.VeniceSystemStoreUtils; | ||
import com.linkedin.venice.exceptions.VeniceException; | ||
import com.linkedin.venice.systemstore.schemas.StoreMetaKey; | ||
import com.linkedin.venice.systemstore.schemas.StoreMetaValue; | ||
import com.linkedin.venice.utils.concurrent.VeniceConcurrentHashMap; | ||
import java.io.Closeable; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
import java.util.concurrent.TimeUnit; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
||
|
||
public class MetaStoreReader implements Closeable { | ||
private static final Logger LOGGER = LogManager.getLogger(MetaStoreReader.class); | ||
private static final int DEFAULT_HEARTBEAT_READ_TIMEOUT_SECONDS = 3; | ||
private final Map<String, AvroSpecificStoreClient<StoreMetaKey, StoreMetaValue>> veniceClients = | ||
new VeniceConcurrentHashMap<>(); | ||
private final D2Client d2Client; | ||
private final String clusterDiscoveryD2ServiceName; | ||
|
||
public MetaStoreReader(D2Client d2Client, String clusterDiscoveryD2ServiceName) { | ||
this.d2Client = d2Client; | ||
this.clusterDiscoveryD2ServiceName = clusterDiscoveryD2ServiceName; | ||
} | ||
|
||
public long getHeartbeat(String storeName) { | ||
AvroSpecificStoreClient<StoreMetaKey, StoreMetaValue> client = getVeniceClient(storeName); | ||
StoreMetaKey key = | ||
MetaStoreDataType.HEARTBEAT.getStoreMetaKey(Collections.singletonMap(KEY_STRING_STORE_NAME, storeName)); | ||
try { | ||
StoreMetaValue value = client.get(key).get(DEFAULT_HEARTBEAT_READ_TIMEOUT_SECONDS, TimeUnit.SECONDS); | ||
if (value == null) { | ||
return 0; | ||
} else { | ||
return value.timestamp; | ||
} | ||
} catch (Exception e) { | ||
throw new VeniceException(e); | ||
} | ||
} | ||
|
||
AvroSpecificStoreClient<StoreMetaKey, StoreMetaValue> getVeniceClient(String storeName) { | ||
return veniceClients.computeIfAbsent(storeName, (s) -> { | ||
ClientConfig clientConfig = | ||
ClientConfig.defaultGenericClientConfig(VeniceSystemStoreUtils.getMetaStoreName(storeName)) | ||
.setD2Client(d2Client) | ||
.setD2ServiceName(clusterDiscoveryD2ServiceName) | ||
.setSpecificValueClass(StoreMetaValue.class); | ||
return ClientFactory.getAndStartSpecificAvroClient(clientConfig); | ||
}); | ||
} | ||
|
||
@Override | ||
public void close() { | ||
veniceClients.forEach((storeName, veniceClient) -> { | ||
try { | ||
veniceClient.close(); | ||
} catch (Exception e) { | ||
LOGGER.error("Can not close VeniceClient.", e); | ||
} | ||
}); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
...nal/venice-common/src/test/java/com/linkedin/venice/system/store/MetaStoreReaderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.linkedin.venice.system.store; | ||
|
||
import static com.linkedin.venice.system.store.MetaStoreWriter.KEY_STRING_STORE_NAME; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.ArgumentMatchers.anyLong; | ||
import static org.mockito.Mockito.doReturn; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.spy; | ||
import static org.mockito.Mockito.verify; | ||
import static org.mockito.Mockito.when; | ||
|
||
import com.linkedin.d2.balancer.D2Client; | ||
import com.linkedin.venice.client.store.AvroSpecificStoreClient; | ||
import com.linkedin.venice.client.store.ClientConfig; | ||
import com.linkedin.venice.systemstore.schemas.StoreMetaKey; | ||
import com.linkedin.venice.systemstore.schemas.StoreMetaValue; | ||
import java.util.Collections; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.TimeoutException; | ||
import org.testng.Assert; | ||
import org.testng.annotations.BeforeMethod; | ||
import org.testng.annotations.Test; | ||
|
||
|
||
public class MetaStoreReaderTest { | ||
private static final String CLUSTER_DISCOVERY_D2_SERVICE_NAME = | ||
ClientConfig.DEFAULT_CLUSTER_DISCOVERY_D2_SERVICE_NAME + "_test"; | ||
|
||
private D2Client d2ClientMock; | ||
private AvroSpecificStoreClient<StoreMetaKey, StoreMetaValue> storeClientMock; | ||
private final static String storeName = "venice-test-meta-store"; | ||
|
||
@BeforeMethod | ||
public void setUp() { | ||
d2ClientMock = mock(D2Client.class); | ||
storeClientMock = mock(AvroSpecificStoreClient.class); | ||
} | ||
|
||
@Test() | ||
public void testGetHeartbeatFromMetaStore() throws ExecutionException, InterruptedException, TimeoutException { | ||
StoreMetaKey storeMetaKey = | ||
MetaStoreDataType.HEARTBEAT.getStoreMetaKey(Collections.singletonMap(KEY_STRING_STORE_NAME, storeName)); | ||
StoreMetaValue storeMetaValue = new StoreMetaValue(); | ||
storeMetaValue.timestamp = 123L; | ||
|
||
MetaStoreReader storeReaderSpy = spy(new MetaStoreReader(d2ClientMock, CLUSTER_DISCOVERY_D2_SERVICE_NAME)); | ||
CompletableFuture<StoreMetaValue> completableFutureMock = mock(CompletableFuture.class); | ||
|
||
doReturn(storeClientMock).when(storeReaderSpy).getVeniceClient(any()); | ||
when(storeClientMock.get(storeMetaKey)).thenReturn(completableFutureMock); | ||
when(completableFutureMock.get(anyLong(), any())).thenReturn(storeMetaValue); | ||
|
||
Assert.assertEquals(storeReaderSpy.getHeartbeat(storeName), 123L); | ||
verify(completableFutureMock).get(anyLong(), any()); | ||
verify(storeClientMock).get(storeMetaKey); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.