基于内存的NoSQL分布式数据库技术研究项目测试方案一、目的研究一种新的快速存储与访问机制,改善内存使用的现状,同时要保证软件架构上不做大的改动,性能没有明显下降。
研究分布式存储技术,优化当前的DB存储,并且研究板内、板间多进程对新存储系统访问效率。
所涉及的技术和平台,既可以运行X86平台上,也可以运行在非X86平台上。
二、测试环境搭建1、任务文档要求(1)每块单板一块8核X86芯片,每个核有两个超线程,可看成16个核。
(2)业务使用进程部署,每个核上分别部署1个进程;每个核上分别部署2个进程;每个核上部署的进程会有扩展的需求。
(3)板内分布式采用分布式算法将将板内所有进程构成一张全局表,每个单板的进程数目可以达到256个。
(4)板间分布式改造后可实现最大200块单板(共200*16个核,进程数目需要增加到10000个进程),系统所有进程构成一张全局表。
实际验证时,可能是由2个分布点、4个…320个…10000个逐步验证,要求每种场景下都给出对比数据。
给出性能同分布节点数的关系。
(5)板间采用xGE交换链接,该交换为无阻塞交换,可忽略其交换时延。
2、进程绑定多核运行名词CPU affinity:中文称作“CPU亲和力”,是指在CMP架构下,能够将一个或多个进程绑定到一个或多个处理器上运行。
如果自己写代码,要把进程绑定到CPU,可以用sched_setaffinity函数。
在Linux上,这会触发一次系统调用。
int sched_setaffinity(pid_t pid, unsigned int len, unsigned long *mask);sched_setaffinity 的第一个参数是pid (进程ID),设置进程为pid的这个进程,让它运行在mask所设定的CPU上。
如果pid的值为0,则表示指定的是当前进程,使当前进程运行在mask所设定的那些CPU上;第二个参数cpusetsize 是mask所指定的数的长度。
通常设定为sizeof(cpu_set_t);如果当前pid所指定的CPU此时没有运行在mask所指定的任意一个CPU上,则该指定的进程会从其它CPU上迁移到mask的指定的一个CPU上运行。
int sched_getaffinity(pid_t pid, unsigned int len, unsigned long *mask);该函数获得pid所指示的进程的CPU位掩码,并将该掩码返回到mask所指向的结构中,即获得指定pid当前可以运行在哪些CPU上。
同样,如果pid的值为0.也表示的是当前进程。
详见文档《进程绑定多核运行》。
三、测试架构与流程1、内存数据库与NoSQL比较DB为内存关系数据库,cache为了加快数据访问而单独增加的表项,实际存放的是全局数据,DB和cache对应一个独立的进程,FLASH为本地化数据库。
正常业务时绝大多数是读操作,当有数据更新(修改、增加、删除)时,由其他任务完成对DB、FLASH数据库和cache的更新。
目标:在保留当前函数调用的基础上,用NoSQL数据库替换现有“关系数据库DB+ CACHE” 模式,以便实现“数据库内存同核/进程/线程”的解耦合。
2、板内分布式改造采用分布式算法将将板内所有进程构成一张全局表,每个单板的进程数目可以达到256个;从DB读写访问比例、查表行为和一致性维度进行模拟,选择达到性能要求的NoSQL数据库;并给出共享内存和分布式的对比数据,并给出一个较优的数据库。
3、板间分布式改造系统所有进程构成一张全局表,算法不限。
实际验证时,可能是由2个分布点、4个。
320个。
10000个逐步验证,要求每种场景下都给出对比数据。
给出性能同分布节点数的关系。
给出分布节点与数据中心的核查算法。
保持同步机制,即使板间使用消息,对外接口上仍体现单一接口调用。
要考虑数据一致性,写数据生效时间小于1ms,(读写关系类似于CPU CACHE读写关系)。
4、测试流程四、数据结构及接口设计1.数据结构及数据库设计(1)数据库就是一个大的顺序内存空间,按照表定义的规格规则排序;系统保存有每张表的起始位置,规格,每个表记录的长度,每个表记录每个元素的长度,表的关键字定义等等信息。
(2)数据库的规模是1000张表,每个表最大20000的记录,每条记录最大1000个字节,每个表的关键字小于10个。
(3)数据库表:1000张表,命名为T1,T2,......,T1000;每个表有10个字段,命名为ID,field1,......,field9;每个表除主键外其它字段都是别的表的外键。
(4)数据结构:/*缓冲结构体*/struct Array {unsigned num;unsigned length;char**point;};(5)全局变量:charT[1000][10]={{"ID","field1","field2","field3","field4","field5","field6","field7","fiel d8","field9"}...};/*保存每个表的字段名*/char table_name[1000]={"T1","T2","T3"......}.; /*保存每个表的名字*/2、接口设计(1)创建表int DBCreateTable(int table_id,char *field_definition);输入参数:table_id新创建的表对应的table_name及T中的表的位置;field_definition创建的表的字段名称及类型返回值:0操作成功;-1操作失败。
(2)删除表int DBDropTable(int table_id);输入参数:table_id将删除的表对应的table_name及T中的表的位置;返回值:0操作成功;-1操作失败。
(3)插入数据int DBInsertData(int table_id,int *index_list,void *P);输入参数:table_id操作的表对应的table_name及T中的表的位置;index_list批量(或单个)插入数据时的关键字列表;P指向插入用的数据;返回值:0操作成功;-1操作失败。
(4)更新数据int DBUpdata(int table_id,int *index_list,int *field_list,void *P);输入参数:table_id操作的表对应的table_name及T中的表的位置;index_list批量(或单个)更新数据时的关键字列表;field_list 要更新的字段P指向更新用的数据;返回值:0操作成功;-1操作失败。
(5)删除数据int DBDeleteData(int table_id,char *filter);输入参数:table_id操作的表对应的table_name及T中的表的位置;filter字段过滤器;返回值:0操作成功;-1操作失败。
(6)顺序查找多个数据int DBGetAllRecords(int table_id,int *field_list,char *filter,int dec,void *P);输入参数:table_id待查询的表对应的table_name及T中的表的位置;field_list 需要查找记录中的某几个字段;filter字段过滤器;dec查找到的数据降序(或升序)排列;P指向查找到的数据;返回值:0操作成功;-1操作失败。
(7)随机查找某个数据int DBGetOneRecord(int table_id,int *field_list,char *filter,void *P);输入参数:table_id待查询的表对应的table_name及T中的表的位置;field_list 需要查找记录中的某几个字段;filter字段过滤器;P指向查找到的数据;返回值:0操作成功;-1操作失败。
五、测试方案1. 数据库Key、Value读写性能测试。
(1)①根据单关键字key,循环读取N次所消耗的时间*int key,table_id;key=Key1;/*获取数据的关键字*/table_id=T1;/*操作的数据表*/for(i=0;i<N;i++)DBGetOneRecord();/*循环N次读取数据*/②给定单关键字Key,Value。
写入单条数据N次所消耗的时间*int key,table_id;char *value;key=Key1;/*写入数据的关键字*/value=Value1/*写入数据的字段值*/table_id=T1;/*操作的数据表*/for(i=0;i<N;i++)DBInsertData();/*循环N次写入数据*/③给定单关键字Key,value。
更新单条数据N次所消耗的时间*int key,table_id;char *value;key=Key1;/*更新的数据关键字*/value=Value1/*更新的字段值*/table_id=T1;/*操作的数据表*/for(i=0;i<N;i++)DBUpdata();/*循环N次更新数据*/(2)①根据关键字列表,读取随机的N条数据所消耗的时间*int *key,table_id;table_id=T1;/*操作的数据表*//*待读取N条数据的关键字*/for(i=0;i<N;i++)key[i]=Keyi;DBGetALLRecord();/*随机读取N条数据*/②给定Key,Value对列表,写入N条数据所消耗的时间*int *key,table_id;char **value;table_id=T1;/*操作的数据表*//*待写入N条数据的关键字及字段值*/for(i=0;i<N;i++){key[i]=Keyi;Value[i]=Valuei;}DBInsertData();/*写入N条数据*/③给定Key,Value对列表,更新N条数据所消耗的时间*int *key,table_id;char **value;table_id=T1;/*操作的数据表*//*待更新N条数据的关键字及字段值*/for(i=0;i<N;i++){key[i]=Keyi;Value[i]=Valuei;}DBUpdata();/*更新N条数据*/2. 级联查找性能测试级联查找K级,每一级级联N条数据,所消耗的时间*(1)Table1(KEY1,V ALUE1)Table2(KEY2=VLAUE1,V ALUE2)Table3(KEY3=VLAUE2,V ALUE3)Table4(KEY4=VLAUE3,V ALUE4)Table5(KEY5=VLAUE4,V ALUE5)根据KEY1得到VLAUE5的值,KEY1~KEY5可能包含多个关键字,VLAUE1~5也可能是多个值。