写点什么

分布式系统关注点——“无状态”详解

  • 2019-01-24
  • 本文字数:2433 字

    阅读完需:约 8 分钟

分布式系统关注点——“无状态”详解

本文中我们开始聊一些让系统更简单,更容易维护的东西——“易伸缩”,首当其冲的第一篇文章就是“stateless”,也叫“无状态”。

一、初识“状态”

我们首先举个例子。


开发 Z 哥对运维 Y 弟喊:“Y 弟,现在系统好卡,刚上了一波活动,赶紧帮我加几台机器上去顶一下。”


Y 弟回复说:“没问题,分分钟搞定”。


然后就发现数据库的压力迅速上升,DBA 就吼了:“Z 哥,你丫的搞什么呢?数据库要被你弄垮了”。


然后客服那边接框也爆炸了,越来越多的用户说刚登陆后没多久,操作着就退出了,接着登陆,又退出了,到底还做不做生意了。


这个案例中的问题,产生的根本原因是因为系统中存在着大量“有状态”的业务处理过程。

二、“有状态”和“无状态”

N.Wirth 曾经在它 1984 年出版的书中将程序的定义经典的概括为:程序=数据结构+算法。(这个概括也是这本书的书名)


这是一个很有意思的启发,受它的影响,z 哥认为程序做的事情本质就是“数据的移动和组合”,以此来达到我们所期望的结果。而如何移动、如何组合是由“算法”来定的,所以 z 哥延伸出一个新的定义:数据+算法=成果。


通过程序处理所得到的“成果”其实和你平时生活中完成的任何事情所得到的“成果”是一样的。任何一个“成果”都是你通过一系列的“行动”将最开始的“原料”进行加工、转化,最终得到你所期望的“成果”。



比如,你将常温的水,通过“倒入水壶”、“通电加热”等工作后变成了 100 度的水,就是这样一个过程。


正如烧水的例子,大多数时候得到一个“成果”往往需要好几道“行动”才能完成。



这个时候如果想降低这几道“行动”总的成本(如:时间)该怎么办呢?


自然就是提炼出反复要做的事情,让其只做一次。而这个事情在程序中,就是将一部分“数据”放到一个“暂存区”(一般就是本地内存),以提供给相关的“行动”共用。



但是如此一来,就导致了需要增加一道关系,以表示每一个“行动”与哪一个“暂存区”关联。因为在程序里,“行动”可能是“多线程”的。


这时,这个“行动”就变成“有状态”的了。



题外话:共用同一个“暂存区”的多个“行动”所处的环境经常被称作“上下文”。


我们再来深入聊聊“有状态”。


“暂存区”里存的是“数据”,所以可以理解为“有数据”就等价于“有状态”。


“数据”在程序中的作用范围分为“局部”和“全局”(对应局部变量和全局变量),因此“状态”其实也可以分为两种,一种是局部的“会话状态”,一种是全局的“资源状态”。


题外话:因为有些服务端不单单负责运算,还会提供其自身范围内的“数据”出去,这些“数据”属于服务端完整的一部分,被称作“资源”。所以,理论上资源可以被每个会话来使用,因此是全局的状态。


本文聊的“有状态”都指的是“会话状态”。


与“有状态”相反的是“无状态”,“无状态”意味着每次“加工”的所需的“原料”全部由外界提供,服务端内部不做任何的“暂存区”。并且请求可以提交到服务端的任意副本节点上,处理结果都是完全一样的。


有一类方法天生是“无状态”,就是负责表达移动和组合的“算法”。因为它的本质就是:


  1. 接收“原料”(入参)

  2. “加工”并返回“成果”(出参)

  3.  

  4. 为什么网上主流的观点都在说要将方法多做成“无状态”的呢?

  5.  

  6. 因为我们更习惯于编写“有状态”的代码,但是“有状态”不利于系统的易伸缩性和可维护性。

  7.  

  8. 在分布式系统中,“有状态”意味着一个用户的请求必须被提交到保存有其相关状态信息的服务器上,否则这些请求可能无法被理解,导致服务器端无法对用户请求进行自由调度(例如双 11 的时候临时加再多的机器都没用)。

  9.  

  10. 同时也导致了容错性不好,倘若保有用户信息的服务器宕机,那么该用户最近的所有交互操作将无法被透明地移送至备用服务器上,除非该服务器时刻与主服务器同步全部用户的状态信息。

  11.  

  12. 但是如果想获得更好的伸缩性,就需要尽量将“有状态”的处理机制改造成“无状态”的处理机制。

三、“无状态”化处理

将“有状态”的处理过程改造成“无状态”的,思路比较简单,内容不多。


