我正在webjob中进行列表排序。当我使用c#list时,它工作得很好。但为了提高性能,我将数据以列表的形式保存到redis缓存中。
我的最终目标是只拿出最近5分钟的数据。
工作c代码-
public class MyObject
{
public uint InstrumentID { get; set; }
public decimal Close { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Open { get; set; }
public DateTime TimeStamp { get; set; }
public uint Volume { get; set; }
public DateTime Created { get; } = DateTime.Now;
public DateTime Ttl { get; } = DateTime.Now.AddMinutes(5);
public DateTime? Persisted { get; set; }
public bool IsDead => DateTime.Now > Ttl;
public bool IsPersisted => Persisted.HasValue;
public bool TimeToPersist => IsPersisted == false && DateTime.Now > Created.AddMinutes(5);
public DateTime GetStartOfPeriodByMins(int numMinutes)
{
int oldMinutes = TimeStamp.Minute;
int newMinutes = (oldMinutes / numMinutes) * numMinutes;
DateTime startOfPeriod = new DateTime(TimeStamp.Year, TimeStamp.Month, TimeStamp.Day, TimeStamp.Hour, newMinutes, 0);
return startOfPeriod;
}
}
var inputList = new SortedSet<MyObject>(new MyObjectComparer());
inputList.Add(new MyObject() { TimeStamp = DateTime.Now, Open = 9, High = 12, Low = 8, Close = 11, InstrumentID = 2526 });
Thread.Sleep(10000);
inputList.Add(new MyObject() { TimeStamp = DateTime.Now, Open = 9, High = 12, Low = 8, Close = 11, InstrumentID = 2526 });
Thread.Sleep(10000);
inputList.Add(new MyObject() { TimeStamp = DateTime.Now, Open = 9, High = 12, Low = 8, Close = 11, InstrumentID = 2526 });
Thread.Sleep(50000);
inputList.Add(new MyObject() { TimeStamp = DateTime.Now, Open = 9, High = 12, Low = 8, Close = 11, InstrumentID = 2526 });
var resultSet = inputList
.GroupBy(i => i.GetStartOfPeriodByMins(5))
.Select(gr =>
new
{
StartOfPeriod = gr.Key,
Min = gr.Min(item => item.Open),
Max = gr.Max(item => item.Open),
Open = gr.OrderBy(item => item.TimeStamp).First().Open,
Close = gr.OrderBy(item => item.TimeStamp).Last().Open
});
现在,我不断地将相同的记录插入redis缓存。当我试图获取最后5分钟的数据时,我想用同样的方法 GetStartOfPeriodByMins
但是它需要一个myobject类的列表,redis返回redisvalue[]。
redis代码-使用stackexchange.redis包
var cache = RedisConnectorHelper.Connection.GetDatabase();
//int i = 0;
for (int i = 0; i < 10000; i++)
{
var tickDataHis = new MyObject()
{
InstrumentID = 2526,
Close = 14 + i,
High = 16 + i,
Low = 11 + i,
Open = 12 + i,
TimeStamp = DateTime.Now,
Volume = 11111
};
// insert into redis
cache.ListRightPush("tickData", JsonConvert.SerializeObject(tickDataHis));
Thread.Sleep(3000);
}
var inputList = cache.ListRange("tickData");
或者有没有其他方法可以从redis缓存中获取最新的5分钟数据?
1条答案
按热度按时间guicsvcw1#
过去我用redis存储timeseries数据。为了优化数据检索,我使用了一个排序集(在这种情况下不止一个,但概念是相同的),其中分数是记录数据时的unix时间戳,我使用
Newtonsoft.Json
图书馆。代码是这样的:
这样做,如果您只想检索最近5分钟的数据,可以直接使用
SortedSetRangeByScore
方法并传递“now-5 minutes”作为起始分数,这样您就可以只反序列化您需要的内容(这当然比反序列化整个列表要便宜):之后,您可以在linq的帮助下轻松地反序列化数据(请考虑
RedisValue
实现运算符到字符串的转换):编辑:我没有使用@hasan emrah s建议的软件包üng公司ü. 也许更有效,我只是解释一下我当时做了什么。
编辑2:
redisDb
是我的StackExchange.Redis.IDatabase
示例。编辑3:有用的参考链接:
redis上的数据持久性:https://redis.io/topics/data-types-intro#redis-过期密钥的生存时间有限
redis排序集:https://redis.io/topics/data-types-intro#redis-排序集
时间序列的排序集:https://redislabs.com/redis-best-practices/time-series/sorted-set-time-series/