系统设计中15 个最重要的权衡
系统设计的第一法则:一切都与权衡有关。
在设计系统时,我们需要决定要包含哪些功能以及要忽略哪些功能。每次我们做这个决定时,我们都在进行权衡。在本文中,我们将探讨系统设计中遇到的15个最常见的权衡问题,并使用实际示例进行说明:
1. 可扩展性与性能
可扩展性涉及系统的规模:“系统是否可以扩展以处理更多的流量和数据?”
性能涉及系统的速度:“系统能多快完成任务?”
们通常相互矛盾,改进一个可能会影响另一个。
示例:向系统添加更多机器可以使其更具可扩展性,但是管理这些机器和协调任务的复杂性可能会导致性能的延迟。
2. 垂直扩展与水平扩展
垂直扩展涉及向现有服务器添加更多资源(例如 CPU、RAM),而水平扩展意味着添加更多服务器。
垂直扩展更简单,但单台计算机再怎么升级也是存在上限的,而且存在单点故障问题。如果机器发生故障,整个系统都不可用。水平扩展允许几乎无限的扩展,但带来了管理分布式系统的复杂性。
**示例:初创公司可能会通过增加CPU和RAM来垂直扩展其服务器以应对增加的负载。随着公司的发展,它可能会转向水平扩展,通过增加服务器来分散负载。
3. 延迟与吞吐量
延迟衡量数据在网络中传输所需的时间。吞吐量是指指在特定时间内通过网络的数据平均量。
低延迟系统对于实时应用至关重要,而高吞吐量系统对于数据密集型应用至关重要。
**示例:**在线游戏需要低延迟来提供玩家之间的实时互动。数据分析服务优先考虑吞吐量,以以处理和分析大量数据集。
4. SQL 与 NoSQL 数据库
**SQL(关系数据库)**建立在关系模型之上,该模型将数据组织成由行和列构成的表表,并使用唯一的键来标识每一行。这些数据库结构严谨,提供强大的查询语言,非常适合处理复杂的查询和事务。例如:MySQL、PostgreSQL。然而,SQL数据库在水平扩展上可能具有挑战性。
**示例:**银行使用 SQL 数据库进行交易管理。这些数据库确保所有交易都得到可靠处理,维护准确的账户余额和交易历史。
**NoSQL(非关系数据库)**提供灵活性并易于扩展,但可能会牺牲类似 SQL 的查询功能和 ACID 事务。NoSQL 遵循 BASE 属性,即基本可用、软状态、最终一致性……例如,它可能无法始终满足一致性,但最终会变得一致。因此,它牺牲了 ACID 属性,但并非完全牺牲!
NoSQL 适合处理大量非结构化或半结构化数据,例如:Cassandra、Amazon DynamoDB。NoSQL有多种类型,包括文档、键值、宽列、文档和图形存储。
**示例:**Netflix等公司使用NoSQL进行实时推荐引擎。NoSQL数据库可以快速处理大量多样化的数据(观看记录、评分、偏好),为数数亿用户提供个性化内容推荐。
5.一致性与可用性(CAP定理)
一致性意味着每次访问系统时都会获得最新数据。
**示例:**在淘宝等电商系统中,当客户下订单时,系统会确保立即更新库存水平。这种一致性可防止其他客户在缺货时订购同一商品。
可用性就是确保系统始终正常运行,即使系统的某些部分出现问题。
**示例:**在在线消息服务中,可用性确保即使部分服务器宕机,你仍然可以发送和接收消息。
根据CAP理论,在分布式系统中,你只能保证一致性、可用性和分区容忍性中的两个。
在一致性和可用性之间进行选择取决于您的系统想要提供的用户体验什么更重要。
6. 强一致性与最终一致性
在分布式系统中,数据存储在多个位置,确保每个人同时看到相同的数据可能具有挑战性。这就是强一致性和最终一致性的概念发挥作用的地方。强一致性意味着一旦发生数据更新,对该数据的任何后续访问都能获取到最新值。
**示例:**在银行系统中,当您将钱从一个账户转移到另一个账户时,系统会立即更新余额。
而最终一致性则意味着更新在系统的所有节点上可见之前可能会有延迟。但是,可以保证的是,如果没有新的更新,最终对该数据的所有访问都将返回更新后的值。
**示例:**在 Instagram 等社交媒体平台上,当您发布新照片时,它可能不会立即出现在所有关注者的动态中。但是,经过短暂的时间后,每个人都将能够看到这张新照片。
7. Read-Through vs Write-Through Cache
缓存是一种通过将经常访问的数据存储在更快的存储介质中来加快数据访问的技术。说到缓存策略,“Read-Through”和“Write-Through”是两种常见的策略。
Read-Through策略在请求数据时会先检查缓存。如果数据不存在(缓存未命中),则会从较慢的主存储加载到缓存中,然后再返回。
它适用于读取频繁但不经常更新的应用程序。
示例:在在线商店中,当客户第一次查看产品时,产品详情从数据库中获取并存储到缓存中。后续查看则从缓存中获取,加快响应时间并减少数据库查询。
Write-Through同时将数据更新写入缓存和主存储,确保数据最新并降低数据丢失风险。
这对于写操作频繁的应用程序非常有益。所有写入都会立即反映在缓存和主存储中。
示例:电影票预订系统使用Write-Through策略,通过立即在缓存和数据库中记录预订来防止超额预订。
8.批处理与流处理
批处理涉及在一段时间内收集数据,然后一次性处理所有数据。流处理意味着实时处理数据,一旦数据到达就立即处理。
示例:信用卡公司使用批处理来生成每日账单和报表。为了检测欺诈,他们实施流处理来实时分析交易并立即标记可疑活动。
9.同步与异步处理
同步处理是指任务一个接一个地执行。必须完成一个任务才能开始下一个任务,系统会等待结果后再继续执行。
示例:当您进行线购物时,付款过程是同步的。单击“立即支付”后,你等待交易处理。网站在确认支付成功前不会让你继续。
异步处理允许任务在后台运行,不需要等待其完成就可以开始本任务。
示例:在社交媒体上上传照片是在后台异步进行的。您可以在照片上传时继续滚动或退出应用程序。
10.有状态架构与无状态架构
有状态系统会记住过去的交互。它存储有关当前会话的信息,从而可以在后续交互中保持连续性和上下文,而无需每次都从头开始。
**例如:**在线购物时,当您将商品添加到购物车时,网站会记住您的选择。如果您离开以浏览更多商品,然后返回购物车,您的商品仍在那里,等待您结账。
无状态系统不会跟踪过去的交互。每个请求都被视为新请求,不会保留先前请求的任何信息。
示例:许多 RESTful Web 服务运行时不会记住过去的请求。例如,当您向公共 API 查询天气信息时,您需要在每次请求中提供所有必要的详细信息(如位置)。
11. 长轮询与 WebSockets
长轮询是一种技术,客户端向服务器请求数据,服务器保持请求打开,直到有新信息可用。收到数据后,客户端立即发送新请求,从而实现即时更新。
**示例:**社交媒体平台的通知系统。浏览器不断向服务器查询新通知,当出现新通知或发生超时时,服务器会做出响应。
WebSockets通过单个长期连接的全双工通信通道,使服务器和客户端可以在数据可用时立即相互发送数据,而无需等待另一方的请求。
示例:在多人在线游戏中,WebSockets通过客户端和服务器之间的持久连接,实时共享玩家动作和游戏更新。
12. 规范化与非规范化
数据库设计中的规范化涉及将数据拆分到相关表中,以确保每条信息只存储一次。其目的是减少冗余并提高数据完整性。
示例:客户数据库可以有两个独立的表:一个用于客户详细信息,另一个用于订单,避免每个订单的客户信息重复。
另一方面,非规范化是将数据重新组合到更少的表中以提高查询性能。这通常会在数据库中引入冗余(重复信息)。
示例:博客网站可以将最新评论与帖子存储在同一张表中(非规范化),以加快帖子和评论的显示,而不是将它们分开存储(规范化)。
13. 单体架构与微服务架构
单体架构将应用的所有功能作为单一、不可分割的单元运行。所有功能都打包在一个进程中,通常作为单一代码库进行开发、测试和部署。
而微服务架构则是将应用分解为一组小型、松散耦合的服务,每个服务都专注于特定功能,并通过轻量级通信协议(如HTTP)相互交互。
单体架构简单易部署,适合小型应用程序或团队。但是,随着应用程序的增长,它可能会减慢开发速度并使可扩展性变得复杂。微服务架构提高了可扩展性和开发速度。但是,它引入了服务管理、数据一致性的复杂性,并增加了通信开销。
**示例:**为简单起见,小型 Web 应用程序可能以单体式架构开始。随着规模的增长,它可以演变为微服务架构,拆分为更小、可独立扩展的服务,从而实现更好的灵活性和可扩展性。
14. REST 与 GraphQL
REST是一个成熟的API标准,提供了简洁性并支持多种格式。使用REST API时,您可以通过访问多个端点来收集数据。
GraphQL提供了更高效的数据获取,减少了请求次数,但需要更高的学习曲线和更多的前期设计。
在 GraphQL 中,您可以向 GraphQL 服务器发送一个包含具体数据需求的查询。服务器然后返回一个JSON对象,其中包含了这些需求的数据。
15. TCP 与 UDP
TCP 和 UDP 是TCP/IP协议中传输层的两种协议。
TCP(传输控制协议) 可确保您的消息完好无损地按照发送的顺序到达。它在发送方和接收方之间建立连接,检查数据是否正确接收,必要时会重新发送丢失的数据。TCP 非常适合用于对可靠性要求很高的应用程序,比如电子邮件服务。
UDP(用户数据报协议) 牺牲了可靠性来换取速度,适用于视频流等对时间敏感的应用程序,在这种情况下,传输过程中丢失一些数据也没关系。UDP发送数据时无需建立连接,也不检查数据是否接收或顺序是否正确。在线游戏和直播服务可能会选择 UDP,因为它的延迟较低,牺牲可靠性来换取速度。
每个权衡的选择因具体项目而异。
理解这些权衡可以帮助您作出明智的选择来设计高性能、可扩展和用户体验优秀的系统。
相关文章:

