Search in sources :

Example 1 with AutoScalingData

use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.

the class GceAutoScaler method terminateWithIds.

/**
 * Terminates the instances in the list of IDs provided by the caller
 */
@Override
public AutoScalingData terminateWithIds(List<String> ids) {
    log.info("Asked to terminate IDs: [%s]", String.join(",", ids));
    if (ids.isEmpty()) {
        return new AutoScalingData(new ArrayList<>());
    }
    try {
        final String project = envConfig.getProjectId();
        final String zone = envConfig.getZoneName();
        final String managedInstanceGroupName = envConfig.getManagedInstanceGroupName();
        List<String> before = getRunningInstances();
        InstanceGroupManagersDeleteInstancesRequest requestBody = new InstanceGroupManagersDeleteInstancesRequest();
        requestBody.setInstances(namesToInstances(ids));
        Compute computeService = createComputeService();
        Compute.InstanceGroupManagers.DeleteInstances request = computeService.instanceGroupManagers().deleteInstances(project, zone, managedInstanceGroupName, requestBody);
        Operation response = request.execute();
        Operation.Error err = waitForOperationEnd(computeService, response);
        if (err == null || err.isEmpty()) {
            List<String> after = null;
            // certain amount of retries in checking)
            for (int i = 0; i < RUNNING_INSTANCES_MAX_RETRIES; i++) {
                after = getRunningInstances();
                if (after.size() == (before.size() - ids.size())) {
                    break;
                }
                log.info("Machines not down yet, waiting");
                Thread.sleep(POLL_INTERVAL_MS);
            }
            // keep only the ones no more present
            before.removeAll(after);
            return new AutoScalingData(before);
        } else {
            log.error("Unable to terminate instances: %s", err.toPrettyString());
        }
    } catch (Exception e) {
        log.error(e, "Unable to terminate any instances.");
    }
    return new AutoScalingData(new ArrayList<>());
}
Also used : InstanceGroupManagersDeleteInstancesRequest(com.google.api.services.compute.model.InstanceGroupManagersDeleteInstancesRequest) AutoScalingData(org.apache.druid.indexing.overlord.autoscaling.AutoScalingData) Compute(com.google.api.services.compute.Compute) Operation(com.google.api.services.compute.model.Operation) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException)

Example 2 with AutoScalingData

use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.

the class GceAutoScaler method provision.

/**
 * When called resizes envConfig.getManagedInstanceGroupName() increasing it by creating
 * envConfig.getNumInstances() new workers (unless the maximum is reached). Return the
 * IDs of the workers created
 */
@Override
public AutoScalingData provision() {
    final String project = envConfig.getProjectId();
    final String zone = envConfig.getZoneName();
    final int numInstances = envConfig.getNumInstances();
    final String managedInstanceGroupName = envConfig.getManagedInstanceGroupName();
    try {
        List<String> before = getRunningInstances();
        log.debug("Existing instances [%s]", String.join(",", before));
        int toSize = Math.min(before.size() + numInstances, getMaxNumWorkers());
        if (before.size() >= toSize) {
            // nothing to scale
            return new AutoScalingData(new ArrayList<>());
        }
        log.info("Asked to provision instances, will resize to %d", toSize);
        Compute computeService = createComputeService();
        Compute.InstanceGroupManagers.Resize request = computeService.instanceGroupManagers().resize(project, zone, managedInstanceGroupName, toSize);
        Operation response = request.execute();
        Operation.Error err = waitForOperationEnd(computeService, response);
        if (err == null || err.isEmpty()) {
            List<String> after = null;
            // certain amount of retries in checking)
            for (int i = 0; i < RUNNING_INSTANCES_MAX_RETRIES; i++) {
                after = getRunningInstances();
                if (after.size() == toSize) {
                    break;
                }
                log.info("Machines not up yet, waiting");
                Thread.sleep(POLL_INTERVAL_MS);
            }
            // these should be the new ones
            after.removeAll(before);
            log.info("Added instances [%s]", String.join(",", after));
            return new AutoScalingData(after);
        } else {
            log.error("Unable to provision instances: %s", err.toPrettyString());
        }
    } catch (Exception e) {
        log.error(e, "Unable to provision any gce instances.");
    }
    return new AutoScalingData(new ArrayList<>());
}
Also used : AutoScalingData(org.apache.druid.indexing.overlord.autoscaling.AutoScalingData) Compute(com.google.api.services.compute.Compute) Operation(com.google.api.services.compute.model.Operation) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException)

