必须给需要查询的属性创建索引,才能根据属性的值进行过滤符合条件的数据,这个设计是不是说明要查数据必须配合es这种引擎使用

  • nebula 版本:nebula-graph-3.0.1.el7.x86_64
  • 部署方式:分布式 /
  • 安装方式:源码编译 /
  • 是否为线上版本:Y
  • 硬件信息
    • 磁盘( 推荐使用 SSD)
    • CPU、内存信息
  • 问题的具体描述
    1、nebula如果必须要给需要检索的字段创建索引,才能根据字段查询数据,那么无论是刚开始创建tag时就要指定索引,还是后面要查的时候,再创建索引有如下几个问题
    1.1、刚开始我不知道后面会用什么字段去查,就算后面知道了,再给已经有上亿的数据创建索引,可想而有多可怕
    1.2、创建索引导致插入性能很慢的话,官方能给个大概的数据的,我看有人说慢90%?那不是可以理解成完全不建议创建索引这个功能
    1.3、基于分布式存储引擎考虑,这种设计我理解初衷,hbase根据字段查询的性能也基本用不了,我们采用方案是es+hbase来解决,查询和存储数据的问题,但是引入es的维护成本可想而知
    1.4、同样是基于rocksdb的ArangoDB其实根据属性查询性能还是挺好的,也不需要必须创建索引才能查,这点可能是比较致命的一个地方,没有根据属性查询的功能,那不就陷入了死循环,刚开始导入数据的时候,不依赖其他存储引擎,就完全没法入手,在画布上也只能随机导入一些数据,最终一步步拓展找到我们最终 要的数据?太离谱了。。

就是想问问,社区的老哥们有没更好的方案?或者说官方有吗考虑怎么解决?

- 相关的 meta / storage / graph info 日志信息(尽量使用文本形式方便检索)
(root@nebula) [basketballplayer]> LOOKUP ON player WHERE player.name == "Kobe Bryant" YIELD id(vertex) AS VertexID, properties(vertex).name AS name;
[ERROR (-1005)]: There is no index to use at runtime

Thu, 25 Aug 2022 10:29:45 CST

(root@nebula) [basketballplayer]> MATCH (v:player { name: 'Tim Duncan' })-->(v2:player) RETURN v2.player.name AS Name;
[ERROR (-1005)]: IndexNotFound: No valid index found

老哥们,能不能出谋划策一下,本来想从arangodb切到nebula,性能啥的都测完了,发现nebula确实更优秀,没想到使用上还是不是很符合我们的业务,或者说大家用图引擎的时候有没碰到过类似的问题,有都是怎么解决的

感谢您的支持!!!感谢选择 NebulaGraph,咱们一起来把它搞的更好用,一点点消除你的痛点

NebulaGraph 和 Arango 的一个区别在于 NebulaGraph 默认把数据存为邻接表,而后者默认还是文档的表形式,然后再做面向图(连接)的索引。

这种取舍、优先级的区别使得我们的存储空间和写入性能只有在确定做哪些面向表结构查询(lookup/match 属性条件为起点)的时候,才会相应再哪些部分付出代价。

不过这种代价也实实在在带来了咱们在决定哪些(和不确定性时候)的负担,它要求我们不得不仔细去设计索引、复合索引的组合、顺序。

