浅谈分布式系统 - 架构演进

news2024/11/20 15:39:04

目录

1. 架构演进

1.1 单机架构

1.2 什么是分布式架构

1.3 数据库和应用分离

1.4 引入负载均衡

1.5 引入数据库读写分离

1.6 引入缓存

1.7 数据库分库分表

1.8 微服务架构

2. 分布式系统下的常见概念


1. 架构演进

1.1 单机架构

单机架构只有一台服务器, 这个服务器需要负责所有的工作.

假定现在有一个电商网站 :

 当用户想要查看商品列表的时候, 有以下几个步骤 :

  • 应用程序服务器通过 selct 语句发送查询请求给 MySQL 服务器;
  • MySQL 服务器处理请求, 查到数据后返回给应用程序;
  • 应用程序通过 Http 协议响应给用户, 显示到浏览器界面;

-- 单机架构在某些场景下, 也是可以省去数据库的, 比如说有些网站只是介绍一下这个公司, 或者这个公司的产品, 就不太需要数据库, 但是大部分网站还是需要使用到数据库的.

-- 单机架构虽然没有分布式架构听起来那么高大上, 但是千万不要瞧不起这个东西, 毕竟绝大部分公司的产品都是这种单机架构. 随着计算机硬件的发展, 现在一台主机的性能都是非常高的, 一台主机就可以支持非常高的并发和非常大的数据存储, 应付几万个用户还是绰绰有余的, 但是绝大部分中小型公司的用户可能还达不到这个水平.

1.2 什么是分布式架构

--- 随着业务进一步增长, 用户量和数据量都水涨船高了, 一台主机难以应付了, 这时候就需要引入更多的主机, 引入更多的硬件资源.

一台主机的以下几个主要资源是有限的 : 

  • CPU
  • 内存
  • 硬盘
  • 网络

服务器每收到一个请求的时候, 都是需要消耗一台主机的主要资源, 如果同一时刻处理的请求多了, 此时就可能会导致某个硬件资源不够用了, 无论是哪个方面不够用了, 都可能会导致服务器处理请求的时间变长, 甚至于处理出错.

遇到资源不够用的情况该怎么解决 : 

1. 开源 : 增加更多的硬件资源.

    但是一台主机上面能够增加的硬件资源也是有限的, 取决于主板的扩展能力.并且不是说新买来的机器就可以直接解决问题了, 也需要软件上做出对应的调整和适配.

2. 节流 : 做出软件上的优化.

    这个就很考验程序员的经验和技术水平, 需要通过性能测试, 找到是哪个环节出现了瓶颈, 再对症下药.

使用上述开源的方法, 一旦引入多台主机了, 咱们的系统就可以称为是 "分布式系统" 了.

 -- 引入分布式系统其实是无奈之举, 因为分布式架构下, 系统的复杂程度会大大提高, 出现 bug 的概率会变高, 进而咱们加班的概率以及丢失年终奖的概率也随之提高了!!

1.3 数据库和应用分离

前边由于硬件资源的不够用, 导致处理请求的时间过长, 或者请求错误, 所以接下来我们就可以针对应用服务器和数据库服务器分别部署在两台主机上. 

1. 应用服务器里面可能会包含很多业务逻辑, 所以比较吃 "CPU" 和 "内存" 资源. 而硬盘资源使用则相对较少.

2. 数据库服务器则需要更大的硬盘空间, 更快的数据访问速度. 

于是我们可以针对不同服务器的类型, 配置不同的硬件类型. 比如说给应用服务器配置机械硬盘(便宜, 慢), 给数据库配置固态硬盘 (贵, 快), 从而达到一个更高的性价比.

1.4 引入负载均衡

由于应用服务器比较吃 "CPU" 和 "内存", 如果把 CPU 或者内存吃没了, 此时应用服务器就顶不住了. 于是我们就需要引入更多的应用服务器, 才能有效的解决上述问题.

       当用户发送请求过来时, 请求会先到达负载均衡器(网关服务器), 然后负载均衡器再将请求分发给下面的应用服务器. (上图看起来是两个应用服务器, 实际上可能是多个)

       假设有 1w 个用户请求, 有两个应用服务器, 此时在引入负载均衡的前提下, 就可以让每个应用服务器承担 5k 的访问量. 如果应用服务器搞个十台, 八台的, 那不就更加能够降低每一台机器所承担的压力. 看到这, 是不是会觉得 "多线程" 有点像!! 但是多线程还只是局限于一台主机, 局限在一个 CPU 上, 而此处的负载均衡则是引入更多的主机, 引入更多的 CPU, 每一台主机里仍然可以按照多线程的方式去安排任务.

       此处的负载均衡器就有点像一个公司的领导, 要负责管理, 要负责把任务分配给每个员工. 而分配任务需要分配的相对均匀一点, 对于负载均衡器来说, 就会牵扯到很多的负载均衡具体的算法. (例如 : 轮询...)

那是否会出现请求量大到负载均衡器也扛不住了呢 ? 

-- 虽然负载均衡器是一个 "领导", 只需要布置任务, 一般情况下, 不会说处理不过来, 但是处理不过来也是有可能的, 如果真的处理不过来了, 我们就可以引入更多的负载均衡器.

1.5 引入数据库读写分离

      当我们引入更多的应用服务器时, 确实能够处理更高的请求量了, 但随之数据库服务器, 要承担的请求量也就更多了, 那怎么办呢 ? 还是要么开源, 要么节流. 由于节流门槛高, 更复杂, 于是我们可以引入更多的机器.

        当我们引入多台数据库服务器时, 数据库服务器又分为两大类, 一种叫做主数据库(master), 一种叫做从数据库(slave). 主数据库负责写 (增删改), 从数据库负责读(查), 并且从数据库中的数据需要从主数据库中同步, 也就是说上面的应用服务器需要读数据的时候, 就从从数据库中读, 需要写数据的时候, 就在主数据库中写, 同时主数据库也会实时地, 定期地将数据同步到从数据库

        这样从一个数据库既负责读又负责写, 过渡到了两个数据库, 一个数据库负责写, 一个数据库负责读, 从而就把每一台机器的压力就降低了.

        而且实际应用场景中, 读的频率是比写的频率要高很多的, 所以一般使用到数据库分离时, 主数据库服务器一般是一个, 从服务器可以有多个 (一主多从). 同时这多个从服务器又可以使用负载均衡的方式让上面的应用服务器进行访问, 这样又可以进一步降低每一台从服务器的压力.

1.6 引入缓存

由于数据库天然有个问题, 响应速度 "慢" !! 不管怎么进行分库, 它终究是要从硬盘读取数据, 而读硬盘在某些场景下是接受不了的, 所以为了更进一步的提高数据访问效率, 还可以将数据进行 "冷热" 拆分, 其中热点数据放到缓存中, 而缓存的访问速度往往比数据库快很多. 

        根据二八原则: 20% 的数据, 能够支持 80% 的访问量. 所以缓存服务器中只是存储了一小部分热点数据, 也就是会被频繁访问到的数据, 而数据库中存储的仍然是完整的全量数据.  

        既然缓存那么快, 为啥不把数据都存在缓存中呢 ? 前面咱们聊到过, 缓存它虽然快, 但是小, 所以需要缓存服务器和数据库服务器搭配来使用, 这才是在有限成本下的一个比较划算的方案. (Redis 就是出现在缓存服务器这个位置) 

        后续应用服务器想要读数据的时候, 就可以先从缓存中读取, 如果缓存中存在,, 就不需要读数据库了, 如果缓存中不存在, 那么再去读数据库. 由于二八原则, 所以大部分的应用服务器请求都能在缓存中找到答案, 这就是数据库服务器所承担的压力又进一步减小了.

此时读数据读的又快, 同时数据库服务器压力又小!!

【问题】缓存和数据库中存在数据同步, 数据一致性问题 ?

如果后续应用服务器在数据库服务器中将数据修改了, 比如说缓存中存储某件商品的价格 20 元, 后续搞活动, 应用服务器在数据库中将价格改到 15, 这就需要缓存和数据库进行数据同步了. 但是这件事也不容易, 可能数据库中的数据改成功了, 但是缓存中的数据改失败了; 也可能数据库中的数据改失败了, 而缓存中的数据改成功了. 所以这件事情又变得复杂起来了!!

(如何解决后续我学会了再慢慢交代)

1.7 数据库分库分表

咱们引入分布式系统, 不光要能够应对更高的请求量(并发量), 同时也要能够应对更大的数据量. 请求量咱们目前解决了, 那么是否可能会出现, 一台数据库服务器已经存不下数据了呢 ? 答案无疑是肯定的. 虽然一台服务器存储的数据量可以达到几十个 TB, 即使如此也可能会存不下, 比如 : 短视频. 于是我们就需要针对数据库进行分库分表.

        最初我们的架构是一个数据库服务器里头有多个数据库(create database...), 而分库就相当于引入多个数据库服务器, 每个数据库服务器存储一个或者一部分数据库. 

