Skip to content

Neo4j 存储指标

存储使用情况指标

存储使用情况是 Neo4j 数据库监控的重要方面,包括数据库文件大小、节点和关系数量、存储增长趋势等指标。合理监控和管理存储使用情况可以帮助优化数据库性能,避免存储容量不足的问题。

核心存储指标

核心存储指标反映了数据库的存储使用情况,包括数据库文件大小、事务日志大小、索引大小以及节点和关系数量等。

数据库文件大小

数据库文件大小是最基本的存储指标,可以通过操作系统命令或 Neo4j 监控工具获取。

bash
# 查看数据库文件大小
du -sh /var/lib/neo4j/data/databases/neo4j/

# 查看事务日志大小
du -sh /var/lib/neo4j/data/transactions/neo4j/

# 查看索引文件大小
du -sh /var/lib/neo4j/data/indexes/neo4j/

指标说明

  • /var/lib/neo4j/data/databases/neo4j/:主数据库文件目录,包含节点、关系和属性数据
  • /var/lib/neo4j/data/transactions/neo4j/:事务日志目录,记录所有数据修改操作
  • /var/lib/neo4j/data/indexes/neo4j/:索引文件目录,包含各种类型的索引数据

存储使用增长趋势

监控存储使用增长趋势可以帮助预测未来存储需求,及时采取扩容或优化措施。

使用Prometheus监控存储使用增长趋势:

txt
# 数据库文件大小增长趋势
rate(node_filesystem_size_bytes{mountpoint="/var/lib/neo4j"}[7d])

# 磁盘使用率
(node_filesystem_size_bytes{mountpoint="/var/lib/neo4j"} - node_filesystem_free_bytes{mountpoint="/var/lib/neo4j"}) / node_filesystem_size_bytes{mountpoint="/var/lib/neo4j"} * 100

指标说明

  • rate(node_filesystem_size_bytes[7d]):计算过去7天的存储增长速率
  • 磁盘使用率公式:(总磁盘大小 - 可用磁盘大小) / 总磁盘大小 * 100%

节点和关系数量

节点和关系数量是衡量数据库规模的重要指标,可以通过 Cypher 查询获取。

cypher
# 统计节点数量
MATCH (n) RETURN count(n) AS total_nodes;

# 统计关系数量
MATCH ()-[r]->() RETURN count(r) AS total_relationships;

# 按标签统计节点数量
CALL dbms.listLabels() YIELD label
CALL apoc.cypher.run("MATCH (n:`" + label + "`) RETURN count(n) AS count", {})
YIELD value
RETURN label, value.count AS count
ORDER BY count DESC;

# 按关系类型统计关系数量
CALL dbms.listRelationshipTypes() YIELD relationshipType
CALL apoc.cypher.run("MATCH ()-[r:`" + relationshipType + "`]->() RETURN count(r) AS count", {})
YIELD value
RETURN relationshipType, value.count AS count
ORDER BY count DESC;

指标说明

  • total_nodes:数据库中所有节点的总数
  • total_relationships:数据库中所有关系的总数
  • 按标签统计节点数量:可以了解不同类型节点的分布情况
  • 按关系类型统计关系数量:可以了解不同类型关系的分布情况

存储使用优化

当存储使用增长过快或容量不足时,可以采取以下优化措施:

数据清理

清理过期数据和孤立节点是减少存储使用的有效方法。

cypher
# 删除过期数据
MATCH (n:Log) WHERE n.timestamp < datetime().epochMillis - 30*24*60*60*1000
DETACH DELETE n;

# 清理孤立节点
MATCH (n) WHERE size((n)--()) = 0
DETACH DELETE n;

清理建议

  • 定期执行数据清理任务,如每周或每月一次
  • 根据业务需求设置合理的过期时间
  • 清理前先备份数据,避免误删
  • 清理后重建索引,确保查询性能

压缩配置

启用压缩可以减少存储使用,特别是事务日志和备份文件。

txt
# neo4j.conf 压缩配置
dbms.logs.debug.enabled=true
dbms.logs.query.enabled=true
dbms.logs.query.threshold=100ms