首先,状态信息前置,丰富入参,将处理需要的数据尽可能都通过上游的客户端放到入参中传过来。



当然,这个方案的弊端也很明显:网络数据包的大小会更大一些。


另外,客户端与服务端的交互中如果涉及到多次交互,则需要来回传递后续服务端处理中所需的数据,以避免需要在服务端暂存。



(橙色请求,绿色响应)


这些改造的目的都是为了尽量少出现类似下面的代码。


func(){    return i++;}
复制代码


而是变成:


func(i){    return i+1;} 
复制代码


要更好的做好这个“无状态”化的工作,依赖于你在架构设计或者项目设计中的合理分层。


尽量将会话状态相关的处理上浮到最前面的层,因为只有最前面的层才与系统使用者接触,如此一来,其它的下层就可以将“无状态”作为一个普遍性的标准去做。


与此同时,由于会话状态集中在最前面的层,所以哪怕真的状态丢失了,重建状态的成本相对也小很多。


比如三层架构的话,保证 BLL 和 DAL 都不要有状态,代码的可维护性大大提高。


如果是分布式系统的话,保证那些被服务化的程序都不要有状态。除了能提高可维护性,也大大有利于做灰度发布、A/B 测试。


题外话:在这里,提到做分层的目的是为了说明,只有将 IO 密集型程序和 CPU 密集型程序分离,才是通往“无状态”真正的出路。一旦分离后,CPU 密集型的程序自然就是“无状态”了。


如此也能更好的做“弹性扩容”。因为常见的需要“弹性扩容”的场景一般指的就是 CPU 负荷过大的时候。


最后,如果前面的都不合适,可以将共享存储作为降级预案来运用,如远程缓存、数据库等。然后当状态丢失的时候可以从这些共享存储中恢复。


所以,最理想的状态存放点。要么在最前端,要么在最底层的存储层。


四、总结

任何事物都是有两面性的,正如前面提到的,我们并不是要所有的业务处理都改造成“无状态”,而只是挑其中的一部分。最终还是看“价值”,看“性价比”。


比如,将一个以“状态”为核心的即时聊天工具的所有处理过程都改造成“无状态”的,就有点得不偿失了。


2019-01-24 09:307680

评论 3 条评论

发布
用户头像
那像flink这样的有状态的流式计算,是不是就是 io密集和cpu密集没有分开呀
2019-09-30 22:29
回复
用户头像
写的很好,不知道什么时候能出下一期?
2019-04-16 21:18
回复
用户头像
学习了
2019-03-05 08:50
回复
没有更多了
  • StatePattern- 状态模式

    状态模式(State Pattern):又称为状态机模式(State Machine Pattern),是允许对象在内部状态发生改变的同时改变对象的行为,使得看起来像是修改了类一样,其核心就是给每一种状态绑定一种行为。

    2022-06-05

  • 状态机的概念与设计

    一般情况下,状态触发器的数量是有限的,其状态数也是有限的,故称为有限状态机(Finite State Machine,简称为FSM)。状态机中所有触发器的时钟输入端被连接到一个公共时钟脉冲源上,其状态的转换是在同一时钟源的同一脉冲边沿同步进行的,所以它也被称作时

    2023-02-09

  • CSS 之选择器(二)

    我们还是进行上一篇的内容,继续我们的 CSS 选择器分类说明,今天要介绍的是我们的条件选择以及状态选择器,条件选择器,可能平时开发的时候接触的比较少,但是状态选择器,你肯定经常会遇到,尤其在表单的填写上,比如说:focus,:valid,接下来,就让我们

    2021-12-10

  • 聊聊 Vuex 原理

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。如果你已经灵活运用,但是依然好奇它底层实现逻辑,不妨一探究竟。

    2022-11-04

  • 了解 Session、LocatStorage、Cache-Control、ETag

    由于 HTTP 协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是 Session. 典型的场景比如购物车,当你点击下单按钮时,由于 HTTP 协议无状态

    2022-06-14

  • React 源码分析 8- 状态更新的优先级机制

    这是我的剖析 React 源码的第二篇文章,如果你没有阅读过之前的文章,请务必先阅读一下 第一篇文章 中提到的一些注意事项,能帮助你更好地阅读源码。

    2022-12-12

  • 05. 产品经理要时刻扪心自问的四个问题

    2023-10-17

  • 课件资料

  • 1. 状态与状态空间

    2023-09-26

  • 5. 动态规划总论:状态设计的要点和技巧

    2023-09-27

  • react 源码解析 12. 状态更新流程

    1.开篇介绍和面试题

    2022-04-14

  • 数字经济的重要基石——数据安全

    数据安全是指通过采取必要措施,确保数据处于有效保护和合法利用的状态,以及具备保障持续安全状态的能力。

    2022-03-26

  • 接口调试时如何请求一个需要登录才能访问的接口

    在后台在开发、调试接口时,常常会遇到需要登陆才能请求的接口。比如:获取登陆用户的收藏列表,此时,我们就需要模拟登陆状态进行接口调试了。今天,我们讲解利用Apipost的环境变量,解决这种需要先登录再请求的接口依赖情况。ApiPost提供了2种方案

    2023-02-17

  • React-hooks 面试考察知识点汇总

    在组件之间复用状态逻辑很难

    2022-11-01

  • JUnit 中的设计模式(下)

    2022-09-10

  • 17|应用状态管理(下):该用 React 组件状态还是 Redux?

    这节课,我们会把Redux与React结合起来使用,看看它能为React的状态管理带来什么好处,同时也要探讨什么时候该用Redux,什么时候用React内建的state,更或者,是否可以混用两种状态管理。

    2022-10-08

  • react 源码解析 12. 状态更新流程

    1.开篇介绍和面试题

    2021-12-15

  • 聊聊 Vuex 原理

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。如果你已经灵活运用,但是依然好奇它底层实现逻辑,不妨一探究竟。

    2022-10-10

  • 深入了解 Flutter 的状态管理机制(上)

    因此,本篇引入了一个 ModelBinding 类,通过继承 InheritedWidget 来实现子组件可以直接访问上级组件的状态,从而避免了状态参数的层层传递,也能清晰地了解状态管理的机制。

    2022-05-09

  • React 源码分析 8- 状态更新的优先级机制

    这是我的剖析 React 源码的第二篇文章,如果你没有阅读过之前的文章,请务必先阅读一下 第一篇文章 中提到的一些注意事项,能帮助你更好地阅读源码。

    2022-11-08

