浅谈指数退避算法

今天简单跟大家聊下指数退避算法(Exponential Backoff ),关于指数避退算法的话题开始前首先向大家抛出几个问题:指数退避算法是什么呢?为什么要用指数退避算法呢?指数退避算法的应用场景有哪些呢?代码如何实现呢?带着这些疑问诸君且向下看。

指数退避算法到底是什么呢?wiki上有这么一段解释:"Exponential backoff is an algorithm that uses feedback to multiplicatively decrease the rate of some process, in order to gradually find an acceptable rate"。通俗点说, 退避算法就是网络上的节点在发送数据冲突后,等待一定时间后再发,等待时间是随指数增长,从而避免频繁的触发冲突。在计算机网络中,二进制指数退避算法或截断指数退避算法常常作为避免网络堵塞的一部分用于同一数据块的重发策略。发生n次冲突后,等待时间在0~2^n-1个间隙时间(slot times) 之间选择随机选择。比如,发生第一次冲突后,每个发送方将会等待0或1个间隙时间(slot times);第二次冲突后,每个发送方的等待时间将会在0到3个间隙时间(slot times) 之间任意选择;第三次冲突后,每个发送方的等待时间将会在0到7个间隙时间(slot times) 之间任意选择,以此类推,随着冲突次数的增加,发送方的等待时间将会有成倍增加的可能性。而从“截断( truncated)”的字面意思我们不妨可以猜出,到一定次数,指数运算会停止,也就是说等待时间不会再无限的增加下去。比如,设置上限n=10,则最长等待时间为1023个间隙时间。因为在等待时间内某些场景同样有冲突发生的可能性,所以一般流程会在16次重试后终止。具体的退避算法如下:

确定基本退避时间,它就是争用期(总线上的单程端到端传播时延记为 x,以太网的端到端往返时间2x)。以太网把争用期定为51.2us。对于10Mb/s以太网,在争用期内可发送512bit,即64字节。也可以说争用期是512比特时间。1比特时间就是发送1比特所需要的时间。所以这种时间单位与数据率密切相关。

从离散的整数集合[0,1,…,]中随机取出一个数,记为r。重传应推后的时间就是r倍的争用期。上面的参数k按下面的公式计算: k=Min[重传次数,10] 可见当重传次数不超过10时,参数k等于重传次数;但当重传次数超过10时,k就不在增大而一直等于10。

当重传达16次仍不能成功时(这表明同时打算发送的数据站太多,以致连续发生冲突),则丢弃该,并向高层报告。例如,在第1次重传时,k=1,随机数r从整数{0,1}中选一个数。因此重传推迟的时间是0或争用期,在这两个时间中随机选择一个。若再发生碰撞,则重传时,k=2,随机数r就从整数{0,1,2,3}中选一个数。因此重传推迟的时间是在0,2x ,4x和6x 这4个时间中随机抽取一个。同样,若在发生碰撞,则重传时k=3,随机数r就从整数{0,1,2,3,4,5,6,7}中选一个数。以此类推。若连续多次发生冲突,就表明可能有较多的站参与争用信道。但使用退避算法可使重传需要推迟的平均时间随重传次数而增大(这也称为动态退避),因而减小发生碰撞的概率,有利于整个系统的稳定。

相信读到这里,大家对第二个问题的答案也呼之欲出了吧, 大多数指数退避算法会利用抖动(随机延迟)来防止连续的冲突。 但是,如果使用并发客户端,抖动可帮助您更快地成功执行请求。

至于指数避退算法的场景有哪些呢?指数退避算法在计算机网络中应用很广泛,这里简单说两个场景,第一个场景,接入三方支付服务,在三方支付提供的接入接口规范中,服务方交易结束结果通知和商户主动查询交易结果都用到重发机制,这就是所谓的退避算法,这地方其实也引出了另一个知识点——接口的幂等性( 使用相同参数对同一资源重复调用某个接口的结果与调用一次的结果相同),这里不再过多赘述。第二个场景,在app应用中,很多场景会遇到轮询一类的问题,一般的轮询对于app性能和电量的消耗都是个巨大的灾难。那如何解决这种问题呢?app在上一次更新操作之后还未被使用的情况下,使用指数退避算法来减少更新频率,从而节省资源和减少电的消耗。

最后一个问题,这里简单的用伪代码和java代码的方式给大家演示一下增量延迟轮询的实现方法。

伪代码

Dosome asynchronous operation.

retries=0

DO

waitfor(2^retries*100)milliseconds

status=Getthe result of the asynchronous operation.

IF status=SUCCESS

retry=false

ELSE IF status=NOT_READY

retry=true

ELSE IF status=THROTTLED

retry=true

ELSE

Someother error occurred,so stop calling the API.

retry=false

ENDIF

retries=retries+1

WHILE(retry AND (retries<MAX_RETRIES))

java代码

public enum Results {

SUCCESS,

NOT_READY,

THROTTLED,

SERVER_ERROR

}

public static void doOperationAndWaitForResult() {

try {

long token = asyncOperation();

int retries = 0;

boolean retry = false;

do {

long waitTime = Math.min(getWaitTimeExp(retries), MAX_WAIT_INTERVAL);

System.out.print(waitTime + "\n");

Thread.sleep(waitTime);

Results result = getAsyncOperationResult(token);

if (Results.SUCCESS == result) {

retry = false;

} else if (Results.NOT_READY == result) {

retry = true;

} else if (Results.THROTTLED == result) {

retry = true;

} else if (Results.SERVER_ERROR == result) {

retry = true;

}

else {

retry = false;

}

} while (retry && (retries++ < MAX_RETRIES));

}

catch (Exception ex) {

}

}

public static long getWaitTimeExp(int retryCount) {

long waitTime = ((long) Math.pow(2, retryCount) * 100L);

return waitTime;

}

ok,就谈到这啦,源于自己认知的局限性,也许谈的一些地方会有错误之处,欢迎大牛指正。

拓展阅读:

https://en.wikipedia.org/wiki/Exponential_backoff

https://www.awsarchitectureblog.com/2015/03/backoff.html

打开手机看微信,加微信公众平台“Martin说”,每天收获更多Martin的闲扯。

原文出处:HugNew » 浅谈指数退避算法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容