本发明涉及的是一种信息处理领域的技术,具体是一种面向对象的内存数据存储系统。
背景技术:
随着大数据时代的来临,数据规模越来越大,数据种类越来越多样化,既包括传统的结构化数据,又包括非结构化数据。大数据所带来的大规模及需要实时处理的特点使得传统内存-磁盘模式的数据库处理大数据时不可避免的存在i/o瓶颈,难以满足处理速度和实时性的要求。
以redis为代表的k/v(key-value)缓存数据库,将所有的数据及计算过程完全置于内存中,性能极高,可以极大提高系统应对高并发的能力,但是难以存储结构较为复杂的对象型数据,而这样的对象型数据在互联网业务中十分常见,所以,需要构建一种支持对象型数据存储的高性能内存数据存储系统。
技术实现要素:
本发明针对现有k/v型内存数据库难以存储较为复杂的对象型数据的问题,提出一种面向对象的内存数据存储系统,能够兼顾高性能与复杂对象型数据存取。
本发明是通过以下技术方案实现的:
本发明包括:网络通信模块、命令解析执行模块和存储模块,其中:网络通信模块对来自客户端的连接请求和计算请求进行调度处理,命令解析执行模块解析客户端发送的数据并对解析得到的结果进行执行,存储模块对内存中的数据进行组织优化处理,从而有效提高命令执行的效率。
所述的调度处理是指:接收新的客户端的连接请求;对已建立连接的客户端的命令及时进行响应;定期清理闲置时间过长的客户端,以优化系统资源分配。
所述的命令解析是指:将客户端发送的数据按照事先规定好的通信协议解析成对应类型的命令,并进行相应的处理。
所述的组织优化处理包括:通过内存池以及封装于操作系统上层的统一的内存管理接口对内存资源进行统一管理以减少内存碎片以及以优化的存储结构存储对象型数据并通过维护索引的方式优化查询请求,实现对对象型数据进行优化操作。
技术效果
本发明整体解决现有的内存数据库难以存储较为复杂的对象型数据的技术问题。
与现有技术相比,本发明支持复杂对象型数据的优化存取,使其更适合处理互联网业务数据;采用明确的模块划分,命令处理相关逻辑和存储模块分离,因此任何符合规范的存储方案都可以作为本发明内存数据存储系统的存储引擎。这种设计使得系统更加灵活,并可以根据具体业务场景选择不同的存储方案来优化系统性能。
附图说明
图1为本发明对象数据存储系统示意图;
图2为本发明网络模块示意图;
图3为本发明内存管理示意图;
图4为本发明对象存储示意图;
图5为本发明跳表索引示意图;
图6为本发明索引页面结构示意图。
具体实施方式
如图1所示,为本实施例涉及一种面向对象的内存数据存储系统,包括:网络通信模块、命令解析执行模块和存储模块,其中:网络通信模块对来自客户端的连接请求和计算请求进行调度处理,命令解析执行模块解析客户端发送的数据并对解析得到的结果进行执行,存储模块对内存的数据进行组织优化处理,从而有效提高命令执行的效率。
所述的调度处理是指:网络通信模块通过主线程接收客户端的连接请求,并将连接相关信息通过工作线程的连接队列传输给工作线程,其中:每个工作线程与一个libevent实例绑定,并通过这个libevent实例对事件(读数据、写数据等)进行处理。
本实施例使用开源的高性能网络事件库libevent来统一处理网络i/o事件和定时事件。
所述的内存数据存储系统在初始化时,创建主线程和指定数量工作线程,其中:①主线程向libevent注册回调函数,当监听的端口接收到连接请求时,通过round-robin算法选择一个工作线程,将连接相关信息添加到该工作线程对应的连接队列中,然后向该工作线程的管道写数据;②工作线程向libevent注册回调函数,当监听到管道有数据写入时,从连接队列取出并接管连接,后续由该工作线程处理该连接对应的客户端的查询请求。
所述的命令解析执行模块包括:命令解析单元、命令执行单元,其中:命令解析单元检验用户发送的命令格式是否符合通信协议规范,并对命令进行解析,将提取出的内容传输给命令执行单元进行执行。
所述的通信协议规范是指:客户端和服务器之间传输的消息格式,其中:每条消息由消息头和消息体组成,消息头为描述消息基本信息的字段;消息体为经过二进制编码序列化的json文档。
所述的命令解析单元从消息头中获取操作类型,对消息体进行解码,获得有关信息。例如,对一条查询命令,命令解析执行模块将在命令格式检验之后从消息体中获取查询条件等信息。
所述的命令执行单元根据不同的命令类型采取不同的处理逻辑进行执行,最终都将转化为对下层存储模块的不同操作。
所述的命令类型包括:类型定义、插入、删除、查询、更新。
所述的存储模块包括:基于内存池的统一内存管理单元、页面存储单元,其中:内存池在操作系统上层封装统一的内存管理接口,供页面存储单元使用,页面存储单元以页为单位对数据进行组织,并使用索引对查询进行优化。
如图3所示,所述的统一内存管理是指:内存池维护若干个大小不同的空闲链表,每次内存请求根据请求大小选择对应的空闲链表,当对应的空闲链表不为空,则直接从空闲链表中分配,否则从内存池中分配内存;当内存池内存不足,则使用glibc中提供的malloc一次向操作系统申请一大块内存,对内存池进行补充;当释放内存时,根据释放的内存块大小插入到对应的空闲链表中。
这种内存管理的方式由于一次分配大块内存,有效减少内存碎片的产生,也减少直接调用glibcmalloc/free的次数,从而提高效率。
所述的以页为单位对数据进行组织是指:以固定大小的页(如4kb),每个页面存放多个对象。如图4所示,本实施例中,对象型数据形式上由键值对组成,且允许嵌套。对于每一个对象,存储在最前面的是键值对的数量和大小等元信息,其后是键指针组和值指针组,分别指向具体的键和值数据。为便于查找,键指针组事先根据键进行排序,值指针组根据对应键的位置依次排列。其中的内存分配回收等操作均置于前述的内存管理器的管理之下。由于内存空间是有限的,因此使用lru(latestrecentused)算法对对象数据进行管理。在本实施例中,将对象数据用指针链接成链表,最频繁使用的数据在lru链表的前端,最少使用的数据在lru链表的尾端。当内存空间不足时,将首先从lru链表中释放尾端的数据。
所述的使用索引对查询进行优化是指:存储模块通过如图5所示的跳表实现对索引提供支持,该跳表是一种允许优化查询、插入和删除的数据结构,时间复杂度均为o(logn)。
如图6所示,所述的索引采用分页的方式进行存储,页面大小固定,包括:头部信息、索引指针数组、实际索引元组,其中:头部信息用于存储页面的元信息,例如已插入的索引元组数等;索引指针数组用于对实际索引元组进行引用,实际索引元组中存储实际的索引数据。
当创建索引时,存储模块为每个需要索引的对象数据生成对应的索引元组,并插入到跳表中适当位置的索引页中,当索引页空闲空间不够,本实施里的存储模块额外申请一个页面,插入到跳表中。
当具体查询,即命令解析执行模块获得客户端发送的索引时,从跳表中查询出索引数据所在页面,在页面中利用二分搜索算法查找相匹配的键,进而获得实际数据,从而避免对全表进行扫描带来的负担,大大提高效率。
本实施例涉及上述系统的优化控制方法,以包含以下用户对象的数据集合为例说明。
所述的用户对象为:
{
“collection”:“user”,
“define”:{
“name”:“string”,
“school”:”string”,
“age”:”int32”,
“sex”:”string”,
“grade”:”int32”
},
“index”:”name”
}
所述的优化查询,包括以下步骤:
①用户发送(根据事先规定好的通信协议编码的)查询命令,比如(编码前):
{
“collection”:“user”,
“by”:{
“age”:18,
“school”:“sjtu”,
“name”:”user1”
}
}
②上述查询指令表示查询年龄(“age”)为18岁,学校(“school”)为”sjtu”,用户名(“name”)为”user1”的用户。系统将查询指令进行解析,包括获取查询条件;定位查询的对象所属的集合”user”。
③命令解析执行模块查找可能的优化查询方案,最终发现”user”集合中的用户名”name”字段已经建立索引,因此先利用索引定位到用户名(“name”)为”user1”的用户集合,再根据学校(“school”)和年龄(“age”)在用户名(“name”)为”user1”的用户集合中进一步筛选,最终得到符合条件的结果。
相比现有内存数据库基本基于简单的k/v存储,缺乏有效的索引策略对较为复杂的查询进行支持、磁盘型数据库基于b树或b 树提供索引,但其专为磁盘i/o优化,且操作复杂,并不适用于内存存储场景,本发明使用跳表进行索引,操作简单且优化,适合内存存储场景;在建立索引的情况下,有效避免查询操作扫描全部数据,查询效率高于简单k/v型数据库。
上述具体实施可由本领域技术人员在不背离本发明原理和宗旨的前提下以不同的方式对其进行局部调整,本发明的保护范围以权利要求书为准且不由上述具体实施所限,在其范围内的各个实现方案均受本发明之约束。
1.一种面向对象的内存数据存储系统,其特征在于,包括:网络通信模块、命令解析执行模块和存储模块,其中:网络通信模块对来自客户端的连接请求和计算请求进行调度处理,命令解析执行模块解析客户端发送的数据并对解析得到的结果进行执行,存储模块对内存中的数据进行组织优化处理,从而有效提高命令执行的效率;
所述的调度处理是指:接收新的客户端的连接请求;对已建立连接的客户端的命令及时进行响应;定期清理闲置时间过长的客户端,以优化系统资源分配;
所述的命令解析是指:将客户端发送的数据按照事先规定好的通信协议解析成对应类型的命令,并进行相应的处理;
所述的组织优化处理包括:通过内存池以及封装于操作系统上层的统一的内存管理接口对内存资源进行统一管理以减少内存碎片以及以优化的存储结构存储对象型数据并通过维护索引的方式优化查询请求,实现对对象型数据进行优化操作。
2.根据权利要求1所述的面向对象的内存数据存储系统,其特征是,所述的命令解析执行模块包括:命令解析单元、命令执行单元,其中:命令解析单元检验用户发送的命令格式是否符合通信协议规范,并对命令进行解析,将提取出的内容传输给命令执行单元进行执行。
3.根据权利要求2所述的面向对象的内存数据存储系统,其特征是,所述的命令解析单元从消息头中获取操作类型,对消息体进行解码,获得有关信息;命令执行单元根据不同的命令类型采取不同的处理逻辑进行执行,最终都将转化为对下层存储模块的不同操作。
4.根据权利要求1~3中任一所述的面向对象的内存数据存储系统,其特征是,在初始化时网络通信模块创建主线程和指定数量工作线程,其中:①主线程向libevent注册回调函数,当监听的端口接收到连接请求时,通过round-robin算法选择一个工作线程,将连接相关信息添加到该工作线程对应的连接队列中,然后向该工作线程的管道写数据;②工作线程向libevent注册回调函数,当监听到管道有数据写入时,从连接队列取出并接管连接,后续由该工作线程处理该连接对应的客户端的查询请求。
5.根据权利要求1所述的面向对象的内存数据存储系统,其特征是,所述的存储模块包括:基于内存池的统一内存管理单元、页面存储单元,其中:内存池在操作系统上层封装统一的内存管理接口,供页面存储单元使用,页面存储单元以页为单位对数据进行组织,并使用索引对查询进行优化。
6.根据权利要求5所述的面向对象的内存数据存储系统,其特征是,所述的统一内存管理是指:内存池维护若干个大小不同的空闲链表,每次内存请求根据请求大小选择对应的空闲链表,当对应的空闲链表不为空,则直接从空闲链表中分配,否则从内存池中分配内存;当内存池内存不足,则使用glibc中提供的malloc一次向操作系统申请一大块内存,对内存池进行补充;当释放内存时,根据释放的内存块大小插入到对应的空闲链表中;
所述的以页为单位对数据进行组织是指:以固定大小的页,每个页面存放多个对象,对象型数据形式上由键值对组成,且允许嵌套,对于每一个对象,存储在最前面的是键值对的数量和大小等元信息,其后是键指针组和值指针组,分别指向具体的键和值数据,为便于查找,键指针组事先根据键进行排序,值指针组根据对应键的位置依次排列,其中的内存分配回收等操作均置于前述的内存管理器的管理之下,由于内存空间是有限的,因此使用lru(latestrecentused)算法对对象数据进行管理,将对象数据用指针链接成链表,最频繁使用的数据在lru链表的前端,最少使用的数据在lru链表的尾端,当内存空间不足时,将首先从lru链表中释放尾端的数据。
7.根据权利要求5所述的面向对象的内存数据存储系统,其特征是,所述的使用索引对查询进行优化是指:存储模块通过如图5所示的跳表实现对索引提供支持,该跳表允许优化查询、插入和删除的数据结构,时间复杂度均为o(logn)。
8.根据权利要求1或5或7所述的面向对象的内存数据存储系统,其特征是,所述的索引采用分页的方式进行存储,页面大小固定,包括:头部信息、索引指针数组、实际索引元组,其中:头部信息用于存储页面的元信息,例如已插入的索引元组数等;索引指针数组用于对实际索引元组进行引用,实际索引元组中存储实际的索引数据;
当创建索引时,存储模块为每个需要索引的对象数据生成对应的索引元组,并插入到跳表中适当位置的索引页中,当索引页空闲空间不够时存储模块额外申请一个页面,插入到跳表中;
当具体查询,即命令解析执行模块获得客户端发送的索引时,从跳表中查询出索引数据所在页面,在页面中利用二分搜索算法查找相匹配的键,进而获得实际数据,从而避免对全表进行扫描带来的负担,大大提高效率。
技术总结