nebula手动导入sst使用ingest报错

大家好,做手动导入sst的时候遇到的几个问题,有了解过的,请帮忙回答 :heart:

  • nebula 版本:3.0.2
  • 部署方式:单机
  • 安装方式:Docker
  • 是否为线上版本:N
  • 问题的具体描述

背景

在nebula-console使用ingest命令导入sst文件失败.

准备工作

sst文件保证是没有问题的,然后我把文件放到对应的storage节点的/data/storage/nebula/3/download目录了
截屏2022-04-19 15.47.45

问题

(1)第一次没有目录,/data/storage/nebula/3/download,手动创建3/download,文件放到下面,执行ingest,然后立马查询,match (n:player) return count(n) 返回数量为0,ingest是否有延迟,大概多久?
(2)第二次找了一个拥有space目录的,/data/storage/nebula/3/download 这个完整路径存在,3下面同时存在data、wal两个其他目录,这时候手动rm -rf 这俩目录,然后吧数据放到download下面。执行ingest失败
控制台现场如下
截屏2022-04-19 15.54.51
日志如下

I20220419 07:41:44.567314   176 NebulaStore.cpp:828] Ingesting extra file: /data/storage/nebula/3/download/1/1-189.sst
E20220419 07:41:44.572053   176 RocksEngine.cpp:426] Ingest Failed: IO error: No such file or directory: While open a file for appending: /data/storage/nebula/3/data/000150.sst: No such file or directory
E20220419 07:41:44.574631   176 StorageHttpIngestHandler.cpp:97] SSTFile Ingest Failed: E_UNKNOWN
E20220419 07:41:44.577844   176 StorageHttpIngestHandler.cpp:71] SSTFile ingest failed

(3)想问一下这个报错什么原因导致的?
(4)这个download目录什么时候会系统自己创建?
(5)如果space下没有数据,这个space的storage目录下面没有这个download的文件夹,我可以自己创建走完整个流程,如果存在系统创建的文件的时候怎么处理?
(6)导入sst是否只支持刚创建space的时候,做第一次导入?还是支持系统已经存在数据的情况下继续导入,还是支持系统存在数据的情况下,进行多次sst导入?
(7)支持多次sst文件追加导入的话,多次的sst文件,都需要永久保留到download目录,还是导入成功后,就可以立马删除

1 个赞
  1. 试一下不删除wal和data目录
  2. 导入sst可以在任意时候进行,但是要保证sst文件符合rocksdb的要求
  3. ingest之后download下的文件可以删除

(1)我又新建了一个space,系统自动创建了文件夹目录:data/storage/nebula/新的空间id,下面存在data和wal文件夹,我在data/storage/nebula/新的空间id下新建download目录,把所有的sst文件拷贝进去。
(2)然后返回nebula-console手动在当前space内创建schema,建立索引。
(3)use 新space
执行ingest,执行成功,如下图


但是查询还是没有查询到导入的数据。截止目前已经距离执行ingest,过了半个小时,查询还是查不到。


附细节:我这里保证sst文件没有问题的原因,是昨天下午测试这个步骤也没有成功,但是今天没有做任何操作,直接进入space查看,竟然可以查到昨天按步骤本应该导入的数据。
也就是过了一夜,自己出来了,所以认为文件没有问题,就是延迟过高,或者不确定哪些细节操作,影响了它刷新导入的数据。

您在Ingest之后可以用show jobs命令看一下Ingest的进度。可能确实是因为您这边数据量比较大,所以它没有执行完。

在测试手动导sst的过程中,引入了另外一个环境问题,我觉得这个可能是手动导sst文件,会出现的一个通用问题,希望帮忙排查一下问题出在哪里。

环境

本地搭建环境参考的文档是这个:Nebula Exchange SST 2.x Hands-on Guide - siwei.io ,本地使用docker compose搭建了3个graphd、3个metad、3个storaged,用来测试导入sst

步骤

通过nebula-console创建了space,并在里面创建了schema,增加了索引,语句如下

