Neo4j---性能优化
不会项目管理的研发不是好司机(^_^ ^_^),开个玩笑,目的是想说项目管理很重要,研发同胞们需要重视、重视、重视(重要的事情说三遍)。随着项目业务扩展,不再是停留在基本某一业务范围,海量数据接踵而至,接口性能明显出现瓶颈,性能优化迫在眉睫。。。
一、性能问题排查及产生问题的根源分析
(1)性能瓶颈问题排查:
结合运行过程中产生的慢的现象,在测试环境中监控日志,多次模拟定位,准确找到需要产生性能问题的原因。
(2)常见产生瓶颈原因:
1、频繁查询数据库造成的获取连接、关闭连接等的资源消耗;
2、单表数据量过大造成扫描过程时间变长;
3、高并发场景下,大量并发请求连接造成IO瓶颈、内存瓶颈(内存耗尽会造成应用程序崩溃(触发操作系统的watchdog机制))、CPU资源瓶颈(操作系统设计机制:CPU资源耗尽会造成单个事件响应时间过长,操作系统会不断轮训执行CPU指令,平均单个事件的执行时间严重受限);
4、硬件资源瓶颈,机械硬盘从磁道分配的扇区中读取数据本身的时间消耗;
5、cql本身执行耗时。
(1)EXPLAIN + 执行的cql语句
仅仅查看执行计划,不执行语句
(2)PROFILE + 执行的cql语句
运行语句,并全程监督资源使用情况
2、 使用建议
1)相关主键创建索引 语法格式CREATE INDEX ON: 标签(待查字段);
①模式索引:模式索引和关系数据库中的索引很相似, 每一个索引会对应一个标签和一组属性,无论是更新还是删除节点,索引都会自动更新或者删除,因此该种创建索引的方式更适用。
注意:索引状态是ONLINE才能生效,否则刚刚建的索引是无效的。
4)不必要的数据,尽可能早的过滤掉,减少后期处理的数据量;
5)避免返回整个节点数据,返回其中需要的属性数据;
6)使用批量查询语句代替单个循环查询,减少数据库连接和释放时间,数据量大的情况下效果非常明显;
7)热点访问数据预热,先执行一次查询,最大化利用neo4j本身的缓存能力设计;
MATCH (n) OPTIONAL MATCH (n)-[r]->() RETURN count(n.prop) + count(r.prop);
8)用空间换时间的原则,启动过程加载定时缓存任务,缓存高频访问数据(使用LRU算法淘汰不常用的数据,防止内存空间浪费)。
9)cql优化建议:
①尽量避免过多or查询,严重影响查询效率;
②引入了辅助 label,这样可以高效地抽出指定任务下的所有数据。
三、优化neo4j配置文件
对neo4j.conf文件并进行相应修改。通过添加jvm虚拟环境可以提高数据库的查询速度,即取消neo4j配置文件中关于dbms.memory.heap.initial_size=512m;dbms.memory.heap.max_size=512m两行的注释,并做合适的修改(最大堆内存越大越好,但是要小于机器的物理内存)。
四、进阶方案解决性能问题
1、合理引入中间件
eg:
①涉及内容关键字检索,可以使用elasticSearch,避免直接从neo4j搜索查询,若能结合redis及内存缓存获取详细资源信息,搜索只返回主键,还能进一步提交查询效率,用户体验大幅提升;
②涉及大量查询可以使用redis作为neo4j的一个缓存库,既能提高查询性能,也能避免neo4j所在机器的IO等资源消耗;
2、分库存储,充分利用neo4j的图存储和查询特点,neo4j中只提供图的存储和查询功能,节点的属性信息保存在mongodb(或其他NoSql 数据库中---字段可以直接存储)进行关联查询,各取所长,充分利优势,优化性能;
3、避免单个节点创建大量关系,容易造成内存暴涨迫使数据库挂掉。可以使用类似关系型数据库主外键关联的方式存储数据,借助id关联关系查询数据,查询性能优于通过关系直接查询。
4、使用neo4j企业版高可用集群方案,适用于不差钱的企业组织哈。
5、硬件升级,如固态硬盘代替机械硬盘。