Example 3 with AutoScalingData

use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.

the class GceAutoScalerTest method testTerminateWithIds.

@Test
public void testTerminateWithIds() throws IOException, GeneralSecurityException, GceServiceException {
    GceAutoScaler autoScaler = EasyMock.createMockBuilder(GceAutoScaler.class).withConstructor(int.class, int.class, GceEnvironmentConfig.class).withArgs(2, 4, new GceEnvironmentConfig(1, "proj-x", "us-central-1", "druid-mig")).addMockedMethod("createComputeServiceImpl").createMock();
    EasyMock.expect(autoScaler.createComputeServiceImpl()).andReturn(null);
    EasyMock.expect(autoScaler.createComputeServiceImpl()).andReturn(mockCompute);
    EasyMock.replay(autoScaler);
    // set up getRunningInstances results
    InstanceGroupManagersListManagedInstancesResponse beforeRunningInstance = createRunningInstances(Arrays.asList("http://xyz/foo", "http://xyz/bar", "http://xyz/baz"));
    InstanceGroupManagersListManagedInstancesResponse afterRunningInstance = createRunningInstances(Arrays.asList("http://xyz/foo", "http://xyz/bar"));
    // 1st call
    EasyMock.expect(mockInstancesRequest.execute()).andReturn(beforeRunningInstance);
    EasyMock.expect(mockInstancesRequest.setMaxResults(500L)).andReturn(mockInstancesRequest);
    // 2nd call
    EasyMock.expect(mockInstancesRequest.execute()).andReturn(afterRunningInstance);
    EasyMock.expect(mockInstancesRequest.setMaxResults(500L)).andReturn(mockInstancesRequest);
    EasyMock.replay(mockInstancesRequest);
    EasyMock.expect(mockInstanceGroupManagers.listManagedInstances("proj-x", "us-central-1", "druid-mig")).andReturn(mockInstancesRequest).times(2);
    // set up the delete operation
    Operation mockResponse = new Operation();
    mockResponse.setStatus("DONE");
    mockResponse.setError(new Operation.Error());
    EasyMock.expect(mockDeleteRequest.execute()).andReturn(mockResponse);
    EasyMock.replay(mockDeleteRequest);
    InstanceGroupManagersDeleteInstancesRequest requestBody = new InstanceGroupManagersDeleteInstancesRequest();
    requestBody.setInstances(Collections.singletonList("zones/us-central-1/instances/baz"));
    EasyMock.expect(mockInstanceGroupManagers.deleteInstances("proj-x", "us-central-1", "druid-mig", requestBody)).andReturn(mockDeleteRequest);
    EasyMock.replay(mockInstanceGroupManagers);
    // called twice in getRunningInstances...
    EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
    EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
    // ...and once in terminateWithIds
    EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
    // and that's all folks!
    EasyMock.replay(mockCompute);
    AutoScalingData autoScalingData = autoScaler.terminateWithIds(Collections.singletonList("baz"));
    Assert.assertEquals(1, autoScalingData.getNodeIds().size());
    Assert.assertEquals("baz", autoScalingData.getNodeIds().get(0));
    EasyMock.verify(mockCompute);
    EasyMock.verify(mockInstanceGroupManagers);
    EasyMock.verify(mockDeleteRequest);
    EasyMock.verify(mockInstancesRequest);
}
Also used : InstanceGroupManagersDeleteInstancesRequest(com.google.api.services.compute.model.InstanceGroupManagersDeleteInstancesRequest) AutoScalingData(org.apache.druid.indexing.overlord.autoscaling.AutoScalingData) InstanceGroupManagersListManagedInstancesResponse(com.google.api.services.compute.model.InstanceGroupManagersListManagedInstancesResponse) Operation(com.google.api.services.compute.model.Operation) Test(org.junit.Test)

Example 4 with AutoScalingData

use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.

the class GceAutoScalerTest method testTerminate.

