社区用户经常会反馈什么都没有做,但是内存持续升高。这里整理了几个解题思路:
- 确定到底什么进程占用过了过多的资源,top 看看到底 CPU、内存哪个进程占用高;
- 如果是 graph 的话,说明系统正在做查询,等查询完成之后看看是否资源占用会有所下降;
- 如果是其他服务,storage 会有一些固定的内存开销,比如:wal 会部分缓存在内存,这个会发生在有数据写入的时候,等数据完成写之后,占用情况会有所下降;此外,当系统在做 Compaction 时,也会导致内存上升;如果你设置的 partition 过多的话,又有可能会导致内存持续上升问题。
关于 storaged 内存占用讲解
以下内容来自 @xjc 的整理,感谢他的整理。
-
storaged 的内存绝大部分是 RocksDB 的cache。另外一部分主要是 wal 的缓存,等于
wal_buffer_size * part个数
,wal_buffer_size
这个参数的默认值是 8M,这部分是固定的。 -
RocksDB 的 cache 主要是两部分 block cache 和 bloom filter,其他 memtable 等占用小且固定;
- block cache 的大小由参数
rocksdb_block_cache
来决定,默认 4M,但通常建议为可用内存的 1/3 来提高性能。默认情况下,当有些数据被 pin 在 cache 中的时候,这个 cache 大小的设置可以被突破。block cache 内存占用可以通过以下 http 接口来查看:
> http://\<ip\>:19779/rocksdb_property?space=space_name&property=rocksdb.block-cache-usage
- bloom filter 的内存占用默认情况下独立于 block cache,有两种配置 whole key 和 prefix,Nebula 2.6之前默认使用 whole key,2.6之后默认使用 prefix。Bloom filter 的内存占用可以通过以下http接口来查看:
> http://\<ip\>:19779/rocksdb_property?space=space_name&property=rocksdb.estimate-table-readers-mem
- whole key 的内存占可以用文档中给出的公式来测算,即点边数量 *15 bytes;
- prefix 中主要是边的部分取决于图中点的出入度,相同点的相同类型的出入边会共用一个 prefix,因此节省内存占用。
- block cache 的大小由参数
-
使用参数
enable_partitioned_index_filter=true
,可以将 bloom filter 进行分片存储以节省内存占用,并将 bloom filter 放入 block cache 中不占用额外内存,但是因为这个配置同时会将 RocksDB L0 的 filter pin 在内存中,根据上述第 2.1 点,实际内存占用会突破rocksdb_block_cache
的配置,在大量导入数据且 auto compaction 关闭的情况下,由于数据集中在 L0,仍然会出现大量内存占用的情况。实践中,大数据量(TB级)情况下建议 auto compaction 打开,且通过增加 max_background_job 来提高 compaction 的性能。
其他参考贴
这里也收录了一些相关的调试 tips,可以参考下:
内容由 @wenhaocs 提供,感谢 ,原帖出处:nebula 日志报错 - #27,来自 wenhaocs
storaged 对内存的使用基本都来源于 rocksdb。对于读,rocksdb 对内存的使用主要是 block cache 和 page cache。对于写,对内存使用只有 memtable 和触发的 compaction。你的操作是 upsert,同时涉及读和写。
对读来说,block cache 大小通过 conf 里 rocksdb_block_cache
调节,rocksdb 可控。page cache 就是 OS 的 page cache,rocksdb 无法控制。因此如果 block cache size 设置合理的话,对于读,问题很可能出在 page cache 上。
对于写,如果存在大量的 update,可能触发大量 compaction,造成严重的写放大,造成 mem 使用率增高,磁盘 I/O bandwidth 使用率增高, 甚至不可用。
有以下可能的解决方法:
-
conf 里 disable_page_cache 设置成 true 以关闭 page cache。我知道有些人会 argue 说利用操作系统的 page cache 在 block cache 不够的时候可以提高性能,但这个坏处以我的观点其实更大。因为第一 mem 不可控,第二完全可以通过增大 block cache 来解决。而且 FB 内部都是关闭 page cache 的。
-
如果你不愿意关闭 page cache,那么考虑其他优化的点。比如如果你的 SST file size 比较大,但是 key-value 又比较小,那么可能造成 index 数目太大。而 index blocks 默认不是在 block cache 里,会占用 page cache。因此可以考虑在 conf 里添加一项:
--enable_partitioned_index_filter = false
以打开cache_index_and_filter_blocks in block cache。或者,也可以在--rocksdb_db_options={}
添加max_open_files=<some number>
来限制 index filter 的数目,但这可能会影响性能。 -
你可以检查 dashboard 里磁盘的性能指标,看看当时磁盘的 IO 情况。同时看看 storaged 的日志看看当时 compaction 情况。如果是 compaction 导致的内存占满的话,说明资源不够,建议添加磁盘, rebalance。
降低内存的小方法
这里收录社区小伙伴降低内存消耗的法子,记得给分享技能的小伙伴点个赞哟
如果你还有其他的调试内存的思路,欢迎在本帖留言哟~ 你将会获得一枚【调优员】徽章