在c+++中如何存储++key-value,但是key有重复,怎么存储

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在c+++中如何存储++key-value,但是key有重复,怎么存储相关的知识,希望对你有一定的参考价值。

参考技术A 对于key - value这种情况的数据,不允许重复的可以选择map存储
如果key有重复的情况,可以选择使用multimap。使用方法跟map一样
问题解决,请采纳!
参考技术B 问题说的再明白点追问

在c++,
如何存储key-value对,
但是key有重复,
存储在哪里比较好?

分布式流式计算系统之Key-Value存储组件

一个人,只有在实践中运用能力,才能知道自己的能力

--小塞涅卡 


动机

1、无论如何设计一个功能完善的分布式流式计算系统,都需要一个快速有效的存储组件

3、随机读取性能要非常高

4、本着系统设计自包含、高内聚的原则,尽最大能力的减少外部依赖,需要一个特定场景使用的Key-Value存储组件

问题域

前段时间仔细考察评估了江湖上几大赫赫有名的KV存储,如C/C++版的LeveldbRocksdbLmdbRedis还有Golang版的BoltdbgoleveldbBadgerdb,这些存储基本都是朝着通用存储方向研发的,其实很多功能是不需要的,数据组的大多数服务应用都是Golang开发的,Golang引入cgo每开一个通道都需要增加额外的2M内存空间,虽然这对于使用Rocksdb来说是值得的,这货太强了,如果玩开了的话,绝对超乎想象,这就暴露出它的一个缺点,设置选项多而复杂,太耗心智,针对不同的物理存储设备需要做不同的优化设置(下面有时间再剖析这个牛叉叉的KV存储吧)。Redis需要独立运行,而且没有用户的概念,在线上跑很容易造成信息被改写,这是对于重要的服务来说是极其不安全的。LeveldbLmdbRocksdb相比的话基本没有什么优势了,Leveldb是谷歌大婶jeff Deam主导研发的,在谷歌内部存储几十亿上百亿的数据,也许是因为这个原因吧,使得其使用的LSM算法很快被技术圈广泛采纳,类似的产品也层出不穷,例如Casandra HBase等,RocksdbFacebook公司fork谷歌的Leveldb,做了很多细致的优化,还增加了如列族等特色功能,但由于是C/C++版的,除了上文已提过的两个缺点之外,windows开发环境编译也蛮蛋疼的,不利于提供开发体验,而且用户社区比较活跃,通常都是一周一个版本,我这样的版本帝,知道新版本出来,总想着要更新,并且了解新特性啥的(当然这个不是关键问题),于是决定舍弃。然后就就在BoltdbgoleveldbBadgerdb三者比较测试了一下,100万条KV数据,key长度16个字节,value长度随机512个字节 10个并行读写处理 测试环境: 24线程 4G内存 7200rpm机械硬盘。

测试结果:

Boltdb:写入速度大约每秒8000左右,读取速度大约每秒25.5万左右

Goleveldb: 写入速度大约每秒4.8万左右,读取速度大约每秒7万左右

Badgerdb: 写入速度大约每秒6.7万左右,读取速度大约每秒10.1万左右

注:这里的读取是指读取到正确数据操作,晒出来都是最好成绩

测试了性能之后,粗略的看了一下源码,Boltdb是采用B+树来组织数据的,GoleveldbportC/C++版的Leveldb,算法如出一辙,都是采用LSM算法,存储采用Level级处理存储,Badgerdb算法与Leveldb算法也是一样的,但采取KeyValue分开存储的方式,据说还根据最新的SSD写放大处理论文做了优化,这在我的测试机上是没法测出来的,从目前的测试结果来看,Boltdb是比较符合我的需求的,其实goleveldb如果加上LRUBloom过滤估计还能提升一些性能,但从其算法来看性能是极其不稳定的。

解决方案

初步决定是采用boltdb来做关键存储组件。在家休息的几天,溜娃的时候就在想,我为什么不用Hash算法实现一个KV存储呢,读写操作都是一个常量时间,想到立马就做,开始构思,怎么整这个玩具(没有投产过,都应该是玩具吧)。

最后,我还想说的是一个服务或者系统性能(处理能力),与开发工具语言有一定的关系,但不是关键因素(虽然golang在底层执行效率上的确不如C/C++Java等老牌工具,但随着时间流逝,这个差距会越来越小的,自从1.8版以后几乎与Java没有差距了),我认为关键因素在于系统设计与算法上,一个基础设施的设计不但要考虑上层应用的使用场景和姿势,还要考虑自身处理算法,更重要的是要符合硬件的尿性!

好了,还想说的是:状态已恢复,“我胡汉三又回来啦”,哈哈……,下一篇估计要等到一两周后,目前还没有想好怎么优化其写入性能(这个KV存储目前还没有名字,暂时叫它skv吧),而读取性能其实仍然还有优化的空间,一个系统的优化应该先从架构算法上进行优化,然后再优化代码层面上的才对。

以上是关于在c+++中如何存储++key-value,但是key有重复,怎么存储的主要内容,如果未能解决你的问题,请参考以下文章

[译]C语言实现一个简易的Hash table

HotRing: A Hotspot-Aware In-Memory Key-Value Store

HotRing: A Hotspot-Aware In-Memory Key-Value Store

Redis与其他数据库key-value存储有什么不同?

c语言中num[k++]=i是啥意思

consul 配置---K/V存储及ACL