当前位置: 首页 > 科技观察

高并发整体可用性:大规模集群下的分片管理策略

时间:2023-03-21 19:49:19 科技观察

大型系统的分片部署是一个难点,不仅要考虑容灾和故障转移,还要考虑负载均衡和资源利用。本文从服务状态、故障转移、负载和资源利用等几个方面来解释它们的关系,带大家看看Facebook是如何面对这一挑战的。有状态服务部署应用服务按照类型一般可以分为两类:无状态服务和有状态服务。无状态服务其实是比较容易扩展的,可以通过流量路由等负载均衡的方式来实现;但是statefulservices并不容易,让所有的服务器一直持有所有的数据是不现实的。--散列是一种方案--比如一致的散列策略,部署数据散列。然而,一致性哈希也存在一些无法避免的问题,主要包括数据倾斜和数据漂移。虽然我们可以通过将某个节点的部分数据移动到其他节点来解决,但这需要一个非常细粒度的负载统计尺度来进行发现和测量。来源:百度百科另外,由于一致性哈希对多数据中心的支持不是很友好,比如想让某些地区的用户去特定的数据中心减少延迟,这种策略不太容易实现实施。--分片是另一种解决方案--它的目的是支持业务增长,应对系统的高并发和吞吐量。并且加载和使用更加灵活。来源:fbengineering数以万计的数据分散存储在多个数据库实例中,每个实例称为分片。另外,为了容错,每个分片可以有多个副本,每个副本可以根据不同的一致性要求分为一个主副本和一个副副本。然后,分片通过多种策略规范计算映射到服务器,为用户提供完整的服务。这些策略规范包括:不同的用户ID选择不同的服务分区,不同地理位置的请求分发到更近的数据中心等等。从这个需求来看,sharding比hashing更灵活,更适合大规模的业务部署。2故障是一种常态在分布式环境中,我们需要对故障有一个清醒的认识——故障的发生不应该看作是小概率事件,而应该看作是一种常态。这也是系统设计应该遵守的前提。这将使系统更加稳定。因此,服务的容错能力和故障恢复能力是实现服务高可用的关键。可以采取什么措施?--复制--数据和服务的冗余部署是提高容错能力的常用手段。比如服务主备和数据库主从。但是,在某些情况下,这种方法是可以协商的。如果单个故障域的故障会导致所有冗余副本宕机,那么复制的作用是什么?--Automaticdetection&failover--高可用性需要故障发现和自动检测机制。然后是故障转移。故障转移的速度决定了程序的可用性。那么,是不是所有的故障都要立即转移,才能达到最好的效果呢?甚至没有。如果新副本的建设成本非常高怎么办?比如要加载海量的数据资源等,在构建完成之前可能会恢复原来的故障机器。--Failover限流--一个服务宕机不是最可怕的,最可怕的是它能把整个链路都宕掉。就像上篇文章写的《Zookeeper引发的全链路崩溃》一样,级联问题绝对不容小觑!因此,在进行failover时,必须引起足够的重视,避免在脉冲流量下造成正常业务崩溃。3、资源宝贵,最好不要浪费。就算阿里有钱,每个季度都会有运维同学和商科同学。因为1%的CPU使用率,服务容器数量的分布存在很多来回博弈。当然商科学生认为机器越多越好,因为机器越多,单个节点失败的概率越低;而运维同学的任务是尽可能提高资源利用率。毕竟想买718和911的人那么多。。.难道你们都拿不到钱吗~--负载均衡--负载均衡是指在应用服务器之间连续均匀地分配分片及其工作负载的过程。它可以有效地利用资源并避免热点。异构硬件。由于硬件规格不同,服务所能承载的压力也不同,因此需要考虑硬件限制来分担负载。动态资源。例如,可用磁盘空间、空闲CPU等。如果将负载绑定到这些动态资源上,那么服务负载就不能在不同时间点泛化。--弹性扩展--很多时候,我们的很多应用都是为用户提供服务的。但是,用户的行为根据日程表现出一定的规律性,比如白天访问次数多,晚上访问次数少。因此,弹性计算实际上是一种在不影响可靠性的情况下提高资源效率的解决方案,即根据负载变化动态调整资源分配。4Facebook如何平衡以上需求[1]我们通常会看到不同的团队有不同的分片管理策略。比如本地生活有自己的一套外卖业务分片的管理容灾方案,大文娱乐也有自己的一套视频业务的分片管理。早期的facebook也是如此。不同的团队有自己的解决方案,但这些方案更侧重于解决故障转移和保证系统可用性,对负载均衡的考虑较少。这种方式其实不适合集团的资源利用和可操作性。基于这样的考虑,Facebook设计了一个通用的分片管理平台ShardManager,简称SM。..到目前为止,已经有数十万个应用被构建或迁移到分片管理器,在数十万台服务器上共构建了超过千万个分片副本。..那么,让我们来看看他们是如何做到的。1.基础架构分层设计facebook基础架构主机管理:主机管理,使用资源配额制度,管理所有物理服务器,为每个团队分配容量。容器管理:每个团队从下层获取容量后,以容器为单位分配给各个应用。分片管理:在底层提供的容器内为分片应用分配分片。分片应用程序:在每个分片中,应用程序被分配并运行相关的工作负载。产品:鞋面应用。2、ShardManagement整体架构来源:fb工程应用实现了shard状态转换接口(该接口由SM库定义,由应用程序实现),根据调度器的调用进行状态转换。应用程序向ZooKeeper报告服务器成员资格和活动状态。应用程序监控的自动态负载信息由ShardManagerScheduler收集。ShardManagerScheduler是协调分片转换和移动的中央服务。它收集应用程序状态;监控状态变化,例如服务器加入、服务器故障和负载变化;并通过对应用程序服务器的RPC调用来驱动分片状态转换,从而实现分片分配调整。ShardManagerScheduler将分片分配的公共视图发布到服务发现系统(保证自身的高可用性和可扩展性);服务发现系统将信息传递给应用程序的客户端以计算请求路由。那么,ShardManagerScheduler宕机了怎么办?首先,可以在内部进行分片扩容,保证其高可用;第二,从上面的设计来看,中央处理程序不在了,现在,应用仍然可以用现有的分片运行,业务不会因为中央处理单元宕机而受到影响。3.标准化分片管理为了实现上述架构,facebook定义了几个原语://分片加载statusadd_shard(shard_id)//分片删除statusdrop_shard(shard_id)//主从切换statuschange_role(shard_id,primary<->secondary)//验证和改变副本成员身份statusupdate_membership(shard_id,[m1,m2,...])//客户端路由计算和直连调用rpc_clientcreate_rpc_client(app_name,shard_id)rpc_client.execute(args)根据以上原语,通过组合,可以合成一个高级的分片移动协议:比如我们希望将分片A从当前负载高的服务器A移动到负载低的服务器B:Statusstatus=A.drop_share(xx);if(status==success){B.add_share(xx)}不仅是一个普通的服务,主从切换和paxos协议的服务管理都可以满足以上原语。有兴趣的同学可以自己尝试组合。这对我们工作中的系统设计很有帮助。那么,facebook在这种架构下是如何处理文章前半部分提到的分片管理的难点和问题的呢?对于容错中的复制,ShardManager允许你在每个分片上配置复制因子,以达到合理的复制,如果不需要复制,可以通过复制因子来控制;对于故障转移,ShardManager通过配置故障转移延迟策略来权衡构建新副本的成本和服务的不可用时间;对于故障节流,ShardManagerManager支持限制分片的故障转移速度,以保护其他健康的服务器不被淹没;对于负载均衡,ShardManager支持根据硬件规格自定义负载因子;通过周期性地收集应用各副本的负载,实现实例间的平衡;支持多资源均衡,保证短板资源可用。对于弹性,ShardManager支持分片缩放和扩展,针对不同的流量实现不同的扩展率。参考文献[1]fb工程:《使用ShardManager扩展服务》