neo4j图数据库

简介

Neo4j是什么

Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。

Neo4j的特点

  • SQL就像简单的查询语言Neo4j CQL
  • 遵循属性图数据模型
  • 通过使用Apache Lucence支持索引
  • 支持UNIQUE约束
  • 包含一个用于执行CQL命令的UI:Neo4j数据浏览器
  • 支持完整的ACID(原子性,一致性,隔离性和持久性)规则
  • 采用原生图形库与本地GPE(图形处理引擎)
  • 支持查询的数据导出到JSON和XLS格式
  • 提供了REST API,可以被任何编程语言(如Java,Spring,Scala等)访问
  • 提供了可以通过任何UI MVC框架(如Node JS)访问的Java脚本
  • 支持三种Java API:Cypher API、SpringData neo4j和Native Java API来开发Java应用程序

集群模式

NEO4J提供了两种集群模式,一种是HA(主备模式),在neo4j 4.0之后就废弃了;另外一种是因果集群模式(causal cluster),它们的架构和特点如下。

因果集群

1.jpg

从上图可见,Neo4j集群由两个不同的角色Core Servers和Read Replicas组成,这两个角色是任何生产部署中的基础,但彼此之间的管理规模不同,并且在管理整个集群的容错性和可伸缩性方面承担着不同的角色。

Core Servers

核心服务器的主要责任是保护数据。 核心服务器通过使用Raft协议复制所有事务来做到这一点。 在确认向最终用户应用程序提交事务之前,Raft确保数据安全持久。 在实际环境中,这意味着一旦集群(N / 2 + 1)中的大多数核心服务器都接受了事务,安全性要求会影响写入延迟。 隐式写入将以最快的多数Core Servers被确认,但是随着群集中核心服务器数量的增加,确认一次写入所需的Core Servers的数量也会增加。实际上,这意味着典型的Core Server集群中需要一定数量的服务器,足以为特定部署提供足够的容错能力。 这是使用公式M = 2F +1计算的,其中M是容忍F故障所需的核心服务器数量。 例如:

为了容忍两个发生故障的核心服务器,我们需要部署五个核心的集群。 最小的容错群集(一个可以容忍一个故障的群集)必须具有三个内核。 也可以创建仅包含两个核心的因果集群。 但是,该群集不是容错的。 如果两个服务器之一发生故障,其余服务器将变为只读。 请注意,如果Core Server集群遭受足够的故障而无法处理写入,则它将变为只读状态以保持安全。

Read Replicas

只读副本的主要职责是扩展图数据负载能力(密码查询,过程等)。 只读副本的作用类似于Core Server保护的数据的缓存,但它们不是简单的键值缓存。 实际上,只读副本是功能齐全的Neo4j数据库,能够完成任意(只读)图数据查询和过程。

只读副本是通过事务日志传送从Core Servers异步复制的。 只读副本将定期(通常在ms范围内)轮询核心服务器以查找自上次轮询以来已处理的任何新事务,并且核心服务器会将这些事务发送到只读副本。 可以从相对较少的Core Server中馈送许多只读副本数据,从而使查询工作量大为增加,从而扩大规模。

但是,与核心服务器不同,只读副本不参与有关群集拓扑的决策。 只读副本通常应以相对较大的数量运行,并视为一次性使用。 丢失只读副本不会影响群集的可用性,除了丢失其图表查询吞吐量的一部分。 它不会影响群集的容错能力。

因果一致性

从应用程序的角度来看,集群的运行机制很有趣,但是考虑应用程序将如何使用数据库完成工作也很有帮助。 在应用程序中,我们通常希望从图中读取并写入图中。 根据工作负载的性质,我们通常希望从图中进行读取以考虑先前的写入,以确保因果一致性。

因果一致性使得可以写入Core Server(数据是安全的)并从Read Replica(其中图操作被扩展)中读取这些写入。 例如,因果一致性可确保当该用户随后尝试登录时,会出现创建该用户帐户的写操作。

在执行事务时,客户可以要求书签,然后将其作为参数提供给后续事务。 使用该书签,集群可以确保只有处理了该客户已添加书签的事务的服务器才能运行其下一个事务。 这提供了因果链,从客户的角度确保了正确的写后读语义。

除了书签之外,其他所有事情都由集群处理。 数据库驱动程序与群集拓扑管理器一起使用,以选择最合适的核心服务器和只读副本,以提供高质量的服务。

高可用集群

