如何使用stackexchange.redis从多个键获取所有哈希元素

时间:2016-04-04 12:36:14

标签: c# lua redis stackexchange.redis

我正在评估redis,并尝试使用lua脚本在一次调用中从redis获取多个哈希键。

我似乎无法让它发挥作用。下面的代码将一系列项目返回给我的c#代码,但我似乎无法获得哈希结果。返回的redisResult是一个数组,数组的每个元素都是一个空数组。我希望每个元素都是哈希值的数组。

        int key1 = 1;
        var sb = new StringBuilder();
        var compositeKeys = new List<RedisKey>();
        for (int key2 = 1; key2 < 1000; key2++)
        {
            compositeKeys.Add((RedisKey)GetRedisKey2(key1, key2));
        }


        sb.AppendLine("local collate = function(key)");
        sb.AppendLine("local raw_data = redis.call('HGETALL', key)");
        sb.AppendLine("local data = {}");
        sb.AppendLine("for idx = 1, #raw_data, 2 do");
        sb.AppendLine(" data[raw_data[idx]] = raw_data[idx + 1]");
        sb.AppendLine("end");
        sb.AppendLine("return data;");
        sb.AppendLine("end");

        sb.AppendLine("local data = {}");
        sb.AppendLine("for _, key in pairs(KEYS) do");
        sb.AppendLine("  data[_] = collate(key)");
        sb.AppendLine("end");

        sb.AppendLine("return data");

        var results = _redDb.ScriptEvaluate(sb.ToString(), compositeKeys.ToArray());

编辑:为了更好地解释我尝试做的事情: 这将用于查找股票市场数据,并且有三种用例可以从缓存中获取数据。

  1. 按符号和时间获取单个项目
  2. 获取单个符号的一系列历史数据
  3. 从特定时间获取一系列符号
  4. 每个数据点当时有大约30个关于股票的数据字段。我使用组合符号和时间的键以及对象中每个字段的哈希字段来存储它。我收到的单个股票查询的表现很好,但我在查找一系列值时遇到了麻烦。

    我实现了此问题中描述的流水线方法:StackExchange.Redis: Batch access for multiple hashes。性能还可以,但不比我今天从SQL Server中获得的要好。我想使用LUA脚本方法对性能进行基准测试,但我必须做错事。

1 个答案:

答案 0 :(得分:0)

不是专注于问题标题(主要是因为我不相信你会得到你正在寻找的性能提升),我会建议另一种方法,专注于你后来添加到你的问题中的目标:

  
      
  1. 按符号和时间获取单个项目
  2.   
  3. 获取单个符号的一系列历史数据
  4.   
  5. 从特定时间获取一系列符号
  6.   

鉴于您对基于时间的范围的兴趣,您可能会发现排序的集合效果更好。

有序集由元素组成,其中每个元素都有一个分数(一个double)和一个值(任何字符串,例如JSON,使用protobuf序列化的对象)。

因此,您可以为每个股票创建一个集合,并在您的集合中添加元素,其中分数是交易时间,以毫秒为单位(*),该值是一个描述您的交易的字符串。如,

ZADD stocks.GOOG 1459956490731 {LastTradePrice:743.16,SomeOtherUsefulInfo:123}

然后查询给定时间范围内的所有交易,

ZRANGE stocks.GOOG <start-time-in-ms> <end-time-in-ms> WITHSCORES

要在特定时间内获得一系列符号,您需要一个额外的集合,其中每个库存添加一个应该返回的元素,例如

ZADD stocks.active 1459956490731 GOOG
ZADD stocks.active 1459956490731 IBM
ZADD stocks.active 1459956490731 AAPL

希望这有帮助!

(*)例如,

var startOfTime = new DateTime(2016, 1, 1); 
var tradeTime = DateTime.Now; 
var ms = (tradeTime - startOfTime).TotalMilliseconds;