moosefs mysql_决定彻底放弃对MooseFS的研究

虽然对 分布式 也有一些了解,但是一直没有深入到代码去 研究 具体的实现。在群里咨询了一下,自己也google了一些资料,最终 决定 从MooseFS入手来深入 研究 分布式 系统 。第一步,就是从网上找文档,自己动手安装部署一番。官方网站上有一个中文的安装手册

虽然对分布式也有一些了解,但是一直没有深入到代码去研究具体的实现。在群里咨询了一下,自己也google了一些资料,最终决定从MooseFS入手来深入研究分布式系统。第一步,就是从网上找文档,自己动手安装部署一番。官方网站上有一个中文的安装手册,非常nice,整个安装配置过程也非常顺利,感觉还不错,就是看它的代码实现。看完之后有些失望,在main函数中的第一个函数strerr_init()中看到了这样的代码:

for (n=0 ; errtab[n].str ; n++) {}而errtab的定义(部分)如下所示:

static errent errtab[] = {

#ifdef E2BIG

{E2BIG,"E2BIG (Argument list too long)"},

#endif

#ifdef EACCES

{EACCES,"EACCES (Permission denied)"},

#endif

......

{0,NULL}

};很明显,那个循环仅仅是为了计算errtab中元素的个数,而这样的计算有必要用一个循环么?sizeof不能解决么?我实现看不出来作者这里要写一个循环的好处是什么?

另一个地方让我感觉作者在写代码的时候很不用心,cfg_reload()在解析配置文件时定义了一个缓冲区linebuff[1000]数组来存储每行读取的内容。mfs解析配置文件时是按行读取的,每行的配置内容类似“key=value"这样的形式。这个缓冲区的长度定义为1000,也让我很不解。因为在定义缓冲区或分配内存的时候,一般都会考虑到对齐,都会对齐到word size或者CPU cache line的长度。这里的1000让我很不解!

代码中还有很多无用的、多余的判断。例如下面的代码段:

logappname = cfg_getstr("SYSLOG_IDENT",STR(APPNAME));

if (rundaemon) {

if (logappname[0]) {

openlog(logappname, LOG_PID | LOG_NDELAY , LOG_DAEMON);

} else {

openlog(STR(APPNAME), LOG_PID | LOG_NDELAY , LOG_DAEMON);

}

}这个APPNAME是在编译的时候通过-DAPPNAME=mfsmaster这样的方式定义的一个宏,所以这个宏是必须定义的,否则前面的代码就没法运行(获取配置文件名称)。而且获取SYSLOG_IDENT配置变量的值是会指定默认值,所以if (logappname[0])这样的判断完全多余。如果是在两个函数中,这样的判断还说的过去,可是获取配置变量值的操作和

判断仅一个空行之隔,没必要到极点了吧。

抛开这些细节性的东西不提,mfs选择的I/O复用机制也让人不敢恭维。现在需要监听套接字的读写事件,毫无疑问首选的eventpoll。如果没有记错的话,moosefs是07年开始的,这个时候内核中的eventpoll机制已经很完善了,实在不懂作者为什么要选用poll()来作为I/O复用的接口。在继续之前,先看一下下面的代码:

i = poll(pdesc,ndesc,50);

......

if (i<0) {

if (errno==EAGAIN) {

syslog(LOG_WARNING,"poll returned EAGAIN");

usleep(100000);

continue;

}

if (errno!=EINTR) {

syslog(LOG_WARNING,"poll error: %s",strerr(errno));

break;

}

} else {

......

} 我不明白在poll()返回-1时,为什么要检查EAGAIN错误。查看了man手册,只有EFAULT、EINTR、EINVAL、ENOMEM错误,看了一下内核代码,也没有返回EAGAIN错误的地方。而且很不明白,为什么在EAGAIN的时候要调用usleep()等待100毫秒,不理解!

最终彻底击穿我的信心的是matoclserv_gotpacket()函数,这个函数通过判断eptr->registered的值来做不同的三种处理,这三个代码块中很多都是可以合并的。要么给每种处理封装成一个函数,要么将这三块代码合并成一块,这样看着不是更简洁么?很多switch-case分支中的处理也不用区分eptr->registered的值,为什么写的这么庞大?难道作者在写的时候为了方便,复制粘贴了一番?反正我是很不理解,这样的代码风格真是让我没办法看下去,我决定放弃了。我知道半途而废很不好,本来自己写代码风格就不好,怕看完之后更偏了,所以果断放弃!

下面是matoclserv_gotpacket()函数的代码,大家欣赏一下:

