一、概要
前文提到调度线程sched_thread_entrance会调度以下三个任务函数log_sync_func、tracker_mem_check_alive、tracker_write_status_to_file。其中log_sync_func用于将缓存中的log刷新到磁盘中,它的使用与log_init()紧密相连,且log_to_cache参数用于设置是否不经过缓存直接刷新到磁盘;tracker_write_status_to_file向文件data/.tracker_status中写入TRACKER_STATUS_ITEM_UP_TIME、TRACKER_STATUS_ITEM_LAST_CHECK_TIME对应的时间。本文不讨论这两个函数。
二、tracker_mem_check_alive
通过时间对比,找出不活动的 storage server,接下来并更改 storage 的状态为 FDFS_STORAGE_STATUS_OFFLINE。
int tracker_mem_check_alive(void *arg)
{
FDFSStorageDetail **ppServer;
FDFSStorageDetail **ppServerEnd;
FDFSGroupInfo **ppGroup;
FDFSGroupInfo **ppGroupEnd;
FDFSStorageDetail *deactiveServers[FDFS_MAX_SERVERS_EACH_GROUP];
int deactiveCount;
time_t current_time;
current_time = g_current_time;
ppGroupEnd = g_groups.groups + g_groups.count;
for (ppGroup=g_groups.groups; ppGroup<ppGroupEnd; ppGroup++) //对每个组
{
deactiveCount = 0;
ppServerEnd = (*ppGroup)->active_servers + (*ppGroup)->active_count;
for (ppServer=(*ppGroup)->active_servers; ppServer<ppServerEnd; ppServer++) //对组中的每个storage server
{
if (current_time - (*ppServer)->stat.last_heart_beat_time > \
g_check_active_interval) //本例配置为120s
{
deactiveServers[deactiveCount] = *ppServer;
deactiveCount++;
if (deactiveCount >= FDFS_MAX_SERVERS_EACH_GROUP)
{
break;
}
}
}
if (deactiveCount == 0)
{
continue;
}
ppServerEnd = deactiveServers + deactiveCount;
for (ppServer=deactiveServers; ppServer<ppServerEnd; ppServer++)
{
(*ppServer)->status = FDFS_STORAGE_STATUS_OFFLINE; //对于超时无心跳的storage server。
tracker_mem_deactive_store_server(*ppGroup, *ppServer); //更新对应组的信息
if (g_use_storage_id)
{ //log
}
else
{
}
}
}
if ((!g_if_leader_self) || (!g_if_use_trunk_file))
{
return 0;
}
for (ppGroup=g_groups.groups; ppGroup<ppGroupEnd; ppGroup++)
{
if ((*ppGroup)->pTrunkServer != NULL)
{//此处处理暂时不考虑
}
else
{
tracker_mem_find_trunk_server(*ppGroup, true);
}
}
return 0;
}
三、Group与storage server的数据信息
FDFSGroups g_groups(全局变量)------FDFSGroupInfo-------FDFSStorageDetail:
typedef struct
{
int alloc_size; //alloc group count
int count; //group count
FDFSGroupInfo **groups;
FDFSGroupInfo **sorted_groups; //groups order by group_name
FDFSGroupInfo *pStoreGroup; //the group to store uploaded files
int current_write_group; //current group index to upload file
byte store_lookup; //store to which group, from conf file
byte store_server; //store to which storage server, from conf file
byte download_server; //download from which storage server, from conf file
byte store_path; //store to which path, from conf file
char store_group[FDFS_GROUP_NAME_MAX_LEN + 8]; //for 8 bytes aliginment
} FDFSGroups;
typedef struct //该结构体对应每一个组
{
char group_name[FDFS_GROUP_NAME_MAX_LEN + 8]; //for 8 bytes alignment
int64_t total_mb; //total disk storage in MB
int64_t free_mb; //free disk storage in MB
int64_t trunk_free_mb; //trunk free disk storage in MB
int alloc_size; //alloc storage count
int count; //total server count
int active_count; //active server count
int storage_port; //storage server port
int storage_http_port; //storage http server port
int current_trunk_file_id; //current trunk file id report by storage
FDFSStorageDetail **all_servers; //all storage servers
FDFSStorageDetail **sorted_servers; //storages order by ip addr
FDFSStorageDetail **active_servers; //storages order by ip addr
FDFSStorageDetail *pStoreServer; //for upload priority mode
FDFSStorageDetail *pTrunkServer; //point to the trunk server
char last_trunk_server_id[FDFS_STORAGE_ID_MAX_SIZE];
#ifdef WITH_HTTPD
FDFSStorageDetail **http_servers; //storages order by ip addr
int http_server_count; //http server count
int current_http_server; //current http server index
#endif
int current_read_server; //current read storage server index
int current_write_server; //current write storage server index
int store_path_count; //store base path count of each storage server
/* subdir_count * subdir_count directories will be auto created
under each store_path (disk) of the storage servers
*/
int subdir_count_per_path;
int **last_sync_timestamps;//row for src storage, col for dest storage
int chg_count; //current group changed count
int trunk_chg_count; //trunk server changed count
time_t last_source_update; //last source update timestamp
time_t last_sync_update; //last synced update timestamp
} FDFSGroupInfo;
typedef struct StructFDFSStorageDetail //该结构体反映了每一个storage server。
{
char status;
char padding; //just for padding
char id[FDFS_STORAGE_ID_MAX_SIZE];
char ip_addr[IP_ADDRESS_SIZE];
char version[FDFS_VERSION_SIZE];
char domain_name[FDFS_DOMAIN_NAME_MAX_SIZE];
struct StructFDFSStorageDetail *psync_src_server;
int64_t *path_total_mbs; //total disk storage in MB
int64_t *path_free_mbs; //free disk storage in MB
int64_t total_mb; //total disk storage in MB
int64_t free_mb; //free disk storage in MB
int64_t changelog_offset; //changelog file offset
time_t sync_until_timestamp;
time_t join_time; //storage join timestamp (create timestamp)
time_t up_time; //startup timestamp
int store_path_count; //store base path count of each storage server
int subdir_count_per_path;
int upload_priority; //storage upload priority
int storage_port; //storage server port
int storage_http_port; //storage http server port
int current_write_path; //current write path index
int chg_count; //current server changed counter
int trunk_chg_count; //trunk server changed count
FDFSStorageStat stat;
#ifdef WITH_HTTPD
int http_check_last_errno;
int http_check_last_status;
int http_check_fail_count;
char http_check_error_info[256];
#endif
} FDFSStorageDetail
四、(*ppServer)->stat.last_heart_beat_time
storage有个专门的report线程向tracker server发送报告,包括发送TRACKER_PROTO_CMD_STORAGE_BEAT至tracker。tracker在tracker_deal_task()中会调用tracker_deal_storage_beat(pTask)(参考《3 tracker中的recv_notify_read》),更新心跳时间。