网易首页 > 网易号 > 正文 申请入驻

高可用系统4大原则之一:无状态服务vs有状态服务

0
分享至

本文内容较多,分为如下部分

  • 无状态服务和有状态服务定义

  • 无状态服务应用场景

  • 有状态服务应用场景

  • 有无状态俩种服务的架构质量对比

  • 实现有状态服务的挑战

  • 有状态服务重构成无状态服务

警告:任何情况下都优先考虑使用无状态服务,即使你阅读本文,包括以后写的有状态服务实现模式后。

高可用4大原则我自认为分别是 端到端[1],有状态vs无状态[2],可观测,万一,其他微服务框架,容器化我认为是次要的。

分布式系统里,节点服务包含了业务处理数据俩部分, 如果数据是从持久化系统加载,则认为是此节点是状态的。 如果数据常驻于节点内,业务逻辑是从外部加载进来的,则认为是有状态节点。


state_definition

绝大多数系统都是无状态服务,服务不需要在服务本地(JVM)记录同一个客户端(如用户,设备,或者其他作为客户端的服务等)请求的的历史状态或者记录客户端的信息,服务需要的这些数据将从数据库或者Redis,MongDB加载。这些服务类似如下

  • 登录服务,服务节点根据请求用户名,从数据库查询用户名和HASH后的密码,然后判断请求的密码是否与数据库查询的密码一致

  • 搜索服务 ,服务节点会把查询条件转为ElasticSearch查询JSON,请求Elastic Search查询结果。

  • 电商中库存查询,服务节点会根据商品SKU以及查询所在的地区,查询存放在Redis的库存信息。同时库存服务节点也会请求商品查询服务查询商品的名称和价格等信息。

  • 物联网中查询家庭设备的状态,服务节点会查询俩个Redis,一个是缓存设备信息的Redis,一个设备在离线状态的Redis

无状态服务的技术实现非常成熟,如果你的服务是无状态,仅仅需要增加节点既可实现系统高可用和高性能。 如下图,代理服务采用轮询(Round Robin)或则随机,对于客户端C,每个服务节点都能提供服务。如果需要扩容,简单增加服务节点4即可。


state_stateless

需要注意的是,随着流量增加,而服务节点增加,导致代理服务和数据库本身可能是高可用高性能的瓶颈。因此代理服务和数据库节点也应该支持扩展节点

无状态服务的主要优点

优点

实现简单

像编写CURD代码那样简单

扩容简单

增加节点即可,代理服务可以使用轮询,随机等路由技术实现。

与无状态是服务对应的是有状态服务,要求服务端记录同一个客户端的交互历史数据和状态数据,有状态服务通常从外部加载执逻辑而不是数据。比如

  • 用户前端流程表单在最终提交前保留在服务端的临时表单数据

  • 用户登录后的会话信息放在Session,Session信息存放在JMV内存里

  • 物联网的接入网关,需要记录长链接到此网关的设备的版本信息。网关服务有可能加载规则脚本,规则引擎会根据设备上报的数据来执行特定的业务逻辑

  • 游戏服务,一群用户会被路由到特定的地图服务器上协作完成游戏

  • 通过互联网协作编写一份文档

  • 导航系统,用户的信息和旅程信息都在一个服务器上。实时导航信息也在这一台服务器上更新

  • Zookeeper 内存中保持的有ZTree数据结构,它通过ZAB协议保持所有节点数据都一致。

  • Redis 本身也是有个有状态服务节点,它支持在内存存储各种数据结构以及加载执行脚本。它通过从节点来实现高可用

有状态需要客户端始终连接到同一个服务节点(持久化连接),需要客户端或者代理服务采取的路由策略保证同一个客户任何请求都在同一个节点执行,比如来自同一个IP的用户


state_statefull.png

有状态服务的主要优点如下

优点

高性能

主要避免了从数据库加载数据的延迟; 也避免了从持久化系统反复加载数据,比如节点1加载数据执行业务逻辑完毕后,当请求路由到节点2的时候,又会在节点2再次加载同样数据

任意状态数据结构

不再需要持久化系统保存状态数据,其状态不限制于JSON,表数据结构。

CAP

分布式常见的AP能得到满足外,由于数据在同一个节点,其C也能满足。需要注意,但是如果主节点宕机(或者客户端认为C宕机路由到从节点),从节点接管,则C不成立。

避免使用性能不佳的数据库

