当前位置: 首页 > 工具软件 > FastDB > 使用案例 >

FastDB杂谈

长孙知
2023-12-01

fastdb用起来还是很方便简单的,但是在使用的过程当中发现了很多问题:

比如:

1、数据库对于内存的消耗实在是太大,尤其是数据量到达千万级时尤为明显。

2、数据量上千万级别以后,性能远地于预期,可能是服务器内存不够的缘故。事务过大后,提交时间很长。

3、在并发访问模式上,同一进程的线程只能用同一模式,只read能够并发。不能够write并发(多个write线程)。进程间也是如此,也就是说多个write并发的话会出现相互阻塞,连write进程读操作都阻塞。所以适用于那些并发读操作,或者只要一个并发写操作的模式。(毕竟只有3万来行的程序,没有提供记录锁甚至页级锁是很正常的)

4、程序出现异常,可以通过清理信号量来进行恢复数据文件,但是有时候数据文件没法恢复造成数据损失。幸亏有在线备份机制和多机器备份功能。

虽然如此,但是在适量的数据规模上,其性能是很彪悍的,加上在使用上特别方便。所以如果对于百万级数据规模的项目,需要简单并发和大量插入、查找、计算时,fastdb是个很不错的选择。毕竟代码很精炼,适当的时候自己可以根据需要进行修改源码。

 

磁盘模式与非磁盘模式的性能http://blog.csdn.net/hejianhua/article/details/6694356

在磁盘模式下,所有的数据将写到磁盘的文件中,对于这种模式,性能和一般的数据库差不多。对于非磁盘模式,效率非常高,网上有一篇文章,对fastdb和磁盘数据库的性能进行了对比。默认情况下是磁盘模式,要使用非磁盘模式,重新编译,加入

-DDISKLESS_CONFIGURATION

 

推荐文章:http://www.360doc.com/content/11/0227/02/6001117_96477992.shtml

 

在采用非磁盘模式的时候,要注意因为内存越界的问题导致进程crash。因为,对于非磁盘模式fastdb是实现划分了一大块共享内存,当超出这块内存的容量时,就会有可能导致程序crash

fastdb 共享内存模式下的限制

最近项目中使用了fast db,为了提高访问效率,fast db采用diskless模式编译。
共享内存的最大尺寸受系统参数限制,
下面数据是在Linux im_monitor 2.6.9-42.ELsmp 下的缺省值:
cat /proc/sys/kernel/shmmax
33554432
默认大小都是32M;

同样fastdb里的代码也用32M作为容量上限,而且一旦越界,不再进行扩容;进程退出;
具体的代码行是:inc/database.h 文件里
#ifdef DISKLESS_CONFIGURATION
// In diskless confiuration database can not be reallocated
const size_t dbDefaultInitDatabaseSize = 32*1024*1024;
#else
const size_t dbDefaultInitDatabaseSize = 1024*1024;
#endif

为了支持fastdb在更大的共享内存下工作,需要做两点修改:
1
、系统参数的修改
修改 /etc/sysctl.cfg,添加入下内容:
kernel.shmmni = 4096
kernel.shmall = 2097152
kernel.shmmax = 1073741824
sysctl -p
执行;
或者echo 1073741824 > /proc/sys/kernel/shmmax ,注意需要加到启动脚本里去;

2、修改fastdb源代码
const size_t dbDefaultInitDatabaseSize = 32*1024*1024;
修改为合适的数值;比如32->1024

鉴于共享内存大小限制,以及不能动态扩容:当容量超过限制,进程不能进行再分配,直接退出,对于大容量的系统,对fastdb的数据使用超过2G, 或者总的虚拟内存使用量可能接近3G, 则不建议在32位操作系统中使用共享内存方式的fastdb,可以改用文件方式,实际上对于文件方式,也是通过mmap的方式来实现,对于io的写基本等同于内存效率,且可以在预分配的基础上扩容。

 

fastdb学习笔记

这几天一直在学习fastdb的使用,将一些学习心得和笔记写出来供大家参考!

1,register_in()宏不能在主函数中使用;
2,
更新和删除操做的游标是updatecurrsor,其他的是一般的currsor;
3,
游标的当前值就是当前查询的对象.
4,
客户端服务器结构程序需要使用cli接口,程序包含cli.lib
5,
如果在CBuilder中使用fastdb.lib,链接出现omf格式问题,直接将所有的src目录下的文件(有几个cpp从名字可以发现是其他平台或者用不上的可以不要)加到一个CBuilderlib工程里边,然后build生成fastdb.lib就可以解决这个问题.同样使用cli的时候也可能出现这个问题,和上边一样,cli.cpp,cgistub.cpp,repsock.cpp,stdtp.cpp,w32sock.cpp添加到一个lib工程里边,生成cli.lib即可解决问题.
6,
不同的数据库之间共享classes,首先定义class,register_unassigned()注册类,使用的时候游标有一个你要操做的数据库的指针作为参数.以此标识你要操作的数据库.如果你要插入数据的话,insert()函数这是是一个database类的成员使用.以此标识要插入的数据库.
7,fastdb
的类(也就是表的数据成员都必须是public),否则外部不可访问.
8,fastdb
表的字段可以是嵌套的结构或者动态增长的数组类型.并且表中可以有方法.
9,fastdb
支持autoincrement字段,int4类型可以在descriptor中声明为autoincrement.
10,
使用fastdb自己带的subsql程序的export命令可以将内存数据库导出成一个xml文件.
11,fastdb
inverse reference 保证了在你删除数据库中的记录的时候数据的引用完整性.当你删除数据库中的记录的时候,inverse reference自动更新.
12,fastdb1.20
以后支持cascade deletes,只要相应的字段声明为owner.如果包含reference的字段为owner则这个字段同时要用relation宏声明.

对开源内存数据库FastDB作了一些测试。
采用两个long字段作为表的字段,首先使用带有文件映像的方式,结果是:
1. 
字段申明时FIELDKEY(,INDEXED)在存储量上没有区别,但是KEY(,HASHED)将额外占用大量空间,几乎增加一倍。
2. 
1,000,000条记录(64M)中查询1,000,000次,耗时5秒,平均每秒20万次,加上修改操作似乎影响不大,插入1,000,000条记录也是5秒。
FastDB库编译成DISKLESS模式后,对每个表的大小似乎有限制,而且是一种以崩溃的方式出现的,同样的记录只能插入100,000个多一些。好像数据库申明时对初始大小的规定没有作用。

 


1. FastDB
中的每个对象(记录)有12字节的头。
   
每个对象都是按32字节对齐的。
   
每个额外的索引占用16字节。
   
每个对象还有4字节的标识OID(Object Identifier),用于对对象的访问,并且OID有两个CurrentShadow,这样每个对象标识就占用8个字节,而且所有对象标识的数量是按2的倍数分配的。
   
如果分配的虚拟内存被耗尽,则总内存将会变为原来的两倍。

2. 
在无盘模式下,数据库声明时的初始内存参数dbInitSize的单位是字节。当初始分配的内存不足时,会抛出OutOfMemory异常。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Database

dbDatabase类控制与数据库的应用交互,比如对数据库的并发访问控制的同步,事务管理,内存分配,纠错处理等等。

         dbDatabase类的构造函数允许程序员指定一些数据库的参数。

dbDatabase(dbAccessType type = dbAllAccess,

                      size_t dbInitSize = dbDefaultInitDatabaseSize,

                      size_t dbExtensionQuantum = dbDefaultExtensionQuantum,

                      size_t dbInitIndexSize = dbDefaultInitIndexSize,

                      int nThreads = 1);

访问模式有以下几种:

访问类型

描述

dbDatabase::dbReadOnly

只读模式

dbDatabase::dbAllAccess

普通模式

dbDatabase::dbConcurrentRead

Read only mode in which application can access the database concurrently with application updating the same database in dbConcurrentUpdate mode

dbDatabase::dbConcurrentUpdate

Mode to be used in conjunction with dbConcurrentRead to perform updates in the database without blocking read applications for a long time

 

 

 类似资料: