Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。
如果在宿主机上安装,可能还需要Java环境。因为neo4j是Java所写,但如果是docker则不需要,我们可以使用search查找相关的版本:
一般如果没有什么特殊要求,我们都默认使用最新版本的:
docker pull neo4j(:版本号) //缺省 “:版本号” 时默认安装latest版本的
但我不知道neo4j是不是对版本有什么要求,这里会遇到一个我在后文提到的导入数据的问题,所以可以考虑拉3点多的版本,我查的博客是没什么问题的,但拉取了最新的也不要紧,接着看是否拉取成功:
docker images
neo4j的主要目录结构:
了解了neo4j的构成,这里需要映射出来的目录是data、logs、conf、import,启动的docker命令为:
docker run -d --name neo4j -p 7474:7474 -p 7687:7687 -v /home/neo4j/data:/data -v /home/neo4j/logs:/logs -v /home/neo4j/conf:/var/lib/neo4j/conf -v /home/neo4j/import:/var/lib/neo4j/import --env NEO4J_AUTH=neo4j/password neo4j
# docker命令解释(不可运行)
docker run -d --name neo4j \ //-d表示容器后台运行 --name指定容器名字
-p 7474:7474 -p 7687:7687 \ //映射容器的端口号到宿主机的端口号
-v /home/neo4j/data:/data \ //把容器内的数据目录挂载到宿主机的对应目录下
-v /home/neo4j/logs:/logs \ //挂载日志目录
-v /home/neo4j/conf:/var/lib/neo4j/conf //挂载配置目录
-v /home/neo4j/import:/var/lib/neo4j/import \ //挂载数据导入目录
--env NEO4J_AUTH=neo4j/password \ //设定数据库的名字的访问密码
neo4j //指定使用的镜像
无明显报错,容器启动后,就能访问相关网页,如果宿主机的7474端口有对外开放,云上是直接修改用户组规则或者防火墙直接添加规则,本地服务器添加命令如下:
// 查看当前防火墙状态,若为“inactive”,则防火墙已关闭,不必进行接续操作。
sudo ufw status
// 若防火墙状态为“active”,则使用下列命令开放端口
sudo ufw allow 7474
sudo ufw allow 7687
// 重启防火墙
sudo ufw reload
然后就可以在局域网内访问,初始账号和密码皆为neo4j,但因为是docker部署的,conf还没改,直接访问会报错如下:
Neo.ClientError.Security.Unauthorized: The client is unauthorized due to authentication failure.
这时候就需要更改neo4j的配置项,如果是根据直接宿主机安装neo4j的conf可以看到很多的配置参数,但docker映射后的neo4j.conf文件只有几行,当然,可以使用linux环境下的Neo4j安装 的方式,写入如下配置:
# 修改第22行load csv时l路径,在前面加个#,可从任意路径读取文件
#dbms.directories.import=import
# 修改35行和36行,设置JVM初始堆内存和JVM最大堆内存
# 生产环境给的JVM最大堆内存越大越好,但是要小于机器的物理内存
dbms.memory.heap.initial_size=5g
dbms.memory.heap.max_size=10g
# 修改46行,可以认为这个是缓存,如果机器配置高,这个越大越好
dbms.memory.pagecache.size=10g
# 修改54行,去掉改行的#,可以远程通过ip访问neo4j数据库
dbms.connectors.default_listen_address=0.0.0.0
# 默认 bolt端口是7687,http端口是7474,https关口是7473,不修改下面3项也可以
# 修改71行,去掉#,设置http端口为7687,端口可以自定义,只要不和其他端口冲突就行
#dbms.connector.bolt.listen_address=:7687
# 修改75行,去掉#,设置http端口为7474,端口可以自定义,只要不和其他端口冲突就行
dbms.connector.http.listen_address=:7474
# 修改79行,去掉#,设置http端口为7473,端口可以自定义,只要不和其他端口冲突就行
dbms.connector.https.listen_address=:7473
# 修改227行,去掉#,允许从远程url来load csv
dbms.security.allow_csv_import_from_file_urls=true
# 修改246行,允许使用neo4j-shell,类似于mysql 命令行之类的
dbms.shell.enabled=true
# 修改235行,去掉#,设置连接neo4j-shell的端口,一般都是localhost或者127.0.0.1,这样安全,其他地址的话,一般使用https就行
dbms.shell.host=127.0.0.1
# 修改250行,去掉#,设置neo4j-shell端口,端口可以自定义,只要不和其他端口冲突就行
dbms.shell.port=1337
# 修改254行,设置neo4j可读可写
dbms.read_only=false
不过我感觉有些麻烦,因为我搭建neo4j主要是想玩一下知识图谱的项目,我直接关闭了auth验证方式,加入了dbms.security.auth_enabled=false,更改如下:
重启neo4j的容器:
docker restart 容器id(或者容器名)
至此,部署完成。
这里我遇到一个问题,就是从其它地方下载了一个graph.db.dump,准备用neo4j的客户端导入数据,命令如下:
neo4j-admin load --from=graph.db.dump --database=graph.db --force
结果报错如下:
然后就去查找错误,但消息太乱,因为我是基于镜像版本的,后来把neo4j.conf改来改去,加了各种配置,同样根据它提示,加上了dbms.allow_upgrade=true也用处不大,之后的配置如下:
dbms.tx_log.rotation.retention_policy=100M size
dbms.memory.pagecache.size=512M
dbms.default_listen_address=0.0.0.0
dbms.security.auth_enabled=false
dbms.allow_format_migration=true
dbms.allow_upgrade=true
dbms.default_database=graph
dbms.directories.logs=/logs
之后搞了半天看得有点迷,就跑去官网搜了一圈,发现了两个比较有参考性的链接:
https://community.neo4j.com/t/unable-to-import-a-dump-showing-error-the-loaded-database-is-not-on-the-latest-format-current-v0-a-9-latest-sf4-3-0/41141
https://community.neo4j.com/t/migrate-data-from-3-5-1-community-to-4-0-0-community/14502
这两篇里提到的加上相应配置我也加上去了,但好像基本没有变化,报错依旧。然后我就放弃了,我猜大概是我拉的neo4j镜像没有指定版本,太新了,目前写这篇博文时,拉的版本在后台可以看到为:
所以可能退版本会有用,但这里我没有再尝试了,因为我在客户端之前就已经用脚本导入过一个中医药的数据:
https://github.com/liuhuanyong/QASystemOnMedicalKG
按照步骤,只需要下载python对应的py2neo包能连接数据库,然后运行脚本就行了:
知识图谱数据导入:python build_medicalgraph.py,导入的数据较多,估计需要几个小时。
本篇主要涉及知识图谱预启动搭建数据库的一个记录过程,因为我后续会做一个知识图谱的小demo,所以将这一过程拆解出一篇博文,同时也记录一下自己遇到的bug。