void matoclserv_gotpacket(matoclserventry *eptr,uint32_t type,const uint8_t *data,uint32_t length) {

if (type==ANTOAN_NOP) {

return;

}

if (eptr->registered==0) {// unregistered clients - beware that in this context sesdata is NULL

switch (type) {

case CLTOMA_FUSE_REGISTER:

matoclserv_fuse_register(eptr,data,length);

break;

case CLTOMA_CSERV_LIST:

matoclserv_cserv_list(eptr,data,length);

break;

case CLTOMA_SESSION_LIST:

matoclserv_session_list(eptr,data,length);

break;

case CLTOAN_CHART:

matoclserv_chart(eptr,data,length);

break;

case CLTOAN_CHART_DATA:

matoclserv_chart_data(eptr,data,length);

break;

case CLTOMA_INFO:

matoclserv_info(eptr,data,length);

break;

case CLTOMA_FSTEST_INFO:

matoclserv_fstest_info(eptr,data,length);

break;

case CLTOMA_CHUNKSTEST_INFO:

matoclserv_chunkstest_info(eptr,data,length);

break;

case CLTOMA_CHUNKS_MATRIX:

matoclserv_chunks_matrix(eptr,data,length);

break;

case CLTOMA_QUOTA_INFO:

matoclserv_quota_info(eptr,data,length);

break;

case CLTOMA_EXPORTS_INFO:

matoclserv_exports_info(eptr,data,length);

break;

case CLTOMA_MLOG_LIST:

matoclserv_mlog_list(eptr,data,length);

break;

default:

syslog(LOG_NOTICE,"main master server module: got unknown message from unregistered (type:%"PRIu32")",type);

eptr->mode=KILL;

}

} else if (eptr->registered<100) {// mounts and new tools

if (eptr->sesdata==NULL) {

syslog(LOG_ERR,"registered connection without sesdata !!!");

eptr->mode=KILL;

return;

}

switch (type) {

case CLTOMA_FUSE_REGISTER:

matoclserv_fuse_register(eptr,data,length);

break;

case CLTOMA_FUSE_RESERVED_INODES:

matoclserv_fuse_reserved_inodes(eptr,data,length);

break;

case CLTOMA_FUSE_STATFS:

matoclserv_fuse_statfs(eptr,data,length);

break;

case CLTOMA_FUSE_ACCESS:

matoclserv_fuse_access(eptr,data,length);

break;

case CLTOMA_FUSE_LOOKUP:

matoclserv_fuse_lookup(eptr,data,length);

break;

case CLTOMA_FUSE_GETATTR:

matoclserv_fuse_getattr(eptr,data,length);

break;

case CLTOMA_FUSE_SETATTR:

matoclserv_fuse_setattr(eptr,data,length);

break;

case CLTOMA_FUSE_READLINK:

matoclserv_fuse_readlink(eptr,data,length);

break;

case CLTOMA_FUSE_SYMLINK:

matoclserv_fuse_symlink(eptr,data,length);

break;

case CLTOMA_FUSE_MKNOD:

matoclserv_fuse_mknod(eptr,data,length);

break;

case CLTOMA_FUSE_MKDIR:

matoclserv_fuse_mkdir(eptr,data,length);

break;

case CLTOMA_FUSE_UNLINK:

matoclserv_fuse_unlink(eptr,data,length);

break;

case CLTOMA_FUSE_RMDIR:

matoclserv_fuse_rmdir(eptr,data,length);

break;

case CLTOMA_FUSE_RENAME:

matoclserv_fuse_rename(eptr,data,length);

break;

case CLTOMA_FUSE_LINK:

matoclserv_fuse_link(eptr,data,length);

break;

case CLTOMA_FUSE_GETDIR:

matoclserv_fuse_getdir(eptr,data,length);

break;

/* CACHENOTIFY

case CLTOMA_FUSE_DIR_REMOVED:

matoclserv_fuse_dir_removed(eptr,data,length);

break;

*/

case CLTOMA_FUSE_OPEN:

matoclserv_fuse_open(eptr,data,length);

break;

case CLTOMA_FUSE_READ_CHUNK:

matoclserv_fuse_read_chunk(eptr,data,length);

break;

case CLTOMA_FUSE_WRITE_CHUNK:

matoclserv_fuse_write_chunk(eptr,data,length);

break;

case CLTOMA_FUSE_WRITE_CHUNK_END:

matoclserv_fuse_write_chunk_end(eptr,data,length);

break;

// fuse - meta

case CLTOMA_FUSE_GETTRASH:

matoclserv_fuse_gettrash(eptr,data,length);

break;

case CLTOMA_FUSE_GETDETACHEDATTR:

matoclserv_fuse_getdetachedattr(eptr,data,length);

break;

case CLTOMA_FUSE_GETTRASHPATH:

matoclserv_fuse_gettrashpath(eptr,data,length);

break;

case CLTOMA_FUSE_SETTRASHPATH:

matoclserv_fuse_settrashpath(eptr,data,length);

break;

case CLTOMA_FUSE_UNDEL:

matoclserv_fuse_undel(eptr,data,length);

break;

case CLTOMA_FUSE_PURGE:

matoclserv_fuse_purge(eptr,data,length);

break;

case CLTOMA_FUSE_GETRESERVED:

matoclserv_fuse_getreserved(eptr,data,length);

break;

case CLTOMA_FUSE_CHECK:

matoclserv_fuse_check(eptr,data,length);

break;

case CLTOMA_FUSE_GETTRASHTIME:

matoclserv_fuse_gettrashtime(eptr,data,length);

break;

case CLTOMA_FUSE_SETTRASHTIME:

matoclserv_fuse_settrashtime(eptr,data,length);

break;

case CLTOMA_FUSE_GETGOAL:

matoclserv_fuse_getgoal(eptr,data,length);

break;

case CLTOMA_FUSE_SETGOAL:

matoclserv_fuse_setgoal(eptr,data,length);

break;

case CLTOMA_FUSE_APPEND:

matoclserv_fuse_append(eptr,data,length);

break;

case CLTOMA_FUSE_GETDIRSTATS:

matoclserv_fuse_getdirstats_old(eptr,data,length);

break;

case CLTOMA_FUSE_TRUNCATE:

matoclserv_fuse_truncate(eptr,data,length);

break;

case CLTOMA_FUSE_REPAIR:

matoclserv_fuse_repair(eptr,data,length);

break;

case CLTOMA_FUSE_SNAPSHOT:

matoclserv_fuse_snapshot(eptr,data,length);

break;

case CLTOMA_FUSE_GETEATTR:

matoclserv_fuse_geteattr(eptr,data,length);

break;

case CLTOMA_FUSE_SETEATTR:

matoclserv_fuse_seteattr(eptr,data,length);

break;

/* do not use in version before 1.7.x */

case CLTOMA_FUSE_QUOTACONTROL:

matoclserv_fuse_quotacontrol(eptr,data,length);

break;

/* for tools - also should be available for registered clients */

case CLTOMA_CSERV_LIST:

matoclserv_cserv_list(eptr,data,length);

break;

case CLTOMA_SESSION_LIST:

matoclserv_session_list(eptr,data,length);

break;

case CLTOAN_CHART:

matoclserv_chart(eptr,data,length);

break;

case CLTOAN_CHART_DATA:

matoclserv_chart_data(eptr,data,length);

break;

case CLTOMA_INFO:

matoclserv_info(eptr,data,length);

break;

case CLTOMA_FSTEST_INFO:

matoclserv_fstest_info(eptr,data,length);

break;

case CLTOMA_CHUNKSTEST_INFO:

matoclserv_chunkstest_info(eptr,data,length);

break;

case CLTOMA_CHUNKS_MATRIX:

matoclserv_chunks_matrix(eptr,data,length);

break;

case CLTOMA_QUOTA_INFO:

matoclserv_quota_info(eptr,data,length);

break;

case CLTOMA_EXPORTS_INFO:

matoclserv_exports_info(eptr,data,length);

break;

case CLTOMA_MLOG_LIST:

matoclserv_mlog_list(eptr,data,length);

break;

default:

syslog(LOG_NOTICE,"main master server module: got unknown message from mfsmount (type:%"PRIu32")",type);

eptr->mode=KILL;

}

} else {// old mfstools

if (eptr->sesdata==NULL) {

syslog(LOG_ERR,"registered connection (tools) without sesdata !!!");

eptr->mode=KILL;

return;

}

switch (type) {

// extra (external tools)

case CLTOMA_FUSE_REGISTER:

matoclserv_fuse_register(eptr,data,length);

break;

case CLTOMA_FUSE_READ_CHUNK:// used in mfsfileinfo

matoclserv_fuse_read_chunk(eptr,data,length);

break;

case CLTOMA_FUSE_CHECK:

matoclserv_fuse_check(eptr,data,length);

break;

case CLTOMA_FUSE_GETTRASHTIME:

matoclserv_fuse_gettrashtime(eptr,data,length);

break;

case CLTOMA_FUSE_SETTRASHTIME:

matoclserv_fuse_settrashtime(eptr,data,length);

break;

case CLTOMA_FUSE_GETGOAL:

matoclserv_fuse_getgoal(eptr,data,length);

break;

case CLTOMA_FUSE_SETGOAL:

matoclserv_fuse_setgoal(eptr,data,length);

break;

case CLTOMA_FUSE_APPEND:

matoclserv_fuse_append(eptr,data,length);

break;

case CLTOMA_FUSE_GETDIRSTATS:

matoclserv_fuse_getdirstats(eptr,data,length);

break;

case CLTOMA_FUSE_TRUNCATE:

matoclserv_fuse_truncate(eptr,data,length);

break;

case CLTOMA_FUSE_REPAIR:

matoclserv_fuse_repair(eptr,data,length);

break;

case CLTOMA_FUSE_SNAPSHOT:

matoclserv_fuse_snapshot(eptr,data,length);

break;

case CLTOMA_FUSE_GETEATTR:

matoclserv_fuse_geteattr(eptr,data,length);

break;

case CLTOMA_FUSE_SETEATTR:

matoclserv_fuse_seteattr(eptr,data,length);

break;

/* do not use in version before 1.7.x */

case CLTOMA_FUSE_QUOTACONTROL:

matoclserv_fuse_quotacontrol(eptr,data,length);

break;

/* ------ */

default:

syslog(LOG_NOTICE,"main master server module: got unknown message from mfstools (type:%"PRIu32")",type);

eptr->mode=KILL;

}

}

}

f68f2add0b68e4f9810432fce46917b7.png

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值