系统设计中15 个最重要的权衡
系统设计的第一法则:一切都与权衡有关。 在设计系统时,我们需要决定要包含哪些功能以及要忽略哪些功能。每次我们做这个决定时,我们都在进行权衡。在本文中,我们将探讨系统设计中遇到的15个最常见的权衡问题,并使用实…...
12年外贸实战经验,一定对你有帮助!
更多外贸干货及开发客户的方法,尽在微信【千千外贸干货】 NO1 客户总是抱怨价格太高,我常以我们产品质量过硬作为回应。但自从我进入贸易公司后,才真正意识到,在商业世界里,价格才是王道。 NO2 如果顾客提出要去工厂检…...

Linux---进程(3)---进程状态
目录 进程排队 进程状态 运行状态 阻塞状态 挂起状态 Linux内核具体进程状态 浅度睡眠状态 运行状态 深度睡眠状态 暂停状态 可被追踪的暂停状态 终止状态 僵尸状态 进程排队 进程不是一直在运行的,进程放在了CPU上,也不是一直运行的。 进程…...
Drools规则引擎实现停车计费
业务规则: 20:00至次日7时不收费白天7:00-20:00每小时5元,每半个小时计费一次进场30分钟内不收费,但计入时间每天最高收费50元 测试项目搭建 pom<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/…...
【python虚拟环境】安装第三方包失败/failed with error code1
问题: 今天新建了一个项目,默认的虚拟环境pip包版本是19.0.3,太低了。安装第三方包的时候一直超时 解决方案: 更新pip: python -m pip install -U --force-reinstall pip然后就可以正常pip install包了 清华镜像源࿱…...

