当前位置: 首页 > news >正文

【kv存储】持久化模块优化----内存映射取代拷贝式加载

一、项目背景

基于EPOLL的轻量级高性能kv存储项目,可对接博客存储、用户信息缓存、短连接系统后台应用。支持内存池,持久化和主从同步,特殊字符和大value兼容。可redis resp指令操作。redis-benchmark实测,裸奔时单机QPS达19w+

1.1 瓶颈分析

当前kvstore项目全量持久化加载模块kvs_hash_load_rdb采用的是fopen后将.rdb文件中的键值对使用fread读取,然后拷贝一份(malloc分配内存)将这份拷贝写入hash中,从而实现加载。

// 循环读取每条记录 - 这里有性能瓶颈while(1){// 瓶颈1: 同步阻塞I/O - 每次fread都会等待磁盘fread(&klen,...);// 阻塞fread(key,...);// 阻塞fread(&vlen,...);// 阻塞fread(val,...);// 阻塞// 瓶颈2: 频繁内存分配和拷贝void*key=malloc(klen);// 系统调用void*val=malloc(vlen);// 系统调用kvs_hash_set(...);// 内部再次malloc拷贝free(key);// 系统调用free(val);// 系统调用}

性能瓶颈分析:fread同步磁盘读取所导致的阻塞,频繁malloc的系统调用开销

优化办法:用mmap内存映射,直接在映射的内存块中解析键值对

二、内存映射优化

2.1 mmap介绍

#include<sys/mman.h>void*mmap(void*addr,size_tlength,intprot,intflags,intfd,off_toffset);
  • mmap核心概念

    • 文件映射到进程地址空间

    • 按需加载(缺页中断)

    • 零拷贝(直接使用映射内存)

2.2 优化后的加载函数

intkvs_hash_load_rdb(kvs_hash_t*hash,constchar*filename){// 1. 参数检查if(!hash||!filename)return-1;// 2. 打开文件intfd=open(filename,O_RDONLY);if(fd<0){printf("[RDB] Failed to open file: %s\n",filename);return-1;}// 3. fstat获取文件大小structstatst;if(fstat(fd,&st)!=0){close(fd);return-1;}size_tsize=st.st_size;if(size==0){close(fd);return0;}// 4. mmap映射文件void*data=mmap(NULL,size,PROT_READ,MAP_PRIVATE,fd,0);close(fd);if(data==MAP_FAILED){return-1;}// ===== mmap映射内存中的键值对解析逻辑 =====char*p=data;// 指向映射内存起始位置char*end=data+size;// 映射内存结束边界intloaded=0;while(p<end){// 5.1 读取key长度(定长)size_tklen=*(size_t*)p;p+=sizeof(size_t);// 5.2 key数据指针(直接指向映射内存)void*key=p;p+=klen;// 5.3 读取value长度(定长)size_tvlen=*(size_t*)p;p+=sizeof(size_t);// 5.4 value数据指针(直接指向映射内存)void*val=p;p+=vlen;// 5.5 插入哈希表(使用直接指针,零拷贝)kvs_hash_set_direct(hash,key,klen,val,vlen);loaded++;}// ======================================// 6. 返回加载数量printf("[RDB] Loaded %d keys\n",loaded);returnloaded;}

总结

mmap的使用

  • mmap参数详解

    • addr:映射起始地址(通常NULL)

    • length:映射长度(fstat获取文件大小)

    • prot:保护标志(PROT_READ/PROT_WRITE)

    • flags:映射标志(MAP_PRIVATE/MAP_SHARED)

    • fd:文件描述符

    • offset:文件偏移量(通常0)

  • 辅助函数

    • open():打开文件

    • fstat():获取文件大小

    • close():关闭文件描述符

    • munmap():解除映射

http://www.jsqmd.com/news/449717/

相关文章:

  • 构建安全桥梁:前后端分离架构下的数据交互与防护指南
  • 基于粒子群算法优化bp神经网络(PSO-BP)回归预测模型 实现平台:Matlab 多特征输入
  • ebmap Tour 导览地图制作之 路网绘制
  • 写作小白救星 10个AI论文平台深度测评,专科生毕业论文写作必备!
  • 实测20款适合东南亚语言配音软件推荐,以下6款全支持
  • 拖延症福音!千笔·专业论文写作工具,领军级的AI论文平台
  • MATLAB高效调试与性能优化全攻略
  • 2026年盘锦大米:揭秘源头厂家背后的秘密与排名!
  • 〘 3-1 〙软考高项 | 第10章:项目进度管理(上)
  • 【Java】随机文件读写利器:RandomAccessFile详解
  • 永磁同步电机(PMSM)的转速环模糊滑模
  • 比迪丽LoRA部署实录:从裸机Ubuntu到WebUI可用的30分钟完整过程
  • 向光生长优化算法(PGA)-2025年SCI一区新算法-公式原理详解与性能测评 Matlab代码免费获取
  • pytest测试框架3-web自动化
  • 基于Django的Python音乐智能推荐系统(含完整源码+12000字毕业论文+实操演示视频)
  • 基于深度学习的绝缘子缺陷识别检测系统|全新web界面|多模态|AI大模型智能分析|YOLOv8、YOLOv10、YOLOv11、YOLOv12
  • YOLOv5+Qwen3-ASR-0.6B构建智能监控告警系统
  • BAT资深工程师主讲|Python自动化运维高阶实战课(含Python零基础入门+全套源码课件)|从0搭建企业级运维自动化平台
  • 文件自动同步软件:PanguFlow
  • 多层电路板哪家强?2026年猎板性能与性价比评测
  • 林俊旸:阿里千问的“吹哨人”
  • 使用Typora撰写FRCRN技术文档:Markdown与图表完美结合
  • 小程序制作平台对比:码云数智、有赞、微盟深度解析
  • 基于MATLAB的D2D Cluster建模与资源分配实现
  • 遗传-粒子群自适应优化算法--MATLAB 两个算法融合且加入自适应变化的权重和学习因子
  • 【MongoDB】深入研究副本集与高可用性——Replica Set 架构、故障转移、读写分离 - 教程
  • 万象熔炉 | Anything XL从零开始:safetensors单文件加载与Euler A调度器调优
  • 那层看不见的防线
  • 低成本玩转AI绘画:Stable Diffusion v1.5 低显存需求与高效部署方案
  • Pi0机器人模型效果实测:生成(50,14)维度数组对接ROS/Mujoco