您的位置:首页 > 其它

性能优化之读写分离二

2015-11-29 23:01 260 查看
上文我们已经说了一些关于读写分离的概念。这篇博客,就大致的写了一个简单的demo 来表现出这种设计思想。

写数据

新建一个类为DataWriter,该类主要用于通过WCF从服务端获取数据。

protected Dictionary<string, double> originalDataCache = new Dictionary<string, double>();//存放缓存数据
public Dictionary<string, double> WriteTypeData()
{
try
{
var dt = QueryServiceFactory.GetDataService(CommonConstants.ServiceEndpointName).GetCurrentData();//获取源数据
if (dt == null || dt.Rows.Count <= 0)
{
return new Dictionary<string, double>();
}
string s_ID;
lock (this)
{
foreach (DataRow item in dt.Rows)
{
s_ID = item[IDColumnName].ToString().Trim();
if (!string.IsNullOrEmpty(s_ID))
{
if (originalDataCache.ContainsKey(s_ID))
{
originalDataCache[s_ID] = Convert.ToDouble(item[ValueColumnName]);
}
}
}

}

return originalDataCache;
}
catch (Exception) { }
return new Dictionary<string, double>();
}


二 存缓存

新建一个类为DataCacheManage,该类主要用于将数据放到缓存中,同时能和读数据的类共享缓存数据。

Dictionary<string, double> DataCache = new Dictionary<string, double>();
/// <summary>
/// 将相应数据放到缓存中
/// </summary>
/// <param name="count"></param>
private void WriteDataCache()
{
try
{
temDataCache = DataWriter.WriteData();
lock (DataCache)
{
DataCache = temDataCache;
}
}
catch (Exception) { }
}


三 从缓存中读取数据

public void AccessData(Dictionary<string, double> temDic)
{
if (temDic==null||temDic.Count <= 0) return;
try
{
foreach (string key in temDic.Keys)
{
var ucValue = StyleFile.StaticStyleValue.GetUcValue(key);
ucValue.RealTimeData = temDic[key];
}
}
catch (Exception)
{
}

}


中间的衔接部分没有细致的写。相信读者可以自行联通起来。

到这一步的,相当于我们已经做好了准备的工作。

即:一方面能将数据源的数据写到缓存。另一方面能从缓存中读取数据更新界面。下一步我们就是安排两个环节做到相互独立不干扰。

于是开启了两个线程。

1)开启一个读线程

#region 界面显示实时数据功能-读数据缓存
/// <summary>
/// 刷新界面
/// </summary>
private void StartDelAccessDataCache()
{
realTimeAccessThreadDelgate realTimeAccessDel = delegate()
{
writeTimer.Start();
writeTimer.Tick += new EventHandler(StartAccessDataCache);
writeTimer.Interval = TimeSpan.FromMilliseconds(800);
};

lock (refreshAccessLock)
{
writeTimer.Dispatcher.BeginInvoke(DispatcherPriority.Normal, realTimeAccessDel);
}
}

private void StartAccessDataCache(object sender, EventArgs e)
{
if (!isAccessingData)//标志位控制如果下面的程序没有执行完即使当前又触发一次该事件也不予执行
{
isAccessingData = true;
accessCounter = accessCounter == timerInfo.RefreshCycle + 1 ? 1 : accessCounter;
ManageAccessDataCache(accessCounter);
writeCounter = writeCounter + 1;
isAccessingData = false;
}
}

private void ManageAccessDataCache(int timerUICount)
{
try
{
if (timerUICount % timerInfo.WindRefreshInterval == 0)//如果到了更新间隔值
{
realTimeDataAccess.WindAccessData(DataCache);
}
}
catch (Exception)
{

}
}


2)开启一个读线程

/// <summary>
/// 开启一个计时器实时写缓存
/// </summary>
private void StartDelWriteDataCache()
{
realTimeWriteThreadDelgate realTimeWriteDel = delegate()
{
realTimeRefreshDataTimer.Start();
realTimeRefreshDataTimer.Tick += new EventHandler(StartWriteDataCache);
realTimeRefreshDataTimer.Interval = TimeSpan.FromMilliseconds(400);
};
lock (refreshAccessLock)
{
realTimeRefreshDataTimer.Dispatcher.BeginInvoke(DispatcherPriority.Normal, realTimeWriteDel);
}
}

/// <summary>
/// 通过计数器计数,控制写数据的过程
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StartWriteDataCache(object sender, EventArgs e)
{
if (!isWrittingData)//标志位控制如果下面的程序没有执行完即使当前又触发一次该事件也不予执行
{
isWrittingData = true;

writeCounter = writeCounter == timerInfo.RefreshCycle + 1 ? 1 : writeCounter;
ManageWriteDataCache(writeCounter);
writeCounter = writeCounter + 1;

isWrittingData = false;
}
}


如此,我们便做完了。篇幅有限,细节的定义和衔接都没有在博客中写出来,不过重要的还是对读写分离这样一个概念的认识和理解。对于之后的大数据的设计非常的有帮助。当然,关联到具体的项目中去的话,还要根据实时性的要求去优化数据源和数据缓存如何能在更小的时间单位里保持一致。也要考虑到对数据块既有读操作也有写操作时,应该在哪里加锁更合适。以上,抛砖引玉。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  缓存 数据 设计