1

问题指的是redis的分片配置。我用 Java 实现了一个小型测试应用程序,它以 user:userID 的形式在 Jedis 上创建了 100.000 个用户哈希。每个散列都有以下元素:姓名、电话、部门、用户 ID。我还使用关键电话:电话号码创建了简单的键值对,其中包含电话号码为 ID 的用户 ID,并为每个部门设置了为该特定部门工作的用户 ID。后两种类型我仅用于搜索。这些结构和搜索类似于Searching in values of a redis db

简而言之,数据结构:

user:userID->{name, department, phone, userID}
department:department->([userID1, userID2,....])
phone:phone->userID

搜索的用例:

  1. 基于密钥(即用户ID)访问用户哈希
  2. 搜索有电话号码的用户
  3. 搜索部门的所有用户

在单实例分片配置中一切正常,但我会有以下问题:

  • 在单实例配置中,可以使用宽卡查找电话号码,例如使用KEY方法,但这在分片配置中不可用。如何查找第一部分已知的密钥?
  • 用户 ID 是从一个 zset 生成的,它的用户 ID 得分增加。这可以在单实例配置的事务中完成,但即使参与的密钥在同一个实例上,jedis 上的分片配置似乎也不支持事务。如果多个客户端线程也可以创建用户,如何解决这个问题?

也提前感谢您的回复。

4

1 回答 1

1

对于您问题的第一部分:

这里没有魔法,如果你想搜索所有的分片,你必须遍历所有的分片。Jedis 没有此方法,但您可以扩展ShardedJedis来添加它(未经测试):

    public Set<String> keys(String pattern) {
    HashSet<String> found = new HashSet<String>();

    for (Jedis jedis : getAllShards()) {
        found.addAll(jedis.keys(pattern));
    }

    return found;
    }

对于您问题的第二部分:

AFAIK,Jedis 在使用分片时不支持事务,即使您确实强制相关键位于同一个分片上(请参阅Jedis 高级用法)。

这个相同的链接提出了一个可能适用于一些场景的解决方法:

混合方法

如果你想轻松分配 ShardedJedis 的负载,但仍然需要事务/管道/pubsub 等,你也可以混合使用普通和分片的方法:将一个 master 定义为普通的 Jedis,其他的定义为 sharded Jedis。然后让所有的分片成为master的slave。在您的应用程序中,将您的写入请求定向到主服务器,将读取请求定向到 ShardedJedis。您的写入不再扩展,但您获得了良好的读取分布,并且您只需使用主控即可拥有事务/流水线/发布订阅。数据集应该适合 master 的 RAM。请记住,如果您让奴隶为主人做持久性,您可以大大提高主人的性能!

于 2013-07-15T14:57:12.297 回答