无状态服务的扩容,也会导致其用的数据库节点扩容。无状态节点因为不需要数据库,则省去了数据库的使用成本,以及其导致的性能瓶颈

有状态服务不难实现,但要达成高可用目标,则难得多。 下图是一个通常有状态服务高可用的部署架构。


state_statefull_slave

这个架构里,有非常多的技术挑战性,列表如下。 这些挑战是分布式系统高可用的深水区,后面章节简述如何攻克这些挑战。

难点

举例

持久连接

代理服务采用何种策略让客户端保持持久连接到同一个节点,包括客户端的每次请求,客户端重启,服务节点重启,以及扩容缩容后通知客户端重连新节点。如果没有代理服务,则需要客户端实现持久化连接

设备总是链接到同一个网关,游戏玩家总是链接到同一个区域服务器

复制

为节点增加一个从节点,数据从主节点备份到从节点。当节点宕机,,从节点接替主节点工作。从节点也可收接收只读服务请求,缓解主节点负载

Redis主从数据复制,Zk的主从数据复制

读写一致

如果从节点提供读服务,如何保证客户端读到最新写到此分区的数据。

阿里云Redis可以配置只有主分片提供服务以避免读写不一致。

分区

把有状态服务分成多个节点,解决有状态服务的存储瓶颈和访问性能。

物联网网关集群,Redis数据分片,数据库分区,Kafka分区等

分区再平衡

在扩容时候,如果不差钱,每个分区都再次拆分2个分区,此分区数据只需要复制到俩分区。这种扩容成本极高但数据均匀。如果扩容时候是增加少量节点。则因为持久化连接缘故,新增节点负载长期都较低。扩容效果不能立即显现出来。

阿里云的Redis扩容采用的是成倍增长,支持4,8,16....2048个分片。不支持增加少量分区

分布式共识

数据备份给多个节点,当主节点挂掉,采用那个节点的数据为主节点。另外,新当选的的主节点需要继续同步数据到从节点

ZK通过ZAB实现分布式共识

集群管理

需要感知整个集群的节点状态,其主从的工作状态。代理服务需要获取这些数据以实现路由

物联网设备的主网关,Redis集群的代理

业务逻辑加载

如果有状态服务的业务逻辑通过外部加载实现,如果管理这些业务逻辑

物联网的规则链,通过配置其规则节点和执行逻辑实现设备在离线,属性上报等执行逻辑。Reids作为有状态节点,可以加载和执行Lua脚本

基于无状态服务和有状态服务各自的优缺点,下表总结了俩种服务的架构质量

架构特点

关注点

无状态服务

有状态服务

高可用

API网关

API网关可以实现各种负载均衡策略。如随机,轮询,负载

API网关实现较为复杂,需要识别客户端,保证每次路由到同一个有状态服务,依据信息可能是客户端IP和端口,也可能是HTTP头中包含的客户ID

故障恢复

重启服务即可恢复故障

有状态服务重启后,状态丢失。需要重新建立这些状态,如设备的版本信息,用户的购物车。因此故障恢复较慢这些状态需要从持久化系统加载,或者依赖客户端重置状态。

故障容错

无状态服务支持重试,当服务宕机,API网关可以将请求路由到另外其他服务。不存在单机故障

有状态服务宕机,状态丢失。需要在其他节点重建状态,比如有状态服务保持的有用户登录信息,当宕机后,用户再访问其他服务前,需要再次登录。

高性能

启动性能

无状态服务不需要加载状态,因此重启后访问较快。

有状态服务,服务重启后,需要初始化端状态,访问性能第一次较慢。重启可能造成服务响应延迟

访问性能

无状态服务通常将状态维护在Redis中,性能稍微慢一些,但考虑到Redis这些延迟都是毫秒级的,整体性能很高。如果状态数据维护在传统数据,则延迟较高

有状态服务在JVM内存在保持状态,访问速度更快。如游戏地图,所有玩家都在一个游戏地图(JVM)里有状态服务适合游戏,导航等场景。

可修改

易于修改

通常无状态服务,不需要在JVM里维护状态,实现更简单,易于修改。

在JVM里维护的状态,数据结构私有,难以修改,另外涉及到并发访问,编写代码容易出错

热发布

无状态服务可以采用任何热发布技术,而没有风险

有状态服务,需要把状态数据迁移到热发布后的结构,难度较大

可伸缩性

节点扩容

集群环境,无状态服务可以任意增加或者减少,无状态服务扩容后,API网关可以通过负载均衡策略,让负载少的这些扩容节点能很快达到满负荷

