需要一个支持查询功能的内存key-value,有没有什么好推荐的?
发布于 7 年前 作者 wenbob 4748 次浏览 最后一次编辑是 5 年前 来自 问答

需求比较独特,就是要一个内存版的mongodb: 1、这个hash的key是有时序的,value是JSON格式的数据 2、JSON的读取支持类似mongodb的projection,只返回指定的数据 3、JSON的更新可以指定字段,类似mongodb的update 4、应该支持丰富的查询,包括按regexp查询一个或多个特定的key,或者查询特定字段是否存在,等等 5、API应该是异步的(对于大量数据来说,同步会卡住js进程) 6、占用内存只受配置或硬件限制,应该可以突破2G内存的局限。V8的BUG导致js对象占用空间无法突破2G,不论是不是64位系统。因此这个k-v必然是C++ Addon的实现。 7、不需要实现持久化功能,但是有持久化的event机制,用户可以自己接管事件,自己按需要做磁盘存储。 8、最好支持embedded模式运行。也就是以npm模块的方式在node内部运行,避免进程间通讯的序列化开销。因为频繁处理大批数据时,序列化的成本非常高。

我自己在断断续续做一个这样的东西,但是完成度还很低。大致上,就是用C++的map做保存,做了js的读写接口包装。查询上重点考虑了regexp的优化,测试之后选了速度最快的grep里的dfasearch模块,异步用的就是uv的工作队列。但是不知道怎么搞的,很多地方执行效率很低。。。如果不考虑这货能多线程的话,很多地方甚至不如纯js的速度。理想和现实相差太多。对v8的秉性不熟悉,对C++的优化毫无头绪。而且这货就算写成了也没法发出来了,直接把MIT GPL一堆柔和在一起,貌似法律上也违和了。如果有个现成的。。。真不想写下去了。

p.s. 请不要推荐类似 nedb 这样的纯 js 实现的库,这种库遇到大量数据的时候 node 进程就崩溃了,是 v8 陈年老 BUG 导致的。再说纯 js 实现的计算,量一大就会卡住js线程的,不可取。

11 回复

没听说过这样的内存数据库…

坐等大神…

memcached 这个应该可以满足吧,我感觉

@seasidesun memcached是完完全全没有查询功能的啊。而且也不能避免序列化的开销,各种不适宜。

占用内存只受配置或硬件限制,应该可以突破2G内存的局限。V8的BUG导致js对象占用空间无法突破2G,不论是不是64位系统。因此这个k-v必然是C++ Addon的实现。

nodejs 的 Buffer 是 V8 以外的内存,不受 2G 限制。所以不是非得用 C++ addon

@leapon 异步查询还是需要uv队列的,怎么绕都没办法绕过去

有特殊的需求,很难直接在现有的系统里找到。有没有考虑在现有的系统基础上开发,比如 redis 是开源的。

@leapon 有想过,但是redis代码太庞大了,我不需要那么丰富的数据结构,也不需要那么多功能,只要一个能存储和查询JSON的,所以要么找现成的,要么自己写算了。我们现在的做法就是用redis顶着用,再给redis里的数据建了查询索引。这样解决了大部分的需求,但是遇到了大批数据序列化的时候,还是比较浪费CPU。

自己回自己吧。我最後用 shm 解決了。數據都保存在 /run/shm 的json文件中。這樣,對數據的訪問就變成了對內存文件的訪問。拆分大的數據,放在多個json文件中,減少序列化成本。仿mongodb寫了個查詢和更新的接口。測試結果,多個node併發訪問的速度果然比redis快,解決了之前用redis會卡的問題。

mysql 内存表不行吗,用memory引擎

@103777673 大尺寸的數據,mysql也會在IPC的內存複製、序列化上花費太多時間。共享內存可以避免這個開銷。

回到顶部