use of io.mantisrx.server.master.client.MantisMasterClientApi in project mantis by Netflix.
the class ConnectToNamedJob method main2.
public static void main2(final String[] args) {
List<String> remArgs = Collections.emptyList();
try {
remArgs = Args.parse(ConnectToNamedJob.class, args);
} catch (IllegalArgumentException e) {
Args.usage(SubmitEphemeralJob.class);
System.exit(1);
}
if (remArgs.isEmpty()) {
System.err.println("Must provide JobId as argument");
System.exit(1);
}
final String jobId = remArgs.get(0);
Properties properties = new Properties();
System.out.println("propfile=" + propFile);
try (InputStream inputStream = new FileInputStream(propFile)) {
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
MasterClientWrapper clientWrapper = new MasterClientWrapper(properties);
clientWrapper.getMasterClientApi().doOnNext(new Action1<MantisMasterClientApi>() {
@Override
public void call(MantisMasterClientApi clientApi) {
logger.info("************** connecting to schedInfo for job " + jobId);
clientApi.schedulingChanges(jobId).doOnNext(new Action1<JobSchedulingInfo>() {
@Override
public void call(JobSchedulingInfo schedulingInfo) {
final WorkerAssignments workerAssignments = schedulingInfo.getWorkerAssignments().get(1);
for (Map.Entry<Integer, WorkerHost> entry : workerAssignments.getHosts().entrySet()) {
System.out.println("Worker " + entry.getKey() + ": state=" + entry.getValue().getState() + ", host=" + entry.getValue().getHost() + ", port=" + entry.getValue().getPort());
}
}
}).subscribe();
;
}
}).subscribe();
// .subscribe();
try {
Thread.sleep(10000000);
} catch (InterruptedException ie) {
}
}
use of io.mantisrx.server.master.client.MantisMasterClientApi in project mantis by Netflix.
the class StageWorkersCount method getWorkerCounts.
Observable<Integer> getWorkerCounts(final int stageNumber) {
final AtomicInteger workerCount = new AtomicInteger(0);
final AtomicBoolean gotCompletion = new AtomicBoolean(false);
return mantisClient.getClientWrapper().getMasterClientApi().flatMap(new Func1<MantisMasterClientApi, Observable<Integer>>() {
@Override
public Observable<Integer> call(MantisMasterClientApi mantisMasterClientApi) {
return mantisMasterClientApi.schedulingChanges(jobId).map(new Func1<JobSchedulingInfo, Integer>() {
@Override
public Integer call(JobSchedulingInfo jobSchedulingInfo) {
final WorkerAssignments assignments = jobSchedulingInfo.getWorkerAssignments().get(stageNumber);
if (assignments == null)
return -1;
else
return assignments.getNumWorkers();
}
}).filter(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer newCount) {
if (newCount == workerCount.get())
return false;
workerCount.set(newCount);
return true;
}
}).doOnCompleted(new Action0() {
@Override
public void call() {
gotCompletion.set(true);
}
});
}
}).takeWhile(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return !gotCompletion.get();
}
});
}
use of io.mantisrx.server.master.client.MantisMasterClientApi in project mantis by Netflix.
the class JobAutoScalerTest method testScaleDownNotLessThanMin.
@Test
public void testScaleDownNotLessThanMin() throws InterruptedException {
final String jobId = "test-job-1";
final int coolDownSec = 2;
final int scalingStageNum = 1;
final MantisMasterClientApi mockMasterClientApi = mock(MantisMasterClientApi.class);
final Map<Integer, StageSchedulingInfo> schedulingInfoMap = new HashMap<>();
final int numStage1Workers = 5;
final int increment = 10;
// decrement by 10 on scale down, this will push num workers below min and below 0.
final int decrement = 10;
final int min = 3;
final int max = 50;
final double scaleUpAbovePct = 45.0;
final double scaleDownBelowPct = 15.0;
final double workerMemoryMB = 512.0;
final StageSchedulingInfo stage1SchedInfo = StageSchedulingInfo.builder().numberOfInstances(numStage1Workers).machineDefinition(new MachineDefinition(2, workerMemoryMB, 200, 1024, 2)).scalingPolicy(new StageScalingPolicy(scalingStageNum, min, max, increment, decrement, coolDownSec, Collections.singletonMap(StageScalingPolicy.ScalingReason.Memory, new StageScalingPolicy.Strategy(StageScalingPolicy.ScalingReason.Memory, scaleDownBelowPct, scaleUpAbovePct, new StageScalingPolicy.RollingCount(1, 2))))).scalable(true).build();
schedulingInfoMap.put(scalingStageNum, stage1SchedInfo);
when(mockMasterClientApi.scaleJobStage(eq(jobId), eq(scalingStageNum), anyInt(), anyString())).thenReturn(Observable.just(true));
Context context = mock(Context.class);
when(context.getWorkerMapObservable()).thenReturn(Observable.empty());
final JobAutoScaler jobAutoScaler = new JobAutoScaler(jobId, new SchedulingInfo(schedulingInfoMap), mockMasterClientApi, context);
jobAutoScaler.start();
final Observer<JobAutoScaler.Event> jobAutoScalerObserver = jobAutoScaler.getObserver();
// should trigger a scale down (below 15% scaleDown threshold)
jobAutoScalerObserver.onNext(new JobAutoScaler.Event(StageScalingPolicy.ScalingReason.Memory, scalingStageNum, workerMemoryMB * (scaleDownBelowPct / 100.0 - 0.01), numStage1Workers, ""));
verify(mockMasterClientApi, timeout(1000).times(1)).scaleJobStage(jobId, scalingStageNum, min, String.format("Memory with value %1$,.2f is below scaleDown threshold of %2$,.1f", (scaleDownBelowPct / 100.0 - 0.01) * 100.0, scaleDownBelowPct));
verifyNoMoreInteractions(mockMasterClientApi);
}
use of io.mantisrx.server.master.client.MantisMasterClientApi in project mantis by Netflix.
the class WorkerMetricHandlerTest method testSourceJobDropMetricTriggersAutoScale.
@Test
public void testSourceJobDropMetricTriggersAutoScale() throws InterruptedException {
final String jobId = "test-job-1";
final String sourceJobId = "source-test-job-1";
final int stage = 1;
final MantisMasterClientApi mockMasterClientApi = mock(MantisMasterClientApi.class);
final Map<Integer, WorkerAssignments> assignmentsMap = new HashMap<>();
assignmentsMap.put(stage, new WorkerAssignments(stage, 2, ImmutableMap.of(1, new WorkerHost("1.1.1.1", 0, Arrays.asList(31300), MantisJobState.Started, 1, 31301, -1), 2, new WorkerHost("2.2.2.2", 1, Arrays.asList(31300), MantisJobState.Started, 2, 31301, -1))));
when(mockMasterClientApi.schedulingChanges(jobId)).thenReturn(Observable.just(new JobSchedulingInfo(jobId, assignmentsMap)));
final CountDownLatch latch = new CountDownLatch(1);
final AutoScaleMetricsConfig aggregationConfig = new AutoScaleMetricsConfig();
final WorkerMetricHandler workerMetricHandler = new WorkerMetricHandler(jobId, new Observer<JobAutoScaler.Event>() {
@Override
public void onCompleted() {
logger.warn("onCompleted");
}
@Override
public void onError(Throwable e) {
logger.warn("onError {}", e.getMessage(), e);
}
@Override
public void onNext(JobAutoScaler.Event event) {
logger.info("got auto scale event {}", event);
// Expected metric value should be (1 + 2 + 3 + 6) / 6.0 / 2
JobAutoScaler.Event expected = new JobAutoScaler.Event(StageScalingPolicy.ScalingReason.SourceJobDrop, stage, 1.0, 2, "");
if (expected.equals(event)) {
latch.countDown();
}
}
}, mockMasterClientApi, aggregationConfig);
final Observer<MetricData> metricDataObserver = workerMetricHandler.initAndGetMetricDataObserver();
List<GaugeMeasurement> gauges = Arrays.asList(new GaugeMeasurement(PROCESSED_COUNTER_METRIC_NAME, 10.0), new GaugeMeasurement(DROPPED_COUNTER_METRIC_NAME, 1.0));
// Source job worker 0 -> job worker 0
metricDataObserver.onNext(new MetricData(sourceJobId, stage, 0, 1, "ServerSentEventRequestHandler:clientId=" + jobId + ":sockAddr=/1.1.1.1", gauges));
gauges = Arrays.asList(new GaugeMeasurement(PROCESSED_COUNTER_METRIC_NAME, 20.0), new GaugeMeasurement(DROPPED_COUNTER_METRIC_NAME, 2.0));
// Source job worker 0 -> job worker 1
metricDataObserver.onNext(new MetricData(sourceJobId, stage, 0, 1, "ServerSentEventRequestHandler:clientId=" + jobId + ":sockAddr=/2.2.2.2", gauges));
gauges = Arrays.asList(new GaugeMeasurement(PROCESSED_COUNTER_METRIC_NAME, 30.0), new GaugeMeasurement(DROPPED_COUNTER_METRIC_NAME, 3.0));
// Source job worker 1 -> job worker 0
metricDataObserver.onNext(new MetricData(sourceJobId, stage, 1, 2, "ServerSentEventRequestHandler:clientId=" + jobId + ":sockAddr=/1.1.1.1", gauges));
gauges = Arrays.asList(new GaugeMeasurement(PROCESSED_COUNTER_METRIC_NAME, 60.0), new GaugeMeasurement(DROPPED_COUNTER_METRIC_NAME, 6.0));
// Source job worker 1 -> job worker 1
metricDataObserver.onNext(new MetricData(sourceJobId, stage, 1, 2, "ServerSentEventRequestHandler:clientId=" + jobId + ":sockAddr=/2.2.2.2", gauges));
// Another datapoint from source job worker 1 -> job worker 1 to verify MAX aggregation
gauges = Arrays.asList(new GaugeMeasurement(PROCESSED_COUNTER_METRIC_NAME, 50.0), new GaugeMeasurement(DROPPED_COUNTER_METRIC_NAME, 5.0));
metricDataObserver.onNext(new MetricData(sourceJobId, stage, 1, 2, "ServerSentEventRequestHandler:clientId=" + jobId + ":sockAddr=/2.2.2.2", gauges));
assertTrue(latch.await(30 + 5, /* leeway */
TimeUnit.SECONDS));
}
use of io.mantisrx.server.master.client.MantisMasterClientApi in project mantis by Netflix.
the class JobAutoScalerTest method testScaleUpOnDifferentScalingReasons.
@Test
public void testScaleUpOnDifferentScalingReasons() throws InterruptedException {
final List<StageScalingPolicy.ScalingReason> scalingReasons = Arrays.asList(DataDrop, KafkaLag, UserDefined);
for (StageScalingPolicy.ScalingReason scalingReason : scalingReasons) {
logger.info("==== test scaling reason {} =====", scalingReason.name());
final String jobId = "test-job-1";
final int coolDownSec = 2;
final int scalingStageNum = 1;
final MantisMasterClientApi mockMasterClientApi = mock(MantisMasterClientApi.class);
final Map<Integer, StageSchedulingInfo> schedulingInfoMap = new HashMap<>();
final int numStage1Workers = 1;
final int increment = 1;
final int decrement = 0;
final int min = 1;
final int max = 5;
final double scaleUpAbove = 2000.0;
final double scaleDownBelow = 0.0;
final double workerMemoryMB = 512.0;
final StageSchedulingInfo stage1SchedInfo = StageSchedulingInfo.builder().numberOfInstances(numStage1Workers).machineDefinition(new MachineDefinition(2, workerMemoryMB, 200, 1024, 2)).scalingPolicy(new StageScalingPolicy(scalingStageNum, min, max, increment, decrement, coolDownSec, Collections.singletonMap(scalingReason, new StageScalingPolicy.Strategy(scalingReason, scaleDownBelow, scaleUpAbove, new StageScalingPolicy.RollingCount(1, 2))))).scalable(true).build();
schedulingInfoMap.put(scalingStageNum, stage1SchedInfo);
when(mockMasterClientApi.scaleJobStage(eq(jobId), eq(scalingStageNum), eq(numStage1Workers + increment), anyString())).thenReturn(Observable.just(true));
Context context = mock(Context.class);
when(context.getWorkerMapObservable()).thenReturn(Observable.empty());
final JobAutoScaler jobAutoScaler = new JobAutoScaler(jobId, new SchedulingInfo(schedulingInfoMap), mockMasterClientApi, context);
jobAutoScaler.start();
final Observer<JobAutoScaler.Event> jobAutoScalerObserver = jobAutoScaler.getObserver();
// should trigger a scale up (above scaleUp threshold)
jobAutoScalerObserver.onNext(new JobAutoScaler.Event(scalingReason, scalingStageNum, scaleUpAbove + 0.01, numStage1Workers, ""));
verify(mockMasterClientApi, timeout(1000).times(1)).scaleJobStage(jobId, scalingStageNum, numStage1Workers + increment, String.format("%s with value %2$.2f exceeded scaleUp threshold of %3$.1f", scalingReason.name(), (scaleUpAbove + 0.01), scaleUpAbove));
// should *not* trigger a scale up before cooldown period (above scaleUp threshold)
jobAutoScalerObserver.onNext(new JobAutoScaler.Event(scalingReason, scalingStageNum, scaleUpAbove + 0.01, numStage1Workers + increment, ""));
jobAutoScalerObserver.onNext(new JobAutoScaler.Event(scalingReason, scalingStageNum, scaleUpAbove + 0.01, numStage1Workers + increment, ""));
Thread.sleep(coolDownSec * 1000);
// retry sending auto scale event till scaleJobStage request sent to master, as there is possible a race between the sleep for coolDownSecs in the Test and the event being processed before coolDownSecs
final CountDownLatch retryLatch = new CountDownLatch(1);
when(mockMasterClientApi.scaleJobStage(eq(jobId), eq(scalingStageNum), eq(numStage1Workers + 2 * increment), anyString())).thenAnswer(new Answer<Observable<Void>>() {
@Override
public Observable<Void> answer(InvocationOnMock invocation) throws Throwable {
retryLatch.countDown();
return Observable.just(null);
}
});
do {
logger.info("sending Job auto scale Event");
// should trigger a scale up after cooldown period (above scaleUp threshold)
jobAutoScalerObserver.onNext(new JobAutoScaler.Event(scalingReason, scalingStageNum, scaleUpAbove + 0.01, numStage1Workers + increment, ""));
} while (!retryLatch.await(1, TimeUnit.SECONDS));
verify(mockMasterClientApi, timeout(1000).times(1)).scaleJobStage(jobId, scalingStageNum, numStage1Workers + 2 * increment, String.format("%s with value %2$.2f exceeded scaleUp threshold of %3$.1f", scalingReason.name(), (scaleUpAbove + 0.01), scaleUpAbove));
}
}
Aggregations