• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

从高可用看待数据密集型应用系统的设计

武飞扬头像
HackDaily
帮助1

一、序言

在应用系统的设计上,会从可靠性、可扩展性、可维护性来评判一个应用系统的,其中,通过数据冗余可以提高系统的可靠性,数据冗余必然涉及到数据之间的复制。数据复制可以减少延时,使得数据与用户在地理上接近,比如CDN缓存的涉及;也可以提高系统可用性,即使系统额一部分节点出现了问题,系统也能继续工作;同时提高系统吞吐量,对于读请求可以伸缩横向扩展。

目前主流的复制模块有三种:主从复制、多主节点复制和无主节点复制,需要考虑采用哪种复制方式以及如何处理失败的副本,本文更多讨论的是主从复制,其他两种复制方式可以留意后续分享。

二、主从节点

每个保存完整数据集的节点叫做副本,有了多副本,如何保证所有副本之间数据的一致性,对于写操作,所有副本需要随之更新,最常见的解决方案就是基于主节点的复制(主从复制),主从复制的工作原理如下:
学新通
主节点接收客户端的读写操作,但从节点只能读。主从复制的设计有三种,分别是同步复制(全同步、半同步)和异步复制。各有各的特点,主要还是要看业务适合哪一种。以更新网站用户头像为例,可以看看包括客户端、主节点、从节点的时间节点顺序。
学新通
同步复制的优点是,一旦用户确认,从节点可以明确保证完成与主节点数据变更的同步,万一主节点发生故障,可以快读切换到从节点恢复业务。异步复制则主节点不会关心从节点的复制状态,存在数据丢失的风险,但是系统的吞吐性能最好。

出于数据安全的考虑,把所有节点设置为同步复制有点不切实际,任何一个同步节点的中断都会导致整个系统的阻塞。所以,在实践中,一般启用的同步复制像上图一样,其中某个从节点是同步的,而其他从节点是异步的,万一同步的从节点不可用或性能降低,则将另一个异步的从节点提升为同步模块,至少保证有两个节点拥有最新的数据,这种配置也叫半同步复制。

异步复制看起来有点不太靠谱,但并非没有系统再看,像MySQL,默认采用的复制是异步复制,可以修改为半同步复制。

三、新节点

如果系统需要增加新的节点数以提高吞吐量或者替换失败的节点,此时需要考虑新增从节点,如何考虑新加入的从节点跟其他节点的数据保持一直呢?

简单的思路是把数据从一个节点拷贝到新增加的节点,但着显然是不够的,因为数据一直在发生变化,会导致部分数据存在不一致。也可以直接锁定数据库,但这种操作往往需要涉及到停服务。好在可以做到不中断数据服务器的前提下做到节点扩容,操作步骤如下:
1:在某个时间点对主节点的数据副本产生一个一致性快照,避免长时间锁定数据库。
2:将快照传输给到新的从节点进行数据变更
3:从节点连接到主节点并请求快照点之后的数据变更日志
4:获取日志后,应用快照点之后的数据变更,这一步叫做追赶

接下来继续处理主节点的数据变更,重复1~4步骤,整体是全量 增量数据同步的思想。像MySQL主从节点的数据同步或者Redis主从节点的数据同步,都是这种依赖日志类似的处理方法,但日志文件有不同的叫法,MySQL的叫BinLog,Redis中叫做RDB和AOF。

四、异常节点

系统中的任何节点都可能因故障或维护而导致中断停机,高可用的目标是尽管个别节点出现终端,但要保证系统整体业务的可持续性,并尽可能减少中断带来的影响。这里主要考虑主节点和从节点异常的处理。

从节点失效处理方式比较容易。因为从节点保存了节点收到的数据变更记录,如果发生故障,从节点可以指导发生故障之前处理的最后一笔事务,连接到主节点后,可以请求自那笔事务之后中断期间所有的数据变更记录,收到数据变更后并应用到本地追赶主节点。增量同步的思想。

主节点故障处理方式比较麻烦,需要选择某个从节点切换为主节点,客户端也需要更新,这样写请求才会发送给到新的主节点;其他从节点也要接收来自新的主节点的变更数据主从切换可以手动执行也可以自动切换,自动切换步骤包含如下:
1:确认主节点失效。主节点失效的原因很多,比如断网、系统崩溃、停电等,没法明确知道原因是什么,大部分系统基于超时机制。节点之间频繁互相发生心跳存活消息,如果发现某个节点在一段时间内(比如30s)没有响应,则认为该节点失效。
2:选举新的主节点。可以通过选举的方式来选举新的主节点,例如Zookeeper采用半数投票机制,或者由之前选定的某控制节点来指定新的节点,例如Redis的哨兵模式。候选节点最好选择与原节点数据差异最小,像MySQL的MHA,当主节点异常,会选择同步最新的从节点升级为主节点。
3:重新配置系统是主节点生效。如果原主节点重新上线,可能自认为是主节点,而没有意识到其他节点已经逼迫他下台,此时系统要确保原主节点降级为从节点,并认可新的主节点。
学新通
上面的切换还是会存在很多变故,如果使用了异步复制,有可能切换的时候主从节点还没完成复制,此时原主节点又很快恢复并加入到集群,此时就会出现数据冲突的问题。常见的处理方案是,原主节点还没完成复制的数据丢弃,违背了数据更新持久化。同时在某些情况下,可能会出现两个节点都自认为是主节点,这种情况被称为脑裂,两个节点都能写入,数据会被被丢失或者破坏,目前没有很好解决冲突的方法,一般可以采用奇数节点部署去降低风险。而且如何设置合适的超时时间,也是一个值得思考的问题。

