Background

我们的多进程程序碰到一个需求:做key-value查询,然后拿获取到的value去做一些事情。这些key-value存储在很多词典文件中,数量级>10w,如果每个进程都加载一份,内存上是很浪费的,所以需要共享访问,看起来就像是一个IPC使用std::map的场景。有很多方法都可以选择,挑选几类比较下。

Socket

多进程程序作为clients,加载词典提供查询服务的程序作为server,通过网络来交互,很好的避免了共享带来的资源竞争,架构上看是解耦的,细看一下交互过程,client首先send request,触发server查询词典,经过两次memcpy后将value送出,随后client也要经过两次memcpy,最后get response,性能上比较差。

SQLlite

同一sqllite db可以被多进程直接访问,性能相比socket要好的多了,但它的写操作是锁保护的,即同时只能有一个进程访问。sqllite是内存数据库,支持KeyValueDatabase,但根据sqllite官方公布的测试数据来看select性能并不理想

Memory-mapped file

内存映射文件是较理想的进程共享方法,这里是使用方法。我们的词典文件比较多也比较大,频繁的read/write必然会产生大量的系统调用和memory copy,这块可以用mmap来优化(详见)。词典文件内容仅仅从disk映射到了内存,从mmap到hash还需要把原始数据映射成hash,这块如果每个进程都要做一次,性能也好不到哪里。

Shm-hash

shm_hash本质是一个hash,它的时间复杂度也是O(1),设想我们给hash增加一个方法:

  1. //从内存地址直接映射成hash
  2. hash_int_from_memory(void *mem, unit32_t len)

这个方法看似不起眼,但却可以为我们提供避免重复构造hash的功能。

Final

用伪代码描述下shm_hash结合mmap在各个进程的构造过程

  1. //******begin
    //进程A将数据导入到hash
  2. fd = fopen("hash.mmap");
  3. lseek(fd);
  4. ptr = mmap(fd);
  5. hash_int_from_memory(ptr);
  6. while(have) {
  7. hash_add("key", "value");
  8. }
  9. //******end
  10.  
  11. //******begin
    //进程A将数据导入到hash
  12. fd = fopen("hash.mmap");
  13. hash_int_from_memory(ptr);
  14. //******end

一个共享内存hash的更多相关文章

  1. Linux 驱动学习笔记05--字符驱动实例,实现一个共享内存设备的驱动

    断断续续学驱动,好不容易有空,做了段字符驱动的例子.主要还是跟书上学习在此记录下来,以后说不定能回过头来温故知新. 首先上驱动源码 gmem.c: /************************* ...

  2. Linux学习笔记(14)-进程通信|共享内存

    在Linux中,共享内存是允许两个不相关的进程访问同一个逻辑内存的进程间通信方法,是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式. 不同进程之间共享的内存通常安排为同一段物理内存.进程可 ...

  3. linux 共享内存 shmat,shmget,shmdt,shmctl

    shmget int shmget(key_t key, size_t size, int flag);//开辟一段共享内存 key_t key :标识符的规则() size_t size :共享内存 ...

  4. linux进程间通信-共享内存

    转载:http://www.cnblogs.com/fangshenghui/p/4039720.html 一 共享内存介绍 共享内存可以从字面上去理解,就把一片逻辑内存共享出来,让不同的进程去访问它 ...

  5. Linux进程间通信之共享内存

    一,共享内存  内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存.  映射物理内存叫挂接,用完以后解除映射叫脱接. 1,共享内存的特点 ...

  6. linux下共享内存mmap和DMA(直接访问内存)的使用 【转】

    转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...

  7. php 共享内存

    共享内存主要用于进程间通信 php中的共享内存有两套扩展可以实现 1.shmop  编译时需要开启 --enable-shmop 参数 实例: $shm_key = ftok(__FILE__, 't ...

  8. C扩展 从共享内存shm到memcache外部内存

    引言 - ipc - shm 共享内存 本文会通过案例了解ipc 的共享内存机制使用, 后面会讲解C 如何使用外部内存服务memcached. 好先开始了解 linux 共享内存机制. 推荐先参看下面 ...

  9. Linux共享内存(一)

    inux系统编程我一直看 <GNU/LINUX编程指南>,只是讲的太简单了,通常是书和网络上的资料结合着来掌握才比较全面 .在掌握了书上的内容后,再来都其他资料 . 原文链接 http:/ ...

随机推荐

  1. HDU 5832 A water problem(某水题)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  2. 利用gitHub搭建博客

    ##1.gitHub Page的的使用我觉得这边博文写的很清楚,方法.步骤.优缺点以及实例,所以就借用一下啦^_^ [搭建一个免费的,无限流量的Blog](http://www.ruanyifeng. ...

  3. InnoDB和MyISAM(转)

    两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁.而MyISAM不支持. 我作为使用MySQL的用户角度出发,Innodb和MyISAM都是比较喜欢的,但是从我目前运维的数据库平台要达 ...

  4. 深入SpringBoot:自定义PropertySourceLoader

    http://www.jianshu.com/p/5206f74a4406 ********************************* 前言 上一篇文章介绍了SpringBoot的Enable ...

  5. Eclipse 最全快捷键

    英文的

  6. 【转】 strcpy和memcpy的区别

    strcpy和memcpy都是标准C库函数,它们有下面的特点.strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符. 已知strcpy函 ...

  7. SPSS数据分析—单因素及多因素方差分析

    t检验可以解决单样本.两个样本时的均值比较问题,但是对于两个以上样本,就不能用t检验了,而要使用方差分析.t检验是借助t分布,方差分析是借助F分布,基于变异分解的思想进行. 在算法上,由于线性模型的引 ...

  8. [kylin] 部署kylin服务

    一.工具准备 zookeeper3.4.6 (hadoop.hbase 管理工具) Hadoop. Hbase1.1.4 Kylin1.5.0-HBase1.1.3 Jdk1.7.80 Hive 二. ...

  9. 20145224&20145238《信息安全系统设计基础》实验三

    20145224陈颢文20145238荆玉茗 <信息安全系统设计基础>第五次实验报告 课程:信息安全系统设计基础 班级: 1452 姓名:荆玉茗 陈颢文 学号:20145238 20145 ...

  10. 读《程序员的SQL金典》[4]--SQL调优

    一.SQL注入 如果程序中采用sql拼接的方式书写代码,那么很可能存在SQL注入漏洞.避免的方式有两种: 1. 对于用户输入过滤敏感字母: 2. 参数化SQL(推荐). 二.索引 ①索引分类 聚簇索引 ...