分布式系统之缓存的微观应用经验谈(二) 【主从和主备高可用篇】 (2)

      对于拓扑结构的设计,应用最多的就是单层拓扑,针对大量类似 keys全表扫描的操作,slave node会做到分担性能压力的作用。如果还想极致一些,把整体阻塞降到最低,可以将拓扑结构转换为树状,最简单的做法,将某个slave node直接转移到最底部,但会带来更多时效上的牺牲,所以需要考虑场景的接受程度了。同时,这里可能在具体架构落地的环节里,会比较分身乏术,需要开始考虑交由专业的运维来参与部署了,涉及上下节点间的通信、带宽监控、级联之间的复制问题,以及一些更独立的高频率统计和管理。ps下,这点一直作为备用,但在截止到目前的工作生涯里还没有找到必要的机会去采用。

 

      对于复制/同步数据本身,无论是全量、还是增量,由于异步性(个人认为不可能设计为同步)和一定的时效损耗,必定存在一个偏移值(offset)。以Redis举例,master node和slave node中,各自对自己的当前复制时的offset做记录,如果两个角色的偏移值存在较大差异(可参考查询对应repl_offset),那么大概率存在频繁的阻塞,包括网络和自身脚本命令的阻塞。一般内部网络都是专线环境,并且都是独立部署,所以优先排查命令执行效率,和不必要的扫描问题(可参考上篇讨论)。但是无论如何,延迟或者说偏移过大的问题,总不可能完全规避,所以在开发里要么利用专业的监控服务,要么使用不同驱动库定时判断,这也无疑增加了编码复杂度,哪怕一些开源库已经尽力做了一些工作。

 

  二、尝试谈谈相关的高可用(High-Availability)

 

    缓存既然作为一种通用的中间件(当然,某些场景里也可能是最后一层,见第一篇),决定了在诸多场景里其交互频率(包括QPS)大多远远高于其他服务,这就需要其具备极高的稳定性、可用性。个人在前面阐述了一些关于主从分离的细节,下面尝试谈谈相关的HA方案和一些思考。

 

    2.1 关于高可用说明

      这里声明下,我认为主从分离和高可用本质上是没有任何一丝关系的,只是有些刚刚好的作用使之结合形成了一些HA方案。

 

      前面提到过,单个相对可靠的缓存服务,除了本身所在服务器自身的内存负载,设计时更需要充分考虑网络I/O、CPU的负载,以及某些场景下的磁盘I/O的代价。而这些条件全部都会拥有瓶颈,除此,你永远无法避免的问题还有服务器造成的直接宕机、服务自身的缺陷造成的某些时候的不可用(单点问题)等等。一套相对能够落地的高可用缓存方案,必然还需要拥有足够健壮的承载和相对完善的内部故障转移机制,从而达到对外提供的是整套程序化的高可用的缓存服务。

 

    2.2 实现HA的原始步骤

      以Redis为例,其本身的设计已经足够优秀和成熟,但在负载过大导致延迟过高、甚至崩溃的过程里,比较原始的方式是这样去操作:将一个关联的备用 slave node升级为 master node,可以一个 slaveof no one 基本处理。然后分析是否还做了业务层面上的主从分离,如果存在,那么还需要手工修改其他slave node 里的旧 master node指向,映射为当前 master node。 最后,当master node 重新上线时,修改自身角色并重新加入集群。

    2.3 谈谈程序化HA方案的部分实践

 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfpxg.html