原文链接:http://highscalability.com/blog/2015/10/12/making-the-case-for-building-scalable-stateful-services-in-t.html
在很长一段时间内,分布式系统都采用无状态服务作为分布式系统扩展的最佳实践。它可以通过简单的循环负载均衡来提供扩展能力。它的缺点则在于数据中心之间复杂的一致性问题。
这里有一篇关于有状态服务(PPT)的分享。这篇分享介绍了基于Azure的Orleans开发Halo4的经验。Orleans基于有状态分布式的Actor模型,节点之间实现了高可用的Gossip协议,一个两层的一致性哈希加上分布式哈希表。基于这些方案提供节点动态负载均衡,动态扩缩容,热点平衡转移等等。
下面简单说一下如何使用有状态服务:
无状态服务带来额外开销
无状态服务可以通过添加节点来实现线性可扩展能力的提升。问题在于,我们开发的应用场景是有状态的,这意味着我们需要通过sharding或者NoSQL来实现扩容。这又丧失了关系型数据库关于强一致性的保证。
对于单个用户,经常需要把这个用户的所有请求路由到同一台服务器上,这样可以通过本地数据缓存的措施来减少IO开销。
集群信息:
静态配置 配置一份包含所有集群信息的静态文件分发到所有机器上,缺点在于不够灵活,线上发生故障需要手动调整配置,不支持动态扩容缩容。
Gossip协议 稳定状态下,系统中所有节点对于节点的健康状态能够达成共识,在发生网络分区或者节点加入/离开时,可能会出现短暂的不一致情况。
共识算法 保证所有节点的一致性,缺点在于可能会是整个系统速度的瓶颈。
路由策略:
随机路由 一般是根据机器的处理能力进行按处理能力的路由。
一致性哈希 问题在于可能会出现热点问题,需要精心选择哈希键。
3.分布式哈希表(DHT) 动态哈希表保存服务状态。
三个例子:
Facebook的Scuba
一个高速的基于内存的分布式数据库,使用了静态成员信息配置,写时采用随机分发策略,读取操作有中间件进行聚合返回,不保证可用。
Uber的Ringpop
Ringpop是一个实现了程序层级分片的node.js库,采用了Swim Gossip协议维护集群信息,这个协议基于AP所以不保证强一致性,一致性哈希负责处理请求路由,所以有可能出现热点问题。
微软的Orleans
Orleans是一个基于分布式系统的Actor模型,Actor是计算的核心单元,彼此之间使用异步消息通信,它持有一系列状态机所以本身是有状态的,Gossip协议负责集群信息,路由策略是一致性哈希与分布式哈希表的结合:当向集群发送对Actor的请求时,Orleans运行时将计算对Actor ID的一致哈希。哈希映射到具有该ID的分布式哈希表的计算机;Actor的分布式哈希表知道哪个机器包含指定ID的Actor。
有状态模型带来的挑战:
需要关注服务器内存状况,缓存建设问题,第一次链接问题等等。
原文地址:https://www.jianshu.com/p/fdfca8f5d9ec
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com