@Test
public void testTerminate() throws IOException, GeneralSecurityException, GceServiceException {
    GceAutoScaler autoScaler = EasyMock.createMockBuilder(GceAutoScaler.class).withConstructor(int.class, int.class, GceEnvironmentConfig.class).withArgs(2, 4, new GceEnvironmentConfig(1, "proj-x", "us-central-1", "druid-mig")).addMockedMethod("createComputeServiceImpl").createMock();
    EasyMock.expect(autoScaler.createComputeServiceImpl()).andReturn(null);
    EasyMock.expect(autoScaler.createComputeServiceImpl()).andReturn(mockCompute);
    EasyMock.replay(autoScaler);
    // testing the ip --> id part
    Instance i0 = makeInstance("baz", "1.2.3.6");
    InstanceList mockInstanceListResponse = new InstanceList();
    mockInstanceListResponse.setNextPageToken(null);
    mockInstanceListResponse.setItems(Collections.singletonList(i0));
    EasyMock.expect(mockIpToIdRequest.execute()).andReturn(mockInstanceListResponse);
    EasyMock.expect(mockIpToIdRequest.setPageToken(EasyMock.anyString())).andReturn(// the method needs to return something, what is actually irrelevant here
    mockIpToIdRequest);
    EasyMock.replay(mockIpToIdRequest);
    EasyMock.expect(mockInstances.list("proj-x", "us-central-1")).andReturn(mockIpToIdRequest);
    EasyMock.expect(mockCompute.instances()).andReturn(mockInstances);
    EasyMock.replay(mockInstances);
    // testing the delete part
    InstanceGroupManagersListManagedInstancesResponse beforeRunningInstance = createRunningInstances(Arrays.asList("http://xyz/foo", "http://xyz/bar", "http://xyz/baz"));
    InstanceGroupManagersListManagedInstancesResponse afterRunningInstance = createRunningInstances(Arrays.asList("http://xyz/foo", "http://xyz/bar"));
    // 1st call
    EasyMock.expect(mockInstancesRequest.execute()).andReturn(beforeRunningInstance);
    EasyMock.expect(mockInstancesRequest.setMaxResults(500L)).andReturn(mockInstancesRequest);
    // 2nd call
    EasyMock.expect(mockInstancesRequest.execute()).andReturn(afterRunningInstance);
    EasyMock.expect(mockInstancesRequest.setMaxResults(500L)).andReturn(mockInstancesRequest);
    EasyMock.replay(mockInstancesRequest);
    EasyMock.expect(mockInstanceGroupManagers.listManagedInstances("proj-x", "us-central-1", "druid-mig")).andReturn(mockInstancesRequest).times(2);
    // set up the delete operation
    Operation mockResponse = new Operation();
    mockResponse.setStatus("DONE");
    mockResponse.setError(new Operation.Error());
    EasyMock.expect(mockDeleteRequest.execute()).andReturn(mockResponse);
    EasyMock.replay(mockDeleteRequest);
    InstanceGroupManagersDeleteInstancesRequest requestBody = new InstanceGroupManagersDeleteInstancesRequest();
    requestBody.setInstances(Collections.singletonList("zones/us-central-1/instances/baz"));
    EasyMock.expect(mockInstanceGroupManagers.deleteInstances("proj-x", "us-central-1", "druid-mig", requestBody)).andReturn(mockDeleteRequest);
    EasyMock.replay(mockInstanceGroupManagers);
    // called twice in getRunningInstances...
    EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
    EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
    // ...and once in terminateWithIds
    EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
    // and that's all folks!
    EasyMock.replay(mockCompute);
    AutoScalingData autoScalingData = autoScaler.terminate(Collections.singletonList("1.2.3.6"));
    Assert.assertEquals(1, autoScalingData.getNodeIds().size());
    Assert.assertEquals("baz", autoScalingData.getNodeIds().get(0));
    EasyMock.verify(mockCompute);
    EasyMock.verify(mockIpToIdRequest);
    EasyMock.verify(mockInstanceGroupManagers);
    EasyMock.verify(mockDeleteRequest);
    EasyMock.verify(mockInstancesRequest);
}
Also used : InstanceGroupManagersDeleteInstancesRequest(com.google.api.services.compute.model.InstanceGroupManagersDeleteInstancesRequest) AutoScalingData(org.apache.druid.indexing.overlord.autoscaling.AutoScalingData) Instance(com.google.api.services.compute.model.Instance) ManagedInstance(com.google.api.services.compute.model.ManagedInstance) InstanceGroupManagersListManagedInstancesResponse(com.google.api.services.compute.model.InstanceGroupManagersListManagedInstancesResponse) Operation(com.google.api.services.compute.model.Operation) InstanceList(com.google.api.services.compute.model.InstanceList) Test(org.junit.Test)