容易造成单点过载。有状态服务扩容后,由于持久化链接需要,至少少量请求能立即路由到新的节点。扩容后需要较长时间新老节点的容量才能达到一个均衡值。

既然无状态服务有如此多的优点,除非有高性能要求,架构中应该优先使用无状态服务,如果是有状态的服务,需要改成无状态服务,这里有4个办法


  • 有状态服务的状态数据存放在Redis等更为可靠的存储介质。比如用户Session,订单,购物车等信息存放到redis,一些长期存在的数据存放到数据库。 一些高可用基础设施的改进采用了此方案,比如Kafka新一代方案 Diskless Kafka [3] 的实现AutoMQ ,消息本地存储变成存储到对象存储服务里。 Nacos将配置数据放到Mysql数据库中。

  • 服务端的状态每次都回传给客户端,客户端下次调用携带这些状态,比如JWT,Cookie

  • 有状态服务把有状态部分单独隔离出来,把其他部分放在无状态服务里。

  • 使用Zookeeper,数据库等强一致工具来实现投票,元数据管理,二阶段提交等,而无需自己实现


下图是Spring Boot提供的Session实现方式,代替传统的保存会话到内存,Spring Boot 配置spring.session.store-type

spring.session.store-type=Redis

配置后,存在内存中的的用户会话数据将序列化后存放在redis中。


state_springsession

其他配置还允许使用数据库,Hazelcast等 存储系统。需要注意,必须确保存储系统的高性能和高可用。在我的一个项目里,用此方案把有状态服务改成无状态服务,额外引入了一个512分片,容量是1024G的Redis集群以避免系统性能问题。

另外一种把有状态服务改成无状态服务的方法是服务器每次把状态回传给客户端。适合用户状态数据较少情况。


state_request

交互过程如下

  • 服务在接受客户端请求后,将数据放回到Cookie中,如加密的用户的信息,或者订单信息

  • 客户端下次请求,服务端从Cookie中取出的状态数据,处理请求后新的状态数据再次保存到Cookie中

在还没有无纸办公时代,我在派出所办理业务的时候,按照要求需要跑多次派出所和其他相关单位,派出所工作人员会把需要跑的单位记录在一张纸上,每次交互后的结果和剩下需要办的事情都有记录,再次去派出所,其他工作人员即使没有给我办理过业务,也会让我拿出这张纸查看,以了解我办理的进度

第三种是在设计有状态服务时候,拆分有状态服务。这样好处是让大部分功能保持在无状态服务里。


state_split

第四种方法与第三种类似,使用zookeeper来管理有状态,相比于自己实现有状态服务,zookeeper/etcd这些基础中间件更为可靠。


有状态服务的高可用涉技术实现包括大量内容,本书将用后续一节内容说明实现有状态服务的高可用有哪些模式,再次警告,有状态服务高可用实现难度较大。类似你正在实现一个Redis,Kafka这样的中间件。你需要承担为了性能引入的复杂性。


参考资料

端到端: https://my.oschina.net/u/567839/blog/19641027

有状态vs无状态: https://my.oschina.net/u/567839/blog/19658871

Diskless Kafka: https://www.toutiao.com/article/7580613850573636096/

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
《爱情没有神话》真正的“商业奇才”赵兰心,跳出桎梏,走向融通

《爱情没有神话》真正的“商业奇才”赵兰心,跳出桎梏,走向融通

花煜寒
2026-05-08 21:08:34
五个水兵死在英格兰,清廷花15英镑买地下葬,这块地如今还属中国

五个水兵死在英格兰,清廷花15英镑买地下葬,这块地如今还属中国

饭小妹说历史
2026-05-07 08:56:08
绝境求生!山东男篮再战上海需破三大困局,誓要把系列赛拖入决胜

绝境求生!山东男篮再战上海需破三大困局,誓要把系列赛拖入决胜

老周观体育
2026-05-08 23:23:50
三星One UI 8.5更新,首批7款机型抢先更

三星One UI 8.5更新,首批7款机型抢先更

辉哥说动漫
2026-05-08 19:31:33
华润:广西100MW光伏项目开工!

华润:广西100MW光伏项目开工!

新浪财经
2026-05-08 21:12:31
儿子好心给买小米手机,用几天后大妈坚称通话有问题,不退就闹

儿子好心给买小米手机,用几天后大妈坚称通话有问题,不退就闹

