写在前面

B站挂了的那天,就想写写机房多活的文章,但考虑到这方面的技术面涉及比较广,一时无从下手就拖到了现在,未来会陆续基于“多活”这个话题聊一聊我的经验。

在互联网行业,一定规模的业务做“异地多活”都是标配了,做好“多活”价值很大,当然做好“多活”设计也很难,涉及到网络、数据、事务、冗余等各种挑战。需要解决多活带来的技术问题,比如“怎么保证跨机房数据的一致性”、“如何保证异地事务一致性”、“怎么在多个异地之间无缝切换”。

通用的多活架构

我们先看一个通用的多活架构图是什么样的,如下图所示:

上图可以看做是一个基于用户分区的架构,每个用户有自己所属的分区,在每个分区内有用户自己相关的主要数据。比如用户A主数据分区是A,用户B主数据分区是B。

用户可以就近接入离他最近的机房,Router层可以看做是一个Nginx or LVS的路由层,我们将路由规则下发到这层,基于用户数据(手机号、uid等)做hash,路由到不同的数据分区,应用服务与数据自闭环在分区内。

为提高分区的容灾能力,每个分区冗余另外两个分区的数据,比如A分区里面除了有自己的分区数据外,还有B、C分区的数据。

业务上的取舍

多活本质上也是可用性的一种保障机制,做好可用性,大家首先想到的就是冗余,而冗余是有成本的,成本包括资源成本和系统因为高可用复杂度提升的人力成本。

所以多活首先要做的就是服务分级,只有那些核心链路上的核心业务才有必要投入这些成本做多活。

也就是说:不是所有业务都需要做异地多活,核心业务才需要。

架构本质是取舍,我们看看如何基于核心业务场景做业务上的取舍。

想象一个问题,比如A用户本来的数据分区是A,但如果A挂掉了,想让A用户到分区B继续工作,由于数据同步是异步的,可能这时B里面并不是所有的A用户数据都有。

这个问题是常态,所以就需要考虑我们业务上是否可以低成本方式兼容类似的问题了。

以注册为例,如果A用户注册数据没有同步到B分区,那在B分区A用户就不能工作了吗?肯定不是。

在业务上让用户A在分区B重新注册就好了,这部分数据一致性与可靠性要求不高。通过这种方式,注册功能就无形中实现了“多活”。

所以让那些真正核心业务做好多活即可,以B站为例,登录、看视频是核心业务场景,充会员、打赏火箭有可能都不是核心业务,也不需要花费成本做多活了。

解决异地数据不一致的关键方案

上面的例子提到了,解决一些业务多活的方式可以是允许不同分区内存在数据不一致的情况,那如果故障恢复之后,如何解决不同分区下数据一致性问题呢?简单来说就是应该用哪份数据?

有可能后修改的数据由于分区之间异地延迟,导致先生效,反之也同样成立。

大部分场景此类问题解决起来并不复杂,可以看成以后修改的为准即可。但这个先后的判断,不能以时间看,因为不同机器、不同机房的时间可能是不准的,最好的方式是采用全局唯一自增id,类似于Snowflake方式,谁大依赖谁。

但需要考虑好这个唯一id生成服务的异地多活,我觉得还好,可以把这个id生成服务部署为分区内独立的,id生成就不存在冲突了。

解决数据不能实时同步的矛盾

做多活,还存在一个误区:“数据需要百分之百实时同步”。

这是不可能的,以北京到上海为例,网络传输延迟20~30ms,再加上上层业务处理的话,可能延迟在秒级,所以百分百实时同步数据是不可能的。

如何平衡业务上要求数据快速同步,而物理上做不到数据快速同步这个矛盾呢?

完全解决这个矛盾是不可能的,我们能做的就是降低这个矛盾:

  1. 尽量减小异地机房之间的距离,搭建专线;

  2. 尽量减少数据同步数量;

  3. 保障最终一致性,不保证实时一致性;

  4. 业务层面容错处理;

尽量减小异地机房之间的距离,搭建专线

减小异地机房之间的距离,可以采用同城双活的方式,就是在一个城市里面搭建多个多活机房,这样这些机房可以逻辑上看成一个机房。

这种方案的优点是:提高了性能;缺点是:不能做到城市层面的容灾。

尽量减少数据同步数量

由于数据同步需要占用机房之间专线带宽,所以尽量只同步需要的数据,不需要的不同步。

保障最终一致性,不保证实时一致性

既然物理上我们难以实现实时性,所以必须接受最终一致性这个事实。反映在架构上,就是我们需要面对最终一致性这个特点设计架构方案。

