在K8s中使用operator部署3.6.0的nebula数据库集群,压测,storaged的内存持续上升,停掉压测,graphd和storaged的内存始终降不下来

  • nebula 版本:3.6.0

  • 部署方式:K8s通过nebula-operator-1.7.6部署,按照官方文档的配置部署的集群,1个graphd,1个metad,3个storaged,和v3.6.0官方文档里的配置比较,仅加入了身份认证,改了镜像仓库地址,无其他改动

  • 安装方式:helm安装

  • 是否上生产环境:N

  • 硬件信息

    • 磁盘 :机械硬盘
    • CPU、内存信息:3*(32C128G)
  • 问题的具体描述:部署完后,做了个简单的压测,搞了2个SPACE,space1里面有5W个点,16W个边,space2里面为空,然后用go-nebula,写了个cron,隔5秒执行10次复杂度各不相同的查询操作(查询space1里的数据),隔30秒执行一次写入+删除操作(往space2里面写100个点,1200个边,然后全部删掉),之后graphd的CPU和内存会维持在一个比较高的水平,但是storaged就比较奇怪,监控来看,内存无法收敛,每隔1小时涨200Mi,3小时后,内存double,之后一直无法收敛,然后停掉压测工具后,graphd的内存有所下降,但是仍然是启动时内存的3倍,storaged的内存则丝毫没有下降,维持在停掉压测工具时的内存值,2天后,仅下降了不到50Mi,基本忽略不计,metad则正常,和刚启动时一样。而且这里还有一个非常奇怪的地方,就是pod启动时,storaged内存400Mi,进容器看和使用kubectl top看,都是400Mi,但是停掉压测工具后,进容器看,内存是800Mi,无其他进程,使用kubectl top看,则是1200Mi,graphd也是一样的问题

  • 相关的 meta / storage / graph info 日志信息(尽量使用文本形式方便检索)

使用kubectl logs看仅有启动日志

我今天尝试通过清理系统缓存的方式,看能否解决这个问题,尝试了后发现:
echo 2 > /proc/sys/vm/drop_caches
之后storaged的内存就降下来了,容器内的内存和k8s top看到的,也一致了,想了解下,这里面是什么原理,我清掉页缓存,是没效果的,但是清索引缓存,却生效了
然后,我的问题是,这个缓存是否可以限制住使用上限?因为是k8s部署,K8s在统计Pod资源占用时,是算上了这部分系统缓存的,如果它使用的特别多,超过了pod的limit资源限制,pod就会被重启,storaged重启,我担心1是稳定性差导致服务不可用,2是出现数据丢失,无法恢复

你压测的时候,把 auto-compaction 关了么?如果开启的话,可能 compaction 在你压测的时候启动了,然后占用了大量内存。

请问下这个怎么关闭呢?我应当没改什么配置,都是默认的

另外,我清明跑了几天,又发现了几个问题,可以麻烦帮忙解答下吗?

  1. 每5秒执行完全一模一样的查询操作,偶现查询失败,storaged报错:
    偶现查询失败,storaged日志报错:
E20240404 05:27:18.828509    47 Serializer.h:43] Thrift serialization is only defined for structs and unions, not containers thereof. Attemping to deserialize a value of type `nebula::HostAddr`.
  1. 同上,执行完全相同操作,偶现查询失败,graphd报错语法错误?比如说这个:
