RPC框架
基本概念
RPC: Remote Procedure Calls
需要解决问题:函数映射,数据转换为字节流,网络传输
一次完整的远程过程调用(RPC)的流程,包含以下关键步骤:
- IDL 文件:用于定义接口,实现不同平台和语言之间的通信。
- 生成代码:使用工具将接口转换为对应语言的静态库。
- 编码解码:将数据从内存表示转换为传输字节序列(编码)以及反向转换(解码)。
- 通信协议:规定传输的格式,包括必需和额外的元数据。
- 网络传输:通过 TCP 或 UDP 传输协议传递数据。
RPC 的好处
- 单一职责,有利于分工协作和运维开发
- 可扩展性强,资源使用率更优
- 故障隔离,服务的整体可靠性更高
分层设计
编解码层 - 二进制编码
TLV 编码
- Tag:标签,可以理解为类型
- Length:长度
- Value:值,Value 也可以是个 TLV 结构
编码系统需要具备的三个关键特性:
- 兼容性:编码系统支持在不破坏现有服务的情况下添加新字段。这种特性允许系统在扩展和更新时保持向后兼容性,即新的字段不会影响到旧的服务的正常工作,从而提高了系统的灵活性。
- 通用性:编码方案应具有跨平台和跨语言的通用性,使得不同的操作系统和编程语言都能够识别和处理相同的编码格式。这对于构建分布式系统或多语言协作系统尤为重要。
- 性能:在设计编码时,需要从空间和时间两个维度去考虑,即数据编码后的大小和编码/解码所需的时间。数据越小、处理越快的编码方式,通常在高性能系统中更受欢迎,因为这有助于减少存储和传输的成本。
协议层
协议构造:
- LENGTH:数据包大小,不包含自身
- HEADER MAGIC:标识版本信息,协议解析时便于快速校验
- SEQUENCE NUMBER:表示数据包的 seqID,可用于多路复用,单连接内递增
- HEADER SIZE:头部长度,从第14个字节开始计算一直到 PAYLOAD 前
- PROTOCOL ID:编解码方式,有 Binary 和 Compact 两种
- TRANSFORM ID:压缩方式,如 zlib 和 snappy
- INFO ID:传递一些定制的 meta 信息
- PAYLOAD:消息体
协议解析:
peek → MagicNumber → peek → PayloadCodec →decode → Payload
网络通信层
Sockets API
网络库
- 提供易用 API
- 封装底层 Socket API
- 连接管理和事件分发
- 功能
- 协议支持:tcp、udp 和 uds 等
- 优雅退出、异常处理等
- 性能
- 应用层 buffer 减少 copy
- 高性能定时器、对象池等
关键指标
稳定性
保障策略
- 熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
- 限流:保护被调用方,防止大流量把服务压垮
- 超时控制:避免浪费资源在不可用节点上
请求成功率——负载均衡
长尾请求
注册中间件
易用性
扩展性
观测性(Log, Metric, Tracing, 内置观测服务)
高性能(高吞吐、低延迟)
连接池,多路复用,高性能编解码协议,高性能网络库
存储与数据库
存储系统
- 块存储:存储软件栈里的底层系统,接口过于朴素
- 文件存储:日常使用最广泛的存储系统,接口十分友好,实现五花八门
- 对象存储:公有云上的王牌产品,immutable 语义加持
- key-value 存储:形式最灵活,存在大量的开源/黑盒产品
REID (redundant array of inexpensive disks)
RAID 0
- 多块磁盘简单组合
- 数据条带化存储,提高磁盘带宽
- 没有额外的容错设计
RAID 1
- 一块磁盘对应一块额外镜像盘
- 实际空间利用率仅 50%
- 容错能力强
RAID 0 + 1
- 结合了 RAID 0 和 RAID 1
- 实际空间利用率仅 50%
- 容错能力强,写入带宽好
数据库
关系型(SQL支持复杂查询)/非关系型(不要求严格的结构化)
单机存储
单个计算机节点上的存储软件系统
本地文件系统:Linux
key-value存储
分布式存储
单机存储基础上实现分布式协议,设计大量网络交互
分布式文件系统HDFS
支持海量数据结构,高容错,弱POSIX语义,使用普通x86架构,性价比高
Ceph
一切皆对象,数据写入采用主备复制模型,数据分布模型采用CRUSH算法
单机数据库
关系型数据库(MySQL, PostgreSQL)
非关系型数据库(MongoDB, Redis, Elasticsearch)
一般使用SQL直接交互
- Elasticsearch:
- 面向文档存储,数据以 JSON 格式存储,支持嵌套结构。文档集合称为
index,相当于数据库的表。 - 依赖 Lucene 引擎提供存储和索引能力,并内置了大量用于搜索和查询的数据结构和算法,适合需要复杂搜索功能的场景。
- 提供 RESTful API 进行交互,也支持弱 SQL 语句,方便数据的查询和分析。
- 面向文档存储,数据以 JSON 格式存储,支持嵌套结构。文档集合称为
- MongoDB:
- 也是面向文档的存储系统,数据可以序列化为 JSON 或 BSON 格式,支持嵌套结构。文档集合称为
collection,类似于关系型数据库的表。 - 使用 wiredTiger 引擎来管理存储和索引,4.0 版本之后支持事务处理,适用于多文档、跨分片等复杂操作。
- 提供丰富的客户端和 SDK 工具,还可以通过插件支持部分 SQL 语句,用于查询和操作。
- 也是面向文档的存储系统,数据可以序列化为 JSON 或 BSON 格式,支持嵌套结构。文档集合称为
- Redis:
- 以丰富的数据结构著称,包括哈希表(hash)、集合(set)、有序集合(zset)和列表(list)等。
- 采用 C 语言实现,具有极高的性能,通常用于缓存和实时数据处理。虽然主要基于内存存储,但也支持 AOF(追加文件)和 RDB(快照)持久化。
- 常用的交互方式包括
redis-cli命令行和多种语言的 SDK,方便与应用程序集成。
分布式数据库
解决单机数据库问题:容量、弹性、性价比
容量问题: 存储节点池化,动态扩缩容
弹性问题:扩缩容的容量问题
性价比问题:CPU利用率
多写、内存弹性、分布式事务优化
新技术
软件架构变更(Bypass OS kernel)
SPDK (Storage Performance Development Kit)
- Kernel Space -> User Space
- 避免 syscall 带来的性能损耗,直接从用户态访问磁盘
- 中断 -> 轮询
- 磁盘性能提高后,中断次数随之上升,不利于 IO 性能
- SPDK poller 可以绑定到特定的 CPU 核心不断轮询,减少上下文切换 (cs),提高性能
- 无锁数据结构
- 使用 Lock-free queue,降低并发时的同步开销
AI增强
智能存储AI决策——> 行列混存
新硬件革命(存储介质,计算单元,网络硬件)
01. RDMA 网络
- 传统的网络协议栈,需要基于多层网络协议处理数据包,存在用户态 & 内核态的切换,足够通用但性能不是最佳。
- RDMA 是 kernel bypass 的流派,不经过传统的网络协议栈,可以把用户态虚拟内存映射给网卡,减少拷贝开销,减少 CPU 开销。
02. Persistent Memory
- 在 NVMe SSD 和 Main Memory 之间有一种全新的存储产品:Persistent Memory。
- IO 延迟介于 SSD 和 Memory 之间,约百纳秒量级。
- 可以用作易失性内存(memory mode),也可以用作持久化介质(app-direct)。
03. 可编程交换机
- P4 Switch,配有编译器、计算单元、DRAM,可以在交换机层对网络包做计算逻辑。在数据库场景下,可以实现缓存一致性协议等。
04. CPU / GPU / DPU
- CPU:从 multi-core 走向 many-core。
- GPU:强大的算力 & 越来越大的显存空间。
- DPU:异构计算,减轻 CPU 的 workload。