不同存储场景需要考虑不同最终一致性的时间窗口,是30ms、30s还是3小时,我们在技术层面需要根据不同的业务特点进行差异化的技术实现,以满足业务需求。

业务层面容错处理

将流量切到不同分区下,可以视为出现了系统故障。一般我们做降级、切流操作过程中,业务可能是有损的。也就是哪怕我们做了多活可用,也不能让业务实现百分百的可用性,很多时候我们只需要实现99.99%即可。

所以业务上需要针对于这个损失窗口做一定的容错设计,提高用户体验。比如分区内缓存兜底、用户动线跳转等,降低对于实时同步数据的依赖。

数据同步

通过上面内容可以看出来,做多活最重要的是对于有状态服务的处理,数据同步是实现多活方案的核心。

常用的中间件本身都具备一定的数据同步方案,比如mysql的主备复制、redis的cluster功能、es的集群功能,但仅仅采用这些存储中间件提供的复制功能是不能解决异地数据复制的问题的。

比如mysql的主从复制,大部分场景是满足的,但对于这种跨异地机房的数据同步场景来说,mysql单线程复制功能在网络抖动时经常发生延迟问题,短则十几秒,长则十几分钟。而且mysql主从复制出现问题时,尽管发现了,但是没办法快速通过扩容方式解决,只能干等。

Redis 3.0之前的主从同步方案存在一个问题,当从机宕机或者与主机断开重连时,会触发全量的主从复制,这时主机会生成大量内存快照,由于数据量大,同步恢复时间长,从机就不能对外提供服务了。

所以光依靠存储系统本身的同步复制功能,在一些场合是不满足业务需求的。特别是异地机房这种场景,宽带有限,长距离传输,网络抖动常态的情况下,光依靠存储系统的同步功能是不能实现多活的。

为解决以上问题,大部分场景还是需要基于MQ实现最终的异地数据复制。一方面自研更适合我们的业务场景,同时MQ本身具备很好的扩容能力,在同步数据有压力的情况下,可以快速进行扩容解决复制延迟问题。

其他数据同步方式:

  • 消息队列同步方式;

  • 二次路由方式:当消息队列同步延迟了,导致目标分区没有数据,可以强制读取原分区获取数据,当然这种只是解决流量进入错误的分区,而不是分区故障的路由;

  • 存储系统主从复制方式:为提高一个分区内多机房的可用性(一般是同城双活这种),可以采用存储系统的主从同步复制能力,比如mysql的主从;

  • 重新生成方式:还有一种方式,数据不需要做跨数据中心的数据同步,或者可以容忍数据同步的丢失或延迟,所以解法可以是数据重建。比如分区内的缓存数据,可以基于跨数据分区同步,也可以基于分区内元数据重建即可;

我们需要做到多活的百分百可用吗?

百分百可用不可用达到,没有任何一个系统可以承诺自己百分百可用。但如果有的业务要求百分百可用怎么办呢?

按照CAP定理来说,这属于CP系统,对于一致性要求高,那么只能舍弃A(可用性)了。

这种场景一般是银行类业务,比如小明办理了招商银行账号,想通过招行转账的话,需要确保招行数据中心是可用的。不然会出现数据不一致问题,解决允许转账再处理数据问题的成本远大于不让转账的成本与风险,不让转账是最合理的选择。

其实我们使用银行类APP转账时,可以看到他有自己的一些处理方式,比如交易时间内不允许操作,先锁金额记录流水再转账等。可以发现为了提高系统对于金钱的一致性处理,业务上牺牲了体验,但这种体验的缺失是可以接受的。

如果想让体验更好一点的话,可以做些降级层面的体验优化,比如挂公告:研发小哥哥在紧急处理问题哦,或做事后的优惠券补偿,这是我们经常采用的一种方式,给用户发券既可以提升体验,又可以增加转化率可能。

