C# 如何处理只需要;最后一句话;数据库C中符号的值#
我有一个高速流的股票价格来自一个供应商。。。也许每秒5000。(约8000个不同的符号) 我的数据库中有一个表(SymbolPrice),需要用最新的最新价格进行更新 我似乎无法保持数据库更新的足够快,以处理最近的价格队列 我使用的是Azure Sql Server数据库,因此我能够将该数据库升级到支持内存表的高级版本,并使我的SymbolPrice表成为内存表。。。但仍然不够好 如果它最终跳过了一个价格,这不是问题,只要最新的价格尽快到达那里。。。所以如果我连续10次被打。。。只有最后一个需要写。。。这听起来很简单,除了一行中的10可能与其他符号混合 因此,我目前的解决方案是使用ConcurrentDictionary只保存最近的价格。并使用符号队列将更新推送到数据库(请参见下面的代码)。。。但这仍然不够快 解决这个问题的一个方法是简单地重复浏览整本字典。。。并用最新价格更新数据库。。。但这有点浪费,因为我也会更新值,这些值可能只会每隔几分钟更新一次,速度与每秒更新多次的值相同 有没有关于如何做得更好的想法 谢谢C# 如何处理只需要;最后一句话;数据库C中符号的值#,c#,sql-server,azure,stockquotes,C#,Sql Server,Azure,Stockquotes,我有一个高速流的股票价格来自一个供应商。。。也许每秒5000。(约8000个不同的符号) 我的数据库中有一个表(SymbolPrice),需要用最新的最新价格进行更新 我似乎无法保持数据库更新的足够快,以处理最近的价格队列 我使用的是Azure Sql Server数据库,因此我能够将该数据库升级到支持内存表的高级版本,并使我的SymbolPrice表成为内存表。。。但仍然不够好 如果它最终跳过了一个价格,这不是问题,只要最新的价格尽快到达那里。。。所以如果我连续10次被打。。。只有最后一个需要
- 布莱恩
public ConcurrentDictionary<string, QuoddLastPriceCache.PriceData> _lastPrices = new ConcurrentDictionary<string, QuoddLastPriceCache.PriceData>(); public ConcurrentQueue<string> _lastPriceSymbolsToUpdate = new ConcurrentQueue<string>(); public void Start() { Task.Run(() => { UpdateLastPricesTask(services); }); lastPriceCache.PriceReceived += (symbol, priceData) => { _lastPrices.AddOrUpdate(symbol, priceData, (key, value) => { return priceData; }); _lastPriceSymbolsToUpdate.Enqueue(symbol); }; } private void UpdateLastPricesTask(IServiceProvider services) { _lastPriceUpdatesRunning = true; while (_lastPriceUpdatesRunning) { if (_lastPriceSymbolsToUpdate.TryDequeue(out string symbol)) { if (_lastPrices.TryRemove(symbol, out QuoddLastPriceCache.PriceData priceData)) { // write to database if (_lastPriceScope == null || _lastScopeCreate + TimeSpan.FromSeconds(60 * 5) < DateTime.UtcNow) { if (_lastPriceScope != null) _lastPriceScope.Dispose(); _lastPriceScope = services.CreateScope(); } var unitOfWork = _lastPriceScope.ServiceProvider.GetRequiredService<IUnitOfWork>(); unitOfWork.SymbolPrice.UpdateLastPrice(symbol, priceData.Price, priceData.Timestamp); } } else Thread.Sleep(1); } }
公共ConcurrentDictionary\u lastPrices=new ConcurrentDictionary(); public ConcurrentQueue_lastPriceSymbolsToUpdate=new ConcurrentQueue(); 公开作废开始() { Task.Run(()=>{UpdateLastPricesTask(服务);}); lastPriceCache.PriceReceived+=(符号,价格数据)=> { _AddOrUpdate(符号,priceData,(键,值)=>{returnpricedata;}); _lastPriceSymbolsToUpdate.Enqueue(符号); }; } 私有void UpdateLastPricesTask(IServiceProvider服务) { _LastPriceUpdateRunning=true; while(_lastPriceUpdatesRunning) { if(_lastpricesymboltUpdate.TryDequeue(输出字符串符号)) { if(_lastPrices.TryRemove(符号,out-QuoddLastPriceCache.PriceData-PriceData)) { //写入数据库 如果(_lastPriceScope==null | | | u lastScopeCreate+TimeSpan.FromSeconds(60*5)
public void Start()
{
Task.Run(() => { UpdateLastPricesTask(services); });
LastPriceCache.PriceReceived += (symbol, priceData) =>
{
_lastPrices.AddOrUpdate(symbol, priceData, (key, value) => { return priceData; });
};
}
public ConcurrentDictionary<string, PriceData> _lastPrices = new ConcurrentDictionary<string, PriceData>();
public bool _lastPriceUpdatesRunning;
public DateTime _lastScopeCreate = DateTime.MinValue;
public IServiceScope _lastPriceScope = null;
private void UpdateLastPricesTask(IServiceProvider services)
{
_lastPriceUpdatesRunning = true;
while (_lastPriceUpdatesRunning)
{
var processed = 0;
foreach (var symbol in _lastPrices.Keys)
{
if (_lastPrices.TryGetValue(symbol, out QuoddLastPriceCache.PriceData priceData))
{
if (priceData.WrittenToDatabase == false)
{
// create a new scope every 5 minutes
if (_lastPriceScope == null || _lastScopeCreate + TimeSpan.FromSeconds(60 * 5) < DateTime.UtcNow)
{
if (_lastPriceScope != null)
_lastPriceScope.Dispose();
_lastPriceScope = services.CreateScope();
}
// write to database
var unitOfWork = _lastPriceScope.ServiceProvider.GetRequiredService<IUnitOfWork>();
unitOfWork.SymbolPrice.UpdateLastPrice(symbol, priceData.Price, priceData.Timestamp);
priceData.WrittenToDatabase = true;
processed++;
}
}
}
if (processed > 0)
Thread.Sleep(1);
else
Thread.Sleep(1000 * 1);
}
}
public void Start()
{
Task.Run(()=>{UpdateLastPricesTask(服务);});
LastPriceCache.PriceReceived+=(符号,价格数据)=>
{
_AddOrUpdate(符号,priceData,(键,值)=>{returnpricedata;});
};
}
公共ConcurrentDictionary_lastPrices=新ConcurrentDictionary();
公共图书馆最近的价格更新运行;
public DateTime\u lastScopeCreate=DateTime.MinValue;
公共IServiceScope_lastPriceScope=null;
私有void UpdateLastPricesTask(IServiceProvider服务)
{
_LastPriceUpdateRunning=true;
while(_lastPriceUpdatesRunning)
{
var=0;
foreach(在_lastPrices.key中的var符号)
{
if(_lastPrices.TryGetValue(符号,out-quodLastPriceCache.PriceData-PriceData))
{
if(priceData.writentodatabase==false)
{
//每5分钟创建一个新范围
如果(_lastPriceScope==null | | | u lastScopeCreate+TimeSpan.FromSeconds(60*5)0)
睡眠(1);
其他的
睡眠(1000*1);
}
}
它有多快,需要多快?在这里,您与数据库的交互方式可能非常关键,您不会显示任何代码。例如,您可以使用表值参数或JSON对更改进行批处理,并每秒左右发送一批更改。这是一个每天每秒5000项的连续流吗?数据是如何到达的、一组HTTP POST、UDP blast或betw中的某些东西