flume之退避算法backoff algorithm[通俗易懂]

flume之退避算法backoff algorithm[通俗易懂]flume之退避算法backoffalgorithm什么是退避算法:Inasinglechannelcontentionbasedmediumaccesscontrol(MAC)protocols,whenevermorethanonestationornodetriestoaccessthemediumatthesameinstantof…

大家好,又见面了,我是你们的朋友全栈君。

什么是退避算法:

In a single channel contention based medium access control (MAC) protocols, whenever more than one station or node tries to access the medium at the same instant of time, it leads to packet collisions. If the collided stations tries to access the channel again, the packets will collide as the nodes are synchrozied in time. So the nodes need to be displaced in time. To displace them temporally, a backoff algorithm is used (example binary exponential backoff (BEB)). For example, in BEB algorithm, whenever a node’s transmission is involved in a collision with another node’s transmission, both nodes will choose a random waiting time and wait for this amoiunt of time before attempting again. If they are not successful in this attempt, they double their contention window and choose a randoim waiting time before transmitting again. This process will be repeated for certain number of attempts. If the nodes are not successful in their transmission after this limit, the packets will be dropped from their queue.

大致意思是,在一个共享信道的情况下,当网络上的节点在发生冲突时,每个节点节点等待一定的时间后重新发送。在二进制指数退避算法中,等待时间随着以二为底的指数增长。如果重试失败,那么下次的等待时间将会是上次的等待时间二倍。如果重试次数大于最大重试次数,那么包将从包队列中去除。

我们认识了什么是退避算法之后,来看一下flume中对退避算法的应用。从退避算法的概念可知,该算法用在网络错误,重试的情况中,例如打开一个网络链接,向网络中发送数据等。在flume中,insistentAppend和insistentOpen封装器都用到了退避算法来处理网络的发送数据和链接打开过程。我们来通过insistentAppend中的append方法例子,看一下怎么对退避算法进行运用。

 

Java代码  

  1. public void append(Event evt) throws IOException, InterruptedException {  
  2.     List<IOException> exns = new ArrayList<IOException>();  
  3.     int attemptRetries = 0;  
  4.     appendRequests++;  
  5.     while (!backoff.isFailed() && isOpen.get()  
  6.         && !Thread.currentThread().isInterrupted()) {  
  7.       try {  
  8.         appendAttempts++;  
  9.         super.append(evt);  
  10.         appendSuccesses++;  
  11.         backoff.reset(); // reset backoff counter;  
  12.         return;  
  13.       } catch (InterruptedException ie) {  
  14.         throw ie;  
  15.       } catch (IOException e) {  
  16.         // this is an unexpected exception  
  17.         long waitTime = backoff.sleepIncrement();  
  18.         LOG.info(“append attempt “ + attemptRetries + ” failed, backoff (“  
  19.             + waitTime + “ms): “ + e.getMessage());  
  20.         LOG.debug(e.getMessage(), e);  
  21.         exns.add((e instanceof IOException) ? (IOException) e  
  22.             : new IOException(e));  
  23.         backoff.backoff();  
  24.         try {  
  25.           backoff.waitUntilRetryOk();  
  26.         } catch (InterruptedException e1) {  
  27.           // got an interrupted signal, bail out!  
  28.           throw e1;  
  29.         } finally {  
  30.           attemptRetries++;  
  31.           appendRetries++;  
  32.         }  
  33.       } catch (RuntimeException e) {  
  34.         // this is an unexpected exception  
  35.         LOG.info(“Failed due to unexpected runtime exception “  
  36.             + “during append attempt”, e);  
  37.         appendGiveups++;  
  38.         throw e;  
  39.       }  
  40.     }  
  41.     appendGiveups++;  
  42.     // failed to start  
  43.     IOException ioe = MultipleIOException.createIOException(exns);  
  44.     if (ioe == null) {  
  45.       return;  
  46.     }  
  47.     throw ioe;  
  48.   }  

 通过对以上代码抽象,一般采用以下形式来运用backoff算法。

 