大厂架构都开始做机房多活了相关推荐

  1. 为什么大厂APP都喜欢做个「极速版」?

    不知道大家有没有注意到,很多APP都有个极速版本: 部分APP甚至有更多个版本,除了普通版.极速版之外,今日头条还有专业版.抖音还有火山版.快手还有概念版- 所以,同一个产品为什么要做多个不同版本呢? ...

  2. kepware怎么读modbus/tcp数据_多机房多活架构,究竟怎么玩?

    前情提要:<当年,我们是怎么平滑上云的?>一文中提到了上云的背景,将所有的系统,从一个机房,迁移到另一个机房.如上图:迁移之前,系统部署在机房A(M6)内,是单机房架构.迁移之后,系统部署 ...

  3. 如何带领团队“攻城略地”?优秀的架构师这样做

    阿里妹导读:架构师是一个既能掌控整体又能洞悉局部瓶颈并依据具体的业务场景给出解决方案的团队领导型人物.看似完美的"人格模型"背后,是艰辛的探索.今天,阿里巴巴技术专家九摩将多年经验 ...

  4. 运维工程师到底都在做些什么?

    我们群里最近讨论500台服务器安装系统的问题.我特意找了一篇高人写的文章来与大家分享,希望对大家能有所帮助哈!(以下为作者原文,未加任何修改哈) 看到chinaunix最近出的门户网站运维板块veyr ...

  5. 快手架构师:3亿日活的快手微服务架构实践!8页ppt分享

    点击"技术领导力"关注∆  每天早上8:30推送 作者| Mr.K   编辑| Emma 来源| 技术领导力(ID:jishulingdaoli) 本文整理了,快手基础平台架构师曹 ...

  6. Java 开发者每天都在做什么?

    作为一名 在大.中.小微企业都待过 的 Java 开发者,今天和大家分享下自己在不同公司的工作日常和收获.包括一些个人积累的工作提升经验,以及一些 Java 学习的方法和资源. 先从我的第一份 Jav ...

  7. 都是做游戏,为嘛国内外出来的产品相差这么大?

    游戏 国内外主流游戏的一个核心差别是,国内游戏玩的是成长乐趣,国外游戏玩的是体验乐趣. 国内游戏的乐趣在于升级,成长,比别人强,我每一刻所做的事情,本身并不一定让我觉得有乐趣,但是这件事会带来的结果, ...

  8. 图灵奖得主John Hennessy、David Patterson 访谈:未来小学生都能做机器学习

    来源:授权自AI科技大本营(ID:rgznai100) 本文约19300字,建议阅读15分钟. 本文针对今年三月获得 2017 年图灵奖的 John L. Hennessy. David A. Pat ...

  9. 学IT进大厂为何都选了超级实习生?

    CSDN推出了超级实习生计划,相信很多CSDN用户都收到了类似推广文案,对此抱有很大困惑,为何CSDN要推出超级实习生计划呢?为何学IT进大厂要选超级实习生呢? 超级实习生是什么呢? CSDN-超级实 ...

最新文章

  1. RecyclerView横向滑动与ViewPager冲突问题
  2. Science子刊:植物所杨元合组揭示矿物保护和微生物属性对冻土碳动态的关键调控作用...
  3. 机器学习--Gradient Boosting Machine(GBM)调参方法详解 转 面试问到的
  4. 深度学习核心技术精讲100篇(六)-keras 实战系列之知识蒸馏(Knowledge Distilling)
  5. android d-bus,android EventBus的使用
  6. redis分片_5000+字硬核干货!Redis 分布式集群部署实战
  7. java.lang.IllegalArgumentException: No enum constant org.apache.ws.commons.schema.XmlSchemaForm.
  8. 【转】javascript 只允许输入数字总结
  9. 经历一番波折后的fedora以及wireshark
  10. Secondary NameNode工作原理
  11. 红帽Linux如何设置root权限,LINUX下 一句话添加用户并设置ROOT权限
  12. Nginx正反向代理的具体步骤讲解
  13. QTP/UFT能捕捉到对象但是点击不了,录制点击也没反应
  14. sw2014计算机配置,solidworks配置要求高吗,solidworks需要什么样的电脑配置
  15. Python 模拟登录知乎
  16. codeforces 416C C. Booking System(贪心)
  17. mysql微擎用户名密码_微擎后台管理员密码忘记怎么办?教你一个简单的方法
  18. 复位IC,低电压检测IC PJ809
  19. 服务器ssl证书安装
  20. vivado2019.1开启代码补全和相同代码高亮

热门文章

  1. 【数学专题】整除相关 - 素数
  2. 【USACO training】Chapter 1 入门
  3. 【数据结构专题】线段树(一)
  4. 数据结构(C语言版) 第 八 章 排序 知识梳理 + 习题详解
  5. 徐直军 华为没有鸿蒙,华为徐直军:“鸿蒙”这个名字是媒体取的
  6. 手写堆模板(指针数组)
  7. web服务器和应用服务器的区别以及负载均衡---学习笔记
  8. C++11可变模版参数的妙用+ 认真分析mmap:是什么 为什么 怎么用
  9. mysql开启慢查询日志
  10. Python之旅.第十章.mysql