Aha, this totally explained. Thank you!
-Leo

On Sat, Oct 31, 2020 at 10:48 PM Xue Junkai <[email protected]> wrote:

> Yeah. That's the reason. In the test, it uses CustomRebalancer which
> extends AbstractRebalancer.
> And here's the definition of that:
> https://github.com/apache/helix/blob/a5cddd4b8fa51b1ea53b2f7082daf79361cd81de/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AbstractRebalancer.java
> .
>
> You can follow the implementation of this class and have a try.
>
> best,
>
> Junkai
>
> On Sat, Oct 31, 2020 at 9:53 PM Leo, Li <[email protected]> wrote:
>
>> did not implement MappingCalculator. here is code copied
>> from TestCustomizedIdealStateRebalancer.  The interface you mentioned seems
>> related with
>> https://github.com/apache/helix/blob/a5cddd4b8fa51b1ea53b2f7082daf79361cd81de/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestCustomRebalancer.java#L76
>> CustomRebalancer.
>>
>> Thanks.
>> Leo
>>
>> public class LeoDefinedRebalancer implements Rebalancer {
>>   private static final Logger LOGGER =
>>       LoggerFactory.getLogger(LeoDefinedRebalancer.class);
>>
>>   @Override
>>   public void init(HelixManager manager){
>>     LOGGER.info("LeoDefinedRebalancer.computeNewIdealState setup!");
>>   }
>>
>>
>>   @Override
>>   public IdealState computeNewIdealState(String resourceName, IdealState 
>> currentIdealState,
>>       CurrentStateOutput currentStateOutput, ClusterDataCache clusterData) {
>>     LOGGER.info("LeoDefinedRebalancer.computeNewIdealState invoked!");
>>
>>     List<String> liveNodes = 
>> Lists.newArrayList(clusterData.getLiveInstances().keySet());
>>     int i = 0;
>>     for (String partition : currentIdealState.getPartitionSet()) {
>>       int index = i++ % liveNodes.size();
>>       String instance = liveNodes.get(index);
>>       currentIdealState.getPreferenceList(partition).clear();
>>       currentIdealState.getPreferenceList(partition).add(instance);
>>
>>       currentIdealState.getInstanceStateMap(partition).clear();
>>       currentIdealState.getInstanceStateMap(partition).put(instance, 
>> "ONLINE");
>>       LOGGER.info("set ###############  {}: {} {} online", resourceName, 
>> instance, partition);
>>     }
>>     currentIdealState.setReplicas("1");
>>     return currentIdealState;
>>   }
>> }
>>
>>
>> On Sat, Oct 31, 2020 at 9:39 PM Xue Junkai <[email protected]> wrote:
>>
>>> What does your class look like? Does it implement the  public interface
>>> MappingCalculator?This is the interface we casted to get  the resource
>>> assignment.
>>>
>>> https://github.com/apache/helix/blob/a5cddd4b8fa51b1ea53b2f7082daf79361cd81de/helix-core/src/main/java/org/apache/helix/controller/rebalancer/internal/MappingCalculator.java
>>>
>>>
>>> best,
>>>
>>> Junkai
>>>
>>> On Sat, Oct 31, 2020 at 9:30 PM Leo, Li <[email protected]> wrote:
>>>
>>>> Hi Junkai,
>>>>
>>>> It's my fault to use a misleading class name.  I renamed the class name
>>>> as LeoDefinedRebalancer. It is triggered:
>>>>
>>>> 2778 20:15:18.606 [GenericHelixController-event_process] INFO
>>>> c.u.k.w.c.LeoDefinedRebalancer - LeoDefinedRebalancer.computeNewIdealState
>>>> invoked!
>>>>
>>>> 2779 20:15:18.606 [GenericHelixController-event_process] INFO
>>>> c.u.k.w.c.LeoDefinedRebalancer - set ###############  dca1e:
>>>> localhost_12001 dca1e_0 online
>>>>
>>>> 2780 20:15:18.606 [GenericHelixController-event_process] INFO
>>>> c.u.k.w.c.LeoDefinedRebalancer - set ###############  dca1e:
>>>> localhost_12002 dca1e_1 online
>>>>
>>>> 2781 20:15:18.606 [GenericHelixController-event_process] WARN
>>>> o.a.h.c.s.BestPossibleStateCalcStage - Event 02e76c7b_DEFAULT : Rebalancer
>>>> does not have a mapping calculator, defaulting to SEMI_AUT     O,
>>>> resource: dca1d
>>>>
>>>>
>>>> LeoDefinedRebalancer class is the test case code
>>>> <https://github.com/apache/helix/blob/a5cddd4b8fa51b1ea53b2f7082daf79361cd81de/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestCustomizedIdealStateRebalancer.java#L54>
>>>> and runs together with other classes, but the issues remain the same.
>>>>
>>>> HelixManager hMan = startStandAloneController();
>>>> LeoDefinedRebalancer rebalancer = new LeoDefinedRebalancer();
>>>> rebalancer.init(hMan);
>>>>
>>>> clusterSetup.addResourceToCluster(CLUSTER_NAME, resource, num, 
>>>> STATE_MODEL_NAME);
>>>> clusterSetup.addResourceProperty(CLUSTER_NAME, resource, 
>>>> IdealState.IdealStateProperty.REBALANCER_CLASS_NAME.toString(), 
>>>> LeoDefinedRebalancer.class.getName());
>>>> clusterSetup.addResourceProperty(CLUSTER_NAME, resource, 
>>>> IdealState.IdealStateProperty.REBALANCE_MODE.toString(), 
>>>> IdealState.RebalanceMode.USER_DEFINED.toString());
>>>> clusterSetup.rebalanceStorageCluster(CLUSTER_NAME, resource, 1, "");
>>>>
>>>>
>>>> On Sat, Oct 31, 2020 at 7:41 PM Xue Junkai <[email protected]> wrote:
>>>>
>>>>> Thanks for the details Leo.
>>>>>
>>>>> I think there is a misunderstanding between customized IdealState and
>>>>> user defined rebalancer. Actually, they are different levels of concept.
>>>>>
>>>>> For customized IdealState, it still uses Helix defined customized
>>>>> rebalancer, but it takes the map field as the final result. Helix only
>>>>> reacts to the map field change for partition/replica assignment.
>>>>>
>>>>> But user defined rebalancer is different. User has to implement the
>>>>> Rebalancer class and include that class in the same JVM when you start the
>>>>> controller. So Helix will try to use the class loader to load your class 
>>>>> to
>>>>> do the computation. So the error could be you dont have the class in the
>>>>> same jar of starting the controller. Either you implement Rebalancer class
>>>>> and include it in controller jar. Or you can switch to use default auto
>>>>> rebalancer but with customized mode for the IdealState.
>>>>>
>>>>> Jiajun provided a test class as a good example of implementing the
>>>>> user defined rebalance. You can take a look if you would like to go that
>>>>> route.
>>>>>
>>>>> best,
>>>>>
>>>>> Junkai
>>>>>
>>>>> On Sat, Oct 31, 2020 at 7:19 PM Leo, Li <[email protected]> wrote:
>>>>>
>>>>>> Hi  JunKai and Jiajun,
>>>>>> Thank you for your help. When I tried to use a customized Rebalancer,
>>>>>> I saw the rebalancer is triggered and the idea state is set by it.
>>>>>>
>>>>>> 3784 18:38:38.268 [GenericHelixController-event_process] INFO
>>>>>> c.u.k.w.c.CustomizedRebalancer - 
>>>>>> CustomizedRebalancer.computeNewIdealState
>>>>>> invoked!
>>>>>>
>>>>>> 3785 18:38:38.268 [GenericHelixController-event_process] INFO
>>>>>> c.u.k.w.c.CustomizedRebalancer - set ###############  dca1d:
>>>>>> localhost_12001 dca1d_0 online
>>>>>>
>>>>>> 3786 18:38:38.268 [GenericHelixController-event_process] INFO
>>>>>> c.u.k.w.c.CustomizedRebalancer - set ###############  dca1d:
>>>>>> localhost_12002 dca1d_1 online
>>>>>>
>>>>>> 3787 18:38:38.269 [GenericHelixController-event_process] WARN
>>>>>> o.a.h.c.s.BestPossibleStateCalcStage - Event b4896f24_DEFAULT : 
>>>>>> Rebalancer
>>>>>> does not have a mapping calculator, defaulting to SEMI_AUT     O,
>>>>>> resource: dca1d
>>>>>>
>>>>>>
>>>>>> However the Helix UI shows "no date to display". The snapshot is
>>>>>> attached. The EXTERNALVIEW and IDEASTATE are:
>>>>>>
>>>>>>
>>>>>> >>> get /Watchdog/EXTERNALVIEW/dca1d
>>>>>>
>>>>>> {
>>>>>>
>>>>>>   "id":"dca1d"
>>>>>>
>>>>>>   ,"simpleFields":{
>>>>>>
>>>>>>     "BUCKET_SIZE":"0"
>>>>>>
>>>>>>     ,"IDEAL_STATE_MODE":"AUTO"
>>>>>>
>>>>>>     ,"NUM_PARTITIONS":"2"
>>>>>>
>>>>>>
>>>>>> ,"REBALANCER_CLASS_NAME":"mypackage.controller.CustomizedRebalancer"
>>>>>>
>>>>>>     ,"REBALANCE_MODE":"USER_DEFINED"
>>>>>>
>>>>>>     ,"REBALANCE_STRATEGY":"DEFAULT"
>>>>>>
>>>>>>     ,"REPLICAS":"1"
>>>>>>
>>>>>>     ,"STATE_MODEL_DEF_REF":"MyStateModel"
>>>>>>
>>>>>>     ,"STATE_MODEL_FACTORY_NAME":"DEFAULT"
>>>>>>
>>>>>>   }
>>>>>>
>>>>>>   ,"listFields":{
>>>>>>
>>>>>>   }
>>>>>>
>>>>>>   ,"mapFields":{
>>>>>>
>>>>>>     "dca1d_0":{
>>>>>>
>>>>>>       "localhost_12010":"ONLINE"
>>>>>>
>>>>>>     }
>>>>>>
>>>>>>     ,"dca1d_1":{
>>>>>>
>>>>>>       "localhost_12000":"ONLINE"
>>>>>>
>>>>>>     }
>>>>>>
>>>>>>   }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> >>> get /Watchdog/IDEALSTATES/dca1d
>>>>>>
>>>>>> {
>>>>>>
>>>>>>   "id" : "dca1d",
>>>>>>
>>>>>>   "simpleFields" : {
>>>>>>
>>>>>>     "IDEAL_STATE_MODE" : "AUTO",
>>>>>>
>>>>>>     "NUM_PARTITIONS" : "2",
>>>>>>
>>>>>>     "REBALANCER_CLASS_NAME" :
>>>>>> "mypackage.controller.CustomizedRebalancer",
>>>>>>
>>>>>>     "REBALANCE_MODE" : "USER_DEFINED",
>>>>>>
>>>>>>     "REBALANCE_STRATEGY" : "DEFAULT",
>>>>>>
>>>>>>     "REPLICAS" : "1",
>>>>>>
>>>>>>     "STATE_MODEL_DEF_REF" : "MyStateModel",
>>>>>>
>>>>>>     "STATE_MODEL_FACTORY_NAME" : "DEFAULT"
>>>>>>
>>>>>>   },
>>>>>>
>>>>>>   "mapFields" : {
>>>>>>
>>>>>>     "dca1d_0" : {
>>>>>>
>>>>>>     },
>>>>>>
>>>>>>     "dca1d_1" : {
>>>>>>
>>>>>>     }
>>>>>>
>>>>>>   },
>>>>>>
>>>>>>   "listFields" : {
>>>>>>
>>>>>>     "dca1d_0" : [ ],
>>>>>>
>>>>>>     "dca1d_1" : [ ]
>>>>>>
>>>>>>   }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> Comparing with before, when i use CUSTOMIZED rebalancer and model, The
>>>>>> EXTERNALVIEW and IDEASTATE were working well with Helix UI:
>>>>>>
>>>>>>
>>>>>> >>> get /Watchdog/IDEALSTATES/dca1d
>>>>>>
>>>>>> {
>>>>>>
>>>>>>   "id":"dca1d"
>>>>>>
>>>>>>   ,"simpleFields":{
>>>>>>
>>>>>>     "IDEAL_STATE_MODE":"CUSTOMIZED"
>>>>>>
>>>>>>     ,"MAX_PARTITIONS_PER_INSTANCE":"1"
>>>>>>
>>>>>>     ,"NUM_PARTITIONS":"2"
>>>>>>
>>>>>>     ,"REBALANCE_MODE":"CUSTOMIZED"
>>>>>>
>>>>>>     ,"REPLICAS":"1"
>>>>>>
>>>>>>     ,"STATE_MODEL_DEF_REF":"MyStateModel"
>>>>>>
>>>>>>     ,"STATE_MODEL_FACTORY_NAME":"DEFAULT"
>>>>>>
>>>>>>   }
>>>>>>
>>>>>>   ,"listFields":{
>>>>>>
>>>>>>   }
>>>>>>
>>>>>>   ,"mapFields":{
>>>>>>
>>>>>>     "0":{
>>>>>>
>>>>>>       "localhost_12004":"ONLINE"
>>>>>>
>>>>>>     }
>>>>>>
>>>>>>     ,"1":{
>>>>>>
>>>>>>       "localhost_12005":"ONLINE"
>>>>>>
>>>>>>     }
>>>>>>
>>>>>>   }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> >>> get /Watchdog/EXTERNALVIEW/dca1d
>>>>>>
>>>>>> {
>>>>>>
>>>>>>   "id":"dca1d"
>>>>>>
>>>>>>   ,"simpleFields":{
>>>>>>
>>>>>>     "BUCKET_SIZE":"0"
>>>>>>
>>>>>>     ,"IDEAL_STATE_MODE":"CUSTOMIZED"
>>>>>>
>>>>>>     ,"MAX_PARTITIONS_PER_INSTANCE":"1"
>>>>>>
>>>>>>     ,"NUM_PARTITIONS":"2"
>>>>>>
>>>>>>     ,"REBALANCE_MODE":"CUSTOMIZED"
>>>>>>
>>>>>>     ,"REPLICAS":"1"
>>>>>>
>>>>>>     ,"STATE_MODEL_DEF_REF":"MyStateModel"
>>>>>>
>>>>>>     ,"STATE_MODEL_FACTORY_NAME":"DEFAULT"
>>>>>>
>>>>>>   }
>>>>>>
>>>>>>   ,"listFields":{
>>>>>>
>>>>>>   }
>>>>>>
>>>>>>   ,"mapFields":{
>>>>>>
>>>>>>     "0":{
>>>>>>
>>>>>>       "localhost_12004":"ONLINE"
>>>>>>
>>>>>>     }
>>>>>>
>>>>>>     ,"1":{
>>>>>>
>>>>>>       "localhost_12005":"ONLINE"
>>>>>>
>>>>>>     }
>>>>>>
>>>>>>   }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> I see that the mapFields key changed after using "USER_DEFINED"
>>>>>> rebalancer.
>>>>>>
>>>>>> Here are the code i used:
>>>>>>
>>>>>> public static void addResource(String resource, int num) {
>>>>>>   clusterSetup.addResourceToCluster(CLUSTER_NAME, resource, num, 
>>>>>> STATE_MODEL_NAME);
>>>>>>   clusterSetup.addResourceProperty(CLUSTER_NAME, resource, 
>>>>>> IdealState.IdealStateProperty.REBALANCER_CLASS_NAME.toString(), 
>>>>>> CustomizedRebalancer.class.getName());
>>>>>>   clusterSetup.addResourceProperty(CLUSTER_NAME, resource, 
>>>>>> IdealState.IdealStateProperty.REBALANCE_MODE.toString(), 
>>>>>> IdealState.RebalanceMode.USER_DEFINED.toString());
>>>>>>   clusterSetup.rebalanceStorageCluster(CLUSTER_NAME, resource, 1, "");
>>>>>>
>>>>>>
>>>>>> What is the right way to set a rebalancer?
>>>>>>
>>>>>>
>>>>>> The rebalancer method has a single resource interface. What is the
>>>>>> right way to rebalance all resources in the cluster for any event change 
>>>>>> in
>>>>>> the cluster? My concern is the sequence and thread safety.
>>>>>>
>>>>>> @Override
>>>>>> public IdealState computeNewIdealState(String resourceName, IdealState 
>>>>>> currentIdealState,
>>>>>>     CurrentStateOutput currentStateOutput, ClusterDataCache clusterData) 
>>>>>> {
>>>>>>
>>>>>>
>>>>>>
>>>>>> Regards,
>>>>>>
>>>>>> Leo
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Fri, Oct 30, 2020 at 10:21 PM Wang Jiajun <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi Leo,
>>>>>>>
>>>>>>> Are you looking for guidance on how to configure the IdealState so
>>>>>>> the resource will be rebalanced by your user_defined rebalancer? Maybe 
>>>>>>> you
>>>>>>> can refer to this test case TestCustomizedIdealStateRebalancer.
>>>>>>>
>>>>>>> Best Regards,
>>>>>>> Jiajun
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Oct 30, 2020 at 10:11 PM Xue Junkai <[email protected]> wrote:
>>>>>>>
>>>>>>>> Hi Leo,
>>>>>>>>
>>>>>>>>  What kind of examples are you looking for? Participant side? Or
>>>>>>>> how to build IdealState?
>>>>>>>>
>>>>>>>> Best,
>>>>>>>>
>>>>>>>> Junkai
>>>>>>>>
>>>>>>>> On Fri, Oct 30, 2020 at 9:57 PM Leo, Li <[email protected]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>> I am a new user of Helix. I wonder if you could give an example
>>>>>>>>> code of using this user_defined model
>>>>>>>>> https://helix.apache.org/1.0.1-docs/tutorial_user_def_rebalancer.html
>>>>>>>>> ?
>>>>>>>>>
>>>>>>>>> Thank you,
>>>>>>>>> Leo
>>>>>>>>>
>>>>>>>>

Reply via email to