用户您好!请先登录!

分类目录分布式架构

分布式事务原理及实现方式

一个复杂的系统往往都是从一个小而简的系统发展衍化而来,为了满足日益增长的业务需求,不断的增加系统的复杂度,从单体架构逐步发展为分布式架构,而分布式系统架构的设计主要关注:高性能,高可用,高拓展,俗称的“三高”。

分布式事务(分布式系统中数据一致性问题)

高可用是指系统无中断的执行功能的能了,代表了系统的可用程度,是进行系统设计时必须要遵守的准则之一。

而高可用的实现方案,无外乎就是冗余,就存储的高可用而言,问题不在于如何进行数据备份,而在于如何规避数据不一致对业务造成的影响。

对于分布式系统而言,要保证分布式系统中的数据一致性就需要一种方案,可以保证数据在子系统中始终保持一致,避免业务出现问题,这种实现方案就叫做分布式事务,要么一起成功,要么一起失败,必须是一个整体性的事务。

阅读更多

Common Implementation of High Availability in Microservice Architecture

高可用并不是一套整体解决方案,而是由诸多环节组成,一环扣一环,最终串起来组成一个整个系统的高可用落地方案。

什么是高可用

在定义什么是高可用,可以先定义下什么是不可用,一个网站的内容最终呈现在用户面前需要经过若干个环节,而其中只要任何一个环节出现了故障,都可能导致网站页面不可访问,这个也就是网站不可用的情况。

参考维基百科,看看维基怎么定义高可用:

系统无中断地执行其功能的能力,代表系统的可用性程度,是进行系统设计时的准则之一。

这个难点或是重点在于“无中断”,要做到 7×24 小时无中断无异常的服务提供。

为什么需要高可用

一套对外提供服务的系统是需要硬件,软件相结合,但是我们的硬件总是会出故障,软件会有 Bug,硬件会慢慢老化,网络总是不稳定,软件会越来越复杂和庞大。

除了硬件软件在本质上无法做到“无中断”,外部环境也可能导致服务的中断,例如断电,地震,火灾,光纤被挖掘机挖断,这些影响的程度可能更大。

阅读更多

微服务分布式事务中的Saga模式

该文是基于《微服务模式》作者Chris Richardson的QCONSF 2017会议上的PPT文章(这里)和其 Eventuate Tram Saga框架之上,对Saga模式进行的原理性解说,其中包含banq个人经验总结和见解,请从批判性视角看待。Chris Richardson的另外一本书籍《POJO in Action》曾经是帮助Spring成功挑战了EJB2。

在微服务环境下为什么不能使用ACID事务?因为每个微服务都拥有自己的私有数据库,比如订单服务有自己的订单数据库,而客户服务有自己的客户数据库,如果有一个业务操作需要跨订单和客户一起操作,那么一般使用JTA+XA方式跨订单数据库和客户数据库操作:

@ Transactional //事务元注解
public void crossAction(XX){
    //事务开始

    //这里ORDERS是属于订单服务的私有数据库
    SELECT ORDER_TOTAL FROM ORDERS WHERE CUSTOMER_ID = ?

    //这里CUSTOMERS是属于客户服务的私有数据库
    SELECT CREDIT_LIMIT FROM CUSTOMERS WHERE CUSTOMER_ID=?

    INERT INTO ORDERS .....

    //提交事务

}
<p>

以上JTA操作如果结合XA数据源配置,将会实现2PC两段事务提交。

阅读更多

蚂蚁金服OceanBase的高可用及容灾方案

众所周知,作为生产系统中极为关键的核心软件,数据库产品的高可用性一直是使用者极为关注的功能点。尤其是在金融这样一个特殊的领域里,无论是从监管的要求来看,还是从业务需求本身来看,都需要提供24*7持续不间断的服务,这就对金融行业中数据库产品的高可用性提出了很高的要求,不但需要应对个别硬件故障的情况,还必须能够应对机房整体故障和城市灾难等极端情况,保证数据库在各种意外情况下都能持续提供服务,即具备机房级容灾能力和城市级容灾能力。

本文的主要目的,是总结和回顾一下传统数据库产品常用的高可用及容灾方案,并向读者介绍一下以OceanBase为代表的分布式数据库常用的方案,希望能够起到抛砖引玉的作用,引发读者关于新型分布式架构下高可用及容灾方案的思考。

阅读更多

系统单点那点事

系统的单点问题是高可用性和高性能的主要屏障之一,在软件系统架构中,为什么会存在单点?

  • 无意为之:存在设计缺陷,出现了单点;
  • 有意为之:简化系统设计,设置单点;

典型互联网高可用架构,哪些地方可能存在潜在单点?

典型互联网高可用架构:

  • 客户端,通过DNS,由域名拿到nginx的外网IP;
  • 反向代理,nginx是后端入口;
  • 站点应用,典型的是tomcat或者apache;
  • 服务,典型的是dubbo提供RPC服务调用,或者其它的RPC调用框架
  • 数据层,典型的是读写分离的db架构;

