`

基于共享内存的key-value存储

阅读更多

<!-- [if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:TrackMoves/> <w:TrackFormatting/> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF/> <w:LidThemeOther>EN-US</w:LidThemeOther> <w:LidThemeAsian>ZH-CN</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:SplitPgBreakAndParaMark/> <w:DontVertAlignCellWithSp/> <w:DontBreakConstrainedForcedTables/> <w:DontVertAlignInTxbx/> <w:Word11KerningPairs/> <w:CachedColBalance/> <w:UseFELayout/> </w:Compatibility> <m:mathPr> <m:mathFont m:val="Cambria Math"/> <m:brkBin m:val="before"/> <m:brkBinSub m:val="&#45;-"/> <m:smallFrac m:val="off"/> <m:dispDef/> <m:lMargin m:val="0"/> <m:rMargin m:val="0"/> <m:defJc m:val="centerGroup"/> <m:wrapIndent m:val="1440"/> <m:intLim m:val="subSup"/> <m:naryLim m:val="undOvr"/> </m:mathPr></w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true" DefSemiHidden="true" DefQFormat="false" DefPriority="99" LatentStyleCount="267"> <w:LsdException Locked="false" Priority="0" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Normal"/> <w:LsdException Locked="false" Priority="9" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="heading 1"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/> <w:LsdException Locked="false" Priority="39" Name="toc 1"/> <w:LsdException Locked="false" Priority="39" Name="toc 2"/> <w:LsdException Locked="false" Priority="39" Name="toc 3"/> <w:LsdException Locked="false" Priority="39" Name="toc 4"/> <w:LsdException Locked="false" Priority="39" Name="toc 5"/> <w:LsdException Locked="false" Priority="39" Name="toc 6"/> <w:LsdException Locked="false" Priority="39" Name="toc 7"/> <w:LsdException Locked="false" Priority="39" Name="toc 8"/> <w:LsdException Locked="false" Priority="39" Name="toc 9"/> <w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/> <w:LsdException Locked="false" Priority="10" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Title"/> <w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/> <w:LsdException Locked="false" Priority="11" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/> <w:LsdException Locked="false" Priority="22" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Strong"/> <w:LsdException Locked="false" Priority="20" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/> <w:LsdException Locked="false" Priority="59" SemiHidden="false" UnhideWhenUsed="false" Name="Table Grid"/> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/> <w:LsdException Locked="false" Priority="1" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 1"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 1"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 1"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/> <w:LsdException Locked="false" Priority="34" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/> <w:LsdException Locked="false" Priority="29" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Quote"/> <w:LsdException Locked="false" Priority="30" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 1"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 1"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 2"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 2"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 2"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 2"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 2"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 3"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 3"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 3"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 3"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 3"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 4"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 4"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 4"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 4"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 4"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 5"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 5"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 5"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 5"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 5"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 6"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 6"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 6"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 6"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 6"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/> <w:LsdException Locked="false" Priority="19" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/> <w:LsdException Locked="false" Priority="21" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/> <w:LsdException Locked="false" Priority="31" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/> <w:LsdException Locked="false" Priority="32" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/> <w:LsdException Locked="false" Priority="33" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Book Title"/> <w:LsdException Locked="false" Priority="37" Name="Bibliography"/> <w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/> </w:LatentStyles> </xml><![endif]--><!-- [if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-font-kerning:1.0pt;} table.MsoTableGrid {mso-style-name:网格型; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-priority:59; mso-style-unhide:no; border:solid black 1.0pt; mso-border-themecolor:text1; mso-border-alt:solid black .5pt; mso-border-themecolor:text1; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-border-insideh:.5pt solid black; mso-border-insideh-themecolor:text1; mso-border-insidev:.5pt solid black; mso-border-insidev-themecolor:text1; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-font-kerning:1.0pt;} </style> <![endif]--><!-- [if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="1035"/> </xml><![endif]--><!-- [if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1"/> <o:rules v:ext="edit"> <o:r id="V:Rule1" type="connector" idref="#_x0000_s1031"/> <o:r id="V:Rule2" type="connector" idref="#_x0000_s1034"/> <o:r id="V:Rule3" type="connector" idref="#_x0000_s1032"/> <o:r id="V:Rule4" type="connector" idref="#_x0000_s1033"/> </o:rules> </o:shapelayout></xml><![endif]-->

1 定义

MemKeyValue 是一个基于共享内存的随机访问存储模型,可供不同的进程同时调用。

2 应用场景及需求

MemKeyValue 主要应用在如下场景,有一份数据,只用初始化一次,然后多个进程都会用到这份数据。采用 MemKeyValue 共享内存的方式,可以多个进程同时共享一份数据,从而能够达到节省内存,减少操作的目的。

根据应用场景,提炼出具体的需求

a 共享内存

b 读写

c c/c++

d 无视线程安全

e 内存利用率 80% 以上

3 实现

3.1 进程间通信方式的选定

由于需要在不同的进程间共享内存,首先,进程间主要需要共享大量的数据,其次,进程间不一定存在父子进程的关系。所以,最终,选择采用 System V 共享内存的方式,主要用到的系统调用如下

shmget() shmat() shmdt() shmctl()

头文件:

#include <sys/ipc.h>

#include <sys/shm.h>

shmget ()用来获得共享内存区域的 ID ,如果不存在指定的共享区域就创建相应的区域。 shmat() 把共享内存区域映射到调用进程的地址空间 中去,这样,进程就可以方便地对共享区域进行访问操作。 shmdt() 调用用来解除进程对共享内存区域的映射。 shmctl 实现对共享内存区域的控制操 作。这里我们不对这些系统调用作具体的介绍,读者可参考相应的手册页面,后面的范例中将给出它们的调用方法。

需要注意的是 shmget 的内部实现包含了许多重要的系统 V 共享内存机制; shmat 在把共享内存区域映射到进程空间时,并不真正改变进程的页 表。当进程第一次访问内存映射区域访问时,会因为没有物理页表的分配而导致一个缺页异常,然后内核再根据相应的存储管理机制为共享内存映射区域分配相应的 页表。

3.2 算法选择及内层模型

结合应用场景及实现方式,采用双重 hash 的方式来实现

A

B

D

C

E

图中

A 无碰撞,

B A 碰撞以,即 A->B

C A B 碰撞 , A->B->C

D 无碰撞

E D 碰撞,即 D->E

由此,我们可以看出,对于这种形式的结构,也维护有一个隐式的“链表”,即 hash 算法的碰撞位置

3.3 主要接口及实现

Hashtable.h

/*

* Creates a new hash table with the specified characteristics.

*

* Returns NULL if insufficent space is available or

* the new hash table otherwise.

*/

struct hashtable *hashtable_create( const char * path,long capacity, float max_usage_percent, short key_size, short value_size,

void * stop_cond, void * del_cond);

/*

* Inserts the specified (key, datum) pair into the specified hash table.

*

* Returns -ENOMEM on memory allocation error,

* -EINVAL for general errors or

* 0 otherwise.

*/

int hashtable_update(struct hashtable *h, void *k, void* d);

/*

* Searches for the entry with the specified key in the hash table.

*

* Returns NULL if no entry has the specified key or

* the datum of the entry otherwise.

*/

int hashtable_search(struct hashtable *h, void* key , void *datum);



Hashtable.c

struct hashtable *hashtable_create( const char * path,long capacity, float max_usage_percent,short key_size,short value_size,void * stop_cond, void * del_cond)

{

struct hashtable * p;

key_t shm_mem_key;

int i;

p = (struct hashtable *) malloc (sizeof(*p));

if (NULL == p)

return NULL;

p->capacity = capacity;

/* initialize the shared memory address space */

shm_mem_key = ftok(path,0);

if (shm_mem_key == -1){

free(p);

perror("ftok error");

return NULL;

}

/*

* Here have two scenario, first,if it's the first time the shared memory

* created, the memory should created and initialized;

* Second,if the memory is already created and "dirty" now, just attached

* on it.

*/

p->shm_id =shmget(shm_mem_key, p->capacity ,IPC_CREAT | IPC_EXCL | 0666);

/* shared memory first created */

if(p->shm_id !=-1){

p->htable=(void *)shmat(p->shm_id,NULL,0);

if( (void *)-1 == p->htable ){

free(p);

perror("shmat error\n");

return NULL;

}

/* does this have problem when we set the stop condition?? */

p->capacity = capacity;

p->size = calculate_size( capacity, key_size, value_size);

p->key_size = key_size;

p->value_size = value_size;

memcpy( p->stop_cond, stop_cond, p->key_size);

memcpy( p->del_cond, del_cond,p->key_size);

if ( p->key_size == 4){

p->hash_value = bit_32_hash;

}else if (p->key_size == 8 ){

p->hash_value = bit_64_hash;

}

memset(p->htable,0,p->capacity);

for ( i =0; i< p->size; i++ ){

memcpy( ((unsigned char *)p->htable) + i* (p->key_size + p->value_size),p->stop_cond,p->key_size);

}

… …

} else {

p->shm_id = shmget(shm_mem_key,p->capacity,IPC_CREAT );

if(p->shm_id==-1)

{

free(p);

perror("shmget error\n");

return NULL;

}

p->htable=(void *)shmat(p->shm_id,NULL,0);

if( (void *)-1 == p->htable ){

free(p);

perror("shmat error\n");

return NULL;

}

… …

if ( p->key_size == 4){

p->hash_value = bit_32_hash;

}else if (p->key_size == 8 ){

p->hash_value = bit_64_hash;

}

}

return p;

}

int hashtable_update(struct hashtable *h, void* k, void* d)

{

long hvalue,rehash_value;

unsigned char * cur;

int n;

… …

n=0;

rehash_value =0;

hvalue = h->hash_value(h,k);

cur = ((unsigned char *) h->htable) + hvalue * (h->key_size + h->value_size );

while ( memcmp(cur,h->stop_cond,h->key_size) !=0 ) {

/* this is update the value with the same key */

if ( memcmp(cur,k,h->key_size) == 0 ){

memcpy( cur + h->key_size, d, h->value_size);

return 1;

}

n++;

/* if some extreme situation, maybe dead loop */

if ( n > 1000000){

h->collision_times += n;

memcpy(h->save_info_base + 16, &h->collision_times,8);

return -2;

}

rehash_value = ( hvalue + n*( 1 + ( hvalue >> 5 + 1) ) ) % (h->size );

cur = ((unsigned char *) h->htable ) + rehash_value * ( h->key_size + h->value_size );

}

memcpy(cur, k, h->key_size);

memcpy( cur + h->key_size, d, h->value_size);

return 0;

}

int hashtable_search(struct hashtable *h, void* k, void * datum)

{

long hvalue,rehash_value;

unsigned char * cur;

int n;

if ( !h)

return 0;

n=0;

rehash_value =0;

hvalue = h->hash_value(h,k);

cur = ((unsigned char *) h->htable) + hvalue * ( h->key_size + h->value_size );

while ( memcmp(cur,h->stop_cond,h->key_size) !=0){

if (memcmp(cur,k,h->key_size ) == 0 ){

memcpy(datum, cur + h->key_size,h->value_size);

return 0;

}

n++;

/* if some extreme situation, maybe dead loop */

if ( n > 1000000){

h->collision_times += n;

memcpy(h->save_info_base + 16, &h->collision_times,8);

return -2;

}

rehash_value = ( hvalue + n*( 1 + ( hvalue >> 5 + 1 ) ) ) % (h->size );

cur = ((unsigned char * ) h->htable) + rehash_value * ( h->key_size + h->value_size);

}

return -1;

}

4 具体的应用场景

5 问题

1 Linux 下共享内存的默认大小太小

linux 下,共享内存的默认大小为 32M, 在实际的应用场景中,是远远不够的。需要采用如下的方式更改共享内存的大小

sysctl -w kernel.shmmax=134217728

( 更改成 128M)

2 MemKeyValue 不是线程安全的

考虑到效率的原因,本没有做同步的机制,因此,在支持多线程的调用时,需要上层应用来做线程间的同步,即在调用 update 操作时加锁。

3 进程间没有同步的机制

进程间没有同步的机制,当前的应用场景是一个进程写,其它的进程多,因此,不考虑多进程间的同步。而如果要扩展到多进程的应用,则需要考虑这个问题。

分享到:
评论

相关推荐

    论文研究-基于关系型与Key-Value型数据库混合存储的多租户数据存储架构 .pdf

    基于关系型与Key-Value型数据库混合存储的多租户数据存储架构,蔺皓,王柏,针对SaaS多租户、可配置、易扩展的特点,在设计其数据存储架构时存在三种主流方案:数据库分离法、表空间分离法以及共享表空间法��

    PerconaFT, PerconaFT是高性能的事务性 key-value 存储.zip

    PerconaFT, PerconaFT是高性能的事务性 key-value 存储 PerconaFTPerconaFT是一个高性能。事务性的key-value 存储,用于Percona服务器和MySQL的TokuDB存储引擎,在TokuMX中。PerconaFT是作为一个共享库提供的,接口...

    keydb:用 Go 编写的高性能键值数据库

    请参阅相关的 ,它允许远程访问 keydb 实例,并允许多个进程共享一个 keydb 数据库待办事项使一些设置可配置清除删除的键/值,它当前存储一个空的 [] 字节如何使用 db, err := keydb.Open("test/mydb", true)if err...

     Android的SharedPreferences的使用

    SharedPreferences是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data/&lt;包名&gt;/shared_prefs目录下。SharedPreferences对象本身只能...

    TiDB 辅导材料,考前必看

    主键(Primary Key)对应的数据作为 value,形成 key-value 对,将这些 key-value 存储在一个 region 中。如果 region 大小超过 96MB,则分裂为 2 个。 6、TiDB Server 的 GC 机制: GC 会被自动触发,默认是 10 ...

    Android实现数据存储技术

    SharedPreferences 存储的数据是基于 XML 文件存储 key-value 键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data/&lt;包名&gt;/shared_prefs 目录下。 文件存储数据 文件存储是 Android 平台上的一种...

    android 数据存储

    SharedPreferences 适合存储一些小型数据,内部存储和外部存储适合存储一些大型文件,SQLite 数据库适合存储大量结构化数据,Content Provider 适合存储一些需要跨应用程序共享的数据。了解这些方式的特点和使用场景...

    C#操作Redis明细内容 C#调用redis c#使用redis业务 C# Redis操作类 C#中Redis封装的类 C#

    是一个key-value存储系统 2)高性能、可靠性 Redis将数据存储在内存中,读写性能高;Redis提供了 RDB和AOF持久化,可将内存数据存盘,避免断电数据丢失 3)支持多种数据类型,常见的如 string、list、hash、set、...

    key-reference:用于共同开发实用程序的共享存储库,用于编写关键参考文件

    密钥参考实用程序 用法 如此调用: key-reference &lt;appname&gt; &lt;ident&gt; 例如: key-reference pkcs11 uaf0c15504eff737138a32527be52cf97ae50118a8 outfile.pem ... "NFKM Hash:" + \0 + &lt;the&gt; + \0 + the value 42

    SpringData.zip

    Spring Data 包含多个子项目:Commons - 提供共享的基础框架,适合各个子项目使用,支持跨数据库持久化Hadoop - 基于 Spring 的 Hadoop 作业配置和一个 POJO 编程模型的 MapReduce 作业Key-Value - 集成了 Redis 和 ...

    Spark大数据处理

    第1章 Spark简介 ...3.2.2 RDD与分布式共享内存的异同 3.2.3 Spark的数据存储 3.3 Spark算子分类及功能 33.3.1 Value型Transformation算子 3.3.2 Key-Value型Transformation算子 3.3.3 Actions算子 3.4 本章小结

    keyvi:Keyvi-键值索引。 它是基于内存FST的数据结构,针对大小和查找性能进行了高度优化

    共享内存的使用使其具有可伸缩性和抵抗力。 与其他存储最大的不同是基于的基础数据结构。 存储空间效率高,速度快,并且通过设计可以进行各种近似匹配,无论是模糊字符串匹配还是地理高效。 不变的FST数据结构可...

    尚硅谷_Redis.docx

    Redis是一个key-value存储系统,是当下互联网公司常用的NoSQL数据库之一,是进入互联网行业的Java开发工程师必备技术。 在本课程中,你将了解Redis是什么、能干什么、如何用,了解NoSQL的使用场景和概念,快速掌握...

    什么是NoSQL数据库?

    这里的key-value存储不像memcached那样在内存中保存数据,而是把数据保存在硬盘上。与memcached在内存中处理数据比起来,由于必然要发生对硬盘的IO操作,所以性能上还是有差距的。但数据不会丢失是它最大的优势。 ...

    尚硅谷Redis入门视频

    Redis(REmote DIctionary Server)是一个key-value存储系统,是当下互联网公司最常用的NoSQL数据库之一,是进入互联网行业的Java开发工程师必备技术。 在本课程中,你将了解Redis是什么、能干什么、如何用,了解...

    Redis 6 入门到精通 超详细 教程

    Redis 是一个开源的 key-value 存储系统,可以作为缓存数据库辅助持久化的数据库。Redis 的数据类型包括 string、list、set、hash、zset 等,支持 push/pop、add/remove 及取交集并集和差集等操作。 Redis 的特点是...

    ios经典面试题

    5. **键-值编码(Key-Value Coding, KVC)和键路径(Key-Value Observing, KVO)**: - KVC是一种间接访问对象属性的技术,通过键来获取或设置对象的属性值,简化了代码,使得动态访问属性成为可能。 - KVO是一种...

    云计算分布式缓存技术及其在物联网中的应用.docx

    因此,IT企业开始探索新的存储方案,如亚马逊的Dynamo,它是一种Key-Value存储系统,被广泛应用于亚马逊的各种服务中。Google的BigTable、Amazon的Dynamo以及Facebook的Cassandra等分布式缓存系统的发展,使得基于...

    HarmonyOS之通过 Preferences 创建、删除、更新和查询应用程序偏好数据实现登录页面偏好数据存取及主页面背景色偏好数据存取.zip

    轻量级偏好数据库主要提供轻量级Key-Value操作,支持本地应用存储少量数据。本示例通过 Preferences 创建、删除、更新和查询应用程序偏好数据,主要实现了登录页面偏好数据存取及主页面背景色偏好数据存取。 说明: ...

    python的redis数据库连接与使用

    Redis 是一个基于内存的 key-value 存储系统,可以存储多种数据类型,包括字符串、链表、集合、有序集合和哈希类型等。Redis支持原子的操作,包括 push/pop、add/remove 等操作,并支持 master-slave 同步。 安装 ...

Global site tag (gtag.js) - Google Analytics