//创建schema
CREATE TAG player(name string, age int);
//创建索引
CREATE  TAG INDEX IF NOT EXISTS age_index  ON player (age) COMMENT '年龄索引';

然后登陆nebula-docker-compose_storaged1_1,发现目录:/data/storage/nebula/,自动创建了spaceid的目录25,并且在文件夹25下面创建了data和wal两个系统文件
然后我手动创建data、wal的同级download目录,把sst文件放到download下面
最终sst存放目录为:/data/storage/nebula/25/download,然后返回nebula-console,执行ingest后,发现没有导入数据

现象

第二天打开容器,发现nebula-docker-compose_storaged1_1容器已经处于restarting状态,不断重启,
有时可以进入容器内部,cd /data目录没有问题,cd /data/storage目录时控制台就会卡死亡,因为存在多个storage,所以另外两个存活的容器在进行选举,整个nebula服务还可以正常查询

日志报错

启动时storage的log日志报错如下

Log file created at: 2022/04/21 09:05:21
Running on machine: e2e5e79b25f5
Running duration (h:mm:ss): 0:00:00
Log line format: [IWEF]yyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg
F20220421 09:05:21.001977     1 RocksEngine.cpp:398] Check failed: key.size() == sizeof(PartitionID) + sizeof(NebulaSystemKeyType) (12 vs. 8) 

问题

(1)希望大佬帮忙分析一下是什么原因导致的nebula-docker-compose_storaged1_1容器挂掉,是否因为我放置sst导致破坏了节点的数据?
(2)我的sst是使用exchange工具从csv到入另外一个space:first时,生成的文件,first和当前手动导入的space空间分片和副本数量不一致,schema创建语句除了vid type不一致其他字段一样,这个是否会导致容器挂掉?或者是否也是我这次导入数据失败原因?
(3)想确认一下,使用exchange生成的sst文件,是否有只能用来手动导入到exchange配置文件里写的space空间,如果换个space空间导入这份sst有什么因素需要保持一致,比如新space分片数、schema需要完全一致等等。
(4)因为这次的场景我认为属于手动导入sst数据很常见的场景,所以想问一下,怎么恢复这个容器,防止线上对一个space导数据出错,导致数据库崩溃,影响其他space使用?

Exchange 的 sst 是针对给定的图空间生成的,我还不确定想做到跨空间(而且副本数不同)的情况下只是改一下目录 id 名字可以不以,看起来是不可以:sob:

大佬,昨天我这边分析结果也是由于这份sst文件不是exchange针对当前空间生成的,所以导入冲突产生的失败。但是没有找到源码对应的位置,所以不太确定原理。
想看看有没有官方的解释,
(1)为什么导入出错不是报错,而是导致整个节点挂掉?
(2)key.size() == sizeof(PartitionID) + sizeof(NebulaSystemKeyType) (12 vs. 8) 这个报错的直接原因是什么?
(3)怎么恢复这个节点?
(4)如果两个space除了名字不一样,其他分片等都完全一致,exchaneg根据其中一个space生成的sst文件,另外一个space是否可以复用?

正在看nebula-exchange源码中,希望自己也找到答案 :imp:

我不是大佬,您这个用exchange来跨space导数据的方法不是 exchange 被设计出来的初衷,我还不懂 SST 的很多知识,但感觉上直接放进去应该不行,比如数据里 key 的部分有 part ID 这个信息,这在跨 space 的情况下已经无效了。

1 个赞

感谢,我看文档的时候注意到这个设计图


本地部署使用的3.0的nebula,所以理解底层设计应该使用的是v3.x的最后一个,去掉tagID的结构

场景

exchange对space1生成sst,对space2倒入这个sst

space1环境

5个分片,3个副本,schema如下

CREATE SPACE IF NOT EXISTS space1 ( partition_num=5,replica_factor = 3,vid_type = FIXED_STRING(30)) COMMENT = 'space1';

space2环境

10个分片,1个副本,schema如下

CREATE SPACE IF NOT EXISTS space2 ( partition_num=10,replica_factor = 1,vid_type = INT64) COMMENT = 'space2';

问题