【对应上图】 用户表由一个主服务器来存, 然后引入多个从服务器, 商品表由一个主服务器来存, 然后引入多个从服务器......

         此时应用服务器想要读取用户表, 就可以访问用户表的服务器, 想要读取商品表, 就可以访问商品表的服务器, 当然读数据之前仍然可以先读缓存, 缓存没有再读数据库(主从). 

         如果某一张表特别大, 比如交易表大到一台主机存不下, 我们也可以针对表进行拆分. 可以将交易表拆成多张表, 分别存储到不同的数据库服务器上. 

注意数据库的分库分表操作解决的是数据量过大的问题, 而不是并发问题. 另外数据库分库分表如何实现, 还是要结合实际的业务场景来展开.

1.8 微服务架构

回到应用服务器上面来, 咱们之前的应用服务器, 一个服务器程序里面做了很多的业务 : 用户,商品,交易等等. 这就可能导致这一个服务器的代码变得越来越复杂. 为了更方便于代码的维护, 就可以把这样的一个复杂的服务器, 拆分成更多的, 功能更单一的, 但是更小的服务器. 于是我们就可以引入微服务!!

 由于系统总的功能是一定的, 现在单个服务器变小, 所以服务器的种类和数量就增加了. 用户相关的搞一组服务器, 商品相关的搞一组服务器, 交易相关的再搞一组服务器, 每一组服务器里面可能又有多台服务器来应对更高的请求量, 同时每组服务器各自又有各自的存储集群和缓存模块.

-- 目的 --> 引入微服务是为了解决 "人" 的问题!! 

        当应用服务器复杂了, 势必就需要更多的人来维护了. 人一旦多了, 就需要配套的管理来把这些人给组织好. 如果管理不到位, 搞了那么多人, 结果都在摸鱼, 或者帮倒忙, 这就会适得其反. 并且如果用户, 商品, 交易相关的人员都坐在一块, 到时候用户这边的人搞出来一个问题, 他们又会觉得是商品或者交易那边没做好导致这边出问题, 就会容易扯皮....

        于是我们可以划分组织结构, 将这些人分成多个组, 然后进行分工, 每个组再别配备领导进行管理. 同时呢, 一个组的技术人员就可以专注于一个模块了, 就可以把这个模块把握的更好. 我们的应用服务器就可以按照功能, 拆分成多组微服务, 就可以有利于上述人员的组织结构分配了.

那么啥时候会涉及到人的问题 ??  --> 大厂

如果是小公司, 就那么几个, 十几个开发, 此时搞微服务就没太大的必要了.

【引入微服务的代价1】系统的性能下降

在引入微服务之前, 我们的用户, 商品, 交易这写模块的相互调用, 直接进程内就能调用. 而现在我们需要跨主机通过网络进行通信, 而网络通信这件事情可就比进程内通信慢太多太多了. 

        要想保证性能不下降那么多, 就只能引入更多的机器, 更多的硬件资源, 换句话来说就是 "充钱"!!, 所以说为什么大厂要搞微服务. 不过目前的硬件水平还是很给力的, 网卡现在有个 "万兆网卡", 它的读写速度已经能超过硬盘的读写速度了, 哪怕是在固态硬盘面前, 万兆网卡依然有优势, 所以有了万兆网卡, 虽然系统的性能会有所下降, 但也不至于下降太多.

-- 万兆网卡 [贵] -- 

        使用万兆网卡虽然有防止性能下降过多的效果, 但是不是光一个万兆网卡就完事了, 首先万兆网卡就很贵了, 其次它还得配备万兆交换机, 万兆路由器, 甚至还要配备万兆带宽的网线, 这一套装备下来可得花不少钱, 所以说微服务可不是一些中小公司折腾的起的, 还得是大厂.

【引入微服务的代价2】系统的复杂程度提高, 可用性受到影响

在微服务环境下, 服务器更多了, 出现问题的概率就更大了, 这就需要一系列的手段来保证系统的可用性了. 比如 : 更丰富的监控报警, 配套的运维人员等等..

🍁微服务的优势

1. 解决了人的问题.

2. 更方便于功能的复用.

        比如说用户模块在其他很多模块都需要使用, 那么单独提取出来就可以起到功能复用的好处.

3. 可以给不同的服务进行不同的部署

        有的模块对于请求量, 或者数据量处理的不是很多, 那么我们给这个模块部署的时候, 机器就可以少部署点, 就可以配置一些低成本的机器; 然后负载量比较大的模块, 就可以部署更多的机器, 配置更好的机器,这样就有利于硬件资源的一个组合调配. 

