Added: helix/site-content/1.4.0-docs/tutorial_controller.html URL: http://svn.apache.org/viewvc/helix/site-content/1.4.0-docs/tutorial_controller.html?rev=1918422&view=auto ============================================================================== --- helix/site-content/1.4.0-docs/tutorial_controller.html (added) +++ helix/site-content/1.4.0-docs/tutorial_controller.html Wed Jun 19 01:36:37 2024 @@ -0,0 +1,383 @@ + +<!DOCTYPE html> + + + + + + +<!-- + Generated by Apache Maven Doxia at 2024-06-18 Rendered using Reflow Maven Skin 2.0.0 (https://olamy.github.io/reflow-maven-skin) +--> +<html xml:lang="en" lang="en"> + + <head> + <meta charset="UTF-8" /> + <title>Apache Helix – Tutorial - Controller</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta name="description" content="" /> + <meta http-equiv="content-language" content="en" /> + + <link href="./css/bootstrap.min.css" rel="stylesheet" /> + <link href="./css/bootstrap-responsive.min.css" rel="stylesheet" /> + <link href="./css/docs.css" rel="stylesheet" /> + <link href="./css/reflow-skin.css" rel="stylesheet" /> + + + <link href="./css/lightbox.css" rel="stylesheet" /> + + <link href="./css/site.css" rel="stylesheet" /> + <link href="./css/print.css" rel="stylesheet" media="print" /> + + <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements --> + <!--[if lt IE 9]> + <script src="./js/html5.js"></script> + <![endif]--> + + + + + + +<!-- Matomo --> +<script> + var _paq = window._paq = window._paq || []; + _paq.push(['disableCookies']); + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + + (function() { + var u="https://analytics.apache.org"; + _paq.push(['setTrackerUrl', u+'/matomo.php']); + _paq.push(['setSiteId', '15']); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.async=true; g.src=u+'/matomo.js'; s.parentNode.insertBefore(g,s); + })(); +</script> +<!-- End Matomo Code --> + </head> + + <body class="page-tutorial_controller project-140-docs" data-spy="scroll" data-offset="60" data-target="#toc-scroll-target"> + + + <div class="navbar navbar-fixed-top"> + <div class="navbar-inner"> + <div class="container"> + <a class="btn btn-navbar" data-toggle="collapse" data-target="#top-nav-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </a> + <a class="brand" href="http://helix.apache.org">Apache Helix</a> + <div class="nav-collapse collapse" id="top-nav-collapse"> + <ul class="nav pull-right"> + <li ><a href="index.html" title="Helix 1.4.0">Helix 1.4.0</a></li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Helix <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="download.html" title="Download">Download</a></li> + <li ><a href="Building.html" title="Building">Building</a></li> + <li ><a href="releasenotes/release-1.4.0.html" title="Release Notes">Release Notes</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Hands-On <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="Quickstart.html" title="Quick Start">Quick Start</a></li> + <li ><a href="Tutorial.html" title="Tutorial">Tutorial</a></li> + <li ><a href="../javadocs/1.4.0" title="Javadocs">Javadocs</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Recipes <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="recipes/lock_manager.html" title="Distributed lock manager">Distributed lock manager</a></li> + <li ><a href="recipes/rabbitmq_consumer_group.html" title="Rabbit MQ consumer group">Rabbit MQ consumer group</a></li> + <li ><a href="recipes/rsync_replicated_file_store.html" title="Rsync replicated file store">Rsync replicated file store</a></li> + <li ><a href="recipes/service_discovery.html" title="Service discovery">Service discovery</a></li> + <li ><a href="recipes/task_dag_execution.html" title="Distributed task DAG execution">Distributed task DAG execution</a></li> + </ul> + </li> + </ul> + </div><!--/.nav-collapse --> + </div> + </div> + </div> + + <div class="container"> + + <!-- Masthead + ================================================== --> + + <header> + <div class="jumbotron subhead"> + <div class="row" id="banner"> + <div class="span12"> + <div class="pull-left"> + <a href="http://helix.apache.org/" id="bannerLeft"><img src="../images/helix-logo.jpg" alt='"''"' /></a> + <p class="lead">A cluster management framework for partitioned and replicated distributed resources</p> + </div> + <div class="pull-right"> + <a href="http://www.apache.org/" id="bannerRight"><img src="../images/feather_small.gif" alt='"''"' /></a> + </div> + </div> + </div> + </div> + <div> + <ul class="breadcrumb"> + <li><a href="../" title="Apache Helix">Apache Helix</a></li> + <li class="divider">/</li> + <li><a href="./" title="Release 1.4.0">Release 1.4.0</a></li> + <li class="divider">/</li> + <li>Tutorial - Controller</li> + <li class="publishDate version-date pull-right">Last Published: 2024-06-18</li> + </ul> + </div> + </header> + + <div class="main-body"> + <div class="row"> + <div class="span12"> + <div class="body-content"> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<section> + <div class="page-header"> + <h2 id="Helix_Tutorial:_Controller"><a href="./Tutorial.html">Helix Tutorial</a>: Controller</h2> + </div> + <p>Next, let's implement the controller. This is the brain of the cluster. Helix makes sure there is exactly one active controller running the cluster.</p> + <section> + <h3 id="Start_a_Connection">Start a Connection</h3> + <p>The Helix manager requires the following parameters:</p> + <ul> + <li>clusterName: A logical name to represent the group of nodes</li> + <li>instanceName: A logical name of the process creating the manager instance. Generally this is host:port</li> + <li>instanceType: Type of the process. This can be one of the following types, in this case use CONTROLLER: + <ul> + <li>CONTROLLER: Process that controls the cluster, any number of controllers can be started but only one will be active at any given time</li> + <li>PARTICIPANT: Process that performs the actual task in the distributed system</li> + <li>SPECTATOR: Process that observes the changes in the cluster</li> + <li>ADMIN: To carry out system admin actions</li> + </ul> </li> + <li>zkConnectString: Connection string to ZooKeeper. This is of the form host1:port1,host2:port2,host3:port3</li> + </ul> + <div class="source"> + <pre><code>manager = HelixManagerFactory.getZKHelixManager(clusterName, + instanceName, + instanceType, + zkConnectString); +</code></pre> + </div> + </section> + <section> + <h3 id="Controller_Code">Controller Code</h3> + <p>The Controller needs to know about all changes in the cluster. Helix takes care of this with the default implementation. If you need additional functionality, see GenericHelixController on how to configure the pipeline.</p> + <div class="source"> + <pre><code>manager = HelixManagerFactory.getZKHelixManager(clusterName, + instanceName, + InstanceType.CONTROLLER, + zkConnectString); +manager.connect(); +</code></pre> + </div> + <p>The snippet above shows how the controller is started. You can also start the controller using command line interface.</p> + <div class="source"> + <pre><code>cd helix/helix-core/target/helix-core-pkg/bin +./run-helix-controller.sh --zkSvr <Zookeeper ServerAddress (Required)> --cluster <Cluster name (Required)> +</code></pre> + </div> + </section> + <section> + <h3 id="Controller_Deployment_Modes">Controller Deployment Modes</h3> + <p>Helix provides multiple options to deploy the controller.</p> + <section> + <h4 id="STANDALONE">STANDALONE</h4> + <p>The Controller can be started as a separate process to manage a cluster. This is the recommended approach. However, since one controller can be a single point of failure, multiple controller processes are required for reliability. Even if multiple controllers are running, only one will be actively managing the cluster at any time and is decided by a leader-election process. If the leader fails, another leader will take over managing the cluster.</p> + <p>Even though we recommend this method of deployment, it has the drawback of having to manage an additional service for each cluster. See the Controller as a Service option.</p> + </section> + <section> + <h4 id="EMBEDDED">EMBEDDED</h4> + <p>If setting up a separate controller process is not viable, then it is possible to embed the controller as a library in each of the participants.</p> + </section> + <section> + <h4 id="CONTROLLER_AS_A_SERVICE">CONTROLLER AS A SERVICE</h4> + <p>One of the cool features we added in Helix was to use a set of controllers to manage a large number of clusters.</p> + <p>For example if you have X clusters to be managed, instead of deploying X*3 (3 controllers for fault tolerance) controllers for each cluster, one can deploy just 3 controllers. Each controller can manage X/3 clusters. If any controller fails, the remaining two will manage X/2 clusters.</p> + <p>Next, let's implement the controller. This is the brain of the cluster. Helix makes sure there is exactly one active controller running the cluster.</p> + </section> + </section> + <section> + <h3 id="Start_the_Helix_agent">Start the Helix agent</h3> + <p>It requires the following parameters:</p> + <ul> + <li>clusterName: A logical name to represent the group of nodes</li> + <li>instanceName: A logical name of the process creating the manager instance. Generally this is host:port.</li> + <li>instanceType: Type of the process. This can be one of the following types, in this case use CONTROLLER: + <ul> + <li>CONTROLLER: Process that controls the cluster, any number of controllers can be started but only one will be active at any given time.</li> + <li>PARTICIPANT: Process that performs the actual task in the distributed system.</li> + <li>SPECTATOR: Process that observes the changes in the cluster.</li> + <li>ADMIN: To carry out system admin actions.</li> + </ul> </li> + <li>zkConnectString: Connection string to Zookeeper. This is of the form host1:port1,host2:port2,host3:port3.</li> + </ul> + <div class="source"> + <pre><code> manager = HelixManagerFactory.getZKHelixManager(clusterName, + instanceName, + instanceType, + zkConnectString); +</code></pre> + </div> + </section> + <section> + <h3 id="Controller_Code">Controller Code</h3> + <p>The Controller needs to know about all changes in the cluster. Helix takes care of this with the default implementation. If you need additional functionality, see GenericHelixController on how to configure the pipeline.</p> + <div class="source"> + <pre><code> manager = HelixManagerFactory.getZKHelixManager(clusterName, + instanceName, + InstanceType.CONTROLLER, + zkConnectString); + manager.connect(); + GenericHelixController controller = new GenericHelixController(); + manager.addControllerListener(controller); + manager.addInstanceConfigChangeListener(controller); + manager.addResourceConfigChangeListener(controller); + manager.addClusterfigChangeListener(controller); + manager.addCustomizedStateConfigChangeListener(controller); + manager.addLiveInstanceChangeListener(controller); + manager.addIdealStateChangeListener(controller); +</code></pre> + </div> + <p>The snippet above shows how the controller is started. You can also start the controller using command line interface.</p> + <div class="source"> + <pre><code>cd helix/helix-core/target/helix-core-pkg/bin +./run-helix-controller.sh --zkSvr <Zookeeper ServerAddress (Required)> --cluster <Cluster name (Required)> +</code></pre> + </div> + </section> + <section> + <h3 id="Controller_Deployment_Modes">Controller Deployment Modes</h3> + <p>Helix provides multiple options to deploy the controller.</p> + <section> + <h4 id="STANDALONE">STANDALONE</h4> + <p>The Controller can be started as a separate process to manage a cluster. This is the recommended approach. However, since one controller can be a single point of failure, multiple controller processes are required for reliability. Even if multiple controllers are running, only one will be actively managing the cluster at any time and is decided by a leader-election process. If the leader fails, another leader will take over managing the cluster.</p> + <p>Even though we recommend this method of deployment, it has the drawback of having to manage an additional service for each cluster. See Controller As a Service option.</p> + </section> + <section> + <h4 id="EMBEDDED">EMBEDDED</h4> + <p>If setting up a separate controller process is not viable, then it is possible to embed the controller as a library in each of the participants.</p> + </section> + <section> + <h4 id="CONTROLLER_AS_A_SERVICE">CONTROLLER AS A SERVICE</h4> + <p>One of the cool features we added in Helix is to use a set of controllers to manage a large number of clusters.</p> + <p>For example if you have X clusters to be managed, instead of deploying X*3 (3 controllers for fault tolerance) controllers for each cluster, one can deploy just 3 controllers. Each controller can manage X/3 clusters. If any controller fails, the remaining two will manage X/2 clusters.</p> + </section> + </section> +</section> + </div> + </div> + </div> + </div> + + </div><!-- /container --> + + <!-- Footer + ================================================== --> + <footer class="well"> + <div class="container"> + <div class="row"> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Get Helix</li> + <li > + <a href="download.html" title="Download">Download</a> + </li> + <li > + <a href="Building.html" title="Building">Building</a> + </li> + <li > + <a href="releasenotes/release-1.4.0.html" title="Release Notes">Release Notes</a> + </li> + </ul> + </div> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Hands-On</li> + <li > + <a href="Quickstart.html" title="Quick Start">Quick Start</a> + </li> + <li > + <a href="Tutorial.html" title="Tutorial">Tutorial</a> + </li> + <li > + <a href="../javadocs/1.4.0" title="Javadocs">Javadocs</a> + </li> + </ul> + </div> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Recipes</li> + <li > + <a href="recipes/lock_manager.html" title="Distributed lock manager">Distributed lock manager</a> + </li> + <li > + <a href="recipes/rabbitmq_consumer_group.html" title="Rabbit MQ consumer group">Rabbit MQ consumer group</a> + </li> + <li > + <a href="recipes/rsync_replicated_file_store.html" title="Rsync replicated file store">Rsync replicated file store</a> + </li> + <li > + <a href="recipes/service_discovery.html" title="Service discovery">Service discovery</a> + </li> + <li > + <a href="recipes/task_dag_execution.html" title="Distributed task DAG execution">Distributed task DAG execution</a> + </li> + </ul> + </div> + </div> + </div> + </footer> + + <div class="container subfooter"> + <div class="row"> + <div class="span12"> + <p class="pull-right"><a href="#">Back to top</a></p> + <p class="copyright">Copyright ©2024 <a href="http://www.apache.org">Apache Software Foundation</a>. All Rights Reserved.</p> + <p><a href="https://github.com/olamy/reflow-maven-skin" title="Reflow Maven skin">Reflow Maven skin</a> maintained by <a href="https://twitter.com/olamy" target="_blank" title="Olivier Lamy">Olivier Lamy</a>.</p> + <div class="row span16"><div>Apache Helix, Apache, the Apache feather logo, and the Apache Helix project logos are trademarks of The Apache Software Foundation. + All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div> + <a href="https://helix.apache.org/1.4.0-docs/privacy-policy.html">Privacy Policy</a> + </div> + </div> + </div> + </div> + + <!-- Le javascript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="./js/jquery.min.js"></script> + + <script src="./js/bootstrap.min.js"></script> + <script src="./js/lightbox.min.js"></script> + <script src="./js/reflow-scroll.js"></script> + + <script src="./js/reflow-skin.js"></script> + + </body> +</html> \ No newline at end of file
Added: helix/site-content/1.4.0-docs/tutorial_customized_view.html URL: http://svn.apache.org/viewvc/helix/site-content/1.4.0-docs/tutorial_customized_view.html?rev=1918422&view=auto ============================================================================== --- helix/site-content/1.4.0-docs/tutorial_customized_view.html (added) +++ helix/site-content/1.4.0-docs/tutorial_customized_view.html Wed Jun 19 01:36:37 2024 @@ -0,0 +1,436 @@ + +<!DOCTYPE html> + + + + + + +<!-- + Generated by Apache Maven Doxia at 2024-06-18 Rendered using Reflow Maven Skin 2.0.0 (https://olamy.github.io/reflow-maven-skin) +--> +<html xml:lang="en" lang="en"> + + <head> + <meta charset="UTF-8" /> + <title>Apache Helix – Tutorial - Customized View</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta name="description" content="" /> + <meta http-equiv="content-language" content="en" /> + + <link href="./css/bootstrap.min.css" rel="stylesheet" /> + <link href="./css/bootstrap-responsive.min.css" rel="stylesheet" /> + <link href="./css/docs.css" rel="stylesheet" /> + <link href="./css/reflow-skin.css" rel="stylesheet" /> + + + <link href="./css/lightbox.css" rel="stylesheet" /> + + <link href="./css/site.css" rel="stylesheet" /> + <link href="./css/print.css" rel="stylesheet" media="print" /> + + <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements --> + <!--[if lt IE 9]> + <script src="./js/html5.js"></script> + <![endif]--> + + + + + + +<!-- Matomo --> +<script> + var _paq = window._paq = window._paq || []; + _paq.push(['disableCookies']); + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + + (function() { + var u="https://analytics.apache.org"; + _paq.push(['setTrackerUrl', u+'/matomo.php']); + _paq.push(['setSiteId', '15']); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.async=true; g.src=u+'/matomo.js'; s.parentNode.insertBefore(g,s); + })(); +</script> +<!-- End Matomo Code --> + </head> + + <body class="page-tutorial_customized_view project-140-docs" data-spy="scroll" data-offset="60" data-target="#toc-scroll-target"> + + + <div class="navbar navbar-fixed-top"> + <div class="navbar-inner"> + <div class="container"> + <a class="btn btn-navbar" data-toggle="collapse" data-target="#top-nav-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </a> + <a class="brand" href="http://helix.apache.org">Apache Helix</a> + <div class="nav-collapse collapse" id="top-nav-collapse"> + <ul class="nav pull-right"> + <li ><a href="index.html" title="Helix 1.4.0">Helix 1.4.0</a></li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Helix <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="download.html" title="Download">Download</a></li> + <li ><a href="Building.html" title="Building">Building</a></li> + <li ><a href="releasenotes/release-1.4.0.html" title="Release Notes">Release Notes</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Hands-On <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="Quickstart.html" title="Quick Start">Quick Start</a></li> + <li ><a href="Tutorial.html" title="Tutorial">Tutorial</a></li> + <li ><a href="../javadocs/1.4.0" title="Javadocs">Javadocs</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Recipes <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="recipes/lock_manager.html" title="Distributed lock manager">Distributed lock manager</a></li> + <li ><a href="recipes/rabbitmq_consumer_group.html" title="Rabbit MQ consumer group">Rabbit MQ consumer group</a></li> + <li ><a href="recipes/rsync_replicated_file_store.html" title="Rsync replicated file store">Rsync replicated file store</a></li> + <li ><a href="recipes/service_discovery.html" title="Service discovery">Service discovery</a></li> + <li ><a href="recipes/task_dag_execution.html" title="Distributed task DAG execution">Distributed task DAG execution</a></li> + </ul> + </li> + </ul> + </div><!--/.nav-collapse --> + </div> + </div> + </div> + + <div class="container"> + + <!-- Masthead + ================================================== --> + + <header> + <div class="jumbotron subhead"> + <div class="row" id="banner"> + <div class="span12"> + <div class="pull-left"> + <a href="http://helix.apache.org/" id="bannerLeft"><img src="../images/helix-logo.jpg" alt='"''"' /></a> + <p class="lead">A cluster management framework for partitioned and replicated distributed resources</p> + </div> + <div class="pull-right"> + <a href="http://www.apache.org/" id="bannerRight"><img src="../images/feather_small.gif" alt='"''"' /></a> + </div> + </div> + </div> + </div> + <div> + <ul class="breadcrumb"> + <li><a href="../" title="Apache Helix">Apache Helix</a></li> + <li class="divider">/</li> + <li><a href="./" title="Release 1.4.0">Release 1.4.0</a></li> + <li class="divider">/</li> + <li>Tutorial - Customized View</li> + <li class="publishDate version-date pull-right">Last Published: 2024-06-18</li> + </ul> + </div> + </header> + + <div class="main-body"> + <div class="row"> + <div class="span12"> + <div class="body-content"> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<section> + <div class="page-header"> + <h2 id="Helix_Tutorial:_Customized_View"><a href="./Tutorial.html">Helix Tutorial</a>: Customized View</h2> + </div> + <p>Helix supports users to define their own per partition states that are different from the states appeared in the state model. These states are called customized states. Helix also provides aggregation function for these per partition states across all participants to facilitate the use of them. The aggregated customized state result is called customized view. Usually users would only need to listen on the customized view change to capture customized state updates.</p> + <p>The relationship between customized states and customized view is very similar to that between current states and external view. Helix controller uses similar logic to aggregate external view and customized view. But the two views are designed for different purposes. External view is mainly used to represent Helix state transition status, while customized view is to record users' own state status. This tutorial provides information for users to get started with using customized view, which needs more user input than external view.</p> + <p>The following figure shows the high level architecture of customized view aggregation. <img src="./images/CustomizedViewSystemArchitecture.jpeg" alt="CustomizedViewSystemArchitecture"></p> + <section> + <h3 id="Terminologies">Terminologies</h3> + <ul> + <li>Customized state: A per partition state defined by users in a string format. Customized state exists under each participant. It may include different types of states. Each type of state is represented as a Znode itself and has different resources as its child Znode.</li> + <li>Customized state config: A cluster level config specifically used for customized state related config. For example, it can include a list of customized states that should be aggregated.</li> + <li>Customized view: An aggregation result for customized states across all participants. It exists under the cluster and can also have a few different types of states depending on users' input. Each type of state is represented as a Znode itself and has different resources as its child Znode.</li> + </ul> + </section> + <section> + <h3 id="How_to_Use_Customized_View">How to Use Customized View</h3> + <section> + <h4 id="Define_Your_Own_Customized_State">Define Your Own Customized State</h4> + <p>Users are responsible for updating customized states in their application code. Helix provides a singleton factory called <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/customizedstate/CustomizedStateProviderFactory.java">Customized State Provider Factory</a>, and users should instantiate it if they want to use customized state.</p> + <p>After instantiation, users should call the function in the factory with user defined parameters to build a <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/customizedstate/CustomizedStateProvider.java">Customized State Provider</a> object.</p> + <p>There are two ways to build <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/customizedstate/CustomizedStateProvider.java">Customized State Provider</a>, and the difference is what kind of <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/HelixManager.java">HelixManager</a> is passed in. As the following code shows, the first one relies on a Helix provided manager, while the second one needs a user-created Helix manager.</p> + <div class="source"> + <pre><code> public CustomizedStateProvider buildCustomizedStateProvider(String instanceName, + String clusterName, String zkAddress) { + HelixManager helixManager = HelixManagerFactory + .getZKHelixManager(clusterName, instanceName, InstanceType.ADMINISTRATOR, zkAddress); + return new CustomizedStateProvider(helixManager, instanceName); + } + + public CustomizedStateProvider buildCustomizedStateProvider(HelixManager helixManager, + String instanceName) { + return new CustomizedStateProvider(helixManager, instanceName); + } +</code></pre> + </div> + <p>Helix provides a a couple of functions in <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/customizedstate/CustomizedStateProvider.java">Customized State Provider</a> that handle operations such as update, get, delete, etc. The underlying logic is already written in an efficient and thread safe way. Users only need to call these functions to update customized states to Zookeeper whenever they want.</p> + <div class="source"> + <pre><code> public void updateCustomizedState(String customizedStateName, String resourceName, + String partitionName, String customizedState); + + public void updateCustomizedState(String customizedStateName, String resourceName, + String partitionName, Map<String, String> customizedStateMap); + + public CustomizedState getCustomizedState(String customizedStateName, String resourceName); + + public Map<String, String> getPerPartitionCustomizedState(String customizedStateName, + String resourceName, String partitionName); + + public void deletePerPartitionCustomizedState(String customizedStateName, String resourceName, + String partitionName); +</code></pre> + </div> + <p>Here are some additional guidelines about how to use <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/customizedstate/CustomizedStateProvider.java">Customized State Provider</a>:</p> + <ul> + <li> <p>When a user would like to drop a certain instance by calling Helix delete instance API, Helix will delete the instance as well as all sub-paths under it with recursive deletion. Therefore, the customized state will also be deleted, and customized view will be updated when the instance is gone.</p> </li> + <li> <p>When a user would like to drop a certain resource by calling Helix delete resource API, he/she will be responsible for deleting customized state of all partitions for that resource across all instances. This operation can be implemented in users' state transition logic.</p> </li> + <li> <p>When Helix rebalance happens, and a certain partition on a certain instance is moved to another instance, customers will need to handle the cleanup in the callback function currently provided by Helix in the state transition logic.</p> </li> + <li> <p>When an unexpected disconnection happens in client side from Zookeeper, but does not trigger rebalance, Helix will still keep the customized state as it is and wait for the connection to be reset.</p> </li> + </ul> + </section> + <section> + <h4 id="Enable_Customized_State_Aggregation_in_Config">Enable Customized State Aggregation in Config</h4> + <p>To use Helix customized state and aggregated view, users should firstly call a Helix REST API or a Helix java API to set a cluster level config, called <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/model/CustomizedStateConfig.java">Customized State Config</a>. If users do not config this field properly, they can still use Helix to record their customized states, but Helix will by default skip the aggregation process, as the aggregation will take a fair amount of computing and storage resources. Only when users correctly notify Helix that they want the aggregation by adding the state type in the aggregation config list field, Helix will do the aggregation and output the results to Zookeeper.</p> + <p>There are two ways to update customized state config. One is through JAVA API inside <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java">ZK Helix Admin</a>, and the other is through REST API in <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ClusterAccessor.java">Cluster Accessor</a>.</p> + <p>The JAVA API provides four different functions as follows.</p> + <div class="source"> + <pre><code> public void addCustomizedStateConfig(String clusterName, CustomizedStateConfig customizedStateConfig); + + public void removeCustomizedStateConfig(String clusterName); + + public void addTypeToCustomizedStateConfig(String clusterName, String type); + + public void removeTypeFromCustomizedStateConfig(String clusterName, String type); +</code></pre> + </div> + <p>Every JAVA API has a corresponding REST API. For example, the function <code>addCustomizedStateConfig</code> can be performed by the following REST call.</p> + <div class="source"> + <pre><code> $curl -X PUT -H "Content-Type: application/json" http://localhost:1234/admin/v2/clusters/myCluster/customized-state-config -d ' + { + "id" : "CustomizedStateConfig", + "listFields" : { + "AGGREGATION_ENABLED_TYPES" : ["CUSTOMIZED_STATE_TYPE_0", "CUSTOMIZED_STATE_TYPE_1""] + }, + "simpleFields" : { + }, + "mapFields" : { + } + }' +</code></pre> + </div> + </section> + <section> + <h4 id="Update_Consuming_Logic_to_Listen_on_Customized_View_Change">Update Consuming Logic to Listen on Customized View Change</h4> + <p>The aggregated results is updated in <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java">RoutingTableProvider</a>. Users need to properly construct the routing table provider in their consuming logic to use the snapshot that contains customized view. <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java">RoutingTableProvider</a> has three different constructors for backward compatibility.</p> + <div class="source"> + <pre><code> public RoutingTableProvider(HelixManager helixManager) throws HelixException { + this(helixManager, ImmutableMap.of(PropertyType.EXTERNALVIEW, Collections.emptyList()), true, + DEFAULT_PERIODIC_REFRESH_INTERVAL); + } + + public RoutingTableProvider(HelixManager helixManager, PropertyType sourceDataType) + throws HelixException { + this(helixManager, ImmutableMap.of(sourceDataType, Collections.emptyList()), true, + DEFAULT_PERIODIC_REFRESH_INTERVAL); + } + + public RoutingTableProvider(HelixManager helixManager, Map<PropertyType, List<String>> sourceDataTypeMap) { + this(helixManager, sourceDataTypeMap, true, DEFAULT_PERIODIC_REFRESH_INTERVAL); + } +</code></pre> + </div> + <p>If users would like to use customized states and customized view, they need to initialize <a class="externalLink" href="https://github.com/apache/helix/blob/master/helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java">RoutingTableProvider</a> with the last constructor. They also need to define the <code>sourceDataMap</code>. For example, if users would like to listen to both external view and customized view, they can do</p> + <div class="source"> + <pre><code>Map<PropertyType, List<String>> sourceDataTypeMap = new Hashmap<>(); +sourceDataTypeMap.put(PropertyType.CUSTOMIZEDVIEW, Arrays.asList(CUSTOMIZED_STATE_0, CUSTOMIZED_STATE_1)) +sourceDataTypeMap.put(PropertyType.EXTERNALVIEW, Collections.emptyList()); + +routingTableProvider = new RoutingTableProvider(helixManager, sourceDataTypeMap); +</code></pre> + </div> + </section> + <section> + <h4 id="Verify_Customized_View_Generated_Properly">Verify Customized View Generated Properly</h4> + <p>After finishing all the steps above, users could verify whether the customized view is generated probably based on customized states. For example, if you have two instances: P0 and P1, one resource: MyResource, with two partitions: MyResource_0 and MyResource_1, and each partition has one state in CUSTOMIZED_STATE_TYPE_1, which includes STATE_NAME_0, STATE_NAME_1 and STATE_NAME_2. At a certain time, the customized states may look like something similar to the following.</p> + <div class="source"> + <pre><code>P0: +{ + "id": "MyResource", + "listFields": {}, + "mapFields": { + "MyResource_0": { + "CURRENT_STATE": "STATE_NAME_1", + "PREVIOUS_STATE": "STATE_NAME_0", + "START_TIME": "1580221789100", + "END_TIME": "1580221.4.097", + }, + "MyResource_1": { + "CURRENT_STATE": "STATE_NAME_2", + "PREVIOUS_STATE": "STATE_NAME1", + "START_TIME": "1580221789880", + "END_TIME": "1580221.4.017" + } + } +} + +P1: +{ + "id": "MyResource", + "listFields": {}, + "mapFields": { + "MyResource_0": { + "CURRENT_STATE": "STATE_NAME_2", + "PREVIOUS_STATE": "STATE_NAME_0", + "START_TIME": "1570221125566", + "END_TIME": "15744432835197", + }, + "MyResource_1": { + "CURRENT_STATE": "STATE_NAME_0", + "PREVIOUS_STATE": "STATE_NAME1", + "START_TIME": "1570221723440", + "END_TIME": "1570321.4.017" + } + } +} +</code></pre> + </div> + <p>After Helix controller aggregation, the customized view should look like the following:</p> + <div class="source"> + <pre><code>{ "id": "MyResource", + "listFields": {}, + "mapFields": { + "MyResource_0": { + "P0": "STATE_NAME_1", + "P1": "STATE_NAME_2" + }, + "MyResource_1": { + "P0": "STATE_NAME_2", + "P1": "STATE_NAME_0" + } +} +</code></pre> + </div> + </section> + </section> +</section> + </div> + </div> + </div> + </div> + + </div><!-- /container --> + + <!-- Footer + ================================================== --> + <footer class="well"> + <div class="container"> + <div class="row"> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Get Helix</li> + <li > + <a href="download.html" title="Download">Download</a> + </li> + <li > + <a href="Building.html" title="Building">Building</a> + </li> + <li > + <a href="releasenotes/release-1.4.0.html" title="Release Notes">Release Notes</a> + </li> + </ul> + </div> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Hands-On</li> + <li > + <a href="Quickstart.html" title="Quick Start">Quick Start</a> + </li> + <li > + <a href="Tutorial.html" title="Tutorial">Tutorial</a> + </li> + <li > + <a href="../javadocs/1.4.0" title="Javadocs">Javadocs</a> + </li> + </ul> + </div> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Recipes</li> + <li > + <a href="recipes/lock_manager.html" title="Distributed lock manager">Distributed lock manager</a> + </li> + <li > + <a href="recipes/rabbitmq_consumer_group.html" title="Rabbit MQ consumer group">Rabbit MQ consumer group</a> + </li> + <li > + <a href="recipes/rsync_replicated_file_store.html" title="Rsync replicated file store">Rsync replicated file store</a> + </li> + <li > + <a href="recipes/service_discovery.html" title="Service discovery">Service discovery</a> + </li> + <li > + <a href="recipes/task_dag_execution.html" title="Distributed task DAG execution">Distributed task DAG execution</a> + </li> + </ul> + </div> + </div> + </div> + </footer> + + <div class="container subfooter"> + <div class="row"> + <div class="span12"> + <p class="pull-right"><a href="#">Back to top</a></p> + <p class="copyright">Copyright ©2024 <a href="http://www.apache.org">Apache Software Foundation</a>. All Rights Reserved.</p> + <p><a href="https://github.com/olamy/reflow-maven-skin" title="Reflow Maven skin">Reflow Maven skin</a> maintained by <a href="https://twitter.com/olamy" target="_blank" title="Olivier Lamy">Olivier Lamy</a>.</p> + <div class="row span16"><div>Apache Helix, Apache, the Apache feather logo, and the Apache Helix project logos are trademarks of The Apache Software Foundation. + All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div> + <a href="https://helix.apache.org/1.4.0-docs/privacy-policy.html">Privacy Policy</a> + </div> + </div> + </div> + </div> + + <!-- Le javascript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="./js/jquery.min.js"></script> + + <script src="./js/bootstrap.min.js"></script> + <script src="./js/lightbox.min.js"></script> + <script src="./js/reflow-scroll.js"></script> + + <script src="./js/reflow-skin.js"></script> + + </body> +</html> \ No newline at end of file Added: helix/site-content/1.4.0-docs/tutorial_distributed_lock.html URL: http://svn.apache.org/viewvc/helix/site-content/1.4.0-docs/tutorial_distributed_lock.html?rev=1918422&view=auto ============================================================================== --- helix/site-content/1.4.0-docs/tutorial_distributed_lock.html (added) +++ helix/site-content/1.4.0-docs/tutorial_distributed_lock.html Wed Jun 19 01:36:37 2024 @@ -0,0 +1,435 @@ + +<!DOCTYPE html> + + + + + + +<!-- + Generated by Apache Maven Doxia at 2024-06-18 Rendered using Reflow Maven Skin 2.0.0 (https://olamy.github.io/reflow-maven-skin) +--> +<html xml:lang="en" lang="en"> + + <head> + <meta charset="UTF-8" /> + <title>Apache Helix – Tutorial - Distributed Lock</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta name="description" content="" /> + <meta http-equiv="content-language" content="en" /> + + <link href="./css/bootstrap.min.css" rel="stylesheet" /> + <link href="./css/bootstrap-responsive.min.css" rel="stylesheet" /> + <link href="./css/docs.css" rel="stylesheet" /> + <link href="./css/reflow-skin.css" rel="stylesheet" /> + + + <link href="./css/lightbox.css" rel="stylesheet" /> + + <link href="./css/site.css" rel="stylesheet" /> + <link href="./css/print.css" rel="stylesheet" media="print" /> + + <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements --> + <!--[if lt IE 9]> + <script src="./js/html5.js"></script> + <![endif]--> + + + + + + +<!-- Matomo --> +<script> + var _paq = window._paq = window._paq || []; + _paq.push(['disableCookies']); + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + + (function() { + var u="https://analytics.apache.org"; + _paq.push(['setTrackerUrl', u+'/matomo.php']); + _paq.push(['setSiteId', '15']); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.async=true; g.src=u+'/matomo.js'; s.parentNode.insertBefore(g,s); + })(); +</script> +<!-- End Matomo Code --> + </head> + + <body class="page-tutorial_distributed_lock project-140-docs" data-spy="scroll" data-offset="60" data-target="#toc-scroll-target"> + + + <div class="navbar navbar-fixed-top"> + <div class="navbar-inner"> + <div class="container"> + <a class="btn btn-navbar" data-toggle="collapse" data-target="#top-nav-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </a> + <a class="brand" href="http://helix.apache.org">Apache Helix</a> + <div class="nav-collapse collapse" id="top-nav-collapse"> + <ul class="nav pull-right"> + <li ><a href="index.html" title="Helix 1.4.0">Helix 1.4.0</a></li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Helix <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="download.html" title="Download">Download</a></li> + <li ><a href="Building.html" title="Building">Building</a></li> + <li ><a href="releasenotes/release-1.4.0.html" title="Release Notes">Release Notes</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Hands-On <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="Quickstart.html" title="Quick Start">Quick Start</a></li> + <li ><a href="Tutorial.html" title="Tutorial">Tutorial</a></li> + <li ><a href="../javadocs/1.4.0" title="Javadocs">Javadocs</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Recipes <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="recipes/lock_manager.html" title="Distributed lock manager">Distributed lock manager</a></li> + <li ><a href="recipes/rabbitmq_consumer_group.html" title="Rabbit MQ consumer group">Rabbit MQ consumer group</a></li> + <li ><a href="recipes/rsync_replicated_file_store.html" title="Rsync replicated file store">Rsync replicated file store</a></li> + <li ><a href="recipes/service_discovery.html" title="Service discovery">Service discovery</a></li> + <li ><a href="recipes/task_dag_execution.html" title="Distributed task DAG execution">Distributed task DAG execution</a></li> + </ul> + </li> + </ul> + </div><!--/.nav-collapse --> + </div> + </div> + </div> + + <div class="container"> + + <!-- Masthead + ================================================== --> + + <header> + <div class="jumbotron subhead"> + <div class="row" id="banner"> + <div class="span12"> + <div class="pull-left"> + <a href="http://helix.apache.org/" id="bannerLeft"><img src="../images/helix-logo.jpg" alt='"''"' /></a> + <p class="lead">A cluster management framework for partitioned and replicated distributed resources</p> + </div> + <div class="pull-right"> + <a href="http://www.apache.org/" id="bannerRight"><img src="../images/feather_small.gif" alt='"''"' /></a> + </div> + </div> + </div> + </div> + <div> + <ul class="breadcrumb"> + <li><a href="../" title="Apache Helix">Apache Helix</a></li> + <li class="divider">/</li> + <li><a href="./" title="Release 1.4.0">Release 1.4.0</a></li> + <li class="divider">/</li> + <li>Tutorial - Distributed Lock</li> + <li class="publishDate version-date pull-right">Last Published: 2024-06-18</li> + </ul> + </div> + </header> + + <div class="main-body"> + <div class="row"> + <div class="span12"> + <div class="body-content"> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<section> + <div class="page-header"> + <h2 id="Helix_Tutorial:_Distributed_Lock"><a href="./Tutorial.html">Helix Tutorial</a>: Distributed Lock</h2> + </div> + <p>In a distributed system, there are many cases that we need a mechanism to make sure different processes can cooperate correctly. For example, if two processes that run on different machines, or different networks, or even different data centers would like to work on the same resource, we must have a mutually exclusive lock to ensure that their operations do not step on each other. Only when a process acquires the lock, it can perform the operation.</p> + <p>Since Helix is built on top of ZooKeeper, which is a widely used framework to manage coordination across a cluster of machines, a natural solution for implementing a distributed lock is to leverage ZooKeeper. Specifically, we can represent the lock itself as a znode. Currently, many distributed systems use Apache Helix as a generic cluster management framework to automatically manage resources hosted on a cluster of nodes. Implementing a distributed lock in Helix would allow Helix's existing customers to use a reliable lock with little overhead.</p> + <section> + <h3 id="Helix_Lock_Interface">Helix Lock Interface</h3> + <p>Helix provides a generic lock interface that can be implemented with different kinds of locks. Several key functions are defined in the interface.</p> + <div class="source"> + <pre><code>/** + * Generic interface for Helix distributed lock + */ +public interface DistributedLock { + /** + * Blocking call to acquire a lock if it is free at the time of request + * @return true if the lock was successfully acquired, + * false if the lock could not be acquired + */ + boolean tryLock(); + + /** + * Blocking call to unlock a lock + * @return true if the lock was successfully released or if the locked is not currently locked, + * false if the lock is not locked by the user or the unlock operation failed + */ + boolean unlock(); + + /** + * Retrieve the information of the current lock on the resource this lock object specifies, e.g. lock timeout, lock message, etc. + * @return lock metadata information + */ + LockInfo getCurrentLockInfo(); + + /** + * If the user is current lock owner of the resource + * @return true if the user is the lock owner, + * false if the user is not the lock owner or the lock doesn't have a owner + */ + boolean isCurrentOwner(); + + /** + * Call this method to close the lock's zookeeper connection + * The lock has to be unlocked or expired before this method can be called + */ + void close(); +} +</code></pre> + </div> + <p>Currently, Helix supports two kinds of locks. One is basic lock, and the other is priority lock. We will describe their definition and usage as follows.</p> + </section> + <section> + <h3 id="Helix_Basic_Lock">Helix Basic Lock</h3> + <section> + <h4 id="Features">Features</h4> + <ul> + <li> <p>Non-blocking lock. It means every request to acquire the lock will immediately get a result (success or failure) instead of waiting until the lock is successfully acquired.</p> </li> + <li> <p>Timeout support. A client needs to input the timeout when it tries to acquire the lock. We use lazy timeout for the lock. It means even after the timeout, if no other client tries to get the lock, the client can still keep the lock, if other client tries to acquire the lock, and finds the previous client already timed out, the previous client will automatically lose the lock.</p> </li> + <li> <p>Lock message support. A client can input the reason for the lock (as a string) when it tries to acquire the lock. This enables future lock operation, when fails, can know the reason from the lock message of the current lock.</p> </li> + <li> <p>Java API support for clients to use the lock.</p> </li> + <li> <p>No notification support. When a client loses its lock after the timeout or due to some urgent maintenance work who does not check the lock, there is no notification sent out to the previous lock owner.</p> </li> + </ul> + </section> + <section> + <h4 id="How_to_Use_Helix_Basic_Lock">How to Use Helix Basic Lock</h4> + <p>The implementation of Helix lock is called âZkHelixNonblockingLockâ. It has two different constructors as shown below. One constructor takes clusterName, and HelixConfigScope as inputs. HelixConfigScope can be âclusterâ, âparticipantâ, or âresourceâ. The other constructor takes a lockPath string as input.</p> + <div class="source"> + <pre><code> /** + * Initialize the lock with Helix scope. + */ + public ZKHelixNonblockingLock(String clusterName, HelixConfigScope scope, String zkAddress, + Long timeout, String lockMsg) + + /** + * Initialize the lock with lock path under zookeeper. + */ + public ZKHelixNonblockingLock(String lockPath, String zkAddress, Long timeout, String lockMsg) +</code></pre> + </div> + <p>The client can use the lock in two different ways. If the client would like to use the lock for some specific Helix resource, it can use the first constructor which requires clusterName and HelixConfigScope. We show an example below on how to use Helix scope. Or the client may choose to use the lock for generic purpose, basically on any resource they have. In this case, the client needs to provide the lock path, which is a string, and it represents where the lock should exist under zookeeper.</p> + <div class="source"> + <pre><code> List<String> pathKeys = new ArrayList<>(); + pathKeys.add(clusterName); + HelixLockScope participantScope = new HelixLockScope(HelixLockScope.LockScopeProperty.CLUSTER, pathKeys); +</code></pre> + </div> + <p>Note that if users have onboarded to ZooScalability that has multiple realms, they should instead use the builder instead of the above constructors.</p> + </section> + </section> + <section> + <h3 id="Helix_Priority_Lock">Helix Priority Lock</h3> + <section> + <h4 id="Features">Features</h4> + <ul> + <li>Priority support. A client with higher priority can override lock owned by a client with lower priority.</li> + <li>Notification support. After the higher priority client overrides the lock owned by lower priority client, the low priority client will get notified.</li> + <li>Cleanup support. The low priority client will be given some time to do the cleanup and roll back the system to normal state when its lock is preempted.</li> + </ul> + </section> + <section> + <h4 id="Priority_Lock_Definitions">Priority Lock Definitions</h4> + <p>There are a few concepts defined for priority lock.</p> + <section> + <h5 id="Definition_1:_Priority_of_the_lock.">Definition 1: Priority of the lock.</h5> + <p>Any client that wants to acquire a lock needs to have a priority so that Helix knows what to do when there are multiple clients that want the same lock. We accept non-negative integers as meaningful priority representation. The lowest priority is 0. The larger the number, the higher the priority is. Same number denotes the same priority. We do not have an upper limit for the priority definition. However, we reserve the value of INT_MAX for emergency use by SREs, i.e., they may override all other priorities in case of urgent operations. If a client does not have a priority defined when it tries to acquire the lock, the default value 0 will be assigned to the client and thus the client is with lowest priority.</p> + </section> + <section> + <h5 id="Definition_2:_Timeout_of_the_lock.">Definition 2: Timeout of the lock.</h5> + <p>When a request for a lock is issued, there can be three types of timeout associated with the lock. We explain them respectively as follows.</p> + <ul> + <li> <p>lease timeout: it is the user's requirement of how long the lease it needs. It denotes how long it takes to finish the work by the client that requires the locked resource. This is the same concept as the timeout in basic lock. This field must be set to a positive value. Otherwise the lock is meaningless.</p> </li> + <li> <p>cleanup timeout: it defines how long it takes for a client to clean up the work done with the locked resource and bring back the resource to a clean state if the client is preempted by a higher priority client. If a user does not define this field, the clean up timeout will be set to the default value 0, meaning no cleanup work is needed. Once there is a higher priority client requested the lock, the lock will be immediately given to the high priority one after the notification is sent to the low priority client.</p> </li> + <li> <p>waiting timeout: it defines how long the client that requests the lock can wait for the lower priority client to finish the cleanup work. Specifically, if the work is urgent to get executed, a client should set a shorter waiting timeout. To the extreme, if users set the waiting timeout to be 0, the lock will be acquired immediately. If the waiting timeout is not set, it will be default as infinite, meaning that the high priority client will not get the lock until the low priority client finishes all the cleanup work.</p> </li> + </ul> + <p>The three timeout are specific to the particular client that requests the lock and should be independent of each other. In short, the lease timeout includes all the time needed in normal operation (perform the work, clean up when work is completed, etc.); cleanup timeout is user's best estimate of time needed for reverting the system to previous stable state in case of preemption; waiting timeout shows how urgent the client needs to acquire the lock. Please note that it is possible that a client's waiting timeout is shorter than the other client's cleanup timeout. In this case, the client's waiting timeout will override the other client's cleanup timeout. We always honor the waiting timeout of the high priority client before cleanup timeout of the low priority client when there is a contention for the lock. Lock users should be responsible for setting up different timeout of their locks. However, it is possible that at the beginning they can only provide an estimation for the timeout which is not accurate enough. Either Helix or user code could implement some statistic logic to analyze the real execution or clean up times used. For example, Helix may be able to calculate how many times the workflow finishes the cleanup job in the designated cleanup timeout, and if not, what is the real cleanup time (in case that the waiting timeout is larger). Based on the results, users could tune their timeout to better handle lock preemption.</p> + </section> + <section> + <h5 id="Definition_3:_Forcefulness_of_the_lock">Definition 3: Forcefulness of the lock</h5> + <p>Forcefulness means whether a lock requested by a client is forceful or not in case of a preemption. If it is a forceful lock, when time is out, no matter whether the cleanup work of low priority client is finished or not, the high priority client will grab the lock from low priority client. However, if it is not a forceful lock, the high priority client will receive an exception, knowing that the low priority client has not finished its work yet. Then it is up to human beings to decide what is the next step. We could trigger an alert based on this kind of exception. Users can set up an approval workflow to act based on the alert. They may manually check the exception and the previous lock owner to make the decision on whether they will respect the previous owner's work or forcefully grab the lock. Or later with some experience on handling these exceptions, they can also make the process fully automatic. For example, with low priority client A and high priority client B, if in the case of exception thrown during preemption, user always chooses to forcefully grab the lock and assign the lock owner to B, we may have a rule set up for this condition which will automatically transfer the lock owner.</p> + </section> + </section> + <section> + <h4 id="Priority_Lock_Workflow">Priority Lock Workflow</h4> + <p>To better visualize the above analysis, we draw the following diagram shows how a client may go through the possible scenarios. <img src="./images/HelixPriorityLockWorkflow.jpeg" alt="HelixPriorityLockWorkflow"></p> + </section> + <section> + <h4 id="Priority_Lock_Usage">Priority Lock Usage</h4> + <section> + <h5 id="Lock_information_Definition">Lock information Definition</h5> + <div class="source"> + <pre><code> public enum LockInfoAttribute { + OWNER, + MESSAGE, + TIMEOUT, + PRIORITY, + WAITING_TIMEOUT, + CLEANUP_TIMEOUT, + REQUESTOR_ID, + REQUESTOR_PRIORITY, + REQUESTOR_WAITING_TIMEOUT, + REQUESTING_TIMESTAMP + } +</code></pre> + </div> + </section> + <section> + <h5 id="Priority_Lock_Constructor">Priority Lock Constructor</h5> + <div class="source"> + <pre><code> /** + * Internal construction of the lock with user provided information, e.g., lock path under + * zookeeper, etc. + * @param lockPath the path of the lock under Zookeeper + * @param leaseTimeout the leasing timeout period of the lock + * @param lockMsg the reason for having this lock + * @param userId a universal unique userId for lock owner identity + * @param priority the priority of the lock + * @param waitingTimeout the waiting timeout period of the lock when the tryLock request is issued + * @param cleanupTimeout the time period needed to finish the cleanup work by the lock when it + * is preempted + * @param isForceful whether the lock is a forceful one. This determines the behavior when the + * lock encountered an exception during preempting lower priority lock + * @param lockListener the listener associated to the lock + * @param baseDataAccessor baseDataAccessor instance to do I/O against ZK with + */ + private ZKDistributedNonblockingLock(String lockPath, Long leaseTimeout, String lockMsg, + String userId, int priority, long waitingTimeout, long cleanupTimeout, boolean isForceful, + LockListener lockListener, BaseDataAccessor<ZNRecord> baseDataAccessor) +</code></pre> + </div> + </section> + <section> + <h5 id="Priority_Lock_Usage_Example:">Priority Lock Usage Example:</h5> + <div class="source"> + <pre><code> ZKDistributedNonblockingLock.Builder lockBuilder = new ZKDistributedNonblockingLock.Builder(); + lockBuilder.setLockScope(new HelixLockScope(HelixLockScope.LockScopeProperty.CLUSTER, pathKeys)).setZkAddress(ZK_ADDR).setTimeout(3600000L) + .setLockMsg("test lock").setUserId("test Id").setPriority(0).setWaitingTimeout(1000) + .setCleanupTimeout(2000).setIsForceful(false) + .setLockListener(new LockListener() {@Override public void onCleanupNotification() {}); + ZKDistributedNonblockingLock testLock = lockBuilder.build(); +</code></pre> + </div> + </section> + </section> + </section> +</section> + </div> + </div> + </div> + </div> + + </div><!-- /container --> + + <!-- Footer + ================================================== --> + <footer class="well"> + <div class="container"> + <div class="row"> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Get Helix</li> + <li > + <a href="download.html" title="Download">Download</a> + </li> + <li > + <a href="Building.html" title="Building">Building</a> + </li> + <li > + <a href="releasenotes/release-1.4.0.html" title="Release Notes">Release Notes</a> + </li> + </ul> + </div> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Hands-On</li> + <li > + <a href="Quickstart.html" title="Quick Start">Quick Start</a> + </li> + <li > + <a href="Tutorial.html" title="Tutorial">Tutorial</a> + </li> + <li > + <a href="../javadocs/1.4.0" title="Javadocs">Javadocs</a> + </li> + </ul> + </div> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Recipes</li> + <li > + <a href="recipes/lock_manager.html" title="Distributed lock manager">Distributed lock manager</a> + </li> + <li > + <a href="recipes/rabbitmq_consumer_group.html" title="Rabbit MQ consumer group">Rabbit MQ consumer group</a> + </li> + <li > + <a href="recipes/rsync_replicated_file_store.html" title="Rsync replicated file store">Rsync replicated file store</a> + </li> + <li > + <a href="recipes/service_discovery.html" title="Service discovery">Service discovery</a> + </li> + <li > + <a href="recipes/task_dag_execution.html" title="Distributed task DAG execution">Distributed task DAG execution</a> + </li> + </ul> + </div> + </div> + </div> + </footer> + + <div class="container subfooter"> + <div class="row"> + <div class="span12"> + <p class="pull-right"><a href="#">Back to top</a></p> + <p class="copyright">Copyright ©2024 <a href="http://www.apache.org">Apache Software Foundation</a>. All Rights Reserved.</p> + <p><a href="https://github.com/olamy/reflow-maven-skin" title="Reflow Maven skin">Reflow Maven skin</a> maintained by <a href="https://twitter.com/olamy" target="_blank" title="Olivier Lamy">Olivier Lamy</a>.</p> + <div class="row span16"><div>Apache Helix, Apache, the Apache feather logo, and the Apache Helix project logos are trademarks of The Apache Software Foundation. + All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div> + <a href="https://helix.apache.org/1.4.0-docs/privacy-policy.html">Privacy Policy</a> + </div> + </div> + </div> + </div> + + <!-- Le javascript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="./js/jquery.min.js"></script> + + <script src="./js/bootstrap.min.js"></script> + <script src="./js/lightbox.min.js"></script> + <script src="./js/reflow-scroll.js"></script> + + <script src="./js/reflow-skin.js"></script> + + </body> +</html> \ No newline at end of file Added: helix/site-content/1.4.0-docs/tutorial_health.html URL: http://svn.apache.org/viewvc/helix/site-content/1.4.0-docs/tutorial_health.html?rev=1918422&view=auto ============================================================================== --- helix/site-content/1.4.0-docs/tutorial_health.html (added) +++ helix/site-content/1.4.0-docs/tutorial_health.html Wed Jun 19 01:36:37 2024 @@ -0,0 +1,270 @@ + +<!DOCTYPE html> + + + + + + +<!-- + Generated by Apache Maven Doxia at 2024-06-18 Rendered using Reflow Maven Skin 2.0.0 (https://olamy.github.io/reflow-maven-skin) +--> +<html xml:lang="en" lang="en"> + + <head> + <meta charset="UTF-8" /> + <title>Apache Helix – Tutorial - Customizing Heath Checks</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta name="description" content="" /> + <meta http-equiv="content-language" content="en" /> + + <link href="./css/bootstrap.min.css" rel="stylesheet" /> + <link href="./css/bootstrap-responsive.min.css" rel="stylesheet" /> + <link href="./css/docs.css" rel="stylesheet" /> + <link href="./css/reflow-skin.css" rel="stylesheet" /> + + + <link href="./css/lightbox.css" rel="stylesheet" /> + + <link href="./css/site.css" rel="stylesheet" /> + <link href="./css/print.css" rel="stylesheet" media="print" /> + + <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements --> + <!--[if lt IE 9]> + <script src="./js/html5.js"></script> + <![endif]--> + + + + + + +<!-- Matomo --> +<script> + var _paq = window._paq = window._paq || []; + _paq.push(['disableCookies']); + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + + (function() { + var u="https://analytics.apache.org"; + _paq.push(['setTrackerUrl', u+'/matomo.php']); + _paq.push(['setSiteId', '15']); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.async=true; g.src=u+'/matomo.js'; s.parentNode.insertBefore(g,s); + })(); +</script> +<!-- End Matomo Code --> + </head> + + <body class="page-tutorial_health project-140-docs" data-spy="scroll" data-offset="60" data-target="#toc-scroll-target"> + + + <div class="navbar navbar-fixed-top"> + <div class="navbar-inner"> + <div class="container"> + <a class="btn btn-navbar" data-toggle="collapse" data-target="#top-nav-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </a> + <a class="brand" href="http://helix.apache.org">Apache Helix</a> + <div class="nav-collapse collapse" id="top-nav-collapse"> + <ul class="nav pull-right"> + <li ><a href="index.html" title="Helix 1.4.0">Helix 1.4.0</a></li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Helix <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="download.html" title="Download">Download</a></li> + <li ><a href="Building.html" title="Building">Building</a></li> + <li ><a href="releasenotes/release-1.4.0.html" title="Release Notes">Release Notes</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Hands-On <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="Quickstart.html" title="Quick Start">Quick Start</a></li> + <li ><a href="Tutorial.html" title="Tutorial">Tutorial</a></li> + <li ><a href="../javadocs/1.4.0" title="Javadocs">Javadocs</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Recipes <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li ><a href="recipes/lock_manager.html" title="Distributed lock manager">Distributed lock manager</a></li> + <li ><a href="recipes/rabbitmq_consumer_group.html" title="Rabbit MQ consumer group">Rabbit MQ consumer group</a></li> + <li ><a href="recipes/rsync_replicated_file_store.html" title="Rsync replicated file store">Rsync replicated file store</a></li> + <li ><a href="recipes/service_discovery.html" title="Service discovery">Service discovery</a></li> + <li ><a href="recipes/task_dag_execution.html" title="Distributed task DAG execution">Distributed task DAG execution</a></li> + </ul> + </li> + </ul> + </div><!--/.nav-collapse --> + </div> + </div> + </div> + + <div class="container"> + + <!-- Masthead + ================================================== --> + + <header> + <div class="jumbotron subhead"> + <div class="row" id="banner"> + <div class="span12"> + <div class="pull-left"> + <a href="http://helix.apache.org/" id="bannerLeft"><img src="../images/helix-logo.jpg" alt='"''"' /></a> + <p class="lead">A cluster management framework for partitioned and replicated distributed resources</p> + </div> + <div class="pull-right"> + <a href="http://www.apache.org/" id="bannerRight"><img src="../images/feather_small.gif" alt='"''"' /></a> + </div> + </div> + </div> + </div> + <div> + <ul class="breadcrumb"> + <li><a href="../" title="Apache Helix">Apache Helix</a></li> + <li class="divider">/</li> + <li><a href="./" title="Release 1.4.0">Release 1.4.0</a></li> + <li class="divider">/</li> + <li>Tutorial - Customizing Heath Checks</li> + <li class="publishDate version-date pull-right">Last Published: 2024-06-18</li> + </ul> + </div> + </header> + + <div class="main-body"> + <div class="row"> + <div class="span12"> + <div class="body-content"> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<section> + <div class="page-header"> + <h2 id="Helix_Tutorial:_Customizing_Health_Checks"><a href="./Tutorial.html">Helix Tutorial</a>: Customizing Health Checks</h2> + </div> + <p>In this chapter, we'll learn how to customize health checks based on metrics of your distributed system.</p> + <section> + <h3 id="Health_Checks">Health Checks</h3> + <p>Note: <i>this in currently in development mode, not yet ready for production.</i></p> + <p>Helix provides the ability for each node in the system to report health metrics on a periodic basis.</p> + <p>Helix supports multiple ways to aggregate these metrics:</p> + <ul> + <li>SUM</li> + <li>AVG</li> + <li>EXPONENTIAL DECAY</li> + <li>WINDOW</li> + </ul> + <p>Helix persists the aggregated value only.</p> + <p>Applications can define a threshold on the aggregate values according to the SLAs, and when the SLA is violated Helix will fire an alert. Currently Helix only fires an alert, but in a future release we plan to use these metrics to either mark the node dead or load balance the partitions. This feature will be valuable for distributed systems that support multi-tenancy and have a large variation in work load patterns. In addition, this can be used to detect skewed partitions (hotspots) and rebalance the cluster.</p> + </section> +</section> + </div> + </div> + </div> + </div> + + </div><!-- /container --> + + <!-- Footer + ================================================== --> + <footer class="well"> + <div class="container"> + <div class="row"> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Get Helix</li> + <li > + <a href="download.html" title="Download">Download</a> + </li> + <li > + <a href="Building.html" title="Building">Building</a> + </li> + <li > + <a href="releasenotes/release-1.4.0.html" title="Release Notes">Release Notes</a> + </li> + </ul> + </div> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Hands-On</li> + <li > + <a href="Quickstart.html" title="Quick Start">Quick Start</a> + </li> + <li > + <a href="Tutorial.html" title="Tutorial">Tutorial</a> + </li> + <li > + <a href="../javadocs/1.4.0" title="Javadocs">Javadocs</a> + </li> + </ul> + </div> + <div class="span3 bottom-nav"> + <ul class="nav nav-list"> + <li class="nav-header">Recipes</li> + <li > + <a href="recipes/lock_manager.html" title="Distributed lock manager">Distributed lock manager</a> + </li> + <li > + <a href="recipes/rabbitmq_consumer_group.html" title="Rabbit MQ consumer group">Rabbit MQ consumer group</a> + </li> + <li > + <a href="recipes/rsync_replicated_file_store.html" title="Rsync replicated file store">Rsync replicated file store</a> + </li> + <li > + <a href="recipes/service_discovery.html" title="Service discovery">Service discovery</a> + </li> + <li > + <a href="recipes/task_dag_execution.html" title="Distributed task DAG execution">Distributed task DAG execution</a> + </li> + </ul> + </div> + </div> + </div> + </footer> + + <div class="container subfooter"> + <div class="row"> + <div class="span12"> + <p class="pull-right"><a href="#">Back to top</a></p> + <p class="copyright">Copyright ©2024 <a href="http://www.apache.org">Apache Software Foundation</a>. All Rights Reserved.</p> + <p><a href="https://github.com/olamy/reflow-maven-skin" title="Reflow Maven skin">Reflow Maven skin</a> maintained by <a href="https://twitter.com/olamy" target="_blank" title="Olivier Lamy">Olivier Lamy</a>.</p> + <div class="row span16"><div>Apache Helix, Apache, the Apache feather logo, and the Apache Helix project logos are trademarks of The Apache Software Foundation. + All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div> + <a href="https://helix.apache.org/1.4.0-docs/privacy-policy.html">Privacy Policy</a> + </div> + </div> + </div> + </div> + + <!-- Le javascript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="./js/jquery.min.js"></script> + + <script src="./js/bootstrap.min.js"></script> + <script src="./js/lightbox.min.js"></script> + <script src="./js/reflow-scroll.js"></script> + + <script src="./js/reflow-skin.js"></script> + + </body> +</html> \ No newline at end of file