Java代码  

  1. while (!backoff.isFailed()) {  
  2.           try {  
  3.             doSomething(); //do something  
  4.             backoff.reset(); // reset backoff counter;  
  5.             return;  
  6.           } catch (Exception e) {  
  7.             backoff.backoff();  
  8.             try {  
  9.               backoff.waitUntilRetryOk();  
  10.             } catch (InterruptedException e1) {         
  11.             }   
  12.          }  
  13.      }  

 

 目前在flume中主要运用了ExponentialBackoff,CappedExponentialBackoff,CumulativeCappedExponentialBackoff三种退避算法。

ExponentialBackOff是个简单的指数退避算法,仅仅让下次的等待时间是上次等待时间的2倍,当重试次数达到最大重试次数时,该任务将不能重试。

CappedExponentialBackoff对ExponentialBackOff算法作了简单的改造,该算法对每次的等待时间做了个限定,即每次的等待时间不超过某个值sleepCap。但该方法没有限定重试次数。

CumulativeCappedExponentialBackoff算法对CappedExponentialBackoff作了些改造,该算法加入了cumulativeCap变量,用来限制重试次数。在第一次backoff的时候设置failTime值为当前时间+cumulativeCap。是否可以重试由当前时间和failTime决定。当前时间小于failTime则表明还可以重试,否则,不能重试。

 

通过对以上的分析,可以得到一个Backoff算法必须提供四个接口(isFailed,backOff,waitUntilRetryOk,reset)。其中,isFailed用来判断是否可以重试,backoff用来设置等待时间,waitUntilRetryOk根据backoff设置的等待时间sleep,以便下次重试。reset的接口是在任务成功后,对backoff算法的一些变量重置。详细可以看ExponentialBackoff等源代码。

 

退避算法为我们在解决重试某项任务的时候,提供了一个比较好的等待思想。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/149186.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • redis安装菜鸟教程_redis集群客户端

    redis安装菜鸟教程_redis集群客户端随笔-848文章-0评论-80阅读-278万转载:windows下安装redis及其客户端-Oops!#-博客园windows下安装redis及其客户端首先下载redis安装包:https://github.com/MSOpenTech/redis/releases解压安装包到相应文件夹,任何盘符都行。文件介绍:redis-server.exe:服务端程序,提供redis服务redis-cli.exe:客户端程序,通过它连接redis服务并…

    2026年1月20日
    3
  • hive的rownumber和group by区别

    hive的rownumber和group by区别1、row_number()over()排序功能:(1)row_number()over()分组排序功能:   在使用row_number()over()函数时候,over()里头的分组以及排序的执行晚于wheregroupby orderby的执行。partitionby用于给结果集分组,如果没有指定那么它把整个结果集作为一个分组,它和聚合函数不同的地方…

    2022年5月1日
    50
  • WebStorm 7.0 注冊码

    WebStorm 7.0 注冊码

    2021年12月4日
    49
  • 网站博客搬家工具大全「建议收藏」

    网站博客搬家工具大全「建议收藏」网站博客搬家工具大全,所有大小网站博客搬家工具应有尽有!2009-07-1214:26目标对象:新浪博客、搜狐博客、网易部落、TOM博客、MSNSpace、天涯社区、中国博客网、中华部落阁、博客中国、博客中国专栏、DoNews、歪酷博客、敏思博客、BlogBUS、BlogDrive、百度空间、mop博客。服务特色:该ID下博客文章、链接、图片;文章内嵌入的流媒体

    2022年7月12日
    19
  • 拉格朗日插值公式详解[通俗易懂]

    拉格朗日插值公式详解[通俗易懂]一.线性插值(一次插值)   已知函数f(x)在区间[xk ,xk+1 ]的端点上的函数值yk =f(xk ),yk+1 =f(xk+1 ),求一个一次函数y=P1 (x)使得yk =f(xk ),yk+1 =f(xk+1 ),其几何意义是已知平面上两点(xk ,yk ),(xk+1 ,yk+1 ),求一条直线过该已知两点。   1.插值函数和插值基函数由直线的

    2025年8月23日
    3
  • java aqs详解_Java中的File文件类详解

    java aqs详解_Java中的File文件类详解今天学了学并发AQS机制,是抽象队列同步器,用户主要通过继承AQS类,来实现自定义锁,从而完成特定功能,AQS提供了两种锁(1)共享锁(2)排他锁。下面这个博客介绍的AQS机制挺不错可以看看原文链接一、概述  谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)!类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock

    2022年8月8日
    13

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号