use of org.apache.helix.HelixAdmin in project helix by apache.
the class TestFullAutoNodeTagging method testUntag.
@Test
public void testUntag() throws Exception {
final int NUM_PARTICIPANTS = 2;
final int NUM_PARTITIONS = 4;
final int NUM_REPLICAS = 1;
final String RESOURCE_NAME = "TestResource0";
final String TAG = "ASSIGNABLE";
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
final String clusterName = className + "_" + methodName;
System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis()));
// Set up cluster
// participant port
TestHelper.setupCluster(// participant port
clusterName, // participant port
ZK_ADDR, // participant port
12918, // participant name prefix
"localhost", // resource name prefix
"TestResource", // resources
1, // partitions per resource
NUM_PARTITIONS, // number of nodes
NUM_PARTICIPANTS, // replicas
NUM_REPLICAS, // use FULL_AUTO mode to test node tagging
"OnlineOffline", // use FULL_AUTO mode to test node tagging
RebalanceMode.FULL_AUTO, // do rebalance
true);
// Tag the resource
final HelixAdmin helixAdmin = new ZKHelixAdmin(_gZkClient);
IdealState idealState = helixAdmin.getResourceIdealState(clusterName, RESOURCE_NAME);
idealState.setInstanceGroupTag(TAG);
helixAdmin.setResourceIdealState(clusterName, RESOURCE_NAME, idealState);
// Get a data accessor
final HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(_gZkClient));
final PropertyKey.Builder keyBuilder = accessor.keyBuilder();
// Tag the participants
for (int i = 0; i < NUM_PARTICIPANTS; i++) {
final String instanceName = "localhost_" + (12918 + i);
helixAdmin.addInstanceTag(clusterName, instanceName, TAG);
}
// Start controller
ClusterControllerManager controller = new ClusterControllerManager(ZK_ADDR, clusterName, "controller");
controller.syncStart();
// Start participants
MockParticipantManager[] participants = new MockParticipantManager[NUM_PARTICIPANTS];
for (int i = 0; i < NUM_PARTICIPANTS; i++) {
final String instanceName = "localhost_" + (12918 + i);
participants[i] = new MockParticipantManager(ZK_ADDR, clusterName, instanceName);
participants[i].syncStart();
}
// Verify that there are NUM_PARTITIONS partitions in the external view, each having
// NUM_REPLICAS replicas, where all assigned replicas are to tagged nodes, and they are all
// ONLINE.
Verifier v = new Verifier() {
@Override
public boolean verify() throws Exception {
ExternalView externalView = pollForProperty(ExternalView.class, accessor, keyBuilder.externalView(RESOURCE_NAME), true);
if (externalView == null) {
return false;
}
Set<String> taggedInstances = Sets.newHashSet(helixAdmin.getInstancesInClusterWithTag(clusterName, TAG));
Set<String> partitionSet = externalView.getPartitionSet();
if (partitionSet.size() != NUM_PARTITIONS) {
return false;
}
for (String partitionName : partitionSet) {
Map<String, String> stateMap = externalView.getStateMap(partitionName);
if (stateMap.size() != NUM_REPLICAS) {
return false;
}
for (String participantName : stateMap.keySet()) {
if (!taggedInstances.contains(participantName)) {
return false;
}
String state = stateMap.get(participantName);
if (!state.equalsIgnoreCase("ONLINE")) {
return false;
}
}
}
return true;
}
};
// Run the verifier for both nodes tagged
boolean initialResult = TestHelper.verify(v, 10 * 1000);
Assert.assertTrue(initialResult);
// Untag a node
helixAdmin.removeInstanceTag(clusterName, "localhost_12918", TAG);
// Verify again
boolean finalResult = TestHelper.verify(v, 10 * 1000);
Assert.assertTrue(finalResult);
System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis()));
}
use of org.apache.helix.HelixAdmin in project helix by apache.
the class TestFullAutoNodeTagging method testResourceTaggedFirst.
/**
* Ensure that no assignments happen when there are no tagged nodes, but the resource is tagged
*/
@Test
public void testResourceTaggedFirst() throws Exception {
final int NUM_PARTICIPANTS = 10;
final int NUM_PARTITIONS = 4;
final int NUM_REPLICAS = 2;
final String RESOURCE_NAME = "TestDB0";
final String TAG = "ASSIGNABLE";
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
String clusterName = className + "_" + methodName;
System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis()));
// Set up cluster
// participant port
TestHelper.setupCluster(// participant port
clusterName, // participant port
ZK_ADDR, // participant port
12918, // participant name prefix
"localhost", // resource name prefix
"TestDB", // resources
1, // partitions per resource
NUM_PARTITIONS, // number of nodes
NUM_PARTICIPANTS, // replicas
NUM_REPLICAS, // use FULL_AUTO mode to test node tagging
"MasterSlave", // use FULL_AUTO mode to test node tagging
RebalanceMode.FULL_AUTO, // do rebalance
true);
// tag the resource
HelixAdmin helixAdmin = new ZKHelixAdmin(ZK_ADDR);
IdealState idealState = helixAdmin.getResourceIdealState(clusterName, RESOURCE_NAME);
idealState.setInstanceGroupTag(TAG);
helixAdmin.setResourceIdealState(clusterName, RESOURCE_NAME, idealState);
// start controller
ClusterControllerManager controller = new ClusterControllerManager(ZK_ADDR, clusterName, "controller");
controller.syncStart();
// start participants
MockParticipantManager[] participants = new MockParticipantManager[NUM_PARTICIPANTS];
for (int i = 0; i < NUM_PARTICIPANTS; i++) {
final String instanceName = "localhost_" + (12918 + i);
participants[i] = new MockParticipantManager(ZK_ADDR, clusterName, instanceName);
participants[i].syncStart();
}
Thread.sleep(1000);
boolean result = ClusterStateVerifier.verifyByZkCallback(new EmptyZkVerifier(clusterName, RESOURCE_NAME));
Assert.assertTrue(result, "External view and current state must be empty");
// cleanup
for (int i = 0; i < NUM_PARTICIPANTS; i++) {
participants[i].syncStop();
}
controller.syncStop();
}
use of org.apache.helix.HelixAdmin in project helix by apache.
the class TestFullAutoNodeTagging method testSafeAssignment.
/**
* Basic test for tagging behavior. 10 participants, of which 4 are tagged. Launch all 10,
* checking external view every time a tagged node is started. Then shut down all 10, checking
* external view every time a tagged node is killed.
*/
@Test
public void testSafeAssignment() throws Exception {
final int NUM_PARTICIPANTS = 10;
final int NUM_PARTITIONS = 4;
final int NUM_REPLICAS = 2;
final String RESOURCE_NAME = "TestDB0";
final String TAG = "ASSIGNABLE";
final String[] TAGGED_NODES = { "localhost_12920", "localhost_12922", "localhost_12924", "localhost_12925" };
Set<String> taggedNodes = Sets.newHashSet(TAGGED_NODES);
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
String clusterName = className + "_" + methodName;
System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis()));
// Set up cluster
// participant port
TestHelper.setupCluster(// participant port
clusterName, // participant port
ZK_ADDR, // participant port
12918, // participant name prefix
"localhost", // resource name prefix
"TestDB", // resources
1, // partitions per resource
NUM_PARTITIONS, // number of nodes
NUM_PARTICIPANTS, // replicas
NUM_REPLICAS, // use FULL_AUTO mode to test node tagging
"MasterSlave", // use FULL_AUTO mode to test node tagging
RebalanceMode.FULL_AUTO, // do rebalance
true);
// tag the resource and participants
HelixAdmin helixAdmin = new ZKHelixAdmin(ZK_ADDR);
for (String taggedNode : TAGGED_NODES) {
helixAdmin.addInstanceTag(clusterName, taggedNode, TAG);
}
IdealState idealState = helixAdmin.getResourceIdealState(clusterName, RESOURCE_NAME);
idealState.setInstanceGroupTag(TAG);
helixAdmin.setResourceIdealState(clusterName, RESOURCE_NAME, idealState);
// start controller
ClusterControllerManager controller = new ClusterControllerManager(ZK_ADDR, clusterName, "controller");
controller.syncStart();
// start participants
MockParticipantManager[] participants = new MockParticipantManager[NUM_PARTICIPANTS];
for (int i = 0; i < NUM_PARTICIPANTS; i++) {
final String instanceName = "localhost_" + (12918 + i);
participants[i] = new MockParticipantManager(ZK_ADDR, clusterName, instanceName);
participants[i].syncStart();
// ensure that everything is valid if this is a tagged node that is starting
if (taggedNodes.contains(instanceName)) {
// make sure that the best possible matches the external view
Thread.sleep(500);
boolean result = ClusterStateVerifier.verifyByZkCallback(new BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName));
Assert.assertTrue(result);
// make sure that the tagged state of the nodes is still balanced
result = ClusterStateVerifier.verifyByZkCallback(new TaggedZkVerifier(clusterName, RESOURCE_NAME, TAGGED_NODES, false));
Assert.assertTrue(result, "initial assignment with all tagged nodes live is invalid");
}
}
// cleanup
for (int i = 0; i < NUM_PARTICIPANTS; i++) {
String participantName = participants[i].getInstanceName();
participants[i].syncStop();
if (taggedNodes.contains(participantName)) {
// check that the external view is still correct even after removing tagged nodes
taggedNodes.remove(participantName);
Thread.sleep(500);
boolean result = ClusterStateVerifier.verifyByZkCallback(new TaggedZkVerifier(clusterName, RESOURCE_NAME, TAGGED_NODES, taggedNodes.isEmpty()));
Assert.assertTrue(result, "incorrect state after removing " + participantName + ", " + taggedNodes + " remain");
}
}
controller.syncStop();
System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis()));
}
use of org.apache.helix.HelixAdmin in project pinot by linkedin.
the class OfflineClusterIntegrationTest method setUp.
@BeforeClass
public void setUp() throws Exception {
//Clean up
ensureDirectoryExistsAndIsEmpty(_tmpDir);
ensureDirectoryExistsAndIsEmpty(_segmentDir);
ensureDirectoryExistsAndIsEmpty(_tarDir);
// Start the cluster
startCluster();
// Unpack the Avro files
final List<File> avroFiles = unpackAvroData(_tmpDir, SEGMENT_COUNT);
createTable();
// Get the list of instances through the REST API
URL url = new URL("http://" + ControllerTestUtils.DEFAULT_CONTROLLER_HOST + ":" + ControllerTestUtils.DEFAULT_CONTROLLER_API_PORT + "/instances");
InputStream inputStream = url.openConnection().getInputStream();
String instanceApiResponseString = IOUtils.toString(inputStream);
IOUtils.closeQuietly(inputStream);
JSONObject instanceApiResponse = new JSONObject(instanceApiResponseString);
JSONArray instanceArray = instanceApiResponse.getJSONArray("instances");
HelixAdmin helixAdmin = new ZKHelixAdmin(new ZkClient(ZkStarter.DEFAULT_ZK_STR, 10000, 10000, new ZNRecordSerializer()));
for (int i = 0; i < instanceArray.length(); i++) {
String instance = instanceArray.getString(i);
if (instance.startsWith("Server_")) {
_serverServiceStatusCallback = new ServiceStatus.IdealStateAndExternalViewMatchServiceStatusCallback(helixAdmin, getHelixClusterName(), instance);
}
if (instance.startsWith("Broker_")) {
_brokerServiceStatusCallback = new ServiceStatus.IdealStateAndExternalViewMatchServiceStatusCallback(helixAdmin, getHelixClusterName(), instance, Collections.singletonList("brokerResource"));
}
}
// Load data into H2
ExecutorService executor = Executors.newCachedThreadPool();
setupH2AndInsertAvro(avroFiles, executor);
// Create segments from Avro data
buildSegmentsFromAvro(avroFiles, executor, 0, _segmentDir, _tarDir, "mytable", false, null);
// Initialize query generator
setupQueryGenerator(avroFiles, executor);
executor.shutdown();
executor.awaitTermination(10, TimeUnit.MINUTES);
// Set up a Helix spectator to count the number of segments that are uploaded and unlock the latch once 12 segments are online
final CountDownLatch latch = setupSegmentCountCountDownLatch("mytable", SEGMENT_COUNT);
// Upload the segments
int i = 0;
for (String segmentName : _tarDir.list()) {
// System.out.println("Uploading segment " + (i++) + " : " + segmentName);
File file = new File(_tarDir, segmentName);
FileUploadUtils.sendSegmentFile("localhost", "8998", segmentName, file, file.length());
}
// Wait for all segments to be online
latch.await();
TOTAL_DOCS = 115545;
long timeInTwoMinutes = System.currentTimeMillis() + 2 * 60 * 1000L;
long numDocs;
while ((numDocs = getCurrentServingNumDocs("mytable")) < TOTAL_DOCS) {
// System.out.println("Current number of documents: " + numDocs);
if (System.currentTimeMillis() < timeInTwoMinutes) {
Thread.sleep(1000);
} else {
Assert.fail("Segments were not completely loaded within two minutes");
}
}
}
use of org.apache.helix.HelixAdmin in project pinot by linkedin.
the class SegmentStatusCheckerTest method basicTest.
@Test
public void basicTest() throws Exception {
final String tableName = "myTable_OFFLINE";
List<String> allTableNames = new ArrayList<String>();
allTableNames.add(tableName);
IdealState idealState = new IdealState(tableName);
idealState.setPartitionState("myTable_0", "pinot1", "ONLINE");
idealState.setPartitionState("myTable_0", "pinot2", "ONLINE");
idealState.setPartitionState("myTable_0", "pinot3", "ONLINE");
idealState.setPartitionState("myTable_1", "pinot1", "ONLINE");
idealState.setPartitionState("myTable_1", "pinot2", "ONLINE");
idealState.setPartitionState("myTable_1", "pinot3", "ONLINE");
idealState.setPartitionState("myTable_2", "pinot3", "OFFLINE");
idealState.setReplicas("2");
idealState.setRebalanceMode(IdealState.RebalanceMode.CUSTOMIZED);
ExternalView externalView = new ExternalView(tableName);
externalView.setState("myTable_0", "pinot1", "ONLINE");
externalView.setState("myTable_0", "pinot2", "ONLINE");
externalView.setState("myTable_1", "pinot1", "ERROR");
externalView.setState("myTable_1", "pinot2", "ONLINE");
HelixAdmin helixAdmin;
{
helixAdmin = mock(HelixAdmin.class);
when(helixAdmin.getResourceIdealState("StatusChecker", tableName)).thenReturn(idealState);
when(helixAdmin.getResourceExternalView("StatusChecker", tableName)).thenReturn(externalView);
}
{
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(externalView.getId(), ControllerGauge.SEGMENTS_IN_ERROR_STATE), 1);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(externalView.getId(), ControllerGauge.NUMBER_OF_REPLICAS), 1);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(externalView.getId(), ControllerGauge.PERCENT_OF_REPLICAS), 33);
Assert.assertEquals(controllerMetrics.getValueOfTableGauge(externalView.getId(), ControllerGauge.PERCENT_SEGMENTS_AVAILABLE), 100);
segmentStatusChecker.stop();
}
Aggregations