DiffusionModel-latent diffusion,VAE,U-Net,Text-encoder
Diffusers StableDdiffusion 参考: Stable Diffusion原理详解(附代码实现) Latent Diffusion 自编码器(Variational Autoencoder, VAE): 自编码器是一种无监督学习的神经网络,用于学习数据的有效表示或编码。在稳定扩…...

C# form的移植工作
前言: 目标,将一个项目的form移植到新的工程下,且能够正确编译执行: 1 Copy form的两个文件到新工程下: 比如笔者的logo form 2 修改命名空间: 然后,找到新项目的主程序: 的命名…...
linux防火墙相关命令
防火墙启动关闭 启动防火墙 systemctl start firewalld 关闭防火墙 systemctl stop firewalld 查看状态 systemctl status firewalld 开放或限制端口 开放端口 firewall-cmd --zonepublic --add-port22/tcp --permanent 重新载入一下防火墙设置,使设置生效…...

实习中学到的一点计算机知识(MP4在企业微信打不开?)
我在实习中,常有同事向我反馈说我在微信发的视频格式打不开。这就导致我还要一帧帧的盯着某一个时刻来截图,今天查了一下资料尝试修改视频后缀来解决视频的播放问题。 在网上下载mp4的格式,在本地都能播放,怎么可能发上企业微信就…...
ElasticSearch入门语法基础知识
1、创建测试索引 PUT /test_index_person {"settings": {"analysis": {"analyzer": {"ik_analyzer": {"type": "custom","tokenizer": "ik_smart"}}}},"mappings": {"proper…...

【C++】C++应用案例-dolphin海豚记账本
目录 一、整体介绍 1.1、需求和目标 1.2、整体功能描述 二、页面及功能描述 2.1 主菜单 2.2 记账菜单 2.3 查询菜单 2.4 退出功能 三、流程设计 3.1 主流程 3.2 记账操作流程 3.3 查询操作流程 四、代码设计 4.1 核心思路 4.2 项目文件分类设计 4.2.1 头文件 …...
Matlab数据处理学习笔记
1 :数据清洗 注:数据读取 (1)读取工作表 % 指定要读取的工作表 filename sales_data.xlsx; sheetName Sheet2; % 或者使用工作表编号,例如:sheetNumber 2;% 读取指定工作表的数据 data readtable(fi…...

浏览器中的同源策略、CORS 以及相关的 Fetch API 使用
前言 笔者对前端 Web 技术的认真学习,其实开始于与 Fetch API 的邂逅。当时觉得 fetch() 的设计很不错,也很希望能够请求其它网站下的数据并作处理和展示。学习过程中 HTML 和 CSS 都还好说,由于几乎没有 Web 技术的基础,学习 Fe…...

爬虫 APP 逆向 ---> 粉笔考研
环境: 粉笔考研 v6.3.15:https://www.wandoujia.com/apps/1220941/history_v6031500雷电9 模拟器:https://www.ldmnq.com/安装 magisk:https://blog.csdn.net/Ruaki/article/details/135580772安装 Dia 插件 (作用:禁…...
2024河南萌新联赛第(三)场 河南大学
B. 正则表达式 题目: https://ac.nowcoder.com/acm/contest/87865/B 给出n个地址,每个地址的形式为x.x.x.x,找四个x都满足x>0&&x<255的个数 思路: 首先定义四个数组和一个字符,然后按题目所给的形式…...
回溯法---分割回文串
题目:给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文串。返回 s 所有可能的分割方案。 思路: 第一步:确定参数与返回值。参数为字符串s,分割起始下标startIndex,无返回值 第二…...

DDR等长,到底长度差多少叫等长?
DDR4看这一篇就够了 - 知乎 (zhihu.com) 【全网首发】DDR4 PCB设计规范&设计要点PCB资源PCB联盟网 - Powered by Discuz! (pcbbar.com) 终于看到较为权威的DDR4等长要求了: !!!! 依据这个要求,H616项目的等长线不合格:...

程序员面试题------N皇后问题算法实现
N皇后问题是一个著名的计算机科学问题,它要求在NN的棋盘上放置N个皇后,使得它们之间不能相互攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。这个问题可以看作是一个回溯算法问题,通过逐步尝试不同的放置位置…...

【C++学习】6、继承
1、什么是继承? 继承描述的是类与类之间的关系,A类继承B类,A类就拥有B类的数据和方法。 继承的方式: 公有继承(public) 保护继承(protected) 私有继承(private&…...
从零开始的MicroPython(三) 按键与外部中断
上一篇:从零开始的MicroPython(二) GPIO及点灯代码 文章目录 前言硬件原理软件原理注意代码编写轮询外部中断其他 前言 点灯是嵌入式GPIO输出的典型,按键则是输入的典型。 硬件原理 按键对角接通。 软件原理 如果是一端接高电平,一端接单…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...

PLC入门【4】基本指令2(SET RST)
04 基本指令2 PLC编程第四课基本指令(2) 1、运用上接课所学的基本指令完成个简单的实例编程。 2、学习SET--置位指令 3、RST--复位指令 打开软件(FX-TRN-BEG-C),从 文件 - 主画面,“B: 让我们学习基本的”- “B-3.控制优先程序”。 点击“梯形图编辑”…...