虽然对 分布式 也有一些了解,但是一直没有深入到代码去 研究 具体的实现。在群里咨询了一下,自己也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 我不明白在poll()返回-1时,为什么要检查EAGAIN错误。查看了man手册,只有EFAULT、EINTR、EINVAL、ENOMEM错误,看了一下内核代码,也没有返回EAGAIN错误的地方。而且很不明白,为什么在EAGAIN的时候要调用usleep()等待100毫秒,不理解! <p> 最终<strong>彻底</strong>击穿我的信心的是matoclserv_gotpacket()函数,这个函数通过判断eptr->registered的值来做不同的三种处理,这三个代码块中很多都是可以合并的。要么给每种处理封装成一个函数,要么将这三块代码合并成一块,这样看着不是更简洁么?很多switch-case分支中的处理也不用区分eptr->registered的值,为什么写的这么庞大?难道作者在写的时候为了方便,复制粘贴了一番?反正我是很不理解,这样的代码风格真是让我没办法看下去,我<strong>决定</strong><strong>放弃</strong>了。我知道半途而废很不好,本来自己写代码风格就不好,怕看完之后更偏了,所以果断<strong>放弃</strong>!</p> <p> 下面是matoclserv_gotpacket()函数的代码,大家欣赏一下:</p> <p></p><pre name="code" class="cpp">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->registeredsesdata==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; } } }

MySQL是一种开源的关系型数据库管理系统,主要用于快速、可靠地存储和检索数据。其工作原理包括客户端请求、查询解析、执行查询和返回结果。使用示例包括创建表、插入和查询数据,以及高级功能如JOIN操作。常见错误涉及SQL语法、数据类型和权限问题,优化建议包括使用索引、优化查询和分表分区。

MySQL是一个开源的关系型数据库管理系统,适用于数据存储、管理、查询和安全。1.它支持多种操作系统,广泛应用于Web应用等领域。2.通过客户端-服务器架构和不同存储引擎,MySQL高效处理数据。3.基本用法包括创建数据库和表,插入、查询和更新数据。4.高级用法涉及复杂查询和存储过程。5.常见错误可通过EXPLAIN语句调试。6.性能优化包括合理使用索引和优化查询语句。

选择MySQL的原因是其性能、可靠性、易用性和社区支持。1.MySQL提供高效的数据存储和检索功能,支持多种数据类型和高级查询操作。2.采用客户端-服务器架构和多种存储引擎,支持事务和查询优化。3.易于使用,支持多种操作系统和编程语言。4.拥有强大的社区支持,提供丰富的资源和解决方案。

InnoDB的锁机制包括共享锁、排他锁、意向锁、记录锁、间隙锁和下一个键锁。1.共享锁允许事务读取数据而不阻止其他事务读取。2.排他锁阻止其他事务读取和修改数据。3.意向锁优化锁效率。4.记录锁锁定索引记录。5.间隙锁锁定索引记录间隙。6.下一个键锁是记录锁和间隙锁的组合,确保数据一致性。

MySQL查询性能不佳的原因主要包括没有使用索引、查询优化器选择错误的执行计划、表设计不合理、数据量过大和锁竞争。 1.没有索引导致查询缓慢,添加索引后可显着提升性能。 2.使用EXPLAIN命令可以分析查询计划,找出优化器错误。 3.重构表结构和优化JOIN条件可改善表设计问题。 4.数据量大时,采用分区和分表策略。 5.高并发环境下,优化事务和锁策略可减少锁竞争。

在数据库优化中,应根据查询需求选择索引策略:1.当查询涉及多个列且条件顺序固定时,使用复合索引;2.当查询涉及多个列但条件顺序不固定时,使用多个单列索引。复合索引适用于优化多列查询,单列索引则适合单列查询。

要优化MySQL慢查询,需使用slowquerylog和performance_schema:1.启用slowquerylog并设置阈值,记录慢查询;2.利用performance_schema分析查询执行细节,找出性能瓶颈并优化。

MySQL和SQL是开发者必备技能。1.MySQL是开源的关系型数据库管理系统,SQL是用于管理和操作数据库的标准语言。2.MySQL通过高效的数据存储和检索功能支持多种存储引擎,SQL通过简单语句完成复杂数据操作。3.使用示例包括基本查询和高级查询,如按条件过滤和排序。4.常见错误包括语法错误和性能问题,可通过检查SQL语句和使用EXPLAIN命令优化。5.性能优化技巧包括使用索引、避免全表扫描、优化JOIN操作和提升代码可读性。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

记事本++7.3.1
好用且免费的代码编辑器

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境