Search in sources :

Example 1 with MantisMasterClientApi

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) {
    }
}
Also used : MasterClientWrapper(io.mantisrx.server.master.client.MasterClientWrapper) WorkerHost(io.mantisrx.server.core.WorkerHost) Action1(rx.functions.Action1) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) JobSchedulingInfo(io.mantisrx.server.core.JobSchedulingInfo) IOException(java.io.IOException) Properties(java.util.Properties) FileInputStream(java.io.FileInputStream) MantisMasterClientApi(io.mantisrx.server.master.client.MantisMasterClientApi) WorkerAssignments(io.mantisrx.server.core.WorkerAssignments) Map(java.util.Map)

Example 2 with MantisMasterClientApi

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();
        }
    });
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Action0(rx.functions.Action0) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MantisMasterClientApi(io.mantisrx.server.master.client.MantisMasterClientApi) JobSchedulingInfo(io.mantisrx.server.core.JobSchedulingInfo) WorkerAssignments(io.mantisrx.server.core.WorkerAssignments) Func1(rx.functions.Func1) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 3 with MantisMasterClientApi

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);
}
Also used : Context(io.mantisrx.runtime.Context) MachineDefinition(io.mantisrx.runtime.MachineDefinition) StageSchedulingInfo(io.mantisrx.runtime.descriptor.StageSchedulingInfo) SchedulingInfo(io.mantisrx.runtime.descriptor.SchedulingInfo) HashMap(java.util.HashMap) Matchers.anyString(org.mockito.Matchers.anyString) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) StageScalingPolicy(io.mantisrx.runtime.descriptor.StageScalingPolicy) MantisMasterClientApi(io.mantisrx.server.master.client.MantisMasterClientApi) StageSchedulingInfo(io.mantisrx.runtime.descriptor.StageSchedulingInfo) Test(org.junit.Test)

Example 4 with MantisMasterClientApi

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));
}
Also used : WorkerHost(io.mantisrx.server.core.WorkerHost) HashMap(java.util.HashMap) JobSchedulingInfo(io.mantisrx.server.core.JobSchedulingInfo) Matchers.anyString(org.mockito.Matchers.anyString) CountDownLatch(java.util.concurrent.CountDownLatch) MantisMasterClientApi(io.mantisrx.server.master.client.MantisMasterClientApi) WorkerAssignments(io.mantisrx.server.core.WorkerAssignments) GaugeMeasurement(io.mantisrx.common.metrics.measurement.GaugeMeasurement) Test(org.junit.Test)

Example 5 with MantisMasterClientApi

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));
    }
}
Also used : HashMap(java.util.HashMap) Matchers.anyString(org.mockito.Matchers.anyString) MantisMasterClientApi(io.mantisrx.server.master.client.MantisMasterClientApi) Context(io.mantisrx.runtime.Context) MachineDefinition(io.mantisrx.runtime.MachineDefinition) StageSchedulingInfo(io.mantisrx.runtime.descriptor.StageSchedulingInfo) SchedulingInfo(io.mantisrx.runtime.descriptor.SchedulingInfo) CountDownLatch(java.util.concurrent.CountDownLatch) Observable(rx.Observable) StageScalingPolicy(io.mantisrx.runtime.descriptor.StageScalingPolicy) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) InvocationOnMock(org.mockito.invocation.InvocationOnMock) StageSchedulingInfo(io.mantisrx.runtime.descriptor.StageSchedulingInfo) Test(org.junit.Test)

Aggregations

MantisMasterClientApi (io.mantisrx.server.master.client.MantisMasterClientApi)12 Test (org.junit.Test)10 HashMap (java.util.HashMap)9 Matchers.anyString (org.mockito.Matchers.anyString)9 CountDownLatch (java.util.concurrent.CountDownLatch)8 JobSchedulingInfo (io.mantisrx.server.core.JobSchedulingInfo)6 WorkerAssignments (io.mantisrx.server.core.WorkerAssignments)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 Context (io.mantisrx.runtime.Context)5 MachineDefinition (io.mantisrx.runtime.MachineDefinition)5 SchedulingInfo (io.mantisrx.runtime.descriptor.SchedulingInfo)5 StageScalingPolicy (io.mantisrx.runtime.descriptor.StageScalingPolicy)5 StageSchedulingInfo (io.mantisrx.runtime.descriptor.StageSchedulingInfo)5 WorkerHost (io.mantisrx.server.core.WorkerHost)5 GaugeMeasurement (io.mantisrx.common.metrics.measurement.GaugeMeasurement)4 Observable (rx.Observable)4 InvocationOnMock (org.mockito.invocation.InvocationOnMock)3 Map (java.util.Map)2 Func1 (rx.functions.Func1)2 MantisServerSentEvent (io.mantisrx.common.MantisServerSentEvent)1