RYU多控制器小结
来源:互联网 发布:mac的airdrop在哪里 编辑:程序博客网 时间:2024/04/26 06:18
- 一多控制器需要同步的信息
- 二主从控制器工作
- 1主控制器模式数据同步
- 2主控制器模式功能执行
- 3从控制器信息同步
- 4主从控制器切换从控制器切换至主控制器
- 三各普通模块主要代码说明
- 四以后普通模块添加同步数据的方法
- 五多控制器与单控制器模式的切换
一、多控制器需要同步的信息
- 路由信息配置
- 单播路由算法类型
- 单播路由算法参数
- 多播路由算法参数
- ARP缓存表信息
- 主机发现信息
- 用于失效恢复的路由信息维护
二、主从控制器工作
由多控制器模块与zookeeper通信,获知当前控制器在zookeeper的角色(master or slave)。
本方案采用逻辑主从,即对于交换机而言每个控制器的角色都是EQUAL,但控制器依据自身的角色进行工作。
1、主控制器模式–数据同步
当zookeeper判断当前控制器为master时,多控制器模块向其他模块发送事件,通知其余模块当前控制器的角色。当packet_in模块得知当前为master时,开始处理交换机发送的packet_in消息;
路由管理模块、代理ARP模块以及主机管理模块发送EventCreateZnode事件至多控制器模块,由多控制器模块执行
@set_ev_cls(multictrler_event.EventLocked) def locked_handle(self, ev): self.logger.info("this controllers is:%s", ev.role) if ev.role is 'master': self.send_event_to_observers(multictrler_event.EventCreateZnode("arp_table", "")) self.send_event_to_observers(multictrler_event.EventWatchZnode("arp_table")) elif ev.role is 'slave': self.send_event_to_observers(multictrler_event.EventWatchZnode("arp_table"))
多控制器模块监听到EventCreateZnode、EventWatchZnode事件,并创建新节点,监听节点数据是否更新。
@set_ev_cls(multictrler_event.EventWatchZnode, MAIN_DISPATCHER) def handle_watch_znode(self, ev): flag = ev.flag watch_file = PATH + FILE_PATH + flag + ".json" fp = open(watch_file, 'w') fp.close() path = DATA_PATH + "/" + flag watch = Watcher(self, path, self.handle, self.role) # greenle = gevent.spawn(watch._watcher) # greenle.join() hub.spawn(watch._watcher)
本方案使用zookeeper的get方法,总节点取数据赖判断节点的数据是否更新。
def _watcher(self): """ While the node that will watch do not exist, the function will create zhe node. """ try: node = zookeeper.get(self.handle, self.path, self._watcher_cb) except zookeeper.NoNodeException: self.handler.create_znode(self.path, '', [ZOO_OPEN_ACL_UNSAFE], 0) node = zookeeper.get(self.handle, self.path, self._watcher_cb) if node[0] != '': flag = self.path[6:] data = eval(node[0]) self.dataupdate(flag, data)
若zk节点的数据有更新,则多控制器模块将zk节点的数据同步至本地文件中。
def dataupdate(self, flag, data): """ If data in zookeeper node has changed, controller whether master or slave will synchronize these data to local file. :param flag: arp_table, host_info ect. :param data: the data in zookeeper node :return: """ data_file = PATH + FILE_PATH + flag + ".json" fp = open(data_file, 'w') fp.truncate() fp.close() data = json.dumps(data) self.logger.debug("Data Synchronization: Flag:%s Data:%s" % (flag, data)) fp = open(data_file, 'w') fp.write(data) fp.close() if self.role == MASTER: return self.handler.send_out_event(multictrler_event.EventDataRecord(flag))
数据同步的重点是要找到普通模块所需同步数据的入口,即需同步的变量发生改变时,通知多控制器模块更新。
本方案中以ARP缓存表为例,在代理arp模块处理完arp报文后,将学习到的arp信息写入proxyarp类的arptable变量之后,发起EventSetZnode事件,将更新之后的arptable信息交由多控制器模块写入zk的节点。
def add_to_arptable(self, msg): """a interface to add new arp entry to ARPTable.""" arp_src_ip, eth_src = msg hub.spawn(self.arp_table.update_entry, arp_src_ip, eth_src) self.send_event_to_observers(multictrler_event.EventSetZnode(self.arp_table.to_json(), 'arp_table'))
2、主控制器模式–功能执行
若多控制器为master,则各模块按照正常的流程进行系统初始化以及交换机初始化。
3、从控制器–信息同步
若多控制器发出slave信息,此控制器为从控制器,从控制器将不处理packet_in等信息,只处理路由发现等控制器与交换机之间非业务的事件。 处于多控制器统一性考虑,从控制器也将不处理web发送的除GET以外的请求,所以在REST API函数上添加装饰器,多web的请求进行筛选。
装饰器函数如下:
class RoleCheck(object): def __init__(self): super(RoleCheck, self).__init__() def app_role(self, func): def wrapper(*args, **kwargs): func_self = args[0] req = args[1] if req.method != 'GET': if isinstance(func_self, OpenRainbowControllerBase): if func_self.inst.controller_role is not 'master': return Response(content_type='application/json', body=ec2json(RAEC.MULTI_CONTROLLER_SLAVE), status='404 Not found') rval = func(*args, **kwargs) return rval return wrapperrole_check = RoleCheck()
4、主从控制器切换–从控制器切换至主控制器
多控制器模块轮询查看当前控制器的角色是否改变,若已经从slave切换至master,则需及时同步信息,并接受网络中交换机发送的packet_in。
由于同步信息已同步至本地文件中,所以此时只需要从文件中读取信息即可。为确保模块功能明显,本方案中,将读取文件的工作交给多控制器模块。由各个需要同步的模块发出同步请求,多控制器读取文件,将文件信息发送给各普通模块,各模块依据信息格式将信息写入各普通模块的变量中。
三、各普通模块主要代码说明
为实现多控制器,各普通模块不需要做出太多的改变,只需依据当前控制器的角色进行简单的操作即可。 主要包含两部分,一是当收到EventLocked事件时声明本模块需要同步的变量并告知多控制器模块,由多控制器模块去创建或监听zookeeper节点; 二是当接受EventRoleChanged事件时,将本地文件写入内存。注: 由于更新本地文件时,多控制器模块会发送EventDataRecord事件,基于此可以实现实时同步数据到内存。但本方案未采用此方法。
@set_ev_cls(multictrler_event.EventLocked)def locked_handle(self, ev): self.logger.info("this controllers is:%s", ev.role) if ev.role is 'master': self.send_event_to_observers(multictrler_event.EventCreateZnode("arp_table", "")) self.send_event_to_observers(multictrler_event.EventWatchZnode("arp_table")) elif ev.role is 'slave': self.send_event_to_observers(multictrler_event.EventWatchZnode("arp_table"))@set_ev_cls(multictrler_event.EventRoleChanged)def role_change_handle(self, ev): arp_table = multiple_controller_api.handle_synchronize_request(self, 'arp_table') if len(arp_table) is 0: return arp_table = eval(arp_table) for arp_info in arp_table: ip = arp_info['ip'] arp_entry = arp_info['arp_entry'] self.arp_table.update_entry_with_entry(ip, arp_entry) self.logger.info("SYN arp table info success!")
四、以后普通模块添加同步数据的方法
1、在模块的_Event中声明EventCreateZnode、EventWatchZnode以及EventSetZnode事件; 2、添加EventRoleLocked事件处理函数:(代码如上); 3、添加EventRoleChanged事件处理函数并在函数中添加解析方法以及写入内存的代码。
五、多控制器与单控制器模式的切换
多控制器是为保持网络的可靠性而诞生,但若不需要多控制器模式,或者当前服务器未安装zookeeper环境,则需当前控制器运行与单一控制器模式下。本方案使用配置文件参数设置赖判断单控制器还是多控制器模式。配置文件字段【MULTIPLE_CONTROLLERS】multiple_controllers_module
为False时,多控制器模块判断单为单控制器模式,否则为多控制器模式。
1、单控制器模式;
此时并不与zk进行通信,直接判断此控制器的角色为master,并且普通模块以master的角色进行工作。此模式下多控制器模块不发送EventRoleLocked事件,因此普通模块也将不会发起同步信息。
2、多控制器模式;略
3、配置文件cfg;
cfg为控制流图,支持多个模块使用同一配置文件。RYU中cfg的用法,在此记录一下:
from ryu import cfgCONF = cfg.CONFmultiple_controllers_cfg_group = cfg.OptGroup( name='MULTIPLE_CONTROLLERS', title='multiple controllers options')CONF.register_group(multiple_controllers_cfg_group)CONF.register_opts([ cfg.IntOpt('controller-id', default=1, # seconds, should be larger than 1 second help='the number of multiple controller' 'should be larger than 1 second.'), cfg.IntOpt('connection-timeout', default=10, # seconds, should be larger than 1 second help='the timeout of connection between zk_client and zk_server' 'should be larger than 1 second.'), cfg.IntOpt('check-controller-role', default=1, help='the time of find the role of controller'), cfg.BoolOpt('multiple-controllers-module', default=True, help='controller working in multiple controllers or not.'),], multiple_controllers_cfg_group)
- RYU多控制器小结
- 控制器ryu安装
- ryu控制器的安装
- SDN控制器-Ryu简单使用
- Ubuntu14.04安装Ryu控制器
- Ubuntu14.04安装Ryu控制器
- RYU控制器代码解析-Hub
- RYU控制器代码结构的总结
- RYU控制器代码结构的总结
- Ryu控制器官方应用simple_switch_13.py解读
- SDN(二)使用Ryu控制器
- SDN,RYU 控制器报错解决
- Ryu控制器controller/event.py源码解析
- RYU控制器代码解析-简单交换机
- SDN控制器RYU基本功能验证详解
- Ryu控制器代码解析-DNS欺骗
- SDN/OpenFlow控制器RYU的简介、安装与使用
- SDN/OpenFlow之Ryu控制器的安装与使用
- Activiti如何替换已部署流程图
- JsHelper操作类实例
- Android6.0之AMS前奏
- Android性能优化之利用LeakCanary检测内存泄漏及解决办法
- CHAR、TCHAR和WCHAR
- RYU多控制器小结
- 紫书例题6-4 UVa 11988 ( 链表
- mysql悲观锁总结和实践
- struts2教程--标签库详解
- 每日刷题:lightoj-1004
- Android studio 通过以servlet搭建的服务器访问 PC端 mysql数据库(一)
- 安卓Studio上使用Git进行代码控制一
- Angular2环境配置
- 语音识别的解码器所生成的lattice,如何以可视化的方式展现出来