五、复制日志

主从复制对于底层的实现原理,在实践中有多种不同的处理方式。

基于语句的复制。在最简单的情况下,主库记录下执行的每个写请求并将该语句日志发送给从库。但是对于非确定性函数的语句,会在每个副本上生成不同的值,比如 NOW()、RAND();如果语句采用了自增列或者依赖于字段更新(比如UPDATE… WHERE <某些条件>),则必须在每个副本按照完全相同的执行顺序处理,很容易出问题。

基于预写日志WAL传输。对于写操作通常是追加到日志中,以Innodb为例,对于覆盖单个磁盘块的B树,每次修改会先写入预写日志(WAL),以便奔溃后可以恢复到一致的状态。所以,日志都是包含数据写入仅追加的字节序列,通过主库把日志发送给从库,可以使用完全相同的日志在另一个节点上构建副本。但也存在一些问题,复制与存储引擎紧密耦合,也导致了主库和从库需要运行相同版本的数据库软件,而且运维如果升级版本,可能需要停机。

基于行的逻辑日志复制。采用逻辑日志,可以把复制与存储逻辑分离。关系型数据库通常以行为粒度记录写入的序列。对于插入的行,日志包含所有列的新值;对于删除的行,日志包含足够的信息来唯一标识已删除的行,通常是主键。对于更新的行,日志包含足够的信息来唯一标识更新的行以及更新列的新值。通过逻辑日志与存储引擎分离,方便向后兼容,对于外部应用,逻辑日志也更容易解析。比如复制到数据仓库,或者自定义索引和缓存,被称为数据变更捕获。阿里开源的Canal框架就是通过MySQL增量日志解析实现的。

六、复制滞后

主从复制要求所有写请求经由主节点,而任何副本只能接受读请求。对于读操作比较多的系统,读写分离是一个不错的选择,能够减轻主节点的压力。在这种体系下,增加更多的从节点,可以提高系统的吞吐量。但这种方式也只能用于半同步、异步复制的模式。不幸的是,半同步、异步复制则主从之间必然存在数据复制的延时问题,会导致应用读取到过期的数据。举个栗子:

读自己的写。如果用户把数据提交到了主库,但是主从有延迟,用户马上看数据的时候请求的从库,会感觉到数据丢失。
学新通
用户发起写请求,然后再滞后的副本上读数据,此时需要写后读一致性,也称读写一致性。基于主从复制实现读写一致性,有几种处理方式:
1:用户访问可能会被修改的数据,则从主库读,否则,在从库读取。比如读个人资料都从主库读,读别人的资料可以读从库;
2:跟踪最近更新的时间,指定更新的时间窗口,如果更新后一分钟内,则总是在主库读;
3:记录一个时间戳,从库提供查询时,保证该时间戳前的变更都已经传播到了本从库,否则等待数据同步或者从另外的从库读;
4:如果副本分布在多数据中心,则比较复杂,必须先把请求路由到包含主库的数据中心。
如果用户可能在多台设备上访问数据,此时记录时间戳比较麻烦,不同设备可能路由到不同的数据中心。如果业务上要求数据实时同步,则需要读主库,就得把同一用户的请求路由到同一个数据中心。

单调读。用户可能会遇到时光倒流,第一次请求到从库看到了评论,第二次请求到另外一个从库发现评论消失。
学新通
单调读保证了这种异常不会发生,确保每个用户总是从同一副本来读取,比如基于用户ID散列来选择副本,而不是随机选。但是如果该副本失败,则需要路由到另一个副本。

同时,在应用系统中使用最终一致性的时候,需要事先思考:如果复制延迟几分钟甚至几小时,如果应用层行为不影响,那没有问题。反之,则需要考虑一个更强的一致性,比如读写一致性。当然,对于程序开发人员也不用过多担心,数据库已经帮我们提供了强有力的保证,这也是单节点事务存在的原因。

七、总结

很喜欢《数据密集型应用系统设计》里面说过的一句话:节点失效、网络不可靠、数据一致性、持久性、可用性与延迟性之间各种细微的权衡,实际也是分布式核心的基本问题。

事实上,很多系统在设计上都是殊途同归,然而这些也是值得我们去思考、学习、借鉴的地方。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggijcf
系列文章
更多 icon
同类精品
更多 icon
继续加载