Kv Store get 使用咨询

在使用 get 和 mget接口得时候某一个 leader 的 GetRequest 总是失败
2台机器:
10.97.174.114
10.97.160.134
10分片,2副本
在get和mget 的时候走 114 的 GetRequest总是失败,134 的没有问题

换成单副本就没有这个问题了

        Optional<Map<String, String>> result = doGet(spaceName, leader, request);
        if (!result.isPresent() || !result.get().containsKey(key)) {
            System.out.println("HostAndPort Fail " + leader.toString());
            return Optional.absent();
        } else {
            System.out.println("HostAndPort Successfully" + leader.toString());
            return Optional.of(result.get().get(key));
        }

目前是只能通过每个partition 的 leader 读取或者写入数据,你现在是两副本,正常情况下是会分布在两个节点,那么其中一个节点是 leader 另一个节点即为 follower。

如果直接向 follower 所在节点请求数据,是会直接返回 error 的。

所以会出现你描述的一个节点的请求成功,另一个节点失败。

建议使用 nebula 封装好的 client 来跟 storage 交互,client 这边会做 leader 的识别,只会向 leader 发送请求。

我使用的是封装好的官方java-client,每次get相同key,client 会随机分配一个节点当做Leader去查,好像没有识别leader,看源码好像没有初始化leader分布信息,走的是最后一个随机分配逻辑。

private HostAndPort getLeader(String spaceName, int part) {
        if (!leaders.containsKey(spaceName)) {
            leaders.put(spaceName, Maps.newConcurrentMap());
        }

        if (leaders.get(spaceName).containsKey(part)) {
            return leaders.get(spaceName).get(part);
        } else {
            List<HostAndPort> address = metaClient.getPartFromCache(spaceName, part);
            if (address != null) {
                Random random = new Random(System.currentTimeMillis());
                int position = random.nextInt(address.size());
                HostAndPort leader = address.get(position);
                leaders.get(spaceName).put(part, leader);
                return leader;
            }
            return null;
        }
    }

现在java client做的比较简单直接通过thrift 协议做的请求 应该还没做leader cache

这里是最开始初始化 leader 的逻辑, 目前 client 对 leader 的处理大体是以下的过程:

  1. 初始时,从 meta 获取 partition 的所有分布信息(ip 地址),这里有 leader 和 follower,然后从中随机指定一个为 leader,这时有可能将 follower 指定为 leader
  2. 用户请求时,查看返回的结果错误码,如果是 leader change 的 error,这时会在 client 端更新 leader 信息,但是本次请求依然返回 error,不做转发给真正的 leader 处理

鉴于以上两点,用户在使用 client 时,最好加上重试的机制,因为最初时随机选取的 leader 不一定是真正的 leader,像你所述中,两副本大概有 50% 的概率是能在第一次就设置正确的。