# 启用事务日志压缩
dbms.tx_log.compression.enabled=true
dbms.tx_log.compression.level=SNAPPY

压缩说明

  • dbms.tx_log.compression.enabled:启用事务日志压缩
  • dbms.tx_log.compression.level:压缩级别,可选值包括 SNAPPY、GZIP 和 LZ4
  • SNAPPY 压缩速度快,压缩率适中,适合生产环境
  • GZIP 压缩率高,但速度较慢,适合备份场景

注意事项

  • 启用压缩会增加 CPU 使用率,需要根据服务器资源情况权衡
  • 建议在写入密集型环境中使用 SNAPPY 压缩
  • 定期监控压缩效果,调整压缩级别

IO性能指标

IO性能是影响 Neo4j 数据库性能的关键因素之一,特别是在写入密集型应用中。监控IO性能指标可以帮助识别IO瓶颈,优化数据库配置,提高整体性能。

磁盘IO指标

磁盘IO指标反映了存储设备的性能状况,包括IOPS、吞吐量、延迟等。

基本IO指标

使用操作系统工具可以实时监控磁盘IO性能:

bash
# 使用iostat监控磁盘IO
iostat -x 1

# 使用iotop监控进程IO
iotop -P -o

# 使用vmstat监控系统IO
vmstat 1

工具说明

  • iostat -x 1:显示详细的磁盘IO统计信息,每秒更新一次
  • iotop -P -o:仅显示有IO活动的进程,按进程名显示
  • vmstat 1:显示系统内存、CPU和IO统计信息,每秒更新一次

Prometheus IO指标

使用Prometheus可以长期监控磁盘IO性能,建立性能基线,配置告警规则:

txt
# IOPS监控
rate(node_disk_reads_completed_total{device="sda"}[5m])
rate(node_disk_writes_completed_total{device="sda"}[5m])

# IO吞吐量监控
rate(node_disk_read_bytes_total{device="sda"}[5m])
rate(node_disk_written_bytes_total{device="sda"}[5m])

# IO延迟监控
rate(node_disk_read_time_seconds_total{device="sda"}[5m]) / rate(node_disk_reads_completed_total{device="sda"}[5m])
rate(node_disk_write_time_seconds_total{device="sda"}[5m]) / rate(node_disk_writes_completed_total{device="sda"}[5m])

指标说明

  • node_disk_reads_completed_total:读取操作完成次数
  • node_disk_writes_completed_total:写入操作完成次数
  • node_disk_read_bytes_total:读取字节总数
  • node_disk_written_bytes_total:写入字节总数
  • node_disk_read_time_seconds_total:读取操作总时间
  • node_disk_write_time_seconds_total:写入操作总时间
  • rate(metric[5m]):计算过去5分钟的平均速率

Neo4j IO指标

Neo4j 提供了专门的IO指标,反映了数据库内部的IO活动,包括页缓存IO和事务日志IO等。

页缓存IO指标

页缓存是Neo4j的重要组件,用于缓存数据库文件的页面,减少磁盘IO。监控页缓存IO指标可以帮助优化页缓存配置。

cypher
# 查看页缓存状态
CALL dbms.queryJmx('org.neo4j:name=PageCache,*') YIELD attributes
RETURN attributes.HitRatio.value AS hit_ratio,
       attributes.CacheSize.value AS cache_size,
       attributes.EvictionCount.value AS evictions,
       attributes.FlushCount.value AS flushes,
       attributes.FlushTime.value AS flush_time,
       attributes.PinCount.value AS pin_count,
       attributes.UnpinCount.value AS unpin_count,
       attributes.HitCount.value AS hit_count,
       attributes.MissCount.value AS miss_count;

指标说明

  • hit_ratio:页缓存命中率,建议保持在95%以上
  • cache_size:页缓存大小
  • evictions:页面淘汰次数,次数过多可能表示页缓存不足
  • flushes:页面刷新次数,反映写入活动
  • flush_time:页面刷新总时间
  • pin_count:页面固定次数
  • unpin_count:页面取消固定次数
  • hit_count:缓存命中次数
  • miss_count:缓存未命中次数

