Chinaunix首页 | 论坛 | 博客
  • 博客访问: 41625
  • 博文数量: 24
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-03 19:07
文章分类
文章存档

2012年(21)

2011年(3)

分类:

2012-05-27 18:30:08

tracker 的入口在 fdfs_trackerd.c, 而 storage 的入口在fdfs_storaged.c.下面首先分析tracker的,我们从main 函数开始。

fdfs_trackerd.c 109 行:

  1.     conf_filename = argv[1];
  2.     memset(bind_addr, 0, sizeof(bind_addr));
  3.     if ((result=tracker_load_from_conf_file(conf_filename, \
  4.             bind_addr, sizeof(bind_addr))) != 0)
  5.     {
  6.         log_destroy();
  7.         return result;
  8.     }
代码分析:
1. 从命令行接收配置文件名称;
2. 调用tracker_load_from_conf_file 载入配置,具体参数保存在对应的全局变量中。

接着往下分析,fdfs_trackerd.c 117 行:

  1.     if ((result=tracker_load_status_from_file(&g_tracker_last_status)) != 0)
  2.     {
  3.         log_destroy();
  4.         return result;
  5.     }
这里面主要是从隐藏文件 .tracker_status 读取 tracker 上次的状态。

接着往下分析,fdfs_trackerd.c 131行:

  1.     if ((result=tracker_mem_init()) != 0)
  2.     {
  3.         log_destroy();
  4.         return result;
  5.     }
tracker_mem* 相关操作目的是 tracker 在内存中维护 storage 运行状态。这里需要进行初始化动作,会调用 tracker_mem.c 1535行的 tracker_load_data 函数,实现包括从文件中载入groups、storage等信息。

接着往下分析,fdfs_trackerd.c 150行:

  1.     daemon_init(true);
  2.     umask(0);
这里是后台守护进程初始化,目的是为了让tracker 后台运行。

接着往下分析,fdfs_trackerd.c 163行:

  1. if ((result=tracker_service_init()) != 0)
  2.     {
  3.         log_destroy();
  4.         return result;
  5.     }
tracker_service_init 是 tracker 服务的初始化函数。里面主要的动作是pthread_create创建工作者线程,线程的执行函数是work_thread_entrance。

接下来,fdfs_trackerd.c 172行开始,是sigaction设置信号的处理方式。这是linux信号处理机制基础。

接着往下分析,fdfs_trackerd.c 242行: 

  1. #ifdef WITH_HTTPD
  2.     if (!g_http_params.disabled)
  3.     {
  4.         if ((result=tracker_httpd_start(bind_addr)) != 0)
  5.         {
  6.             logCrit("file: "__FILE__", line: %d, " \
  7.                 "tracker_httpd_start fail, program exit!", \
  8.                 __LINE__);
  9.             return result;
  10.         }

  11.     }

  12.     if ((result=tracker_http_check_start()) != 0)
  13.     {
  14.         logCrit("file: "__FILE__", line: %d, " \
  15.             "tracker_http_check_start fail, " \
  16.             "program exit!", __LINE__);
  17.         return result;
  18.     }
  19. #endif
代码分析:
1. tracker 内置了 httpd 服务,但是需要开启编译选项 WITH_HTTPD
fdfs_trackerd.c 270行: 
  1.     scheduleArray.entries = scheduleEntries;
  2.     scheduleArray.count = SCHEDULE_ENTRIES_COUNT;

  3.     memset(scheduleEntries, 0, sizeof(scheduleEntries));
  4.     scheduleEntries[0].id = 1;
  5.     scheduleEntries[0].time_base.hour = TIME_NONE;
  6.     scheduleEntries[0].time_base.minute = TIME_NONE;
  7.     scheduleEntries[0].interval = g_sync_log_buff_interval;
  8.     scheduleEntries[0].task_func = log_sync_func;
  9.     scheduleEntries[0].func_args = &g_log_context;

  10.     scheduleEntries[1].id = 2;
  11.     scheduleEntries[1].time_base.hour = TIME_NONE;
  12.     scheduleEntries[1].time_base.minute = TIME_NONE;
  13.     scheduleEntries[1].interval = g_check_active_interval;
  14.     scheduleEntries[1].task_func = tracker_mem_check_alive;
  15.     scheduleEntries[1].func_args = NULL;

  16.     scheduleEntries[2].id = 3;
  17.     scheduleEntries[2].time_base.hour = 0;
  18.     scheduleEntries[2].time_base.minute = 0;
  19.     scheduleEntries[2].interval = TRACKER_SYNC_STATUS_FILE_INTERVAL;
  20.     scheduleEntries[2].task_func = tracker_write_status_to_file;
  21.     scheduleEntries[2].func_args = NULL;
  22.     if ((result=sched_start(&scheduleArray, &schedule_tid, \
  23.         g_thread_stack_size, &g_continue_flag)) != 0)
  24.     {
  25.         log_destroy();
  26.         return result;
  27.     }
