use of com.linkedin.pinot.common.metrics.ControllerMetrics in project pinot by linkedin.
the class LLCSegmentCommitTest method testSegmentCommit.
@Test
public void testSegmentCommit() throws Exception {
SegmentCompletionManager.create(createMockHelixManager(), null, new ControllerConf(), new ControllerMetrics(new MetricsRegistry()));
FakeLLCSegmentCommit segmentCommit = new FakeLLCSegmentCommit();
Representation representation;
String strResponse;
JSONObject jsonResponse;
// If commitStart returns failed, upload should not be called, and the client should get 'failed'
segmentCommit._uploadCalled = false;
segmentCommit._scm.commitStartResponse = SegmentCompletionProtocol.RESP_FAILED;
representation = segmentCommit.post(null);
strResponse = representation.getText();
jsonResponse = JSONObject.parseObject(strResponse);
Assert.assertEquals(jsonResponse.get(SegmentCompletionProtocol.STATUS_KEY), SegmentCompletionProtocol.ControllerResponseStatus.FAILED.toString());
Assert.assertFalse(segmentCommit._uploadCalled);
// if commitStart returns continue, and upload fails, then commitEnd should indicate upload failure.
segmentCommit._uploadCalled = false;
segmentCommit._scm.commitStartResponse = SegmentCompletionProtocol.RESP_COMMIT_CONTINUE;
segmentCommit._scm.commitEndResponse = SegmentCompletionProtocol.RESP_FAILED;
segmentCommit._uploadReturnValue = false;
representation = segmentCommit.post(null);
strResponse = representation.getText();
jsonResponse = JSONObject.parseObject(strResponse);
Assert.assertEquals(jsonResponse.get(SegmentCompletionProtocol.STATUS_KEY), SegmentCompletionProtocol.ControllerResponseStatus.FAILED.toString());
Assert.assertTrue(segmentCommit._uploadCalled);
Assert.assertFalse(segmentCommit._scm.uploadSuccess);
// If commitstart returns CONINUE and upload succeeds, we should return whatever commitEnd returns.
segmentCommit._uploadCalled = false;
segmentCommit._scm.commitStartResponse = SegmentCompletionProtocol.RESP_COMMIT_CONTINUE;
segmentCommit._scm.commitEndResponse = SegmentCompletionProtocol.RESP_COMMIT_SUCCESS;
segmentCommit._uploadReturnValue = true;
representation = segmentCommit.post(null);
strResponse = representation.getText();
jsonResponse = JSONObject.parseObject(strResponse);
Assert.assertEquals(jsonResponse.get(SegmentCompletionProtocol.STATUS_KEY), SegmentCompletionProtocol.ControllerResponseStatus.COMMIT_SUCCESS.toString());
Assert.assertTrue(segmentCommit._uploadCalled);
Assert.assertTrue(segmentCommit._scm.uploadSuccess);
}
use of com.linkedin.pinot.common.metrics.ControllerMetrics in project pinot by linkedin.
the class SegmentStatusCheckerTest method nonLeaderTest.
@Test
public void nonLeaderTest() throws Exception {
final String tableName = "myTable_REALTIME";
List<String> allTableNames = new ArrayList<String>();
allTableNames.add(tableName);
HelixAdmin helixAdmin;
{
helixAdmin = mock(HelixAdmin.class);
}
{
helixResourceManager = mock(PinotHelixResourceManager.class);
when(helixResourceManager.isLeader()).thenReturn(false);
when(helixResourceManager.getAllPinotTableNames()).thenReturn(allTableNames);
when(helixResourceManager.getHelixClusterName()).thenReturn("StatusChecker");
when(helixResourceManager.getHelixAdmin()).thenReturn(helixAdmin);
}
{
config = mock(ControllerConf.class);
when(config.getStatusCheckerFrequencyInSeconds()).thenReturn(300);
when(config.getStatusCheckerWaitForPushTimeInSeconds()).thenReturn(300);
}
metricsRegistry = new MetricsRegistry();
controllerMetrics = new ControllerMetrics(metricsRegistry);
segmentStatusChecker = new SegmentStatusChecker(helixResourceManager, config);
segmentStatusChecker.setMetricsRegistry(controllerMetrics);
segmentStatusChecker.runSegmentMetrics();
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.SEGMENTS_IN_ERROR_STATE), 0);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.NUMBER_OF_REPLICAS), 0);
segmentStatusChecker.stop();
}
use of com.linkedin.pinot.common.metrics.ControllerMetrics in project pinot by linkedin.
the class SegmentStatusCheckerTest method noReplicas.
@Test
public void noReplicas() throws Exception {
final String tableName = "myTable_REALTIME";
List<String> allTableNames = new ArrayList<String>();
allTableNames.add(tableName);
IdealState idealState = new IdealState(tableName);
idealState.setPartitionState("myTable_0", "pinot1", "OFFLINE");
idealState.setPartitionState("myTable_0", "pinot2", "OFFLINE");
idealState.setPartitionState("myTable_0", "pinot3", "OFFLINE");
idealState.setReplicas("0");
idealState.setRebalanceMode(IdealState.RebalanceMode.CUSTOMIZED);
HelixAdmin helixAdmin;
{
helixAdmin = mock(HelixAdmin.class);
when(helixAdmin.getResourceIdealState("StatusChecker", tableName)).thenReturn(idealState);
when(helixAdmin.getResourceExternalView("StatusChecker", tableName)).thenReturn(null);
}
{
helixResourceManager = mock(PinotHelixResourceManager.class);
when(helixResourceManager.isLeader()).thenReturn(true);
when(helixResourceManager.getAllPinotTableNames()).thenReturn(allTableNames);
when(helixResourceManager.getHelixClusterName()).thenReturn("StatusChecker");
when(helixResourceManager.getHelixAdmin()).thenReturn(helixAdmin);
}
{
config = mock(ControllerConf.class);
when(config.getStatusCheckerFrequencyInSeconds()).thenReturn(300);
when(config.getStatusCheckerWaitForPushTimeInSeconds()).thenReturn(300);
}
metricsRegistry = new MetricsRegistry();
controllerMetrics = new ControllerMetrics(metricsRegistry);
segmentStatusChecker = new SegmentStatusChecker(helixResourceManager, config);
segmentStatusChecker.setMetricsRegistry(controllerMetrics);
segmentStatusChecker.runSegmentMetrics();
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.SEGMENTS_IN_ERROR_STATE), 0);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.NUMBER_OF_REPLICAS), 1);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.PERCENT_OF_REPLICAS), 100);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.PERCENT_SEGMENTS_AVAILABLE), 100);
segmentStatusChecker.stop();
}
use of com.linkedin.pinot.common.metrics.ControllerMetrics in project pinot by linkedin.
the class SegmentStatusCheckerTest method noIdealState.
@Test
public void noIdealState() throws Exception {
final String tableName = "myTable_REALTIME";
List<String> allTableNames = new ArrayList<String>();
allTableNames.add(tableName);
IdealState idealState = null;
HelixAdmin helixAdmin;
{
helixAdmin = mock(HelixAdmin.class);
when(helixAdmin.getResourceIdealState("StatusChecker", tableName)).thenReturn(idealState);
when(helixAdmin.getResourceExternalView("StatusChecker", tableName)).thenReturn(null);
}
{
helixResourceManager = mock(PinotHelixResourceManager.class);
when(helixResourceManager.isLeader()).thenReturn(true);
when(helixResourceManager.getAllPinotTableNames()).thenReturn(allTableNames);
when(helixResourceManager.getHelixClusterName()).thenReturn("StatusChecker");
when(helixResourceManager.getHelixAdmin()).thenReturn(helixAdmin);
}
{
config = mock(ControllerConf.class);
when(config.getStatusCheckerFrequencyInSeconds()).thenReturn(300);
when(config.getStatusCheckerWaitForPushTimeInSeconds()).thenReturn(300);
}
metricsRegistry = new MetricsRegistry();
controllerMetrics = new ControllerMetrics(metricsRegistry);
segmentStatusChecker = new SegmentStatusChecker(helixResourceManager, config);
segmentStatusChecker.setMetricsRegistry(controllerMetrics);
segmentStatusChecker.runSegmentMetrics();
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.SEGMENTS_IN_ERROR_STATE), 0);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.NUMBER_OF_REPLICAS), 1);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.PERCENT_OF_REPLICAS), 100);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(tableName, ControllerGauge.PERCENT_SEGMENTS_AVAILABLE), 100);
segmentStatusChecker.stop();
}
use of com.linkedin.pinot.common.metrics.ControllerMetrics in project pinot by linkedin.
the class ControllerStarter method start.
public void start() {
LOGGER.info("Starting Pinot controller");
Utils.logVersions();
component.getServers().add(Protocol.HTTP, Integer.parseInt(config.getControllerPort()));
component.getClients().add(Protocol.FILE);
component.getClients().add(Protocol.JAR);
final Context applicationContext = component.getContext().createChildContext();
LOGGER.info("Controller download url base: {}", config.generateVipUrl());
LOGGER.info("Injecting configuration and resource manager to the API context");
applicationContext.getAttributes().put(ControllerConf.class.toString(), config);
applicationContext.getAttributes().put(PinotHelixResourceManager.class.toString(), helixResourceManager);
MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.getParams().setConnectionTimeout(config.getServerAdminRequestTimeoutSeconds());
applicationContext.getAttributes().put(HttpConnectionManager.class.toString(), connectionManager);
applicationContext.getAttributes().put(Executor.class.toString(), executorService);
controllerRestApp.setContext(applicationContext);
component.getDefaultHost().attach(controllerRestApp);
MetricsHelper.initializeMetrics(config.subset("pinot.controller.metrics"));
MetricsHelper.registerMetricsRegistry(_metricsRegistry);
final ControllerMetrics controllerMetrics = new ControllerMetrics(_metricsRegistry);
try {
LOGGER.info("Starting Pinot Helix resource manager and connecting to Zookeeper");
helixResourceManager.start();
// Helix resource manager must be started in order to create PinotLLCRealtimeSegmentManager
PinotLLCRealtimeSegmentManager.create(helixResourceManager, config, controllerMetrics);
ValidationMetrics validationMetrics = new ValidationMetrics(_metricsRegistry);
validationManager = new ValidationManager(validationMetrics, helixResourceManager, config, PinotLLCRealtimeSegmentManager.getInstance());
LOGGER.info("Starting Pinot REST API component");
component.start();
LOGGER.info("Starting retention manager");
retentionManager.start();
LOGGER.info("Starting validation manager");
validationManager.start();
LOGGER.info("Starting realtime segment manager");
realtimeSegmentsManager.start(controllerMetrics);
PinotLLCRealtimeSegmentManager.getInstance().start();
LOGGER.info("Starting segment status manager");
segmentStatusChecker.start(controllerMetrics);
LOGGER.info("Pinot controller ready and listening on port {} for API requests", config.getControllerPort());
LOGGER.info("Controller services available at http://{}:{}/", config.getControllerHost(), config.getControllerPort());
} catch (final Exception e) {
LOGGER.error("Caught exception while starting controller", e);
Utils.rethrowException(e);
throw new AssertionError("Should not reach this");
}
controllerMetrics.addCallbackGauge("helix.connected", new Callable<Long>() {
@Override
public Long call() throws Exception {
return helixResourceManager.getHelixZkManager().isConnected() ? 1L : 0L;
}
});
controllerMetrics.addCallbackGauge("helix.leader", new Callable<Long>() {
@Override
public Long call() throws Exception {
return helixResourceManager.getHelixZkManager().isLeader() ? 1L : 0L;
}
});
controllerMetrics.addCallbackGauge("dataDir.exists", new Callable<Long>() {
@Override
public Long call() throws Exception {
return new File(config.getDataDir()).exists() ? 1L : 0L;
}
});
controllerMetrics.addCallbackGauge("dataDir.fileOpLatencyMs", new Callable<Long>() {
@Override
public Long call() throws Exception {
File dataDir = new File(config.getDataDir());
if (dataDir.exists()) {
try {
long startTime = System.currentTimeMillis();
final File testFile = new File(dataDir, config.getControllerHost());
FileOutputStream outputStream = new FileOutputStream(testFile, false);
outputStream.write(Longs.toByteArray(System.currentTimeMillis()));
outputStream.flush();
outputStream.close();
FileUtils.deleteQuietly(testFile);
long endTime = System.currentTimeMillis();
return endTime - startTime;
} catch (IOException e) {
LOGGER.warn("Caught exception while checking the data directory operation latency", e);
return DATA_DIRECTORY_EXCEPTION_VALUE;
}
} else {
return DATA_DIRECTORY_MISSING_VALUE;
}
}
});
ServiceStatus.setServiceStatusCallback(new ServiceStatus.ServiceStatusCallback() {
private boolean _isStarted = false;
@Override
public ServiceStatus.Status getServiceStatus() {
if (_isStarted) {
// If we've connected to Helix at some point, the instance status depends on being connected to ZK
if (helixResourceManager.getHelixZkManager().isConnected()) {
return ServiceStatus.Status.GOOD;
} else {
return ServiceStatus.Status.BAD;
}
}
// Return starting until zk is connected
if (!helixResourceManager.getHelixZkManager().isConnected()) {
return ServiceStatus.Status.STARTING;
} else {
_isStarted = true;
return ServiceStatus.Status.GOOD;
}
}
});
helixResourceManager.getHelixZkManager().addPreConnectCallback(new PreConnectCallback() {
@Override
public void onPreConnect() {
controllerMetrics.addMeteredGlobalValue(ControllerMeter.HELIX_ZOOKEEPER_RECONNECTS, 1L);
}
});
controllerMetrics.initializeGlobalMeters();
ControllerRestApplication.setControllerMetrics(controllerMetrics);
}
Aggregations