我的一些看法:

  • 如果可能,充分利用 string key 的设计,如果可以逻辑确认唯一的情况下,可以利用前缀(比如 p_ 代表 player),多因素比如(p_tim_duncan_1986名字小写+生日)去定义 vid,这样的好处是我们在一些本来依赖索引才能进行的起点查询上,可以不用索引,直接构造 vid(key),这也是 nebulaGraph 不自增 key 设计的优势,能充分利用 identity 信息
  • 需要索引的时候大胆去创建,只要你心里知道你的查询起点不得不通过属性过滤而得,索引的按需创建是一个 gift 不是 curse,慢只是针对 NebulaGraph 的无索引情况基线来的(需要索引再性能上是给出了选择-gift,不是一个诅咒 :stuck_out_tongue_closed_eyes: )。它的代价我在(Nebula Graph 索引详解 - siwei.io )也有介绍,bilibili 上也有我们存储同学的一期直播分享讲解
  • 对于前期不知道会涉及哪些索引、而且就算知道了,后边业务多变可能带来新的属性过滤起点查询需求的焦虑,我能深深感受到,其实现在据我所知3.1 还是 3.2之后只要存在一个属性索引或者 tag/edge (无属性)索引,各种查询也是能做的,不会像以前拒绝说没有索引了,只是你知道这样的查询是顺着索引捞取属性然后再过滤,比较昂贵(但是只要内存够,就可以查),这方面算是一些进步。
    未来我们可以做的更好,减轻这种的焦虑 @MuYi ,不知道有没有可能做 pushdown 宽索引 indexscan filter @critical27 呢?这样可以在比如 tag 索引下,极其方便特别多复杂组合的 filter 条件的查询,降低心智负担?创建了 issue 哈 https://github.com/vesoft-inc/nebula/issues/4581
1 个赞

感谢回答,还是有两点疑惑点:
1、设计好vid的话,一般也是通过多个字段的值拼接,vid能模糊查询吗这一点存疑,第二选哪些字段做vid,vid能用中文吗,比如车牌号和车身颜色,必定有中文,如果vid不支持中文,那又得编码后才能当vid吧,然后再模糊查询,无论是设计还是效率上似乎都很难实现
2、大多数要用到字段查询的情况,在实际的使用中,其实不是创建schema的用户确定的,而是使用的用户决定的,用户随意用哪个字段查询数据,然后再考虑用不用把过滤出来的数据导入到画布进行拓展或者其他功能,我们就在已经有几千万数据的情况下,为他需要查询的字段创建索引然后去查,性能消耗可想而知,然后后续这个tag或者edge有要继续接入数据,你这所有一创建,接入性能又差,又可能反复创建同样的索引,后续维护成本不可想象
3、我知道nebula设计初衷是好的,避免不当的使用导致内存占用过高的问题,但是我的愚见是,这个不应该在设计层面直接屏蔽,至少可以提示用户少用,实际上用除了定位数据接入是不是对的时候才会去看一下数据,用的确实少,用户说买的机器这么好,搞个你们昂贵的查询拥有又怎么了,又不是用不起,而且用了图数据库,我连基本查询都用的不顺,其实挺尴尬的
4、这个迫使我们反思自己的业务问题,tag或者edge没有必要设计很多字段,比如tag才10个字段,建立十个索引去查询,插入性能能查到哪去,索引创建十个是不是有点多,会不会有其他问题,这个问题如果老哥知道,烦请提醒

不如加急做一个数据导入到 es 的功能 :person_fencing:(逃

哈哈,es那边得导入导出倒是不用担心,毕竟es这么强大,就是怕nebula有很多坑,就像老兄吐槽的,就官方文档来说,nebula就显得写的很差,有种非常应付的感觉,对比之下就算ArangoDB没人用,人家官方文档写的就是很一流很专业,这个可能是我们国内开发者要学习的。。。你不能写个官方文档,搞得很菜鸟教程那个网站一样,官方文档都写的这么敷衍还有很多版本语法对不上的错误,也没有说明和修正,是真的难搞,哪个后面做大的数据库官方文档不是一流的。

文档好的项目,用起来是真的舒服 :drooling_face:

哪个语法版本有错误,方便指出一下嘛?

3.0.1的手册,nGQL=>子句和过滤选项=>where

MATCH (v:player)  WHERE v.player.name == "Tim Duncan" XOR (v.player.age < 30 AND v.player.name == "Yao Ming") OR NOT (v.player.name == "Yao Ming" OR v.player.name == "Tim Duncan") RETURN v.player.name, v.player.age;

报错:

-1005:Scan vertices or edges need to specify a limit number, or limit number can not push down.

老哥你以前也是用ArangoDB的?要不加个好友?平时有问题可以讨论一下

这个是MATCH的限制,不是WHERE的限制。

第一点不敢苟同,vid 本身是限制长度的,很多场景下这个长度是不可控的,就需要取摘要,这时候和没做 vid 格式的设计就没什么区别了

嗯嗯,是的,如果可能。

浙ICP备20010487号