事务日志IO指标

事务日志记录了所有数据修改操作,是Neo4j实现ACID特性的重要组成部分。监控事务日志IO指标可以帮助优化事务处理性能。

cypher
# 查看事务日志状态
CALL dbms.queryJmx('org.neo4j:name=TransactionLog,*') YIELD attributes
RETURN attributes.LogVersion.value AS log_version,
       attributes.LogSize.value AS log_size,
       attributes.LogRotationCount.value AS rotation_count,
       attributes.AppendedOperations.value AS appended_operations,
       attributes.AppendedBytes.value AS appended_bytes;

指标说明

  • log_version:当前日志版本
  • log_size:当前日志大小
  • rotation_count:日志轮转次数
  • appended_operations:追加的操作数
  • appended_bytes:追加的字节数

IO性能优化

优化IO性能可以显著提高Neo4j数据库的整体性能,特别是在写入密集型应用中。

存储设备优化

存储设备的性能直接影响Neo4j的IO性能,选择合适的存储设备是优化IO性能的基础。

  • 使用SSD/NVMe:SSD/NVMe存储设备的IO性能远高于传统HDD,可以显著提高Neo4j的读写性能
  • RAID配置:使用RAID 10可以同时提高性能和可靠性,适合生产环境
  • 磁盘调度器:使用deadline或none调度器可以提高SSD/NVMe设备的性能
bash
# 设置磁盘调度器
echo deadline > /sys/block/sda/queue/scheduler

Neo4j配置优化

通过调整Neo4j配置参数,可以进一步优化IO性能:

txt
# neo4j.conf IO优化配置
dbms.threads.io.reader_count=8
dbms.threads.io.writer_count=4
dbms.pagecache.flush_io_size=512k
dbms.checkpoint.iops.limit=1000
dbms.checkpoint.interval.time=30m
dbms.checkpoint.interval.tx=100000

配置说明

  • dbms.threads.io.reader_count:IO读取线程数,根据CPU核心数调整
  • dbms.threads.io.writer_count:IO写入线程数,根据CPU核心数调整
  • dbms.pagecache.flush_io_size:页面刷新IO大小,建议设置为512k或1M
  • dbms.checkpoint.iops.limit:检查点IOPS限制,避免检查点期间IO过载
  • dbms.checkpoint.interval.time:检查点时间间隔,建议设置为30-60分钟
  • dbms.checkpoint.interval.tx:检查点事务间隔,建议设置为100000-200000

优化建议

  • 根据服务器硬件配置和工作负载调整IO线程数
  • 合理设置检查点间隔,平衡数据安全性和IO性能
  • 监控检查点期间的IO活动,避免检查点过载
  • 考虑使用多个磁盘分区,将数据库文件和事务日志分离存储

存储引擎指标

页缓存指标

页缓存命中率

页缓存命中率是衡量存储性能的关键指标,建议保持在95%以上:

cypher
# 计算页缓存命中率
CALL dbms.queryJmx('org.neo4j:name=PageCache,*') YIELD attributes
RETURN attributes.HitCount.value / (attributes.HitCount.value + attributes.MissCount.value) AS hit_ratio;

页缓存使用情况

cypher
# 查看页缓存使用情况
CALL dbms.queryJmx('org.neo4j:name=PageCache,*') YIELD attributes
RETURN attributes.CacheSize.value AS cache_size,
       attributes.FileCount.value AS file_count,
       attributes.PinnedPagesCount.value AS pinned_pages,
       attributes.EvictionCount.value AS evictions,
       attributes.FlushCount.value AS flushes;

事务处理指标

事务提交速率

cypher
# 查看事务提交速率
CALL dbms.queryJmx('org.neo4j:name=Transactions,*') YIELD attributes
RETURN attributes.Committed.value AS committed,
       attributes.RolledBack.value AS rolled_back,
       attributes.Started.value AS started,
       attributes.LastCommittedTxId.value AS last_tx_id;

锁竞争情况

