@ironzhang
2017-06-15T01:38:56.000000Z
字数 1370
阅读 587
工作/mqtt
可伸缩的主要目标是接入节点可随着设备接入规模的增长而横向扩容。
高可用的主要目标是除接入节点外,其余服务节点的单点故障都不会造成服务的不可用,而接入节点的故障,只会对连接在该节点的设备造成影响,可通过客户端重连机制迅速连接到另一个接入节点,将故障影响降到最低。
分布路由模型
redis-cluster存储topic到mqtt-gateway节点的映射关系,每个mqtt-gateway节点负责维护自身订阅的topic并同步到redis-cluster,mqtt-gateway通过etcd同步彼此的状态信息。
在两种情况下,会存在mqtt-gateway中的本节点订阅的topic列表和redis-cluster中存储的不一致的情况,一是mqtt-gateway重启,这种情况可通过topic订阅节点离散淘汰删除机制来恢复一致性。另一种情况是,redis在修改数据后还未落地到磁盘然后宕机重启了,针对这种情况,可以在mqtt-gateway节点中针对topic设置一个校验一致性时间阀值,如果一个topic超过阀值时间没有收到任何消息,mqtt-gateway需要针对该topic发起一致性检验修复流程。
* topic订阅节点离散淘汰删除机制
topic到mqtt-gateway节点的映射关系在redis中按如下格式存储
<topic1, set(node1:timestamp, node2:timestamp)>
timestamp是mqtt-gateway在启动时记录的,在mqtt-gateway将自身节点添加到topic的订阅节点集合中时,会将timestamp作为节点信息的一部分记录在redis中。
任意一个mqtt-gateway在从redis-cluster中根据topic获取订阅节点列表后,需要对列表中的节点做筛选处理,具体方法如下:假设通过etcd同步的mqtt-gateway节点状态中,节点的启动时间戳为t1,列表的节点中的时间戳为t2,如果t1>t2,表明该节点经过重启,redis-cluster中存储的是过期数据,需要删除。我们通过这种离散的淘汰机制来避免停机或宕机时一次性地更新redis-cluster中topic的订阅节点集合。
问题:分布式模型在最坏情况下是我们有m个mqtt-gateway,1个topic被n个conn订阅,而这n个conn分布在了m个mqtt-gateway上,这种情况下分布路由模型的性能是等价于广播模型的。但物联网领域一个设备通常只属于一个用户,所以一个设备相关的topic通常很少被多个连接订阅。这种模型下最坏情况应当不会发生。此外我们还可以在负载均衡时通过对domain做hash,使同一domain下的设备连接集中在几台mqtt-gateway上,这也能避免这种最坏情况发生。