Neo4j HA群集由一个主实例和多个从属实例组成。集群中的所有实例在其本地数据库文件中均具有数据的完整副本。基本集群配置包含三个实例: 2.jpg

每个实例都包含集群管理功能、数据复制功能和选举管理功能,如上图的绿色箭头所示。每个非仲裁实例(从属实例)均与主实例进行通信,以使数据库保持最新状态,如上图中的蓝色箭头所示。

仲裁者实例

从属实例的一个特例是仲裁者实例。仲裁程序实例包含在仲裁程序模式下运行的完整Neo4j软件,因此它参与集群通信,但不复制数据存储的副本。

事务传播

直接在主服务器上执行的写事务和在非集群模式下执行模式一致。成功后,该事务将被推送到其它从属实例。如果其它实例推送失败,此事务仍然保持成功,这种模式和乐观锁类似。

在从实例上执行写事务时,每个写操作将与主机同步。主锁和从锁都将获得锁。当事务提交时,它将首先在主服务器上提交,如果成功,则在从服务器上提交。为了确保一致性,在执行写操作之前,主从必须保持一致并且最新。从实例的自动更新内置在主从之间的通信协议中。

故障转移

每当Neo4j数据库不可用(例如,由硬件故障或网络中断引起)时,群集中的其他实例将检测到该情况并将其标记为暂时失败。数据库实例故障恢复后将自动追赶集群。

如果主服务器出现故障,则在集群中达到法定人数后,将选举另一个成员,并将其角色从从服务器切换为主服务器。新的主服务器将向群集的所有其他成员广播其可用性。通常,几秒钟之内就会选出一个新的主机并启动。在这段时间内无法进行写操作。

法定人数

群集必须具有法定人数才能选举新的主服务器。法定人数定义为:活动集群成员的50%以上。设计集群时的经验法则是:必须能够容忍n个主实例故障的集群需要2n + 1个实例来满足仲裁并允许进行选举。因此,最简单的有效群集大小是三个实例,这允许单个主服务器故障。

选举规则

如果主服务器发生故障,或者在集群的冷启动时,具有最高已提交事务ID的从服务器将被选作新的主服务器。该规则确保具有最新数据存储的从站成为新的主服务器。 如果一个主服务器发生故障,并且两个或多个从服务器绑定在一起,即具有相同的最高提交事务ID,则ha.server_id值最低的从属服务器将被选举为新的主服务器。这是一个简易并快速的做法,因为ha.server_id在集群中是唯一的,并且可配置。

数据分支

数据分支的产生可能有如下两种不同的方式:

一个从服务器落在主服务器之后,然后离开或重新加入集群。这种分支是无害的。 发生主服务器重新选举,并且旧的主服务器具有一个或多个已提交的事务,而从服务器在死前没有收到。这种分支是有害的,需要采取措施。 数据库通过创建一个目录来充分利用这种情况,该目录包含分支发生之前的数据库文件的内容,以便可以对其进行检查并解决该情况。在正常操作下不会发生数据分支。

使用场景

  1. 欺诈检测:通过人员关系图分析可以清楚地知道洗钱网络及相关嫌疑,例如对用户所使用的帐号、发生交易时的IP地址、MAC地址、手机IMEI号等进行关联分析。

  2. 推荐系统:比如你在淘宝上浏览了某一个商品,它在下面有“猜你喜欢”版块,推荐你搜索商品相关的、相似的商品。

  3. 社交网络图:社区聚类分析,朋友朋友推荐(就像使用QQ、微信、支付宝的时候,韩某某和你有N个共同好友),社交电商里面的绑定关系。

  4. 身份和访问管理:使用图形数据库进行身份和访问管理时,可以快速有效地跟踪用户,资产,关系和授权。

  5. 企业关系构建:使用图形数据库可以有效、快速的查询出企业的投资关系图,或者相关联的企业。

调优

一、增加索引

经查阅相关资料可知,neo4j数据库的索引一般分为三类。

① 手动索引:Neo4j数据库若采用手动方式创建索引,则索引并不会随着数据的改变而自动更新。虽然该种方法可以手动创建和维护索引,但由于较为麻烦,所以一般不采用。

② 自动索引:自动索引是一种通过修改配置文件来创建索引的方法,但是在目前的neo4j 3.x版本中已经摒弃了用该方法来创建索引,并建议使用模式索引代替之。