cypher
# 查看锁竞争情况
CALL dbms.queryJmx('org.neo4j:name=Locking,*') YIELD attributes
RETURN attributes.LockCount.value AS lock_count,
       attributes.WaitCount.value AS wait_count,
       attributes.MaxWaitTime.value AS max_wait_time,
       attributes.AvgWaitTime.value AS avg_wait_time;

存储引擎优化

页缓存大小调整

txt
# neo4j.conf 页缓存配置
server.memory.pagecache.size=64g

事务配置优化

txt
# neo4j.conf 事务配置
dbms.tx_state.memory_allocation=ON_HEAP
dbms.tx_state.max_off_heap_memory=2g
dbms.tx_timeout=30s
dbms.tx_log.rotation.size=256m
dbms.tx_log.rotation.retention_policy=100M size

索引指标

索引使用情况

索引大小

cypher
# 查看索引大小
CALL dbms.listIndexes() YIELD name, populationProgress, online
sCALL apoc.schema.indexStats() YIELD name, size, uniqueness, type
RETURN name, type, size, uniqueness, populationProgress, online;

索引访问频率

cypher
# 查看索引访问统计
CALL dbms.queryJmx('org.neo4j:name=IndexCounts,*') YIELD attributes
RETURN attributes.IndexName.value AS index_name,
       attributes.SampleSize.value AS sample_size,
       attributes.IndexUpdates.value AS updates,
       attributes.IndexReads.value AS reads;

索引优化

优化索引使用

cypher
# 分析查询执行计划,查看索引使用情况
EXPLAIN MATCH (n:User {email: 'user@example.com'}) RETURN n;

# 查看未使用的索引
CALL apoc.schema.assert(
  {User: ['id', 'email']}, 
  {User: ['email']}
);

# 删除未使用的索引
DROP INDEX FOR (n:User) ON (n.old_property);

索引重建

bash
# 重建索引
neo4j-admin index rebuild --database=neo4j

监控配置与告警

Prometheus配置

配置Neo4j JMX Exporter

txt
# neo4j.conf 添加JMX Exporter配置
server.jvm.additional=-javaagent:/path/to/jmx_prometheus_javaagent-0.16.1.jar=9404:/path/to/neo4j-jmx-config.yaml

JMX Exporter配置文件

yaml
---
lowercaseOutputName: true
rules:
  - pattern: 'org.neo4j<type=PageCache,.*><>(.*)':
      name: neo4j_pagecache_$1
  - pattern: 'org.neo4j<type=TransactionLog,.*><>(.*)':
      name: neo4j_transactionlog_$1
  - pattern: 'org.neo4j<type=Transactions,.*><>(.*)':
      name: neo4j_transactions_$1
  - pattern: 'org.neo4j<type=Locking,.*><>(.*)':
      name: neo4j_locking_$1
  - pattern: 'org.neo4j<type=IndexCounts, name=(.*)><>(.*)':
      name: neo4j_index_$2
      labels:
        index: $1
  - pattern: 'java.lang<type=Memory><HeapMemoryUsage>(.*)':
      name: jvm_memory_heap_usage_$1
  - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>(.*)':
      name: jvm_memory_nonheap_usage_$1
  - pattern: 'java.lang<type=GarbageCollector, name=(.*)><>(.*)':
      name: jvm_gc_$2
      labels:
        gc: $1
  - pattern: 'org.neo4j<type=Kernel><>(StoreSize)':
      name: neo4j_store_size
  - pattern: 'org.neo4j<type=Kernel><>(NodeCount)':
      name: neo4j_node_count
  - pattern: 'org.neo4j<type=Kernel><>(RelationshipCount)':
      name: neo4j_relationship_count

Grafana Dashboard

核心存储指标面板

创建Grafana Dashboard,包含以下面板:

  1. 存储使用概览:数据库大小、节点数量、关系数量
  2. IO性能:IOPS、吞吐量、延迟
  3. 页缓存状态:命中率、缓存大小、 evictions
  4. 事务处理:提交速率、锁竞争
  5. 索引状态:索引大小、访问频率
  6. 磁盘空间趋势:磁盘使用率、增长趋势