映射生活的身影
2026-05-08 23:17:58
吴宜泽已回国!对比他与赵心童的接机待遇,同为冠军差距一目了然

吴宜泽已回国!对比他与赵心童的接机待遇,同为冠军差距一目了然

晓踏就是我
2026-05-07 10:50:04
李泽楷被她迷得神魂颠倒,林丹为她不顾妻儿,她到底有什么魅力?

李泽楷被她迷得神魂颠倒,林丹为她不顾妻儿,她到底有什么魅力?

悦君兮君不知
2026-05-07 20:59:18
深圳网约车真实一天!早6充电干到到晚9,一天流水太现实!

深圳网约车真实一天!早6充电干到到晚9,一天流水太现实!

三农老历
2026-05-08 14:47:16
争议拉满!库里索要球队股权!球迷:打工仔也敢跟老板要股份?

争议拉满!库里索要球队股权!球迷:打工仔也敢跟老板要股份?

听我说球
2026-05-08 09:22:00
网友匿名爆料自己身边的八卦,你永远也想不到,到底能有多炸裂!

网友匿名爆料自己身边的八卦,你永远也想不到,到底能有多炸裂!

夜深爱杂谈
2026-05-03 11:22:10
女足U17亚洲杯赛后评球,朝鲜vs韩国

女足U17亚洲杯赛后评球,朝鲜vs韩国

酷马西者野
2026-05-08 22:56:32
河南省委常委、副省长张敏已负责省政府常务工作

河南省委常委、副省长张敏已负责省政府常务工作

澎湃新闻
2026-05-08 13:10:26
快讯!DeepSeek创始人梁文锋发言了!

快讯!DeepSeek创始人梁文锋发言了!

达文西看世界
2026-05-08 13:04:03
朱梅也没料到,刀郎爆红乐坛后,他的前妻杨娜居然意外承受了恶意

朱梅也没料到,刀郎爆红乐坛后,他的前妻杨娜居然意外承受了恶意

原来仙女不讲理
2026-05-08 18:49:55
胖东来否认套取国补之后,王海又开始借机举报厂家

胖东来否认套取国补之后,王海又开始借机举报厂家

映射生活的身影
2026-05-08 21:53:17
爱是藏不住的!感觉张豆豆真心爱着孙杨,生活中尽量包容他的短板

爱是藏不住的!感觉张豆豆真心爱着孙杨,生活中尽量包容他的短板

小丸子Showw
2026-05-07 21:05:57
12名农民工遭“车位抵薪”32万余元,当事人担心被法院查封坚持货币支付,劳动监察大队已向法院申请强制执行

12名农民工遭“车位抵薪”32万余元,当事人担心被法院查封坚持货币支付,劳动监察大队已向法院申请强制执行

极目新闻
2026-05-08 21:04:26
研究200个婚外情案例后发现_敢和婚外男人偷情的女人,都有以下两个“厉害之处”

研究200个婚外情案例后发现_敢和婚外男人偷情的女人,都有以下两个“厉害之处”

心理观察局
2026-05-08 09:11:09
亨德利与特鲁姆普就世锦赛2029年易地产生分歧

亨德利与特鲁姆普就世锦赛2029年易地产生分歧

绿茵狂热者
2026-05-07 18:46:47
2026-05-08 23:56:49
开源中国 incentive-icons
开源中国
每天为开发者推送最新技术资讯
7724文章数 34540关注度
往期回顾 全部

科技要闻

SK海力士平均奖金600万 工服成相亲神器

头条要闻

外籍银行高层在香港豪宅性虐及杀害两女子 内幕解密

头条要闻

外籍银行高层在香港豪宅性虐及杀害两女子 内幕解密

体育要闻

他把首胜让给队友,然后用一年时间还清账单

娱乐要闻

古天乐被曝隐婚生子,新娘竟是她

财经要闻

估值3000亿 DeepSeek寻求500亿元融资

汽车要闻

MG 4X实车亮相 将于5月11日开启盲订

态度原创

教育
数码
艺术
手机
本地

教育要闻

当函数有了声音,原来数学是音乐老师教的

数码要闻

天选7 Pro/Pro Max同步登场:300Hz屏幕下放主流价位

艺术要闻

探索施密德的油画,感受无法抵挡的艺术魅力!

手机要闻

小米超大屏旗舰杀回来了!小米17 Max入网配置全曝光,价格很香

本地新闻

用苏绣的方式,打开江西婺源

无障碍浏览 进入关怀版