尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

聊天室项目遗存问题分析

聊天室项目遗存问题分析 目录答辩中的遗存问题一、进程1. 进程间通信 IPC2. 虚拟内存二、MySQL底层架构2.1 Server层2.2 存储引擎层2.3 InnoDB 存储结构三、Redis底层架构3.1 整体架构分层3.2 为什么Redis这么快四、零拷贝技术sendfile/mmap4.1 传统IO的性能瓶颈4.2 mmap write4.3 sendfile 零拷贝项目中的问题分析一、发送消息慢问题现象1. 根因分析2. 优化方案二、发送文件慢问题现象1. 根因分析2. 优化方案答辩中的遗存问题一、进程进程是操作系统资源分配的基本单位是程序的一次运行实例。每个进程拥有独立的虚拟地址空间包含代码段、数据段、堆、栈等资源进程间相互隔离。线程是CPU调度的基本单位同一进程内的多个线程共享进程的地址空间与系统资源切换开销远小于进程。1. 进程间通信 IPC为了解决进程地址空间隔离、无法直接交换数据的问题。实现分为两大思想共享内存和消息传递。1.1 共享内存多个进程直接映射同一块物理内存区域数据不需要在内核态与用户态之间来回拷贝是速度最快的IPC方式。优势数据直接读写内存无额外拷贝性能最高。劣势进程间没有访问隔离必须配合同步机制保证数据安全。需要配合的同步机制信号量本质是计数器用于控制共享资源的并发访问数量。分为二元信号量和计数信号量通过P操作申请资源、V操作释放资源。互斥锁保证同一时刻只有一个进程进入临界区访问共享内存。条件变量实现进程间的等待-通知机制必须与互斥锁配合使用。1.2 消息传递1管道匿名管道pipe数据只能单向流动仅能用于有亲缘关系的进程通过fork继承文件描述符实现生命周期随进程结束而销毁数据是无格式字节流。命名管道mkfifo支持无亲缘关系的任意进程通信可持久存在。2消息队列对比管道自带消息边界、有数据格式无需额外同步生命周期随内核进程退出后数据仍可保留。3套接字SocketUnix域套接字用于同一主机进程间通信无需经过网络协议栈打包拆包、计算校验和性能远高于网络套接字。接口与网络套接字一致socket/bind/listen/connect仅地址结构不同。网络套接字TCP/UDP基于TCP/IP协议栈实现跨主机通信TCP是可靠字节流UDP是不可靠数据报是分布式系统通信的基础。4信号唯一的异步IPC方式内核向进程发送事件通知进程可注册处理函数响应信号。标准信号131号不可靠信号相同信号多次到达会合并只处理一次不保证传递顺序不携带额外数据。实时信号34~64号可靠信号支持排队每个信号都会被处理保证按发送顺序到达可携带附加数据。2. 虚拟内存虚拟内存是操作系统最核心的内存管理技术为每个进程提供独立、连续、私有的虚拟地址空间让进程以为自己独占全部内存。核心作用进程隔离每个进程地址空间独立一个进程崩溃不会影响其他进程提升系统稳定性与安全性。内存扩展通过Swap交换分区将不常用的内存页换出到磁盘用磁盘空间模拟内存让物理内存可以运行更多进程。简化内存管理进程无需关心物理内存的分配与碎片问题统一使用虚拟地址由操作系统完成映射。实现原理主流采用分页机制。将虚拟内存与物理内存都划分为固定大小的页虚拟地址分为虚拟页号 页内偏移。通过页表维护虚拟页号到物理页号的映射关系。二、MySQL底层架构MySQL采用经典的插件式存储引擎架构整体分为Server层与存储引擎层。2.1 Server层负责MySQL的通用逻辑与核心功能与存储引擎无关所有存储引擎共享这一层能力。连接器管理客户端连接负责身份认证、权限校验维持连接会话与连接池。查询缓存执行查询前先匹配缓存命中则直接返回结果。分析器对SQL进行词法分析、语法分析构建语法树校验SQL语法与表、字段的合法性。优化器生成SQL执行计划选择最优索引决定表的连接顺序与执行方式是SQL性能的关键环节。执行器根据执行计划调用存储引擎接口真正执行SQL语句遍历并返回结果集。2.2 存储引擎层负责数据的存储、读取、事务、锁等底层能力以插件形式挂载到Server层。InnoDB支持ACID事务、行级锁、外键约束采用聚簇索引组织表数据与主键索引存储在一起适合高并发读写、事务型场景。2.3 InnoDB 存储结构InnoDB的存储单位从小到大依次为页Page默认16KB→ 区Extent1MB64个连续页→ 段Segment分为数据段、索引段等。聚簇索引主键索引的叶子节点直接存储完整行数据。二级索引叶子节点存储主键值查询非主键字段需要回表。三、Redis底层架构Redis是高性能内存键值数据库核心采用单线程命令执行 IO多路复用模型。3.1 整体架构分层网络层基于epoll实现IO多路复用单线程处理所有客户端的网络连接与命令请求避免线程切换与锁竞争开销。命令执行层解析客户端命令路由到对应处理函数操作内存数据。存储层内存存储核心支持多种数据类型底层由高效的数据结构实现。持久化层提供RDB快照、AOF日志两种持久化机制防止内存数据丢失。3.2 为什么Redis这么快纯内存操作数据读写都在内存中完成访问延迟低。单线程执行命令无多线程上下文切换开销无锁竞争。IO多路复用模型单线程可处理上万并发连接。四、零拷贝技术sendfile/mmap零拷贝是IO性能优化的核心技术核心目标是减少CPU参与的数据拷贝次数降低内核态与用户态的上下文切换开销广泛应用于文件服务器、消息队列、网关等场景。4.1 传统IO的性能瓶颈使用read write传输文件到网络时会经历 4次数据拷贝 4次上下文切换第一步DMA将磁盘数据拷贝到内核缓冲区内核态。第二步CPU将内核缓冲区数据拷贝到用户缓冲区用户态上下文切换。第三步CPU将用户缓冲区数据拷贝到内核Socket缓冲区内核态上下文切换。第四步DMA将Socket缓冲区数据拷贝到网卡发送。性能损耗核心两次不必要的CPU拷贝以及频繁的状态切换。4.2 mmap write零拷贝mmap将内核缓冲区的地址映射到用户空间用户进程可以直接操作内核缓冲区省去内核到用户的CPU拷贝。第一步mmap 调用DMA将磁盘数据拷贝到内核缓冲区用户空间与内核空间共享该缓冲区。第二步write调用CPU直接将内核缓冲区数据拷贝到Socket缓冲区。第三步DMA拷贝到网卡发送。拷贝次数3次2次DMA拷贝 1次CPU拷贝4.3 sendfile 零拷贝第一步sendfile调用DMA将磁盘数据拷贝到内核缓冲区。第二步CPU仅向Socket缓冲区传递文件描述符与数据长度无数据拷贝。第三步DMA根据描述符直接将内核缓冲区数据拷贝到网卡。拷贝次数2次2次DMA拷贝0次CPU拷贝。项目中的问题分析一、发送消息慢问题现象消息推送模块初期每条消息直接同步写入MySQL高并发下消息延迟高、吞吐低甚至出现数据库连接超时。1. 根因分析第一每次请求都新建数据库连接频繁创建销毁连接开销大。第二单条消息单次写入MySQL磁盘IO次数多事务提交与行锁竞争严重。第三无流量缓冲突发流量直接打到底层数据库容易引发阻塞崩溃。2. 优化方案引入MySQL连接池复用数据库连接避免频繁创建销毁的开销通过连接池控制最大连接数防止连接数过多压垮数据库。Redis做异步缓冲 批量落库消息先写入Redis内存操作毫秒级响应立即返回成功实现削峰填谷后台启动定时消费线程批量将Redis中的消息聚合后写入MySQL。二、发送文件慢问题现象文件传输功能使用传统 read write 实现大文件传输速度慢服务器CPU占用率高并发上传下载能力弱。1. 根因分析传统IO模型下文件数据需要经过磁盘→内核→用户→内核→网卡的多次拷贝CPU大量时间消耗在无意义的数据复制上同时频繁的内核/用户态切换进一步放大系统开销。2. 优化方案使用sendfile减少内核到用户的拷贝减少上下午切换。
返回列表