在这个互联网架构中,站点、服务、数据库的从库都容易通过冗余的方式来保证高可用,但:

  • nginx是一个潜在的单点;
  • 数据库写库也是一个潜在的单点;

哪些例子,因为设计需要,有意设置的单点?

在诸多的互联网框架中,不管是哪一类基础应用,一般都会有一个所谓的 Master节点,用来控制和调度,非常类似通信协议中的控制层协议,而为了简化,这类Master节点通常都设计为单点。这里就面临两个大问题:

  • 高可用问题:单点一旦发生故障,服务就会受到影响;
  • 性能瓶颈:单点不具备良好的扩展性,单点的性能上限往往就是整个系统的性能上限;

“高可用”问题通常怎么优化?

shadow-master是一种很常见的解决单点高可用问题的技术方案。shadow-master,顾名思义,它只是单点master的一个shadow(影子):

  1. master工作时,shadow-master只备份;
  2. master出现故障时,shadow-master会自动变成master,继续提供服务;

shadow-master它能够解决高可用的问题,并且故障的转移是自动的,不需要人工介入,但不足是它使资源的利用率降为了50%,业内经常使用keepalived+vip的方式实现这类单点的高可用。

除了GFS与MapReduce系统中的主控master,nginx和数据库的主库master亦可用类似的方式来保证高可用:

  1. 两个主库设置相互同步的双主模式;
  2. 平时只有一个主库提供服务;
  3. 异常时,虚IP漂移到另一个主库,shadow-master变成主库继续提供服务;

“性能瓶颈”的单点问题通常怎么优化?

有时候,单点设计是有意为之,此时单点的性能(例如GFS中的master)有可能成为系统的瓶颈,那么,减少与单点的交互,便成了存在单点的系统优化的核心方向。如何来减少与单点的交互,有两种常见的方法:

  1. 批量写;
  2. 客户端缓存;

如何利用“批量写”减少与单点的交互,提升整体性能?(可以参见ID生成器的例子)

如何利用“客户端缓存”减少与单点的交互,提升整体性能?

这类缓存的命中非常非常高,在99%以上(因为文件的自动迁移是小概率事件),这样与master的交互次数就降低了100倍。

批量写,客户端缓存,对性能的提升也有极限,单点性能优化还有没有其他方法?

以nginx为例,如何来进行水平扩展呢?

通过DNS轮询,在DNS-server,一个域名可以配置多个IP,每次DNS解析请求,轮询返回不同的IP,就能实现nginx的水平扩展,扩充负载均衡层的整体性能。

数据库单点写库也是同样的道理,在数据量很大的情况下,可以通过水平拆分,来提升写入性能。

分布式系统中的唯一id生成策略及实现

系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。生成ID的方法有很多,适应不同的场景、需求以及性能要求。所以有些比较复杂的系统会有多个ID生成的策略。

简单分析一下需求

所谓全局唯一的 id 其实往往对应是生成唯一记录标识的业务需求

这个 id 常常是数据库的主键,数据库上会建立聚集索引(cluster index),即在物理存储上以这个字段排序。这个记录标识上的查询,往往又有分页或者排序的业务需求。所以往往要有一个time字段,并且在time字段上建立普通索引(non-cluster index)。普通索引存储的是实际记录的指针,其访问效率会比聚集索引慢,如果记录标识在生成时能够基本按照时间有序,则可以省去这个time字段的索引查询。

这就引出了记录标识生成的两大核心需求:

  • 全局唯一
  • 趋势有序

阅读更多

分布式系统的本质之一(队列)

就我个人理解,分布式系统的核心也即整个网络编程的核心只有两个队列与调度,如果非常加上第三个就是监控。现在吹的天花乱坠的东西,早在几十年前,计算机的先行者们就考虑到了。

今天,谈谈分布式系统本质实现之一:队列

简单吧,换句话说,只要掌握了队列,就掌握了分布式系统构件方式。所有的分布式系统,不管规模大小,都是不同类型队列的堆砌而已。

那么队列是什么?

它既简单又复杂,在各个层次的描述并不一致。例如,我们从一个网站举例:

从宏观上来说它包含一个web服务器的消息处理队列,http消息到达服务器后是要排队处理的,这就是一个fifo队列;更进一步,如果这个网站的业务比较复杂,需要分布式部署,还需要像rabbitmq,kafka这样的队列服务器来分担应用层的压力,这也是一种高级的队列形式,提供的算法就不只是fifo可能还有广播,主题等特性。

我们进一步往下,下面就是操作系统了,操作系统跟队列有啥关系?或者跟并发有啥关系?可以说,一个系统的并发能力很大程度取决于os的设计。从网络协议栈的处理到进程线程的调度,到cpu cache相关的锁同步都直接或者间接跟os关系,毕竟程序写了千万条,最终在os才能执行。

阅读更多

高速服务框架 HSF (High-speed Service Framework)

高速服务框架 HSF (High-speed Service Framework)是阿里巴巴内部的分布式服务框架,是在阿里巴巴内部广泛使用的分布式 RPC 服务框架。

HSF 联通不同的业务系统,解耦系统间的实现依赖。HSF 从分布式应用的层面,统一了服务的发布/调用方式,从而帮助您方便、快速的开发分布式应用,以及提供或使用公共功能模块,并屏蔽了分布式领域中的各种复杂技术细节,如:远程通讯、序列化实现、性能损耗、同步/异步调用方式的实现等。

当年为何阿里选择了开源Dubbo而不是HSF,很大原因是因为Dubbo是阿里B2B团队开发的,而HSF是淘宝团队开发的,在当年的应用规模和用户基础上HSF明显胜出。以至于后期开源之后停止更新维护到这几年重启维护与后续开发很难说不是一种面子工程了,如今的开发团队也不是当年了。

阅读更多

美团即时物流的分布式系统架构设计

背景

美团外卖已经发展了五年,即时物流探索也经历了3年多的时间,业务从零孵化到初具规模,在整个过程中积累了一些分布式高并发系统的建设经验。最主要的收获包括两点:

  1. 即时物流业务对故障和高延迟的容忍度极低,在业务复杂度提升的同时也要求系统具备分布式、可扩展、可容灾的能力。即时物流系统阶段性的逐步实施分布式系统的架构升级,最终解决了系统宕机的风险。
  2. 围绕成本、效率、体验核心三要素,即时物流体系大量结合AI技术,从定价、ETA、调度、运力规划、运力干预、补贴、核算、语音交互、LBS挖掘、业务运维、指标监控等方面,业务突破结合架构升级,达到促规模、保体验、降成本的效果。

本文主要介绍在美团即时物流分布式系统架构逐层演变的进展中,遇到的技术障碍和挑战:

  • 订单、骑手规模大,供需匹配过程的超大规模计算问题。
  • 遇到节假日或者恶劣天气,订单聚集效应,流量高峰是平常的十几倍。
  • 物流履约是线上连接线下的关键环节,故障容忍度极低,不能宕机,不能丢单,可用性要求极高。
  • 数据实时性、准确性要求高,对延迟、异常非常敏感。

阅读更多

分布式全局唯一ID生成策略

“唯一ID”在应用程序中是一个很常见的需求,它用于唯一标识一个业务对象、一个资源、或者一个消息等等。在数据库中,唯一ID一般是用来做为一个数据的主键。看过前面介绍MySQL索引原理的文章的朋友应该知道,主键对于数据库的重要性不言而喻。

在单机场景下,要得到一个全局唯一的ID是非常容易的,你可以使用数据库的自增功能。

但是如果在分布式的场景下,想要构建构建一个全局唯一的ID就有些不一样。因为分布式系统一般是高并发场景,那自然不适合使用单机数据库的自增功能了。如果你的技术选型恰好是MySQL这样的“非分布式数据库”,那就得参考一下业界常见的分布式全局唯一ID生成策略了。

阅读更多

Raft 协议学习笔记

好久没有更新博客了,最近研究了Raft 协议,谈谈自己对 Raft 协议的理解。希望这篇文章能够帮助大家理解 Raft 论文。

Raft 是什么?

Raft 是一种分布式系统的一致性算法。

在分布式系统中,我们需要让一组机器作为一个整体向外界提供服务。由于在实际的条件下,我们认为每台机器都是不100%可靠的,随时都可能发生宕机。每台机器之间的通信也不是可靠的,可能发生通信的阻塞、丢失、重试。所以需要某些算法来保证在大多数机器都正常的情况下向外提供可靠的服务。

在 Raft提出之前,Paxos 已经被提出,但是 Paxos 相当复杂。Raft 的目标就是提出一种易于理解的分布式一致性算法。

阅读更多

基于 MySQL 主从模式搭建上万并发的系统架构

一、主从复制基础概念

在了解主从复制之前必须要了解的就是数据库的二进制日志(binlog),主从复制架构大多基于二进制日志进行。

1.1 二进制日志管理说明

二进制日志在哪?如何设置位置和命名?

在my.cnf文件中使用 log-bin = 指定;命名规则为 mysql-bin.000000 (后为6位数字)

二进制日志位置

mysql> show variables like '%log_bin%' ;
+---------------------------------+-----------------------------------------+
| Variable_name | Value |
+---------------------------------+-----------------------------------------+
| log_bin | ON |
| log_bin_basename | /application/mysql/data/mysql-bin |
| log_bin_index | /application/mysql/data/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |
+---------------------------------+-----------------------------------------+
6 rows in set (0.06 sec)

日志命名:

mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 2979 |
| mysql-bin.000002 | 120 |
+------------------+-----------+
2 rows in set (0.00 sec)

二进制日志记录什么?二进制日志中记录的是一个个完成的事件

阅读更多