FastDb client-server模式

就个人理解而言,fastdb client-server模式,只是在client和server之间添加了一个socket通信,其实操作都是在server端完成的。

但是client-server也有很多好处,其中一个就是可以同一个进程可以同时运用fastdb的无盘模式,和磁盘模式。

当然其中一个模式只是client(比如这个进程开启时需要用无盘模式,将数据全部存入内存,以方便读取,但是记录日志时希望用fastdb记录到库中,这时候就可以另外开始一个server进程,用磁盘模式打开数据库,client连接到server进行insert操作。)

server端代码:

// Sev_log.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "fastdb.h"

class CLog
{
	public:
		char const* sdatetime;
		int4		ProcessNo;
		int4		level;
		char const* logtext;
		char const* ifwrited;

	TYPE_DESCRIPTOR((FIELD(sdatetime),
					 FIELD(logtext),
					 FIELD(ProcessNo),
					 FIELD(level),
					 FIELD(ifwrited)
					 ));
};

#pragma comment(lib, "fastdb.lib")
#pragma comment(lib, "wsock32.lib")

#if THREADS_SUPPORTED && !defined(NO_SOCKETS)
#define SERVER_SUPPORTED 1
#include "server.h"
#else
#define SERVER_SUPPORTED 0
#endif

USE_FASTDB_NAMESPACE

REGISTER(CLog);

int _tmain(int argc, _TCHAR* argv[])
{	
	//由于不关闭数据库的话,内存占用会越来越大,所以定时重启数据库
	while(1)
	{
		dbDatabase* m_pdb;
		m_pdb = NULL;

		size_t dbInitSize = 16 * 1024 * 1024;			// 16M	指定了数据库文件的初始大小	缺省值为4MB
		size_t dbExtensionQuantum = 1 * 1024 * 1024;		//  1M	内存分配位图的扩展量子		缺省值为4MB
		size_t dbInitIndexSize = 2 * 1024 * 1024;		//  2M	指定了初始的索引大小			64K个对象标识符

		m_pdb = new dbDatabase(dbDatabase::dbAllAccess, dbExtensionQuantum, dbInitIndexSize);
	
		if(m_pdb->open("test"))
		{
			m_pdb->scheduleBackup("backup.fdb",2); //定时备份 2s备份一次
			char serverURL[64];
			strcpy(serverURL, "localhost:2100");
			dbServer* server = dbServer::find(serverURL);

			if (server == NULL){
				/*
				dbServer::dbServer(dbDatabase* db,
					char const* serverURL, 
					int optimalNumberOfThreads, 
					int connectionQueueLen)
				*/
				server = new dbServer(m_pdb, serverURL, 8);
				if (server != NULL){
					server->start();
					printf("Server started for URL %s\n", serverURL);
				}
			}

			Sleep(60000);

			if (server != NULL) { 
				server->stop();
				delete server;
				server = NULL;
				printf("Server stopped for URL %s\n", serverURL);
			} 

			m_pdb->close();
			printf("fastdb close!\n");
		}

		delete m_pdb;
		m_pdb=NULL;
	}
	return 0;
}
client端代码:

// cli_writelog.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "cli.h"
#include <string.h>
#include <process.h> //windows
//#include "unistd.h"  //linux

#include "fastdb.h"

class CLog
{
	public:
		char const* sdatetime;
		int4		ProcessNo;
		int4		level;
		char const* logtext;
		char const* ifwrited;

	TYPE_DESCRIPTOR((FIELD(sdatetime),
					 FIELD(logtext),
					 FIELD(ProcessNo),
					 FIELD(level),
					 FIELD(ifwrited)
					 ));
};

#pragma comment(lib, "cli.lib")
#pragma comment(lib, "wsock32.lib")

USE_FASTDB_NAMESPACE;

#define SUCCESS			1
#define CREATE_STATEMENT_ERROR -1
#define BIND_COLUMN_ERROR      -2
#define INSERT_ERROR	       -3
#define PRECOMMIT_ERROR        -4
#define FREE_STATEMENT_ERROR   -5


int WriteLog(char *format,...)
{
	FILE * fp;
	va_list args;
	char sLogFile[100];
	
	memset(sLogFile,0,sizeof(sLogFile));
	
	strcpy(sLogFile,"log.txt");
	
	if((fp=fopen(sLogFile,"a+"))==NULL)
	{
		//printf("open file happened errors!\n");
		return -1;
	}

	va_start(args,format);
	vfprintf(fp,format,args);
	va_end(args);
	
	fclose(fp);
	return 0;
}

