docker搭建neo4j与elasticsearch数据同步

文章目录
  1. 需求
  2. 方案
    1. 安装ElasticSearch
    2. 安装Neo4j及neo-elasticsearch插件
  3. 测试

需求

现在有图数据,包含节点和边,节点或者关系都有大段的文本属性,并且需要对全文文本进行检索,因此计划使用Neo4j 进行关系存储以及图算法的应用,使用Elastic Search 进行全文搜索,因此需要Neo4j的数据与Elastic Search进行自动同步,从而实现节点/关系搜索使用Neo4j, 全文搜索使用Elastic Search, 各发挥自己的长处。

方案

正巧的Neo4j官方提供了一个插件neo-elasticsearch, 可以直接Neo4j的数据实时同步到ElasticSearch中。 不过由于官网文档的说明比较简单,以及本人对docker的熟练度有限,在使用docker搭建的过程中,遇到了很大的坑,记录于此。

环境如下:

  • Ubuntu 16.04LST
  • Docker 18.06.0-ce
  • Neo4j:3.4
  • ElasticSearch:6.4.2

安装ElasticSearch

ES的安装比较简单,直接按照官网说明 即可(2018.10当前版本号6.4.2)。

1
2
docker run -p 9200:9200 -p 9300:9300 --name es \
-d -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.4.2

这样我们新建了一个名称为es,web端口为9200,在后台运行的的elastic search容器,可以访问http://ip:9200查看

安装Neo4j及neo-elasticsearch插件

前面一篇博客Neo4j初探 已经提到了使用Docker安装Neo4j的启动失败的大坑,这里就不再赘述。因为在后续安装插件的时候,需要修改配置文件和拷贝插件,所以在新建neo4j容器的时候暴露出来conf和plugins目录,具体的命令如下:

1
2
3
4
docker run -p 7474:7474 -p 7687:7687 -v $HOME/neo4j/data:/data \
-v $HOME/neo4j/conf:/var/lib/neo4j/conf \
-v $HOME/neo4j/plugins:/var/lib/neo4j/plugins \
--name neo4j --link es:es -d neo4j:3.4

其中 --link=es:es 表示neo4j这个容器依赖于es容器,可以使用docker ps 以及docker logs -f -t neo4j 查看运行状态和日志。 下面开始安装插件:

  • 下载插件jar包: https://github.com/neo4j-contrib/neo4j-elasticsearch/releases 然后将jar包拷到plugins 目录里面
  • 修改配置文件(假设在Neo4j中有两类节点Person与Place):

    1
    2
    elasticsearch.host_name=http://es:9200
    elasticsearch.index_spec=people:Person(first_name,last_name), places:Place(name)

  • 重启neo4j即可 docker restart neo4j,可以通过日志来验证是否载入了 docker exec neo4j cat /var/lib/neo4j/logs/debug.log | grep elastic

    1
    2
    3
    396:2018-10-29 11:58:13.988+0000 INFO [o.n.k.i.DiagnosticsManager] elasticsearch.index_spec=people:Person(first_name,last_name), places:Place(name)
    403:2018-10-29 11:58:13.989+0000 INFO [o.n.k.i.DiagnosticsManager] elasticsearch.host_name=http://es:9200
    530:2018-10-29 11:58:14.023+0000 INFO [o.n.k.i.DiagnosticsManager] [classpath + loader.0] file:/var/lib/neo4j/plugins/neo4j-elasticsearch-3.4.5.jar

这里面有一点很关键的是host_name, 因为官方的文档是直接在主机搭建因此直接是localhost, 但是在docker中两个容器是独立的ip,独立的服务,这里需要讲host_name改成上面创建elastic search容器的名称即es, 这是因为在docker中,如果使用了--link的话,docker会给当前容器内部写入一个连接容器的名字的环境变量。通过docker inspect查看两个容器的ip地址,假设neo4j的ip为172.17.0.3, es的ip为172.17.0.2,这样docker会给neo4j注册一个名称为es,指向es容器的环境变量,因此需要这样填写:elasticsearch.host_name=http://es:9200

此外,elasticsearch.index_spec=people:Person(first_name,last_name), places:Place(name) 这条命令表示将neo4j中的Person节点存为es的people索引,Place节点存为places索引。

测试

首先使用neo4j新建节点:

1
CREATE (n:Person { first_name : "A", last_name: "Han" }) RETURN n;

执行了之后,查看es中是否存在新插入的节点: http://ip:9200/people/_search?pretty=
当然修改,删除等操作都可以来实时同步到es。比较方便

当然也可以使用docker-compose来同时集成两个容器, 附docker-compose.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: '2'
services:
es:
container_name: es
image: docker.elastic.co/elasticsearch/elasticsearch:6.4.2
ports:
- 9200:9200
- 9300:9300
environment:
- "discovery.type=single-node"
neo4j:
image: neo4j:3.4
container_name: neo4j
volumes:
- $HOME/neo4j/data:/data
- /$HOME/neo4j/plugins:/var/lib/neo4j/plugins
- /$HOME/neo4j/conf:/var/lib/neo4j/conf
links:
- es
ports:
- 7474:7474
- 7687:7687