发现更多内容

【案例分析】一个小型数据管理系统

贺公子之数据科学与艺术

【论文速读】 | AI驱动修复:漏洞自动化修复的未来

云起无垠

怎样降低LED显示屏模组的成本

Dylan

科技 LED显示屏 户外LED显示屏 led显示屏厂家 户内led显示屏

成功入选CVPR2024!毫末提出一种基于摄像头的4D占据网格预测的Cam4DOcc新方案

极客天地

NineData与OceanBase携手完成产品兼容认证,共筑企业级数据库新生态

NineData

数据库 oceanbase 兼容 NineData 奥星贝斯

从原理到实践,拆解人工智能的神秘面纱

测吧(北京)科技有限公司

测试

Apps分类:深度解析多维度标准与应用领域

天津汇柏科技有限公司

创业 软件开发 小程序开发 app定制开发 软件开发定制

程序员有哪些常用的技术网站呢?

小齐写代码

专为大模型训练优化,百度集合通信库 BCCL 万卡集群快速定位故障

百度Geek说

从原理到实践,大咖带你拆解人工智能的神秘面纱

霍格沃兹测试开发学社

康士柏四驱版2000马力机,助你玩转改装界

极客天地

AI加速“应用现代化”,金融核心系统转型正当时

华为云开发者联盟

云计算 华为云 华为云开发者联盟 华为云CodeArts 华为云盘古大模型

用几张图实战讲解MySQL主从复制

华为云开发者联盟

后端 开发 华为云 华为云开发者联盟

让运维无忧,实战解析巡检报告功能实现方案

袋鼠云数栈

大数据 运维 大数据运维 巡检报告

OpenTiny 妇女节限时特别活动来啦~

OpenTiny社区

开源 Vue 前端 低代码 组件库

Golang微服务对接Spring-Cloud Gateway

于顾而言

golang Spring Cloud Gateway #微服务

京东JD商品详情API引领电商智能化新潮流

技术冰糖葫芦

API 接口

QCN9274/WiFi 7: Exploring the cornerstone of the next generation of digital life

wallysSK

浅谈漏洞扫描技术

于顾而言

网络安全 云安全 漏洞扫描 漏洞检测 web漏洞

智能便捷|AIRIOT智慧充电桩管理解决方案

AIRIOT

物联网平台 智慧系统 智慧充电桩

读架构整洁之道的一些感悟

于顾而言

架构设计 架构设计原则 编程范式

速存,详细罗列香橙派AIpro外设接口样例大全(附源码)

华为云开发者联盟

开发 华为云 开发板 昇腾AI处理器 华为云开发者联盟

分布式系统关注点——“无状态”详解_后端_张帆_InfoQ精选文章