总言之, 微服务既有它的优势, 也有它的劣势, 具体怎么搞, 还得根据业务场景, 还得根据公司的钞能力!!

2. 分布式系统下的常见概念

应用 (Applicaction) / 系统 (System)

一个应用就是一个组, 或者说服务器程序

模块 Module / 组件 (Component)

一个应用里面有很多个功能, 每个独立的功能, 就可以称为是一个模块/组件

分布式 (Distributed)

引入多个主机/服务器, 协同配合完成系列的工作 (物理上的多个主机)

集群 (Cluster)

引入多个主机/服务器, 协同配合完成系列的工作 (逻辑上的多个主机)

中间件 (Middleware)

和业务无关的服务(功能更通用的服务)

可用性 (Avaliablility)

系统整体可用的时间 / 总的时间      // 一个系统的第一要务

响应时长 (Response Time RT)

处理一次请求需要消耗多长时间. 用于衡量服务器的性能.

吞吐 (Throughput) VS 并发 (Concurrent)

衡量系统处理请求的能力.也是用来衡量服务器的性能的.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/755651.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML+CSS+JavaScript:渲染柱形统计图

一、需求 用户输入四个季度的数据&#xff0c;根据数据生成柱形统计图&#xff0c;浏览器预览效果如下 二、完整代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content&q…

Java利用POI导入Excel数据(多个sheet、模板)

需求&#xff1a;根据excel模板导入数据 sheet1&#xff1a;1-6行为固定格式&#xff0c;且需要取值({xxx});7行开始为数据集合(list) sheet2&#xff1a;都为固定格式&#xff0c;取值地方&#xff1a;{xxx} 1、数据格式&#xff08;两个Sheet&…

从零开始理解Linux中断架构(19)--中断线程化irq_thread

前面一节讲到的中断流处理流程是在hard_irq 流程上&#xff0c;工作在中断堆栈上。还有一种情况是使用中断线程的情形。request_threaded_irq参数中有两个处理函数handler,thread_fn是有区别的。handler主中断处理例程&#xff0c;运行hard_irq 流程上。而如果驱动程序填写thre…

利用R分别绘制配对连线散点图、云雨图、山脊图

大家好&#xff0c;我是带我去滑雪&#xff01; 精美的科研绘图总会给人眼前一亮&#xff0c;今天学习利用R绘制多组配对连线散点图、云雨图、山脊图&#xff0c;这三幅图最近都曾出现在Nature Communications (IF 16.6)中&#xff0c;比如配对连线散点图&#xff0c;如下所示&…

AI智能助手的未来:与人类互动的下一代人工智能技术

自我介绍⛵ &#x1f4e3;我是秋说&#xff0c;研究人工智能、大数据等前沿技术&#xff0c;传递Java、Python等语言知识。 &#x1f649;主页链接&#xff1a;秋说的博客 &#x1f4c6; 学习专栏推荐&#xff1a;人工智能&#xff1a;创新无限、MySQL进阶之路、C刷题集、网络安…

AIGC文生图:使用ControlNet 控制 Stable Diffusion

1 ControlNet介绍 1.1 ControlNet是什么&#xff1f; ControlNet是斯坦福大学研究人员开发的Stable Diffusion的扩展&#xff0c;使创作者能够轻松地控制AI图像和视频中的对象。它将根据边缘检测、草图处理或人体姿势等各种条件来控制图像生成。 论坛地址&#xff1a;Adding…

操作系统进行设备控制的方式

一.I/O控制方式 上一篇的博客介绍了设备管理的一些概念基础知识点&#xff0c;其中I/O控制方式这一块没有详细说明。设备管理的主要任务之一是控制设备和内存或CPU之间的数据传送。外围设备和内存之间的输入/输出控制方式有4种&#xff0c;下面分别加以介绍。 二.程序直接控制…

ITIL 4—事件管理实践

1 关于本文 本文档提供事件管理实践实用指南。分为五个主要部分&#xff0c;内容包括&#xff1a; 本实践的一般信息实践的流程和活动及其在服务价值链中的作用参与实践的组织和人员支持实践的信息和技术对实践的合作伙伴和供应商的考虑。 1.1 ITIL4 认证方案 本文档的部分…

Ubuntu 安装 Docker

