View Source

{color:#666666}by {color}{color:#666666}陈思儒{color}

{color:#000000}在{color}{color:#000000}MySQL{color} {color:#000000}中在线对表对象做{color} {color:#000000}DDL{color} {color:#000000}操作是要锁表的,对可用性要求比较高而且应用变化又比较频繁的环境,这是个非常很糟糕的。{color}

{color:#000000}有同事在讨论{color}{color:#000000}Amoeba{color}{color:#000000}的时候提起了这个事情,并且给了一个很好的建议。{color}

{color:#000000}客户端与{color}{color:#000000}Amoeba{color}{color:#000000}的{color}{color:#000000}Connection{color} {color:#000000}(这儿称为{color}{color:#000000}ClientConnection{color}{color:#000000}) 跟{color}{color:#000000}Amoeba{color}{color:#000000}与{color}{color:#000000}mysql{color}{color:#000000}的{color}{color:#000000}Connection{color} {color:#000000}(这儿称为{color}{color:#000000}ServerConnection{color}{color:#000000})是完全不同的{color}{color:#000000}Connection{color}{color:#000000},他们之间并没有存在关系,只有在确定一条{color}{color:#000000}sql{color} {color:#000000}路由到具体的{color}{color:#000000}mysql Server{color}{color:#000000}的时候。那么{color}{color:#000000}ClientConnection{color} {color:#000000}才与{color}{color:#000000}ServerConnection{color}{color:#000000}建立一种{color}{color:#000000}Session{color}{color:#000000}。他们所有数据交互都通过这个{color}{color:#000000}Session{color}{color:#000000}进行数据包转发,这种{color}{color:#000000}query{color}{color:#000000}语句结束以后,他们之间的关系也将断开,{color}{color:#000000}ServerConnection{color}{color:#000000}也就回到了{color}{color:#000000}ConnectionPool{color}{color:#000000}等待下一次任务。{color}

{color:#000000}在{color}{color:#000000}Amoeba{color}{color:#000000}内部有一个虚拟的{color}{color:#000000}ConnectionPool{color}{color:#000000},这个虚拟{color}{color:#000000}Pool{color}{color:#000000}负责多个{color}{color:#000000}ConnectionPool{color}{color:#000000}的负载均衡、{color}{color:#000000}failOver{color}{color:#000000}。 {color}

{color:#000000} {color}{color:#000000}那么利用这个优点,{color}{color:#000000}Amoeba{color} {color:#000000}虚拟{color}{color:#000000}Pool{color}{color:#000000}可以将即将做{color}{color:#000000}DDL{color} {color:#000000}操作的{color} {color:#000000}mysql{color}{color:#000000}从这个虚拟{color}{color:#000000}Pool{color}{color:#000000}中{color}{color:#000000}disable{color}{color:#000000}掉。所有的{color}{color:#000000}query{color}{color:#000000}将转发至虚拟{color}{color:#000000}Pool{color}{color:#000000}中的其他{color}{color:#000000}Pool{color}{color:#000000}。{color}{color:#000000}DDL{color}{color:#000000}完毕以后,将其{color}{color:#000000}Enable{color}{color:#000000}回来。{color}

{color:#000000}{*}传统的{*}{color}{color:#000000}{*}F5{*}{color}{color:#000000}{*}设备为什么无法做到这种方式呢?*{color}

{color:#000000}对于客户端采用连接池直接连接{color}{color:#000000}mysqlServer{color}{color:#000000}的客户端来说,即使{color}{color:#000000}F5 Disable{color}{color:#000000}即将{color}{color:#000000}Online DDL{color}{color:#000000}操作的{color}{color:#000000}mysqlServer{color}{color:#000000}。也无法将存在的连接断开。除非强制性断开或者等待{color}{color:#000000}Pool{color}{color:#000000}的收缩(时间可能会相当长,时间不可控制){color}

{color:#000000}对非采用保持连接的方式倒是可以采用{color}{color:#000000}F5{color}{color:#000000}设备来控制,当不采用保持连接在应用性能上面将非常低下。创建连接的时间往往比一次普通的{color}{color:#000000}query{color}{color:#000000}时间要多上好几倍甚至{color}{color:#000000}10{color}{color:#000000}多倍。{color}

{color:#000000}* *{color}{color:#000000}{*}Amoeba{*}{color} {color:#000000}{*}要如何解决这个问题?*{color}

{color:#000000}目前有一个想法,由{color}{color:#000000}Amoeba Manager{color}{color:#000000}来统一管理一组配置相同的{color}{color:#000000}Amoeba{color}{color:#000000}。{color}

{color:#000000}Amoeba{color} {color:#000000}启动的时候将从{color}{color:#000000}Amoeba Manager{color}{color:#000000}读取配置。并且能够在{color}{color:#000000}Amoeba Manager{color}{color:#000000}上面进行实时对多台{color}{color:#000000}Amoeba{color}{color:#000000}进行管理(动态添加{color}{color:#000000}dbServer{color}{color:#000000}、{color}{color:#000000}disable/enable{color} {color:#000000}虚拟{color}{color:#000000}Pool{color}{color:#000000}中的{color}{color:#000000}DBPool{color}{color:#000000},动态修改{color}{color:#000000}QeuryRouter{color}{color:#000000}规则)。{color}

{color:#000000}那么在{color}{color:#000000}Online DDL{color}{color:#000000}的时候首先将其从虚拟{color}{color:#000000}Pool{color}{color:#000000}中{color}{color:#000000}disable{color}{color:#000000}掉,{color}{color:#000000}DDL{color}{color:#000000}操作完毕以后将其{color}{color:#000000}Enable{color}{color:#000000}。{color}