0%

6-横向扩展 集群化

横向扩展 集群化

为什么要微服务化

  1. 单机能提供的资源有限(primary)

一个物理机器的硬件资源,网络资源总是有限的, 可能需要多个机器才能支持需求.并且在GC的时候可能会stop the world. 将其余的线程暂停, GC线程启动, 对Eden区的对象做连通的计算. 对象目前是存活对象的图的予以保留, 对于在不在的予以清理.如果Survice的空间很大的话 那stop the world 所需要的时间也就会很长, 导致业务暂停的时间也会延长.

  1. 方便项目管理、发布测试等的流程的进行(secondary)

集群和集群内部节点的状态

集群就是一组可以互相通信的服务器, 他们向外界透明的提供一致服务. 集群可以动态的修改大小, 并且在发生错误的时候时候继续运行.集群需要具备两个功能

  1. 发现失败
  2. 集群中的所有成员最终能提供统一的视图

###失败检测

我们要知道集群中那些节点现在处于不能服务的状态, 我们就不把任务分配给这些节点了.在这里有若干的算法可以使用, 以下内容抄袭自分布式中几种服务注册与发现组件的原理与比较

  1. Eureka

    节点定时给注册中心发送心跳进行注册, 它会告知服务中心自己的ip port 以及自己的service-id (能提供怎样的服务). 注册中心在响应节点请求的时候告诉节点目前集群中存在的其他节点的信息.

    Eureka中没有使用任何的数据强一致性算法保证不同集群间的Server的数据一致,仅通过数据拷贝的方式争取注册中心数据的最终一致性,虽然放弃数据强一致性但是换来了Server的可用性,降低了注册的代价,提高了集群运行的健壮性。

  2. Consul

    Consul提供强大的一致性保证,因为服务器使用Raft协议复制状态 。Consul支持丰富的健康检查,包括TCP,HTTP,Nagios / Sensu兼容脚本或基于Eureka的TTL。客户端节点参与基于八卦的健康检查,该检查分发健康检查工作,而不像集中式心跳检测那样成为可扩展性挑战。发现请求被路由到选举出来的领事领导,这使他们默认情况下强烈一致。允许陈旧读取的客户端使任何服务器都可以处理他们的请求,从而实现像Eureka这样的线性可伸缩性.

    内部有若干的角色

    • Client:作为一个代理(非微服务实例),它将转发所有的RPC请求到Server中。作为相对无状态的服务,它不持有任何注册信息。

    • Server:作为一个具备扩展功能的代理,它将响应RPC查询、参与Raft选举、维护集群状态和转发查询给Leader等。

    • Leader-Server:一个数据中心的所有Server都作为Raft节点集合的一部分。其中Leader将负责所有的查询和事务(如服务注册),同时这些事务也会被复制到所有其他的节点。

    • Data Center:数据中心作为一个私有的,低延迟和高带宽的一个网络环境。每个数据中心会存在Consul集群,一般建议Server是3-5台(考虑到Raft算法在可用性和性能上取舍),而Leader只能唯一,Client的数量没有限制,可以轻松扩展。

所有的要求问询集群中状态的请求都会被发送到client. Client 不存储任何集群的的信息. 它会把请求转发给Server.Client之间通过gossip 来知晓目前集群中能够服务的Server有哪些.然后请求任何一个能够服务的Server.

Server分为Leader Server 和 Follower Server. Follower Server 只是Leader的copy. 所有的事务信息都是被Leader记录 然后通知到Follower的. 这里由Raft算法提供一致性保证.

示意图

  1. Zookeeper
  • Leader-Server:Leader负责进行投票的发起和决议,更新系统中的数据状态

  • Server:Server中存在两种类型:Follower和Observer。其中Follower接受客户端的请求并返回结果(事务请求将转发给Leader处理),并在选举过程中参与投票;Observer与Follower功能一致,但是不参与投票过程,它的存在是为了提高系统的读取速度

  • Client:请求发起方,Server和Client之间可以通过长连接的方式进行交互。如发起注册或者请求集群信息等。

在Akka cluster 中是通过Gossip 协议来同步事务的状态的. 每个节点都会监控它后面的节点(默认最大监控数量是5). 然后”邻居”把自己所知道的情况告诉自己的”邻居” 然后整个节点都知道了.

CAP

c为Consistency 一致性. A为Available 可用性. P为Partition Tolerance 分区容错性. 因为系统是不稳定的, 肯定是会P的.CAP 其实就是发生了不一致的情况P, 是要C还是要A. 对于一个事情, 比方说扣账户里面的余额, 减库存. 当发生了请求扣余额的动作超时的时候, 我们要怎么做. 减库存那就是选择了A, 如果是报错就是选择了C.

  • CP

    比方说一个系统有一个关系型数据库.leader和若干个follower. follower通过读leader的bin log 来实现数据的同步. 当leader不能工作的时候,那么整个系统也就不能处理请求了. 这个系统是是CP的.

  • AP

    比方说有一个存储单元, 里面有三个节点,他们都是互相独立的,我们可以访问当中的任意一个节点来获取数据.即使一个不能工作了,我们可以访问其他任意一个来获得数据.

  • CP和AP的着重程度是可以转变的

    比方说对于之前CP的情况,我们可以把follower当作是读库, Leader 当作是写库, 通过乐观锁来保证最终一致性.(update 的数量和期望的一致, 否则就说明这个数据从follower中拿到的不是最新的, 抛错). 对于AP的情况比方说当中的某个数据是需要被超过1/2节点所认可的.

Akka Cluster

分区与线性扩展

通过hash mode x = n来计算结果存放在哪个节点, 对于这个x可以适当的大于目前的值, 比方说64 或者128 然后定义结果在[a-b) 之间的分配到 1 , [b-c) 之间分配到2.

节点冗余

读取请求会发送到任意一个节点,该节点负责进行协调, 计算 partition key的哈希值, 然后把请求发送给实际存储数据的3个节点, 当至少两个节点返回结果成功,即成功.

获取Identity

1
2
3
Identify identify = new Identify(1);
Future future = ask(selection, identify, 1000);
return (ActorIdentity)Await.result(future, timeout.duration());