Example 5 with AutoScalingData

use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.

the class EC2AutoScalerTest method testScale.

@Test
public void testScale() {
    RunInstancesResult runInstancesResult = EasyMock.createMock(RunInstancesResult.class);
    EC2AutoScaler autoScaler = new EC2AutoScaler(0, 1, ENV_CONFIG, amazonEC2Client, managementConfig);
    EasyMock.expect(amazonEC2Client.runInstances(EasyMock.anyObject(RunInstancesRequest.class))).andReturn(runInstancesResult);
    EasyMock.expect(amazonEC2Client.describeInstances(EasyMock.anyObject(DescribeInstancesRequest.class))).andReturn(describeInstancesResult);
    EasyMock.expect(amazonEC2Client.terminateInstances(EasyMock.anyObject(TerminateInstancesRequest.class))).andReturn(null);
    EasyMock.replay(amazonEC2Client);
    EasyMock.expect(runInstancesResult.getReservation()).andReturn(reservation).atLeastOnce();
    EasyMock.replay(runInstancesResult);
    EasyMock.expect(describeInstancesResult.getReservations()).andReturn(Collections.singletonList(reservation)).atLeastOnce();
    EasyMock.replay(describeInstancesResult);
    EasyMock.expect(reservation.getInstances()).andReturn(Collections.singletonList(instance)).atLeastOnce();
    EasyMock.replay(reservation);
    AutoScalingData created = autoScaler.provision();
    Assert.assertEquals(created.getNodeIds().size(), 1);
    Assert.assertEquals("theInstance", created.getNodeIds().get(0));
    AutoScalingData deleted = autoScaler.terminate(Collections.singletonList("dummyIP"));
    Assert.assertEquals(deleted.getNodeIds().size(), 1);
    Assert.assertEquals(INSTANCE_ID, deleted.getNodeIds().get(0));
    EasyMock.verify(runInstancesResult);
}
Also used : AutoScalingData(org.apache.druid.indexing.overlord.autoscaling.AutoScalingData) RunInstancesResult(com.amazonaws.services.ec2.model.RunInstancesResult) RunInstancesRequest(com.amazonaws.services.ec2.model.RunInstancesRequest) DescribeInstancesRequest(com.amazonaws.services.ec2.model.DescribeInstancesRequest) TerminateInstancesRequest(com.amazonaws.services.ec2.model.TerminateInstancesRequest) Test(org.junit.Test)

Aggregations

AutoScalingData (org.apache.druid.indexing.overlord.autoscaling.AutoScalingData)12 Operation (com.google.api.services.compute.model.Operation)7 Test (org.junit.Test)7 InstanceGroupManagersListManagedInstancesResponse (com.google.api.services.compute.model.InstanceGroupManagersListManagedInstancesResponse)6 InstanceGroupManagersDeleteInstancesRequest (com.google.api.services.compute.model.InstanceGroupManagersDeleteInstancesRequest)4 DescribeInstancesRequest (com.amazonaws.services.ec2.model.DescribeInstancesRequest)2 Instance (com.amazonaws.services.ec2.model.Instance)2 RunInstancesRequest (com.amazonaws.services.ec2.model.RunInstancesRequest)2 RunInstancesResult (com.amazonaws.services.ec2.model.RunInstancesResult)2 TerminateInstancesRequest (com.amazonaws.services.ec2.model.TerminateInstancesRequest)2 Compute (com.google.api.services.compute.Compute)2 Function (com.google.common.base.Function)2 IOException (java.io.IOException)2 GeneralSecurityException (java.security.GeneralSecurityException)2 DescribeInstancesResult (com.amazonaws.services.ec2.model.DescribeInstancesResult)1 Filter (com.amazonaws.services.ec2.model.Filter)1 InstanceNetworkInterfaceSpecification (com.amazonaws.services.ec2.model.InstanceNetworkInterfaceSpecification)1 Placement (com.amazonaws.services.ec2.model.Placement)1 Reservation (com.amazonaws.services.ec2.model.Reservation)1 Instance (com.google.api.services.compute.model.Instance)1