代码分析:
1. sched_start 是开启线程 sched_thread_entrance (sched_thread.c 260行),定期执行指定的任务;
2. 这些任务有log_sync_func、tracker_mem_check_alive、tracker_write_status_to_file;
我们深入分析下 tracker_mem_check_alive,tracker_mem.c 5139行:

  1.     current_time = time(NULL);
  2.     ppGroupEnd = g_groups.groups + g_groups.count;
  3.     for (ppGroup=g_groups.groups; ppGroup<ppGroupEnd; ppGroup++)
  4.     {
  5.     deactiveCount = 0;
  6.     ppServerEnd = (*ppGroup)->active_servers + (*ppGroup)->active_count;
  7.     for (ppServer=(*ppGroup)->active_servers; ppServer<ppServerEnd; ppServer++)
  8.     {
  9.         if (current_time - (*ppServer)->stat.last_heart_beat_time > \
  10.             g_check_active_interval)
  11.         {
  12.             deactiveServers[deactiveCount] = *ppServer;
  13.             deactiveCount++;
  14.             if (deactiveCount >= FDFS_MAX_SERVERS_EACH_GROUP)
  15.             {
  16.                 break;
  17.             }
  18.         }
  19.     }
这里,通过时间对比,找出不活动的 storage server,接下来并更改 storage 的状态为 FDFS_STORAGE_STATUS_OFFLINE。

接着往下分析,fdfs_trackerd.c 301行:  
  1.     if ((result=tracker_relationship_init()) != 0)
  2.     {
  3.         log_destroy();
  4.         return result;
  5.     }
tracker 间地位相对平等的,首先初始化tracker间的关系,tracker_relationship_init 内部是创建线程 relationship_thread_entrance。在线程内部,会执行 relationship_select_leader、relationship_ping_leader等函数。tracker leader 的内部机制,以后章节会详细展开。

fdfs_trackerd.c 接下来的代码,就是进入上节分析过的网络部分。至此,tracker 入口分析完成。

我们在分析storage的入口,整体来说和tracker 的入口很相似,我们只分析不同的地方。
fdfs_storage.c 144行:  
  1.     if ((result=storage_sync_init()) != 0)
  2.     {
  3.         logCrit("file: "__FILE__", line: %d, " \
  4.             "storage_sync_init fail, program exit!", __LINE__);
  5.         g_continue_flag = false;
  6.         return result;
  7.     }

  8.     if ((result=tracker_report_init()) != 0)
  9.     {
  10.         logCrit("file: "__FILE__", line: %d, " \
  11.             "tracker_report_init fail, program exit!", __LINE__);
  12.         g_continue_flag = false;
  13.         return result;
  14.     }

  15.     if ((result=storage_service_init()) != 0)
  16.     {
  17.         logCrit("file: "__FILE__", line: %d, " \
  18.             "storage_service_init fail, program exit!", __LINE__);
  19.         g_continue_flag = false;
  20.         return result;
  21.     }
代码分析:
1. storage_sync_init  同步初始化,storage_sync.c 990行。包括 读取 binlog 的index 动作,binlog 会在对FastDFS 同步机制的分析章节详细介绍;
2.storage_service_init 内部和 tracker 的一样,是创建工作者线程。

fdfs_storage.c 263行: 
  1.     if ((result=tracker_report_thread_start()) != 0)
  2.     {
  3.         logCrit("file: "__FILE__", line: %d, " \
  4.             "tracker_report_thread_start fail, " \
  5.             "program exit!", __LINE__);
  6.         g_continue_flag = false;
  7.         storage_func_destroy();
  8.         log_destroy();
  9.         return result;
  10.     }
这里tracker_report_thread_start是创建上报线程tracker_report_thread_entrance。里面涉及到同步机制,这里暂时不做展开,后面章节详细分析。

fdfs_storage.c 327行:  
  1.     if ((result=storage_dio_init()) != 0)
  2.     {
  3.         log_destroy();
  4.         return result;
  5.     }
storage 是存储服务,通过执行storage_dio_init 实现dio (磁盘IO)的初始化。storage_dio_init函数是创建dio线程 dio_thread_entrance。关于dio的机制,我们可以放到upload、download 里面分析。

fdfs_storaged.c 接下来的代码,就是进入上节分析过的网络部分。 OK, 入口分析完成。
欢迎感兴趣的朋友一起交流研究,提出意见。
FastDFS技术交流群:164684842








阅读(718) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~