服务器程序中如何设计backup task功能
来源:互联网 发布:按键精灵脚本转换vb 编辑:程序博客网 时间:2024/05/10 07:46
retry
集群中有client、server1, server2三台机器,client需要向server请求数据,如果server1响应超时,则请求server2。server1、server2互为备份,包含同样的数据。
client:
- for (id = 0; id < 2; id++)
- {
- if (TIMEOUT == do_request(server[id], timeout, req) )
- {
- continue; // retry next server
- }
- }
timeout是外部传给client的总超时数。上面的代码有一个问题:当网络阻塞或者server十分繁忙的时候,do_request会超时,一旦超时,则总超时时间都被耗尽,根本没有剩余时间去重试下一个server。
因此,正确的retry设计需要考虑到“网络阻塞或者server十分繁忙”的情况,分给每个server的timeout时间只能是总timeout的一部分,代码改写如下:
- for (id = 0; id < 2; id++)
- {
- if (TIMEOUT == do_request(server[id], timeout * get_timeout_percent(), req) )
- {
- continue; // retry next server
- }
- }
不过,对于server挂掉的情况(socket层面无法连接)do_request请求这个server会立即失败,可以不设置timeout_percent。
Backup Task
Jeff Dean的一篇论文中介绍了Google利用backup request来大幅度降低响应延迟的问题,在论文中他将这种请求成为Tied Request。他在Achieving Rapid Response Times in Large Online Services这篇ppt中对此进行了专门的论述。
其原理很简单,还是用上一篇博客一个例子来简单阐述:
集群中有client、server1, server2三台机器,client需要向server请求数据,如果server1响应超时,则请求server2。server1、server2互为备份,包含同样的数据。client收到任意响应数据后立即通知其他请求过的server取消操作。
有两种设计方案:
方案一:
1. client向server1发出req请求,req在server1任务队列中排队
2. server1开始执行req,在执行前给client发一个quick response
3. client如果在超时时间内收到quick response则不发起backup task,否则client一旦超时,就立即发起backup task
3. client收到任意server的结果时,立即给其它所有发给过请求的server发cancel request
4. client先行退出
5. 对于执行任务的server,它如果及时收到了cancel request,则直接取消任务,如果收到不及时,任务已经开始,则还是老老实实做任务。任务做完后丢弃结果。
6. client收到过期的结果直接丢弃
方案二:
1. client向server1发出req请求
2. client等待超时,则立即向server2发req请求
3. 任意server返回了req结果,则发cancel request给其它相关server
4. client收到过期的结果直接丢弃
note:无论方案1还是方案二,实现这样的异步系统的时候都要很小心,一要防止内存泄露,一要方式提前析构导致野指针。
设计要点
设计Backup task的关键是要防止服务器繁忙时期的请求风暴。在服务器繁忙时期client容易发生等待超时,倾向于发送backup request。大量的backup request会进一步让服务器更繁忙,于是请求风暴诞生了。防止请求风暴的要点是区分普通超时和风暴期超时。
从统计的角度看,普通超时的模式与风暴期超时的模式肯定有很大区别,这是一个入手点。
从使用方式上,区分scan和get也可以一定程度防止请求风暴。在OceanBase中,get请求是对延迟敏感的,scan请求则要求低一些。而恰好get请求对系统的压力也小很多。所以,在OceanBase中可以只对get请求使用backup task。
小结
retry和backup task之前的区别在于retry不会给server发送cancel request。 0 0
- 服务器程序中如何设计backup task功能
- 服务器程序中如何设计backup task功能
- 服务器程序中如何设计retry功能
- 如何使用Delphi设计强大的服务器程序
- 如何使用Delphi设计强大的服务器程序
- 如何使用Delphi设计强大的服务器程序
- 如何使用Delphi设计强大的服务器程序
- 如何使用Delphi设计强大的服务器程序
- android backup功能介绍
- 跨服务器 backup
- 如何在PCB设计中增强防静电ESD功能
- 如何在PCB设计中增强防静电ESD功能
- 如何在自己的程序中加入宏的功能
- 如何在Java程序中实现FTP的上传下载功能
- 如何在单文档程序中实现TAB键功能
- 如何在程序中,实现比大小的功能
- 如何在Web程序中实现定时运行的功能?
- cinder-backup程序流程
- Ubuntu 16.04 64位中文版 配置 LAMP+phpMyAdmin PHP(7.0)开发环境
- 使用Intellij IDEA搭建Ext JsMVC web项目
- 关于希尔伯特变换的 c语言实现
- Git新手安装教程
- Linux初级 命令基本格式
- 服务器程序中如何设计backup task功能
- Ardupilot任务调度的理解
- Unity Shaders and Effects Cookbook (6-1) 使用 alpha 参数的 半透明着色器
- 算法练习-快速排序
- R学习笔记(4): 使用外部数据
- java支付宝
- JAVA从sqlserver2012数据库读数据并写出到Excel文件里
- 机器学习——Gradient Boost Decision Tree(&Treelink)
- Linux上vim编辑器缩进的设置(方便如书写python代码)