E20240404 09:42:37.358704    25 QueryInstance.cpp:151] SyntaxError: Unterminated string:  near `S '9', query: USE `test`;
  1. 在有大量数据写入时,studio上面统计点和边的数量(40万点,700W边),storaged内存一下增加了3G,达到了4.9G,且之后无下降,并且由于还存在着查询操作,内存依然持续上涨,达到5G后,被K8s OOM kill掉了

公司最近要要孵化新项目,TL硬要引入nebula图数据库,我现在在弄预研,头都大了,给各位爹磕头了,麻烦帮忙解答下,我看社区好多帖子都有我类似的问题,但都没有最终结论

稍等,我找个人给你看看。

贴一下配置文件:
graphd的:

--daemonize=true
--pid_file=pids/nebula-graphd.pid
--enable_optimizer=true
--default_charset=utf8
--default_collate=utf8_bin
--heartbeat_interval_secs=10
--local_config=true
--log_dir=logs
--minloglevel=0
--v=0
--logbufsecs=0
--redirect_stdout=true
--stdout_log_file=graphd-stdout.log
--stderr_log_file=graphd-stderr.log
--stderrthreshold=3
--timestamp_in_logfile_name=true
--accept_partial_success=false
--max_allowed_query_size=4194304
--meta_server_addrs=127.0.0.1:9559
--local_ip=127.0.0.1
--listen_netdev=any
--port=9669
--reuse_port=false
--listen_backlog=1024
--client_idle_timeout_secs=28800
--session_idle_timeout_secs=28800
--num_accept_threads=1
--num_netio_threads=0
--num_max_connections=0
--num_worker_threads=0
--ws_ip=0.0.0.0
--ws_http_port=19669
--storage_client_timeout_ms=60000
--enable_record_slow_query=true
--slow_query_limit=100
--slow_query_threshold_us=200000
--ws_meta_http_port=19559
--enable_authorize=true
--auth_type=password
--system_memory_high_watermark_ratio=0.8
--enable_audit=false
--audit_log_handler=file
--audit_log_file=./logs/audit/audit.log
--audit_log_strategy=synchronous
--audit_log_max_buffer_size=1048576
--audit_log_format=xml
--audit_log_es_address=
--audit_log_es_user=
--audit_log_es_password=
--audit_log_es_batch_size=1000
--audit_log_exclude_spaces=
--audit_log_categories=login,exit
--enable_space_level_metrics=false
--enable_experimental_feature=false
--ng_black_box_switch=false
--ng_black_box_home=black_box
--ng_black_box_dump_period_seconds=5
--ng_black_box_file_lifetime_seconds=1800
--max_sessions_per_ip_per_user=300
--memory_tracker_limit_ratio=0.8
--memory_tracker_untracked_reserved_memory_mb=50
--memory_tracker_detail_log=false
--memory_tracker_detail_log_interval_ms=60000
--memory_purge_enabled=true
--memory_purge_interval_seconds=10
--max_job_size=1
--min_batch_size=8192
--optimize_appendvertices=false
--path_batch_size=10000
--enable_http2_routing=false
--stream_timeout_ms=30000
--enable_ssl=false
--enable_graph_ssl=false
--enable_meta_ssl=false
--cert_path=certs/server.crt
--key_path=certs/server.key
--ca_path=certs/ca.crt
--ca_client_path=certs/ca.crt
--password_path=certs/password
--ssl_watch_path=certs

metad:

--daemonize=true
--pid_file=pids/nebula-metad.pid
--log_dir=logs
--minloglevel=0
--v=0
--logbufsecs=0
--redirect_stdout=true
--stdout_log_file=metad-stdout.log
--stderr_log_file=metad-stderr.log
--stderrthreshold=3
--timestamp_in_logfile_name=true
--meta_server_addrs=127.0.0.1:9559
--local_ip=127.0.0.1
--port=9559
--ws_ip=0.0.0.0
--ws_http_port=19559
--ws_storage_http_port=19779
--data_path=data/meta
--minimum_reserved_bytes=268435456
--default_parts_num=10
--default_replica_factor=3
--heartbeat_interval_secs=10
--agent_heartbeat_interval_secs=60
--rocksdb_wal_sync=true
--ng_black_box_switch=false
--ng_black_box_home=black_box
--ng_black_box_dump_period_seconds=5
--ng_black_box_file_lifetime_seconds=1800
--enable_ssl=false
--enable_meta_ssl=false
--cert_path=certs/server.crt
--key_path=certs/server.key
--ca_path=certs/ca.crt
--ca_client_path=certs/ca.crt
--password_path=certs/password
--ssl_watch_path=certs

storaged:

--daemonize=true
--pid_file=pids/nebula-storaged.pid
--local_config=true
--log_dir=logs
--minloglevel=0
--v=0
--logbufsecs=0
--redirect_stdout=true
--stdout_log_file=storaged-stdout.log
--stderr_log_file=storaged-stderr.log
--stderrthreshold=3
--timestamp_in_logfile_name=true
--meta_server_addrs=127.0.0.1:9559
--local_ip=127.0.0.1
--port=9779
--ws_ip=0.0.0.0
--ws_http_port=19779
--heartbeat_interval_secs=10
--raft_heartbeat_interval_secs=30
--raft_rpc_timeout_ms=500
--wal_ttl=14400
--snapshot_send_files=true
--data_path=data/storage
--minimum_reserved_bytes=268435456
--rocksdb_batch_size=4096
--rocksdb_block_cache=4096
--disable_page_cache=false
--engine_type=rocksdb
--rocksdb_compression=lz4
--rocksdb_compression_per_level=
--enable_rocksdb_statistics=false
--rocksdb_stats_level=kExceptHistogramOrTimers
--enable_rocksdb_prefix_filtering=true
--enable_rocksdb_whole_key_filtering=false
--rocksdb_db_options={}
--rocksdb_column_family_options={"write_buffer_size":"67108864","max_write_buffer_number":"4","max_bytes_for_level_base":"268435456"}
--rocksdb_block_based_table_options={"block_size":"8192"}
--enable_storage_cache=false
--storage_cache_capacity=0
--storage_cache_entries_power=20
--enable_vertex_pool=false
--vertex_pool_capacity=50
--vertex_item_ttl=300
--enable_negative_pool=false
--negative_pool_capacity=50
--negative_item_ttl=300
--query_concurrently=true
--auto_remove_invalid_space=true
--num_io_threads=16
--num_max_connections=0
--num_worker_threads=32
--max_concurrent_subtasks=10
--snapshot_part_rate_limit=10485760
--snapshot_batch_size=1048576
--rebuild_index_part_rate_limit=4194304
--rebuild_index_batch_size=1048576
--nv_cache_path=/tmp/cache
--nv_cache_size=0
--nv_dram_size=50
--nv_bucket_power=20
--nv_lock_power=10
--ng_black_box_switch=false
--ng_black_box_home=black_box
--ng_black_box_dump_period_seconds=5
--ng_black_box_file_lifetime_seconds=1800
--memory_tracker_limit_ratio=0.8
--memory_tracker_untracked_reserved_memory_mb=50
--memory_tracker_detail_log=false
--memory_tracker_detail_log_interval_ms=60000
--memory_purge_enabled=true
--memory_purge_interval_seconds=10
--enable_ssl=false
--enable_meta_ssl=false
--cert_path=certs/server.crt
--key_path=certs/server.key
--ca_path=certs/ca.crt
--ca_client_path=certs/ca.crt
--password_path=certs/password
--ssl_watch_path=certs
--enable_partitioned_index_filter=true

另外贴一张疑似storaged内存泄漏的图,后面不涨了是因为graphd OOM,客户端挂掉了:

你可以看看不写入数据的时候,内存的一个增长情况。

这个报错的话,可能是执行语句的客户端的版本号和内核的版本号对齐有问题,你可以看下版本匹配问题。

可以贴下具体的查询是啥。:thinking: 如果 space 的 name 里有特殊符号的话,需要用反引号,`space#Name` 这样包裹下。