告警规则

存储告警规则

yaml
# Prometheus告警规则
- alert: Neo4jDiskSpaceLow
  expr: (node_filesystem_size_bytes{mountpoint="/var/lib/neo4j"} - node_filesystem_free_bytes{mountpoint="/var/lib/neo4j"}) / node_filesystem_size_bytes{mountpoint="/var/lib/neo4j"} * 100 > 80
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "Neo4j磁盘空间不足"
    description: "Neo4j磁盘使用率超过80%,当前使用率: {{ $value }}%"

- alert: Neo4jPageCacheHitRatioLow
  expr: neo4j_pagecache_hitcount / (neo4j_pagecache_hitcount + neo4j_pagecache_misscount) * 100 < 90
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "Neo4j页缓存命中率低"
    description: "Neo4j页缓存命中率低于90%,当前命中率: {{ $value }}%"

- alert: Neo4jHighIOLatency
  expr: rate(node_disk_write_time_seconds_total{device="sda"}[5m]) / rate(node_disk_writes_completed_total{device="sda"}[5m]) > 0.01
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "Neo4j磁盘IO延迟高"
    description: "Neo4j磁盘写延迟超过10ms,当前延迟: {{ $value }}s"

- alert: Neo4jHighLockWait
  expr: neo4j_locking_avgwaittime > 100
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "Neo4j锁等待时间长"
    description: "Neo4j平均锁等待时间超过100ms,当前等待时间: {{ $value }}ms"

常见问题(FAQ)

Q1: 如何监控Neo4j存储使用增长趋势?

A1: 可以通过以下方式监控存储使用增长趋势:

  1. 使用Prometheus收集磁盘使用指标,绘制增长趋势图
  2. 定期执行Cypher查询统计节点和关系数量
  3. 使用du命令定期检查数据库文件大小
  4. 配置告警规则,当存储增长速率异常时触发告警

Q2: 页缓存命中率多少算正常?

A2: 页缓存命中率建议保持在95%以上。如果命中率低于90%,可能需要:

  1. 增加页缓存大小
  2. 优化查询,减少全图扫描
  3. 添加合适的索引
  4. 考虑使用更快的存储设备

Q3: 如何优化Neo4j的IO性能?

A3: 优化Neo4j IO性能的方法包括:

  1. 使用SSD/NVMe存储设备
  2. 配置合适的RAID级别(如RAID 10)
  3. 调整页缓存大小
  4. 优化检查点配置
  5. 调整IO线程数
  6. 使用合适的磁盘调度器

Q4: 如何处理存储容量不足的问题?

A4: 处理存储容量不足的方法包括:

  1. 清理过期数据和孤立节点
  2. 压缩事务日志和数据库文件
  3. 考虑数据归档策略
  4. 升级存储设备,增加存储容量
  5. 考虑分片或分布式部署

Q5: 如何监控索引使用情况?

A5: 监控索引使用情况的方法包括:

  1. 使用EXPLAINPROFILE命令分析查询执行计划
  2. 通过JMX指标监控索引访问频率
  3. 定期检查未使用的索引
  4. 监控索引大小和增长趋势

Q6: 事务日志过大怎么办?

A6: 处理事务日志过大的方法包括:

  1. 调整事务日志保留策略
  2. 启用事务日志压缩
  3. 增加检查点频率
  4. 定期清理旧的事务日志文件
  5. 考虑使用更高效的存储设备

Q7: 如何优化锁竞争问题?

A7: 优化锁竞争问题的方法包括:

  1. 减少事务持有锁的时间
  2. 避免长时间运行的事务
  3. 优化查询,减少锁的范围
  4. 考虑使用更细粒度的锁
  5. 增加并发处理能力

Q8: 如何监控Neo4j的事务处理能力?

A8: 监控Neo4j事务处理能力的方法包括:

  1. 监控事务提交速率和回滚率
  2. 监控锁竞争情况
  3. 监控事务日志写入速率
  4. 监控检查点频率和持续时间
  5. 执行负载测试,评估最大事务处理能力