• KV 接口
    • 接口示例
    • 处理返回结果
      • 读取返回值

    KV 接口

    接口示例

    Nebula Graph storage 提供 key-value 接口,用户可以通过 StorageClient 进行 kv 的相关操作,请注意用户仍然需要通过 console 来创建 space。目前支持的接口有 Get 和 Put,接口如下。

    1. folly::SemiFuture<StorageRpcResponse<storage::cpp2::ExecResponse>> put(
    2. GraphSpaceID space,
    3. std::vector<nebula::cpp2::Pair> values,
    4. folly::EventBase* evb = nullptr);
    5. folly::SemiFuture<StorageRpcResponse<storage::cpp2::GeneralResponse>> get(
    6. GraphSpaceID space,
    7. const std::vector<std::string>& keys,
    8. folly::EventBase* evb = nullptr);

    后续将提供 remove,removeRange 以及 scan 的方法。

    下面结合示例说明 kv 接口的使用方法:

    1. // Put 接口
    2. std::vector<nebula::cpp2::Pair> pairs;
    3. for (int32_t i = 0; i < 1000; i ++) {
    4. auto key = std::to_string(folly::Random::rand32(1000000000));
    5. auto value = std::to_string(folly::Random::rand32(1000000000));
    6. pairs.emplace_back(apache::thrift::FragileConstructor::FRAGILE,
    7. std::move(key), std::move(value));
    8. }
    9. // 通过 StorageClient 发送请求,相应的参数为 spaceId,以及写入的键值对
    10. auto future = storageClient->put(spaceId, std::move(pairs));
    11. // 获取结果
    12. auto resp = std::move(future).get();
    1. // Get 接口
    2. std::vector<std::string> keys;
    3. for (auto& pair : pairs) {
    4. keys.emplace_back(pair.first);
    5. }
    6. // 通过 StorageClient 发送请求,相应的参数为 spaceId,以及要获取的 keys
    7. auto future = storageClient->get(spaceId, std::move(keys));
    8. // 获取结果
    9. auto resp = std::move(future).get()

    处理返回结果

    用户可以通过检查 rpc 返回结果查看相应操作是否成功。此外由于每个 Nebula Graph storage 中都对数据进行了分片,因此如果对应的 Partition 失败了,也会返回每个失败的 Partition 的错误码。若任意一个 Partition 失败,则整个请求失败(resp.succeeded()为 false),但是其他成功的 Partition 仍然会成功写入或读取。

    用户可以进行重试,直至所有请求都成功。目前 StorageClient 不支持自动重试,用户可以根据错误码决定是否进行重试。

    1. // 判断调用是否成功
    2. if (!resp.succeeded()) {
    3. LOG(ERROR) << "Operation Failed";
    4. return;
    5. }
    6. // 失败的 Partition 以及相应的错误码
    7. if (!resp.failedParts().empty()) {
    8. for (const auto& partEntry : resp.failedParts()) {
    9. LOG(ERROR) << "Operation Failed in " << partEntry.first << ", Code: "
    10. << static_cast<int32_t>(partEntry.second);
    11. }
    12. return;
    13. }

    读取返回值

    对于 Get 接口,用户需要一些操作来获取相应的返回值。Nebula storage 是基于 Raft 的多副本,所有读写操作只能发送给对应 partition 的 leader。当一个 rpc 请求包含了多个跨 partition 的 get 时,Storage Client 会给访问这些 key 所对应的 Partition leader。每个 rpc 返回都单独保存在一个 unordered_map 中,目前还需要用户在这些 unordered_map 中遍历查找 key 是否存在。示例如下:

    1. // 查找 key 对应的 value 是否在返回结果中,如果存在,则保存在 value 中
    2. bool found = false;
    3. std::string value;
    4. // resp.responses()中是多个 storage server 返回的结果
    5. for (const auto& result : resp.responses()) {
    6. // result.values 即为某个 storage server 返回的 key-value paris
    7. auto iter = result.values.find(key);
    8. if (iter != result.values.end()) {
    9. value = iter->second;
    10. found = true;
    11. break;
    12. }
    13. }