关于VID类型选择以及磁盘空间占用大小的疑问

  • nebula 版本:3.8.0
  • 部署方式:分布式集群 3节点,3副本,3分片
  • 安装方式:k8s operator
  • 是否上生产环境:Y / N
  • 硬件信息
    • 磁盘:HDD
    • CPU、内存信息:32C256G

问题1:为什么创建1个空的图空间,不管VID是INT还是STRING类型,都需要消耗较大的磁盘空间呢?这里面都有些什么呢?


问题2:点边的schema如下:

# 这两个属性长度,固定16
CREATE TAG IF NOT EXISTS `endpoint` ( `vpcId` string NULL, `subnetId` string NULL)
CREATE EDGE IF NOT EXISTS `accessible` () 

然后,我分别创建2个图空间,VID类型分别是INT64和FIXED_STRING(128)的,往两个图空间写入相同的点边数量(12593个点,2153035个边),然后查看磁盘占用,如下图所示:

这里,为什么128字节的FIXED_STRING(128)类型的VID,占用的磁盘空间大小,仅为8字节的INT64类型的VID的5倍?理论上不应当是128/8=16倍吗?为什么落差这么大呢?


问题3:注意这张图中:


我第一次插入完成后,占用大小为339M,然后我执行submit job compact,然后等任务FINISHED后(大概就5s,感觉很诧异),再次查看磁盘占用大小,变成345M了,为什么反而磁盘大小变多了呢?compaction操作不是删除无用文件,合并文件吗?怎么磁盘占用还变大了呢?


麻烦社区大佬们帮忙解答下小白的疑惑,感谢!

问题 1 和 2 可以看下下面连接,主要是存储格式,注意的是边是边切,有两份

问题 3:这个不太清楚

大佬,这个VID类型是INT64和FIXED_STRING(128),磁盘存储差距仅有5-6倍,没有理论的16倍,这个原因是什么呀?我在你发的这个链接里面没有找到答案,可以说一下吗?感谢了

还有1个问题4:

2个图空间,完全一模一样的数据,一个VID是INT,一个VID是STRING(128),过了一晚,磁盘占用大小都变小了,是什么原因呢?

这里面VID是INT类型的,磁盘空间减少了1倍,STRING(128)类型的减少了快5倍,是什么原因导致的?我手动执行compaction并等待任务完成后,并没有出现这个现象,是还有其它方式压缩文件吗?

因为 VID 只是数据的一部分,还有其他的,举个夸张的例子,比如一条数据的属性有1 个 G,那 vid 的大小的差异就没那么重要了

大概率是 compaction 完导致的;
如果原来已经数据本身没有太多冗余了,你执行 compaction 也就没什么效果

大佬,可是我手动执行 submit job compact,然后执行show job jobId 看到compaction的任务状态变成FINISHED后,虽然这个job从CREATEFINISHED状态,只花了5s,期间也没有发现数据的磁盘大小变化,反而是过了一夜,减少了数倍,这个好疑惑呀,难不成show job jobId看到的只是异步任务下发是否成功?而不是任务是否执行完成?

问题 1

storage 底层用的 rocksdb,每个 rocksdb 实例初始化会有这么多的磁盘占用,数据不一定有这么多,主要是先占用磁盘,后面往上面写数据,具体可以搜一下 rocksdb 的文章。

问题 2
如果刚导入完,磁盘里除了真正的数据,还有 raft 同步数据的 wal,默认是 4 小时

问题 3
同上,先排除 wal 文件的大小
如果你导入完后,立刻 compact,理论上没有重复的文件,数据上不会有变化,只是 LSM 的层数变了,但是有可能有多的 wal 文件

问题 4
过了一夜,那就是 wal 少了

1 个赞

减少 wal 的时间,可以参考 Storage 服务配置 - NebulaGraph Database 手册

有个 wal_ttl 的配置

大佬,这个VID的呢?我加上文档里面的一些其它的附加数据结构,进行计算,INT64和STRING(128)差距也不会只有5-6倍呀,虽然没有16倍,但10倍应当是有的呀

甚至过了一夜,相同的数据,INT64的VID和STRING(128)只差了2倍左右

信息比较少,几个猜测

  1. 你的数据有其他的属性,vpcId string NULL, subnetId string NULL, 这个大不大。看边上是没属性。
  2. vid 只是 key 的一部分,比如 点上其实还有 part id,边上还有 rank 之类,导致 vid 占比比较小
  3. rocksdb key 上有前缀压缩,简单的说,假设有很多个 key,每个 key 的前几位字节一样,内部并不是每个 key 都完全的存一样的数据

所以只看单纯几倍的意义,我理解意义不是很大?
如果你想比较 vid 不同类型的存储,我理解最好不要有任何属性,然后数据量最好大一点,分布均匀一点,比如不要边都是某几个点的。

1 个赞

大佬,我确认了下,还真是WAL文件导致写入时的体积跟过了一夜的体积对不上,我后面看了下写入后的文件,有3种:
xxx.log:这个文件只有1个,占了70M左右,貌似不是日志文件,里面的内容看不了
xxx.sst:这个文件貌似是rocksdb的源文件
xxx.wal:这类文件起码占了50%以上的磁盘空间,而且数量很多,过了一夜后,数量明显减少,但还是剩下了几个,这些文件我理解应当是记录了DML操作记录,用于异常重启后的数据恢复。

这里面的log文件,wal文件,我可以通过配置stoarged的参数,来不产生这些文件,减少磁盘空间占用体积,缩短客户端写入请求的时间吗?

首先是,log 和 wal 不能不产生,这个是用来保证数据一致性的。
xxx.log 是 rocksdb 的 mem table 的持久化,它会先预申请一个文件,然后顺序写
xxx.wal 是 raft 用来保证数据一致性同步的

其次,你可以贴一下磁盘写入到监控,先看看客户端写入的瓶颈,是不是在磁盘 io 写上

PS:
刚看到磁盘是 HDD,那瓶颈大概率还是在磁盘上,是不能换 ssd 么
生产上的话,不建议 HDD

我用5块HDD组raid0来提高读写速度不行吗?

我没试过,你可以试试,然后监控看一下 io 写

还有,想请问下,插入点、边,在IO方面,属于顺序写入,还是随机写入呢?关注磁盘哪个指标准确一些呢?

另外,我想优化下写入速度,发现,将VID从STRING(128)换成INT后,磁盘空间下降了5倍,但是我写入速度无法提示5倍,目前发现最多能提示2.5倍左右,用STRING(128),IO写的峰值还可以达到200M/s,用INT作为VID后,写IO峰值只能达到90M/s了