转自:http://blog.csdn.net/fuyun10036/article/details/8620816感谢。
就个人理解而言,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; <span style="white-space:pre"> </span>// 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;
- }