流量调度:不要将流量调度和服务治理混为一谈 (服务治理是流量调度的前提);主要功能;关键技术。
状态数据调度:完整解决数据 Scale 问题的应该还是数据结点自身,相应的技术方案。
流量调度(是内部的,更是外部接入层的事;中心之外的事,边缘计算,类似于 CDN 上完成的事)
服务治理(内部系统、中心的事),所以两个还是应该分开的。
一、流量调度的主要功能:
1.自动地进行流量调度,提升整个系统的稳定性;
2.让系统应对爆品等突发事件时,在弹性计算扩缩容的较长时间窗口内 、底层资源消耗殆尽的情况下,保护系统平稳运行,提高系统架构的稳定性和高可用性。
此外,这个流量调度系统还可以完成以下几方面的事情。
服务流控。服务发现、服务路由、服务降级、服务熔断、服务保护等。
流量控制。负载均衡、流量分配、流量控制、异地灾备(多活)等。
流量管理。协议转换、请求校验、数据缓存、数据计算等。
这些都应该是一个 API Gateway (API网关)应该做的事。
二、流量调度的关键技术
好的 API Gateway 需要具备以下的关键技术。
1.高性能。使用高性能的语言。
2.扛流量。需要使用集群技术,在集群内的各个结点中共享数据。像 Paxos、Raft、Gossip 这样的通讯协议 Gateway 需要部署在广域网上,集群的分组技术。
3.业务逻辑。简单的业务逻辑,像 AWS 的 Lambda 服务一样,可注入不同语言的简单业务逻辑。
4.服务化。通过 Admin API 来不停机地管理配置变更的,而不是通过一个.conf 文件来人肉地修改配置。
三、状态数据调度
最难办的就是有状态的服务了,保存一些数据,不能丢失的,需要随服务一起调度的。
把问题转移到了第三方服务上, Java中没有状态,但是 Redis 和 MySQL 有状态。
所以,分布式系统架构中出问题的基本都是这些存储状态的服务。数据存储结点在 Scale 上比较困难,成了一个单点的瓶颈。
四、分布式事务一致性的问题
要想让数据有高可用性,就得写多份数据,会导致数据一致性的问题;数据一致性的问题又会引发性能问题。
在解决一致性问题时,我们有一些技术方案。
Master-Slave 方案。
Master-Master 方案。
两阶段和三阶段提交方案。
Paxos 方案。
3 年前写的《分布式系统的事务处理》这篇文章。可看到各种不同方案的对比
分布式系统事务基本上都是两阶段提交的变种。阿里的 TCC–Try–Confirm–Cancel,或是我在亚马逊见到的 Plan–Reserve–Confirm 的方式,通过业务补偿,或在业务应用层上做的分布式事务的玩法,基本上都是两阶段提交(或变种)。
应用层上解决事务问题,只有“两阶段提交”这样的方式,数据层解决事务问题,Paxos 算法则是不二之选。
五、数据结点的分布式方案
数据存储结果有太多不同的 Scheme,有文件系统,有对象型的,有 Key-Value 式,有时序的,有搜索型的,有关系型的……这个“数据存储的动物园”中,基本上都在解决数据副本、数据一致性和分布式事务的问题。
比如:AWS 的 Aurora,改写了 MySQL 的 InnoDB 引擎。为了高可用的 SLA,写 6个副本。其不像MySQL 的通过 bin log 的数据复制,而是更为“惊艳”地复制 SQL 语句,使用各种 tricky 的方式来降低 latency。使用多线程并行、使用 SQL 操作的merge 等。
MySQL 官方也有 MySQL Cluster 的技术方案。MongoDB、国内的 PingCAP 的 TiDB、国外的 CockroachDB,还有阿里的 OceanBase 都是为了解决大规模数据的写入和读取的问题而出现的数据库软件。
文件存储的,需要分布式文件系统的支持。一个 Kafka 或 ZooKeeper 把数据存储到文件系统上。结点有问题时,再启动一个 Kafka 或ZooKeeper 的实例,也要把它们持久化的数据搬迁到另一台机器上。
(注意,虽然 Kafka 和 ZooKeeper 是 HA 的,数据会在不同的结点中进行复制,但是我们也应该搬迁数据,这样有利用于新结点的快速启动。否则,新的结点需要等待数据同步,这个时间会比较长,可能会导致数据层的其它问题。)
需要一个底层是分布式的文件系统,新的结点只做一个简单的远程文件系统的 mount 就可以把数据调度到另外一台机器上了。
解决数据结点调度的方案应该是底层的数据结点,业务层可以像操作单机数据库一样来操作分布式数据库,阿里的用于分库分表的数据库中间件 TDDL 都会成为过渡技术。
状态数据调度小结
应用层上的分布式事务一致性,只有两阶段提交这样的方式。
底层存储可以解决这个问题的方式是通过一些像 Paxos、Raft 或是 NWR 这样的算法和模型来解决。
状态数据调度应该是由分布式存储系统来解决的,这样会更为完美。但是因为数据存储的Scheme 太多,所以,导致我们有各式各样的分布式存储系统,有文件对象的,有关系型数据库的,有 NoSQL 的,有时序数据的,有搜索数据的,有队列的……
状态数据调度应该是在 IaaS 层的数据存储解决的问题,而不是在 PaaS 层或者 SaaS层来解决的。有三种方案:
1.使用比较廉价的开源产品,如:NFS、Ceph、TiDB、CockroachDB、ElasticSearch、InfluxDB、MySQL Cluster 和 Redis Cluster 之类的;
2.另一种是用云计算厂商的方案。
3.如果不差钱的话,可以使用更为昂贵的商业网络存储方案。