③ 模式索引:模式索引和关系数据库中的索引很相似, 每一个索引会对应一个标签和一组属性,无论是更新还是删除节点,索引都会自动更新或者删除,因此该种创建索引的方式更适用。很显然采用模式索引会更简单方便,而建立模式索引,需要使用Cypher语句:CREATE INDEX ON: 标签(待查字段)。一般在浏览器http://172.18.34.25:7474/browser/ 网页上,可分别为待查字段建立模式索引。然而实验结果表明,建立索引后的查询时间虽有减少但不足以满足实际需求。另外有一点非常重要,索引建立后只是Populating状态,一定要一定要一定要重启数据库并关闭http://172.18.34.25:7474/browser/ 网页让索引ONLINE生效,否则刚刚建的索引是无效的,望大家切记。若不知道待查字段是否已有索引,可用“:schema”指令查看当前数据库中已建好的所有索引和索引是否ONLINE。

二、优化neo4j配置文件

# java heap 初始值
dbms.memory.heap.initial_size=1g
# java heap 最大值,一般不要超过可用物理内存的80%
dbms.memory.heap.max_size=16g
# pagecache大小,官方建议设为:(总内存-dbms.memory.heap.max_size)/2,这样算下来我这台服务器应该设为(32g-16g)/2=8g,但由于服务器上面还有其他程序在占用内存,我这里根据实际情况,调整为2g
dbms.memory.pagecache.size=2g

三、调整Linux的swap分区大小

调整完neo4j.conf参数后,发现还是存在内存问题,再看Linux服务器的swap分区,只有512M,全部被占满,后来将swap分区调整为32G。 (调整swap分区大小的方法可参考:https://blog.csdn.net/andyguan01_2/article/details/86680635)

配置选项

dbms.connector.bolt.thread_pool_min_size:运行状态的最小线程数,默认是5

dbms.connector.bolt.thread_pool_max_size:最大线程数,默认是400

dbms.connector.bolt.thread_pool_keep_alive:线程空闲等待时间,超过此时间线程会被回收,默认5分钟

调整Bolt连接池大小

一个较为合适且典型的配置如下:

dbms.connector.bolt.thread_pool_min_size=10

dbms.connector.bolt.thread_pool_max_size=100

dbms.connector.bolt.thread_pool_keep_alive=10m

数据采集和执行计划

Neo4j会不断的采集节点和关系的信息来调整每次查询的执行计划。

信息采集

Neo4j采集的信息主要包含如下几点:

1、特定标签的节点数

2、特定类型的关系数

3、以某类标签开始或结束的节点和关系数

4、每种索引是否有效?

Neo4j有两种方式进行数据统计和采集:

1、标签和关系的数量,当给某一个节点删除或者设置标签的时候自动更新

2、索引就需要进行全表扫描,由于这是一个非常耗时的操作,所以是当积累到一定的数据更改,在后台执行收集。下面的几个配置是控制是否采集以及以什么速率进行采集:

dbms.index_sampling.background_enabled:数据到一定量之后,后台索引采集是否自动运行,默认是开启的。

dbms.index_sampling.update_percentage:控制在触发新的采样运行之前必须已更新的索引的百分比。默认是5%。

这些采样也可手动触发,如下:

db.resampleIndex():触发索引的重采样

db.resampleOutdatedIndexes():触发所有过时索引的重新采样

执行计划

执行计划被执行后会进行缓存,直到用于生成计划的统计信息发生更改,才会对其进行重新修改计划。使用以下设置,可以通过如下参数来控制重新修改计划对数据库更新的敏感程度:

cypher.statistics_divergence_threshold:

执行计划被视为过时的阈值,默认是0.75。如果用于创建执行计划的任何基础统计数据的更改超过了此值,则该执行计划将被视为过期,并将重新修改执行计划。阈值的计算方式为:abs(new-old)/max(new,old)。这意味着,默认阈值要求数据库的大小变化约为之前的四倍。值0表示尽快重新计划,但是仍然由参数定义cypher.min_replan_interval,默认为10秒。在此间隔之后,发散阈值将开始缓慢下降,大约7小时后达到10%。这保障了即使是很小的更改,长时间运行的数据库仍将获得查询重新修改执行计划,除非更改很大,否则不会频繁重新修改执行计划。

https://blog.csdn.net/vivian_ll/article/details/89312526 https://zhuanlan.zhihu.com/p/158369006 https://www.cnblogs.com/alltoforever/p/12678474.html https://blog.csdn.net/yangfengling1023/article/details/89413232


已有 0 条评论

    欢迎您,新朋友,感谢参与互动!