本文目录 1. 卸载旧版本 Docker2. 更新及安装工具软件2.1 更新软件包列表2.2 安装几个工具软件2.3 增加一个 docker 的官方 GPG key2.4 下载仓库文件 3. 安装 Docker3.1 再次更新系统3.2 安装 docker-ce 软件 4. 查看是否启动 Docker5. 验证是否安装成功 1. 卸载旧版本 Docker …

图片文字对齐 图片文字居中对齐

方法一: 用 vertical-align: middle; <view class="container"><view class="search"><image src="../../images/icon/search.png" alt="" /><text class="tex">搜索</text></view>&…

手写对象浅比较(React中pureComponent和Component区别)

PureComponent和Component的区别 PureComponent会给类组件默认加一个shouldComponentUpdate这样的周期函数 //PureComponent类似自动加了这段shouldComponentUpdate(nextProps,nextState){let { props, state } this;// props/state:修改之前的属性状态// nextProps/nextState…

layui入门增删改查

layui入门增删改查 创建Lauiyi对象1.后台准备1.dao方法2.子实现类 2.R工具类的使用3.查询前端代码实现前端页面 4.增删改实现2.浮层3分离的js代码1.userManage.js2.userEdit.js3.index.js 5.运行效果 作为一名开发人员&#xff0c;我们经常需要对数据库中的数据进行增删改查&am…

120、仿真-51单片机温湿度光照强度C02 LCD1602 报警设计(Proteus仿真+程序+元器件清单等)

方案选择 单片机的选择 方案一&#xff1a;STM32系列单片机控制&#xff0c;该型号单片机为LQFP44封装&#xff0c;内部资源足够用于本次设计。STM32F103系列芯片最高工作频率可达72MHZ&#xff0c;在存储器的01等等待周期仿真时可达到1.25Mip/MHZ(Dhrystone2.1)。内部128k字节…

刷题 DAY4

题目1 给定一个有序数组arr&#xff0c;给定一个正数aim (1)返回累加和为aim的&#xff0c;所有不同二元组 (2)返回累加和为aim的&#xff0c;所有不同三元组 问题一 暴力的解法就是 遍历每一个二元组 找和为aim的 当然 只用暴力解很难ac 想一想有序 那肯定就是能加速 我们…

RocketMQ下载安装、集群搭建保姆级教程

目录 1.下载安装 2.配置 3.测试 4.集群配置 4.1.规划 4.2.环境准备 4.3.节点配置 4.3.1.master1 4.3.2.slave2 4.3.3.master2 4.3.4.slave1 4.4.启动 4.5.测试 1.下载安装 前置条件&#xff1a; JDK环境 下载地址&#xff1a; 下载 | RocketMQ 博主下载的是4.…

排序算法笔记--摩尔投票算法

摩尔投票算法 摩尔投票算法是一种用于在数组中查找出现次数超过一半的元素的有效算法。算法的核心思想是利用候选元素和计数器进行投票&#xff0c;通过消除不同元素之间的抵消来找到出现次数超过一半的元素。 算法原理 如果数组中存在一个出现次数超过一半的元素&#xff0…

【从零开始学习CSS | 第三篇】选择器优先级

目录 前言&#xff1a; 常见选择器的优先级&#xff08;从高到低&#xff09; 选择器的权重&#xff1a; 总结&#xff1a; 前言&#xff1a; 在前几篇文章中我们介绍了大量的选择器&#xff0c;那么大量的选择器在使用的时候&#xff0c;一定是有一个优先级顺序的&#xff…

graylog源码搭建

这里主要讲如何源码安装graylog 下载地址&#xff1a; https://www.graylog.org/downloads/ 下载带有JVM的源码文件源码安装 下载graylog-5.1.3-linux-x64.tgz&#xff0c;并上传到Centos中&#xff0c;执行以下操作 tar -zxvf graylog-5.1.3-linux-x64.tgzcd /etcmkdir -p …

Python GUI编程利器:Tkinker中的颜色选择对话框(15)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 和猫妹学Python&#xff0c;一起趣味学编程。 今日目标 学习Tkinter中的颜色对话框的使用&#xff0c;实现如下效果&#xff1a; 颜色选择对话框 颜色选择对话框可以提供一…

JavaWeb 笔记——6

JavaWeb 笔记——6 一、Vue1.1、Vue-概述1.2、Vue快速入门1.3、Vue常用指令1.3、Vue生命周期1.4、查询所有-案例1.5、新增品牌-案例 二、Element2.1、Element概述2.2、快速入门2.3、Element布局2.4、常用组件 三、综合案例3.1、换件搭建3.2、查询所有3.3、新增品牌3.4、Servlet…