fastdfs之sync源码分析

1. sync流程简介

sync行为是由storage向tracker report的时候,响应信息触发为组内每一个storage服务器创建一个同步线程(仅仅一个,单线程同步),并且响应信息还更新线程中storage的状态。同步线程根据storage状态判断工作状态,根据binlog改变实现文件同步。

sync被触发的流程如下,从下而上。

2. storage sync相关源码解析 

2.1 sync 触发

sync线程由tracker_merge_servers函数触发。其功能合并storage服务器的状态,触发sync线程,向tracker上报状态不同的storage。

storage/tracker_client_thread.c

static int tracker_merge_servers(ConnectionInfo *pTrackerServer, \
		FDFSStorageBrief *briefServers, const int server_count)
{
	FDFSStorageBrief *pServer;
	FDFSStorageBrief *pEnd;
	FDFSStorageServer *pInsertedServer;
	FDFSStorageServer **ppFound;
	FDFSStorageServer **ppGlobalServer;
	FDFSStorageServer **ppGlobalEnd;
	FDFSStorageServer targetServer;
	FDFSStorageServer *pTargetServer;
	FDFSStorageBrief diffServers[FDFS_MAX_SERVERS_EACH_GROUP];
	FDFSStorageBrief *pDiffServer;
	int res;
	int result;
	int nDeletedCount;

	memset(&targetServer, 0, sizeof(targetServer));
	pTargetServer = &targetServer;

	nDeletedCount = 0;
	pDiffServer = diffServers;
	pEnd = briefServers + server_count;
	for (pServer=briefServers; pServer<pEnd; pServer++)
	{
		// 获取输入信息的一个storage信息
		memcpy(&(targetServer.server),pServer,sizeof(FDFSStorageBrief));

		// 在本地已排序的全局storage服务器列表(g_sorted_storages)查找,是否存在输入的storage信息
		ppFound = (FDFSStorageServer **)bsearch(&pTargetServer, \
			g_sorted_storages, g_storage_count, \
			sizeof(FDFSStorageServer *), storage_cmp_by_server_id);
		if (ppFound != NULL) // 存在该storage信息
		{
			if (g_use_storage_id) // 如果使用id方式,更新g_sorted_storages中该storage ip addr
			{
				strcpy((*ppFound)->server.ip_addr, pServer->ip_addr);
			}

			/*
			//logInfo("ip_addr=%s, local status: %d, " \
				"tracker status: %d", pServer->ip_addr, \
				(*ppFound)->server.status, pServer->status);
			*/
			if ((*ppFound)->server.status == pServer->status)
			{ // 如果状态没改变,判断下一个。
				continue;
			}

			// 当输入状态改变为:离线
			if (pServer->status == FDFS_STORAGE_STATUS_OFFLINE)
			{
				if ((*ppFound)->server.status == \
						FDFS_STORAGE_STATUS_ACTIVE
				 || (*ppFound)->server.status == \
						FDFS_STORAGE_STATUS_ONLINE)
				{ // 本地状态为:活动或者在线,则改变为离线
					(*ppFound)->server.status = \
					FDFS_STORAGE_STATUS_OFFLINE;
				}
				else if ((*ppFound)->server.status != \
						FDFS_STORAGE_STATUS_NONE
				     && (*ppFound)->server.status != \
						FDFS_STORAGE_STATUS_INIT)
				{ // 本地状态为:无或者初始化,加入不同状态服务列表,准备告知tracker
					// add differ server
					memcpy(pDiffServer++, \
						&((*ppFound)->server), \
						sizeof(FDFSStorageBrief));
				}
			}
			// 当输入状态不为离线
			else if ((*ppFound)->server.status == \
					FDFS_STORAGE_STATUS_OFFLINE)
			{ // 本地状态为:离线,更新本地状态
				(*ppFound)->server.status = pServer->status;
			}
			else if ((*ppFound)->server.status == \
					FDFS_STORAGE_STATUS_NONE)
			{ // 本地状态:无
				if (pServer->status == \
					FDFS_STORAGE_STATUS_DELETED \
				 || pServer->status == \
					FDFS_STORAGE_STATUS_IP_CHANGED)
				{ //ignore
					// 输入状态:删除,ip改变,直接忽略。
				}
				else
				{
// *** 本地状态为无,变了状态,说明该storage工作了,启动同步线程。
					// 备注:storage与storage之间同步线程,是单线程的。
                    //        仅仅启动一个storage-storage sync线程。
                    // 注意:函数输入参数为FDFSStorageBrief,指向全局变量g_sorted_storages之中
					(*ppFound)->server.status = \
							pServer->status;
					// start sync threads [ppFound is none, and then change]
					if ((result=tracker_start_sync_threads(\
						&((*ppFound)->server))) != 0)
					{
						return result;
					}
				}
			}
			else if (((pServer->status == \
					FDFS_STORAGE_STATUS_WAIT_SYNC) || \
				(pServer->status == \
					FDFS_STORAGE_STATUS_SYNCING)) && \
				((*ppFound)->server.status > pServer->status))
			{
                *(pServer->ip_addr + IP_ADDRESS_SIZE - 1) = '\0';
				if (is_local_host_ip(pServer->ip_addr) && \
					buff2int(pServer->port) == g_server_port)
				{
					need_rejoin_tracker = true;
					logWarning("file: "__FILE__", line: %d, " \
						"tracker response status: %d, " \
						"local status: %d, need rejoin " \
						"tracker server: %s:%d", \
						__LINE__, pServer->status, \
						(*ppFound)->server.status, \
						pTrackerServer->ip_addr,
						pTrackerServer->port);
				}
				// pxxian: add differ server
				memcpy(pDiffServer++, &((*ppFound)->server), \
					sizeof(FDFSStorageBrief));
			}
			else
			{
				(*ppFound)->server.status = pServer->status;
			}
		} // pxxian: end of if (ppFound != NULL)
		else if (pServer->status == FDFS_STORAGE_STATUS_DELETED
		      || pServer->status == FDFS_STORAGE_STATUS_IP_CHANGED)
		{   //ignore
			nDeletedCount++;
		}
		else
		{
			/*
			//logInfo("ip_addr=%s, tracker status: %d", 
				pServer->ip_addr, pServer->status);
			*/

			if ((res=pthread_mutex_lock( \
				 &reporter_thread_lock)) != 0)
			{
				logError("file: "__FILE__", line: %d, "\
					"call pthread_mutex_lock fail,"\
					" errno: %d, error info: %s", \
					__LINE__, res, STRERROR(res))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值