int WriteLog(const char* log , const int level , const int session)
{
	const int MAXSTRLEN = 256;
	int inst_level,inst_processno;
	char inst_sdatetime[MAXSTRLEN];
	char inst_logs[MAXSTRLEN];

	int StatementToInst = cli_statement(session, "insert into CLog");

	if (StatementToInst < 0) { 
		WriteLog("cli_statement failed with code %d\n", StatementToInst);
		return CREATE_STATEMENT_ERROR;
	}

	int rc;//用于返回错误代码
	if ((rc = cli_column(StatementToInst, "sdatetime",cli_asciiz, NULL, &inst_sdatetime)) != cli_ok ||
		(rc = cli_column(StatementToInst, "logtext", cli_asciiz, NULL, &inst_logs)) != cli_ok		||
		(rc = cli_column(StatementToInst, "ProcessNo", cli_int4, NULL, &inst_processno)) != cli_ok   ||
		(rc = cli_column(StatementToInst, "level", cli_int4, NULL, &inst_level)) != cli_ok )
	
	{
		WriteLog("cli_column failed with code %d\n", rc);
		return BIND_COLUMN_ERROR;
	}

	char buf[MAXSTRLEN];//用于临时存储时间

	strcpy(inst_sdatetime,dbDateTime::current().asString(buf,sizeof buf,"%Y-%m-%d %H:%M:%S"));
	strcpy(inst_logs,log);
	inst_processno = (int)getpid();
	inst_level = level;

	if((rc = cli_insert(StatementToInst,NULL))!= cli_ok)
	{
		WriteLog("cli_insert failed with code %d\n", rc);
		return INSERT_ERROR;
	}

	/*
	if((rc = cli_commit(session)) != cli_ok)       //直接commit非常慢!
	{
		printf("cli_commit failed with code %d\n", rc);
		return PRECOMMIT_ERROR;
	}
	*/
	
	
	
	if((rc = cli_precommit(session)) != cli_ok)
	{
		WriteLog("cli_precommit failed with code %d\n", rc);
		return PRECOMMIT_ERROR;
	}
	
	
	if((rc = cli_free(StatementToInst)) != cli_ok){
		WriteLog("cli_free failed with code %d\n", rc);
		return FREE_STATEMENT_ERROR;
	}

	return SUCCESS;
}


int _tmain(int argc, _TCHAR* argv[])
{
	char* const serverURL = "127.0.0.1:2100";

	int session = cli_open(serverURL,10,1);//重连次数10,重连间隔1s
	if (session < 0) { 
        printf("cli_open failed with code %d\n", session);
		return -1;
    }
	
	DWORD dstart = GetTickCount();

	for(int i=0;i < 10;i++)
		WriteLog("this is a log test",i%10,session);

	printf("time is %d\n",GetTickCount()-dstart);

	int rc;
	/*
	if((rc = cli_commit(session)) != cli_ok)  //批量提交速度最快  但是在提交之前,这部分日志无法取出
	{
		printf("cli_commit failed with code %d\n", rc);
		return PRECOMMIT_ERROR;
	}
	*/

	//precommit最好加上定时备份日志
	/*FastDB为数据库提供了precommit的接口,用于完成除sync到磁盘文件外的所有事物操作
	,如释放mutex资源等。同时提供了backup接口,用来完成内存数据到磁盘文件的备份,
	甚至支持打开数据库时同时指定定时备份到磁盘文件的间隔,但是cli这个功能还没完善*/


	if ((rc = cli_close(session)) != 0) { 
		printf("cli_close failed with code %d\n", rc);
		return -1;	
	}
	printf("fastdb insert successfully!\n");

	dstart = GetTickCount();
	for(int i=0;i < 100;i++)
		WriteLog("this is a log test\n",i%10);

	printf("time is %d\n",GetTickCount()-dstart);                                                                  
	printf("file insert successfully!\n");


	getchar();

	return 0;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
概述FastDB是一个高效率的内存数据库系统,具有实时性能和方便的C++接口。 FastDB并不支持客户端/服务器结构,所有使用FastDB数据库的应用程序都必须运行在同一台主机上。FastDB为具有主导读取访问模式的应用程序作了优化。通过消除数据传输的开销和使用高性能的锁工具实现了查询执行的高速度。数据库文件和使用该数据库的每一个应用程序占用的虚拟内存空间相映射。所以查询在应用程序的任务中执行,不需要进行任务切换和数据传输。在FastDB中,通过原子指令来实现对数据库并发访问的同步,对查询处理几乎不增加任何开销。FastDB假设整个数据库都在当前内存中,并且在这个假设的基础上优化查询算法和结构。另外,数据库缓存管理几乎不会给FastDB增加任何开销,同时FastDB也不需要在数据库文件和缓冲池中进行数据传送。这就是为什么FastDB比将所有数据放在缓冲池中的传统数据库明显速度快的原因。   FastDB支持事务、在线备份和系统崩溃之后的自动恢复。事务提交协议基于一个影子根页算法,对数据库执行原子更新操作。恢复操作执行起来非常快,给关键应用程序提供了高效率。另外,它还取消了事务日志,提高了系统的整体性能,并且能够更加有效地使用系统资源。   FastDB是面向应用程序的数据库,使用应用程序的类信息来构建数据库的表。FastDB支持自动系统赋值,只允许你在一个地方——你的应用程序的类中,改变它们的值。FastDB为从数据库中提取数据提供了一个灵活而方便的接口。使用类似于SQL的语言来书写查询语句。这些非原子字段、嵌套数组、用户自定义类型和方法、直接指向对象内部的指针等后关系性能,简化了数据库应用程序的设计,并且使得它们更加高效。   虽然FastDB的优化是基于整个数据库都存放在机器的物理内存的这个假设上的,我们依然可以将FastDB使用在那些大小超过系统物理内存的数据库上。最后,标准操作系统的交换机制将会起作用。但是所有的FastDB的算法和结构的优化都是基于数据存放在内存中这个假设上的,所以数据交换的效率不会很高。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值