快狗打车CTO 沈剑
快狗打车原名58速运,是同城即时货运平台。目前支持拉货、搬家和运东西等一些业务。本文讲述了快狗打车上云的缘由,如何平滑地、客户无感知地上云以及上云给快狗打车带来的价值。
我们先思考一些问题:为什么要上云?
第一,成本考虑:快狗打车作为初创公司,未必有资源组建大规模的运维团队,dba团队,sa团队,所以成本这块是我们考虑的。
第二,可用性考虑:我们可以自建机房,但目前我们没有信心比阿里云做的更好。
第三,扩展性考虑:快狗打车作为快速发展的公司,按需使用,对于机房的扩展性,对于机器的扩展性是有非常强的要求的。如果像传统的互联网公司,如果要扩容,可能需要季度初做预算规划,像一些大促活动,明天要做活动,今天就扩容。
最后,是服务能力考虑:不管是数据库、缓存、搜索、大数据、监控等等,如果我们从头都自己来的话,可能会比较耗费时间,而且搭建的服务可能也没有已有的云能力那么强。所以这里我们的结论是让专业的人做专业的事情,少造轮子,让我们就专注在业务研发,云的一些能力交给专业的云去做。
上云之前,看一下我们的架构,我们最早是在一个自建机房里面的。我们是一个典型的大规模的互联网应用,架构特点是并发量非常的高,流量非常的大,数据量非常的大。对于架构有可用性,扩展性的要求,而且我们实施的是微服务分层架构,整个在迁移之前,我们其实是一个单机房的架构,如果让我用一个词来形容的话,那就是全连。
大家可以看一下上面左边的架构图,我们原来在机房A。端上是我们的PC站、M站以及APP。然后我们的后端服务的这一块,整个机房的这一块分为了三层:
(1)站点层是我们所有的web应用;
(2)中间是服务层,我们有很多业务service,以及基础service;
(3)最底层是数据层,我们有数据库,数据库我们主要是用MySQL;我们有缓存,我们主要用的是memcached和redis;然后还有一些图片的服务。
为什么说它是一个全连的架构呢?你会看到我们的web层一个集群有多个节点,服务层一个集群有多个节点,你会发现它是一个节点会连接下层的所有节点,业务service调用基础service,一个节点会连接下层的所有节点,基础service调用数据层一个节点会连接下层一个集群的所有节点,所以它是一个全连的架构。
我们机房迁移的目标是什么呢?
上面右边的这幅图,左边的一半是我们原来的机房架构,另外一半可能最终我们要将我们所有的系统架构迁移到云上,迁移到云上你会发现从反向代理,到web,到业务service,到基础service,到db,全部要部署一套。最早的话是左边的一半,然后最终要到右边的一半。中间是专线和公网进行连接。在这个过程中,最难的,也是我们迁移的目标,是要平滑。因为牵扯几乎所有的业务,所有的部门需要联动,如何做到平滑、蚂蚁搬家式的迁移,并且保证这个数据的一致性,业务的一致性,流量的平滑,是我们机房迁移的首要目标。
我们如何做到平滑呢?
很容易想到的方案是,我们把所有的业务系统从站点层,到业务服务层,到基础服务层,到数据层,在阿里云全部部署一套,然后在某一个时间节点,旧机房终止流量,流量全部切到新机房。但是这种方案的风险极高,因为我们有非常多的业务,非常多的机器,可能站点都有几千个,服务可能有几百个,然后数据量也非常的大。如果一次性进行迁移出现任何问题的话,可能都会导致服务不可用。所以这种方案明显是不可行的。
我们所谓的平滑是什么平滑呢?我们所谓的平滑有4个特点:
第一,可分批。可以一个业务一个业务地迁移,我们大大小小可能有几十个业务,每个业务可能要有一些子系统,每个子系统是可以分批迁移的。
第二,可以分层迁移,就是对于同一个业务子系统,你可以先迁站点层,再迁业务service层,再迁数据service层,再迁数据层,可以分层的迁移。当然迁移的方向可能是自顶向下的,也可能是自底向上的,你可以先迁数据层,最后再迁应用层再切流量也是可以的。
第三,在任何一个步骤我们都要是可回滚的,任何一层在迁移的过程中可以随时切回流量,并且保证业务不受影响。
第四,整个过程中我们要不停止服务,整个过程对于用户是透明的,用户是无感知的,全部是保持HA的,这个是我们平滑迁移的目标。
要平滑的话,你会发现其实短暂的多机房架构是不可避免的,左边是我们最初的机房,右边可能我们要迁移阿里云,我们是蚂蚁搬家分模块分层地迁移,一定在中间有一个临时节点,两边的机房都有流量。这个过渡的过程,你会发现它其实是一个多机房的架构。
多机房多活的架构的特点是什么呢?用一个词来概括,其实是同连,你所有层次的连接,要连同一机房,站点层连服务层只能连同一机房,业务服务层连基础服务层只能连同一机房。但是这里面有一个问题就是数据层,你为了防止数据不一致,其实你只有一个写库,所以不可避免的有少量的请求必须跨机房,你不能够做到完全的同机房连接,但是我们能够做到最少的跨机房连接请求,所以你会发现整个过程它不是一个纯多机房多活的架构,是一个伪多机房多活的架构。纯同连的是有一部分,这架构图里面就是基础service调用数据库主库的时候,它是跨机房的,但是web层调用业务service,业务service调用基础service,基础service调用db,你会发现都是同机房连接的。这个多机房,或者叫伪多机房的多活的架构,它最大的关键词是同连,单机房的话其实是全连。
自顶向下的平滑迁移方案
我们知道了在迁移的过程中不可避免的有多机房的多活的一个方案,然后我们在制定平滑迁移方案的时候又有两套方案,一套是自顶向下的迁移方案,就是我们先迁站点层,再迁业务服务、基础服务,最后迁数据库。还有一种方案是自底向上的方案,可以先迁数据库,再迁基础service,再迁业务service,再迁web应用。两种方案都是可以的。然后我们实际采用的是自顶向下的迁移方案。
我们来看一下我们的迁移步骤,所谓自顶向下,那肯定是先迁上层的站点层和服务层。
我们的第一个步骤,左边是m6,是我们的旧机房,右边是我们待迁移过去的阿里云的机房。我们第一步,搭建相关的站点和服务,比如说你有一个业务模块想要迁移,你就在新机房搭建反向代理层、站点应用层,部署好后,搭建业务服务层、基础服务层,然后把DNS也提前做好。数据层你会发现此时是不变的,数据层和缓存层还是访问旧机房的服务。
搭建好之后,第二步逐步切流量。你把一个小的业务模块的流量的5%,切到了阿里云,然后这5%的流量会走阿里云的nginx反向代理层,web应用层Tomcat,业务服务层和基础服务层,但是你会发现它的缓存和数据库仍然是通过专线访问原机房的,因为此时缓存层和数据库层还没有迁移,也不会引发数据不一致。有一部分流量切到了阿里云的新机房,此时如果你发现异常,可以迅猛的将5%的流量切回来,这样的话其实整个业务又恢复了,因为整个数据还是在原机房的,发现问题可以随时回滚。如果没有问题,就逐步的放量,5%、10%、20%、50%、100%,把这个模块的所有反向代理、web应用、业务service和基础service就迁到了阿里云。这样的话你的一个小业务的站点层和服务层就迁移完了。迁移完之后,旧机房也不用急着下线,因为还预留了一个回滚的方案,你会发现这是一个蚂蚁搬家式的,你可以一个业务迁过去,再一个业务迁过去,再一个业务迁过去都是没有问题的。
先进行了站点层和服务层的迁移之后,接下来是缓存层的迁移。缓存层迁移之前,你会发现其实整个反向代理、站点应用、业务service和基础service的流量都已经到了阿里云上,相当于入口的所有流量都已经进了阿里云了,只是说你的缓存和db其实是通过专线访问的原来的机房。
缓存这里也是蚂蚁搬家分模块迁移,第一步,你先搭建某一个模块的缓存,在新的阿里云机房上搭建缓存,然后再切流量之前,你要把内网的缓存域名和IP进行修改。你的业务service和基础service是通过域名去访问缓存的,最早这个域名是指向旧机房的缓存,你要把它修改为指向新机房的缓存,修改完之后流量是不是就过来了呢?
并不是的,是因为缓存的连接,很多时候是长链接,你必须经过步骤三:切断原有的旧连接。相当于 service通过专线连接cache的连接你要切断,切断的话,其实缓存的客户端它会有重连机制,它会重新连接缓存域名,但是此时你已经将缓存域名切换到新机房阿里云上了,所以它会自动的连接阿里云上的缓存,这样的话缓存就切过来了。
你会发现这种方式它并没有进行缓存里的数据迁移,它只适用于允许cache miss的缓存,但是99%的业务场景是允许cache miss的。如果你缓存里这个为空,可以去数据库里去取相关的数据。这种方案还有一个好处,就除了它是按业务按流量逐步迁移,蚂蚁搬家式迁移之外,你会发现业务层是无需重启的,只需要运维统一操作,统一的修改内网域名的指向,统一的切断旧连接,重新指向新连接就可以了。就相当于业务的系统是不需要重启服务的,只需要配合观察业务的可用性和业务是否有异常就可以。
缓存层迁移完了之后,最后是数据层的迁移,数据层迁移你会发现迁移之前所有的站点服务和缓存都已经迁移完了,但是数据库的流量还是访问旧的m6机房的。此时你先要进行数据库的搭建和数据的同步,因为此时阿里云的rds上是没有数据的。没有数据,你就在阿里云上搭建rds建库建表,然后通过 dts或者是你自己的工具,将数据从原机房同步到阿里云上,在同步完成之前,还是依然是旧的机房的数据库提供服务的。
同步完成之后到某一个节点,你认为几乎同步上了,这个时候我们进行步骤三,原机房进行一个 read only 操作,不能让原机房的数据再进行修改了。Service修改配置重启指向阿里云的新机房,整个过程中可能有秒级的服务不可用,所以这个操作必须在流量低峰,凌晨的时候进行。秒级的 read only ,写不可用,以及秒级的流量切换,然后他也是可以支持蚂蚁搬家式,一个库一个库,一个子系统一个子系统地迁移的,所以风险也非常的小。
然后我们在迁移的过程中还发现了阿里云的工具的一些不足。这里也给阿里云提几个建议。DTS数据同步工具早期的话只支持公网的数据同步,通过专线进行数据同步,其实可以极大的提升数据同步的速度。第二个建议是好像rds是不能够支持定制化端口的,所以必须修改配置重启。像我们原来老机房数据库的端口是58885,但是迁移到阿里云就必须使用3200,这样的话你的业务服务必须修改配置,不能够通过像缓存一样统一的运维侧的切断重连。最后一个建议是如果DTS它支持数据库的这种Master-Master架构的话,其实风险会更小一点,现在好像是不支持的,如果支持Master-Master架构,那么其实原机房和阿里云机房做一个Master-Master架构,这样的话其实可以来回切可回滚,可能风险会更小。
我们通过这样的步骤,从站点层、服务层,服务层可能又分为业务服务层和基础服务层、缓存层以及数据库层,一步一步的蚂蚁搬家式的随时可回滚的高可用的、平滑的对业务无影响的,把整个大几百台服务上的所有站点、应用、服务、数据、缓存全部平滑的迁移到阿里云上,整个过程耗时了有一个多季度,四五个月,但是对业务对用户是透明的,是无感知的。
迁移完成之后,我们现在的话相当于整个业务是在云上了,我们后续有什么样的一些规划呢?方向上还是充分发挥云的优势。我们自身专注在业务研发上,让一些基础设施基础体系基础服务交给云去做,后续至少我们有两项计划,第一项我们原来的大数据体系也是自研的,有专门的团队,然后有专门的机器搭建了一些基础设施,后续也是计划全面的迁到阿里云上,用MaxCompute来替代,我们算了一下,应该成本能够节省不少,而且扩展性也比较好。第二块是原来我们在自己的机房上是有全套自研的监控体系的,包括调用链跟踪、服务的监控、一些基础资源的监控、机器运维层面的一些监控。我们现在也是准备切换阿里云的监控体系,当然现在还是在调研中,然后通过与阿里云的协作,给我们的业务也是带来了不小的价值,成本上有所降低,可用性加强了,扩展性,毋庸置疑,随时可以加机器,随时可以扩缩容。服务的能力也是非常强的。
最后总结一句话,还是让专业的人做专业的事情,少造轮子,让我们自身专注在业务研发中。
谢谢大家!
更多大数据客户实战案例:https://developer.aliyun.com/article/772449