graph应该是使用完内存就会释放的,你确认下是graph进程占用内存吗或者是有query还没执行完。storage又一些固定内存开销,比如block_cache,默认是4G。其他还有一些内存占用你可以看看论坛上关于storage内存的帖子。

storaged的block_cache,默认4G,这个我试过改成100M,对比了下,无明显变化,然后,如果是只查不写,storaged内存基本不会上升或者上升量非常小

查询写死的,就那么几个,我都是每5s执行下这个文件里面的语句,数据集用的那个电影推荐的,不读不写,空负载的情况下,内存很稳定,只读不写,内存增长也是特别缓慢,基本没有增长,然后查询的话,用的是go客户端,代码从官方文档里面copy来的,这个版本匹配在哪里看呢?
sql.rar (14.2 KB)

我看了你的语句,像是 ngql1 这种语句的话,执行起来应该耗时不低的,:thinking: 你为啥要每 5s 执行一次呢?压测也不合适用这种语句啊。

主要是想模拟一下业务方的真实查询吧,比如说有快查询,也会有烂代码,弄一些慢查询

写数据也会导致内存上升,会先写入memtable里面,这个可以看下rocksdb的写入流程

这个我之前简单看了下介绍,这个我认为是正常的,但是为什么在我写完数据之后,内存仍然不释放呢?停止写入,内存停止增长不下降,开始写入,在原有内存基础上继续增长

看看这个吧

看过了,无法解决目前的问题…

你能说下做了哪些处理吗?内存一定时间范围内线性增长不一定是问题。比如是为了 cache 等。所以要看是不是长时间不断的线性增长

  1. 往nebula中反复读取,storaged内存基本不增长
  2. 往nebula中反复执行:创建space,插入schema,update schema,drop space ,内存一晚上从500M涨到3G
  3. 高频率往nebula写入数据,内存最开始涨的较快,从500M到8G用了一晚,然后删掉这个space(内含300W点,5000W边),内存没有下降,之后再创建space,写入,一天后,内存从8G涨到11G,然后就基本不增长了,这个内存增长是有上限吗

建议你可以再研读下上面那篇文章,比较多,耐心看可能有些收获