但是没有理解,上面报错这个具体原因,比如根据什么计算出来的,特别是12与8

Check failed: key.size() == sizeof(PartitionID) + sizeof(NebulaSystemKeyType) (12 vs. 8) 

挂的原因就是生成的sst文件里面key不合法,大概说下原因:
挂的这行这个前缀的key长度必须是8(内部使用的),但是遇到了一个长度是12的,所以直接挂了。详细点说是:期望的前四个字节是NebulaKeyType::kSystem, 后四个字节必须是 NebulaSystemKeyType 里的一个值。所以生成的sst里肯定有同时满足这个条件的……然后启动时候扫描这个内部的key,不符合预期,crash。

enum class NebulaKeyType : uint32_t {
  kTag_ = 0x00000001,
  kEdge = 0x00000002,
  kIndex = 0x00000003,
  kSystem = 0x00000004,
  kOperation = 0x00000005,
  kKeyValue = 0x00000006,
  kVertex = 0x00000007,
  kPrime = 0x00000008,        // used in TOSS, if we write a lock succeed
  kDoublePrime = 0x00000009,  // used in TOSS, if we get RPC back from remote.
};

1 个赞
  1. 你这个是 system 的 key,exchange sst 只生产 tag 和 edge 的数据,和 system 没有关系。检查一下你 生成 sst 的机器,和运行 nebula 的机器,是不是都是大端或都是小端。
echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6 
  1. 需要先创建 space,按这个 space 生成 sst,再导入到这个 space 里。导入其他 space,即便导出成功,也是有可能查不出数据的。

原因:
sst 里的 key 有 tagId,value 有 tag 的 version,如果生成 sst 和导入的 space 这些信息不一致,是读不出来数据的。

1 个赞

@HarrisChu @critical27 都是使用的docker容器,测试了一下容器环境都是属于小端
还不太清楚这个非法的系统key是哪里的来的,请问nebula-exchange 2.x和3.x的版本有生成系统key这块规则的变化吗?
我初步怀疑是我使用的nebula-exchange 2.x生成sst 和nebula数据库3.0.x环境不兼容的问题,不过使用 client 模式时没有问题

    type: {
        source: csv
        sink: client
      }

exchange 一直都不会生成系统的 key
方便的话,可以传 1 个生成的 SST 文件

这个是sst文件
1.zip (8.8 KB)

看了下,数据量很少,插了 9 个带 tag 的点,2个不带 tag 的点?

没有系统的 key,你再想想看你环境里做了啥吧。

1 个赞

假如我在大端机器上生成的sst文件,放到小端机器导入sst文件,是否会有问题?

会有问题。

代码里有部分值是按大端还是小端来取的。

1 个赞

手动ingest数据sst需要注意,先测试client模式,这个比较简单
1.neubla-exchange的版本与nebula-graph、spark版本保持兼容,具体参考官方文档版本号之间的关系
nebula-exchange与nebula-graph:使用限制 - Nebula Graph Database 手册
2.针对具体数据库和space生成的sst文件,只能用于这个空间的ingest,即使重新创建space,创建的space和内部schema一模一样也不行
3.放置sst的位置需要放在:storage/nebula/{spaceId}/download 下面
4.需要在-c 的exchange.conf配置文件里,强制指定: repartitionWithNebula: true,文档位置:配置参数 - Nebula Graph Database 手册
这里有bug,具体信息参考:exchange 3.0 的生成的sst只包含不带tagID的数据
https://github.com/vesoft-inc/nebula-exchange/issues/71
https://github.com/vesoft-inc/nebula-exchange/pull/49
5.集群情况(todo)还未测试完成,可以先从单机测试,分区、副本、节点数都可能成为导数据的影响因素

感谢大佬们的回复,如果有不对的请帮忙指正,以上为本人操作具体实践结论。

1 个赞

感谢 @neo4j ,看起来这里是有问题的,我们要看下 repartitionWithNebula: false 在什么情况下才可以使用,还是 false 时候有 bug。
非常棒的总结,辛苦你趟了这么久:+1:t2::handshake: