Redis:使用Message Pack在Lua中读取Java Map

我想在 Redis 中存储 Java 数据结构。我编写了以下 Java 代码:

public static void main(String[] args) throws IOException {
    Map<String, String> map = new HashMap<String, String>();
    map.put("foo", "1");
    map.put("bar", "2");
    map.put("baz", "3");
    ArrayList<String> list = new ArrayList<String>();
    list.add("foo");
    list.add("bar");
    MessagePack mp = new MessagePack();
    byte[] serializedMap = mp.write(map);
    byte[] serializedList = mp.write(list);
    Jedis jedis = new Jedis("localhost");
    jedis.zadd("test".getBytes(), 1000, serializedMap);
    jedis.zadd("test2".getBytes(), 1000, serializedList);
    jedis.close();
}

我可以轻松对 Redis 中“test2”的值(serializedList)进行反序列化:

eval "local r = redis.call('zrange', 'test2', 0, 1); return cmsgpack.unpack(r[1]);" 0
1) "foo"
2) "bar"

不幸的是,我无法处理serializedMap。我尝试过类似以下的方法,但没有成功:

eval "local r = redis.call('zrange', 'test', 0, 1); return cmsgpack.unpack(r[1]);" 0
(empty list or set)

有谁能给我一个提示如何正确做到这一点?

点赞
用户1688185
用户1688185

请参考Redis EVAL文档中的 _在Lua和Redis数据类型之间进行转换_一节。如您所见,Lua到Redis转换规则只处理:

  • Lua table(数组)= 序列,
  • 一个具有单个 ok字段的Lua table、
  • 一个具有单个 err字段的Lua table。

这就是为什么通用映射没有被处理(如果任意一个元素为nil,则会将其截断到Lua数组中的第一个nil):

$ redis-cli
> eval 'return cmsgpack.pack{foo="1", bar="2", baz="3"}' 0
"\x83\xa3baz\xa13\xa3bar\xa12\xa3foo\xa11"
> eval 'return cmsgpack.unpack(ARGV[1])' 0 "\x83\xa3baz\xa13\xa3bar\xa12\xa3foo\xa11"
(empty list or set)

注意:有关更多详细信息,请参见此回答

2015-02-05 09:03:41