Skip to content

Neo4j Docker/K8s部署

本文档详细介绍了Neo4j在Docker和Kubernetes环境中的部署方法,包括单实例部署、集群部署、持久化存储配置等,适合数据库管理员(DBA)和运维人员参考。通过容器化部署,可以提高Neo4j的可移植性、可扩展性和管理效率,是现代云原生环境中的最佳实践。

Docker 单实例部署

Docker单实例部署是Neo4j容器化部署的基础,适合开发测试环境和小型生产环境。通过Docker容器技术,我们可以快速启动一个Neo4j实例,无需复杂的安装配置过程,大大简化了部署和管理工作。

拉取 Neo4j Docker 镜像

首先需要从Docker Hub拉取Neo4j官方镜像。Neo4j提供了企业版和社区版两种镜像,可根据实际需求选择:

  • 企业版:提供完整的企业级功能,包括高可用性集群、备份恢复、高级监控等,适合生产环境使用
  • 社区版:免费开源,适合学习、开发和测试环境
  • 版本选择建议:生产环境建议使用固定版本的企业版镜像,确保系统稳定性和一致性
bash
# 拉取最新的Neo4j企业版镜像
docker pull neo4j:enterprise

# 拉取特定版本的Neo4j社区版镜像
docker pull neo4j:5.14.0-community

运行 Neo4j 容器

基础运行命令

基础运行命令可以快速启动一个Neo4j实例,但不包含持久化存储和自定义配置,适合临时测试使用:

bash
# 基础运行命令
docker run --name neo4j \
  -p 7474:7474 -p 7687:7687 \
  -d neo4j:enterprise

参数说明

  • --name neo4j:指定容器名称为neo4j,便于后续管理
  • -p 7474:7474:将容器的HTTP端口映射到主机,用于访问Neo4j Browser管理界面
  • -p 7687:7687:将容器的Bolt端口映射到主机,用于应用程序连接数据库
  • -d:以守护进程方式后台运行容器
  • neo4j:enterprise:指定使用的Docker镜像,这里使用企业版

配置环境变量

通过环境变量可以自定义Neo4j的配置参数,包括认证信息、内存配置等,适合需要特定配置的场景:

bash
# 配置环境变量运行
docker run --name neo4j \
  -p 7474:7474 -p 7687:7687 \
  -e NEO4J\_AUTH=neo4j/password \
  -e NEO4J\*dbms\*memory\*heap\*initial\\*\\*size=4G \
  -e NEO4J\*dbms\*memory\*heap\*max\\*\\*size=8G \
  -e NEO4J\*dbms\*memory\*pagecache\*size=4G \
  -d neo4j:enterprise

关键环境变量说明

  • NEO4J\_AUTH:设置Neo4j的认证信息,格式为用户名/密码,这里设置用户名为neo4j,密码为password
  • NEO4J\*dbms\*memory\*heap\*initial\_\_size:初始堆内存大小,设置为4GB
  • NEO4J\*dbms\*memory\*heap\*max\\*\\*size:最大堆内存大小,设置为8GB
  • NEO4J\*dbms\*memory\*pagecache\*size:页面缓存大小,用于缓存数据文件,设置为4GB

注意:环境变量中的双下划线被Neo4j转换为点,用于表示嵌套的配置参数,例如dbms.memory.heap.initial\*size。例如,环境变量中的NEO4J*dbms*memory*heap*initial\*\*size会被解析为dbms.memory.heap.initial*size

挂载持久化存储

对于生产环境,必须配置持久化存储,确保数据不会因为容器重启或删除而丢失。Neo4j的主要数据目录包括:

bash
# 创建数据和日志目录
mkdir -p /data/neo4j/{data,logs,import,plugins,conf}

# 挂载持久化存储运行
docker run --name neo4j \
  -p 7474:7474 -p 7687:7687 \
  -e NEO4J\_AUTH=neo4j/password \
  -v /data/neo4j/data:/data \
  -v /data/neo4j/logs:/logs \
  -v /data/neo4j/import:/var/lib/neo4j/import \
  -v /data/neo4j/plugins:/var/lib/neo4j/plugins \
  -v /data/neo4j/conf:/var/lib/neo4j/conf \
  -d neo4j:enterprise

挂载目录说明

  • /data/neo4j/data:Neo4j数据文件目录,包含图数据、索引等核心数据
  • /data/neo4j/logs:日志文件目录,包含Neo4j运行日志,用于故障排查和性能分析
  • /data/neo4j/import:导入数据目录,用于存放导入的CSV文件,方便数据批量导入
  • /data/neo4j/plugins:插件目录,用于存放APOC、Graph Data Science等扩展插件
  • /data/neo4j/conf:配置文件目录,包含neo4j.conf等配置文件,用于高级配置

访问 Neo4j

容器启动后,可以通过以下方式访问Neo4j:

  • Neo4j Browser:通过浏览器访问 http://localhost:7474,使用设置的用户名和密码登录
  • Bolt 连接:应用程序通过bolt://localhost:7687连接Neo4j数据库

管理 Neo4j 容器

Docker提供了丰富的命令来管理Neo4j容器:

bash
# 查看容器状态
docker ps -a

# 停止容器
docker stop neo4j

# 启动容器
docker start neo4j

# 查看容器日志(实时)
docker logs -f neo4j

# 进入容器内部
docker exec -it neo4j bash

# 删除容器
docker rm -f neo4j

Docker 因果集群部署

对于生产环境,单实例部署无法满足高可用性和可扩展性需求,因此需要部署Neo4j集群。Neo4j提供了因果集群(Causal Clustering)架构,通过多个节点协同工作,实现数据冗余和自动故障切换,确保系统的高可用性和可靠性。

Docker Compose是一种简单的方式来部署和管理Neo4j集群,它使用YAML文件定义多容器应用,支持一键启动整个集群,大大简化了集群的部署和管理工作。

使用 Docker Compose 部署

创建 docker-compose.yml 文件

以下是一个使用Docker Compose部署Neo4j因果集群的示例配置,包含3个核心节点和1个只读副本:

  • 核心节点(Core Nodes):共3个,构成集群的核心,负责事务处理和数据一致性,采用Raft协议确保数据同步
  • 只读副本(Read Replicas):共1个,负责处理只读查询,提高读性能,减轻核心节点负担
  • 端口映射:为每个节点映射不同的端口,避免冲突,确保节点间通信正常
  • 持久化存储:为每个节点配置独立的数据和日志目录,确保数据安全
yaml
version: '3.8'

services:
  # 核心节点1
  core1:
    image: neo4j:5.14.0-enterprise
    container\_name: neo4j-core1
    ports:
      - "7474:7474"  # HTTP端口,用于访问Neo4j Browser
      - "7687:7687"  # Bolt端口,用于应用程序连接
      - "5000:5000"  # 发现端口,用于节点发现
      - "6000:6000"  # 事务端口,用于事务处理
      - "7000:7000"  # Raft端口,用于共识机制
    volumes:
      - ./data/core1:/data  # 数据目录,存储图数据和索引
      - ./logs/core1:/logs  # 日志目录,存储运行日志
      - ./conf/core1:/var/lib/neo4j/conf  # 配置目录,存储neo4j.conf等配置文件
    environment:
      - NEO4J\*ACCEPT\*LICENSE\_AGREEMENT=yes  # 接受Neo4j企业版许可协议
      - NEO4J\_AUTH=neo4j/password  # 设置用户名和密码
      - NEO4J\*dbms\*mode=CORE  # 设置为核心节点模式
      - NEO4J\*causal\*\*clustering\*initial\_\*discovery\\*\\_members=core1:5000,core2:5000,core3:5000  # 初始发现成员列表
      - NEO4J\*causal\*\*clustering\*discovery\_\*listen\\*\\_address=:5000  # 发现服务监听地址
      - NEO4J\*causal\*\*clustering\*transaction\_\*listen\\*\\_address=:6000  # 事务服务监听地址
      - NEO4J\*causal\*\*clustering\*raft\_\*listen\\*\\_address=:7000  # Raft服务监听地址
      - NEO4J\*dbms\*connector\*bolt\*listen\\*\\*address=:7687  # Bolt服务监听地址
      - NEO4J\*dbms\*connector\*http\*listen\\*\\*address=:7474  # HTTP服务监听地址
      - NEO4J\*dbms\*memory\*heap\*initial\\*\\*size=4G  # 初始堆内存大小
      - NEO4J\*dbms\*memory\*heap\*max\\*\\*size=8G  # 最大堆内存大小
      - NEO4J\*dbms\*memory\*pagecache\*size=4G  # 页面缓存大小

  # 核心节点2,配置与core1类似,仅端口映射不同
  core2:
    image: neo4j:5.14.0-enterprise
    container\_name: neo4j-core2
    ports:
      - "7475:7474"
      - "7688:7687"
      - "5001:5000"
      - "6001:6000"
      - "7001:7000"
    volumes:
      - ./data/core2:/data
      - ./logs/core2:/logs
      - ./conf/core2:/var/lib/neo4j/conf
    environment:
      - NEO4J\*ACCEPT\*LICENSE\_AGREEMENT=yes
      - NEO4J\_AUTH=neo4j/password
      - NEO4J\*dbms\*mode=CORE
      - NEO4J\*causal\*\*clustering\*initial\_\*discovery\\*\\_members=core1:5000,core2:5000,core3:5000
      - NEO4J\*causal\*\*clustering\*discovery\_\*listen\\*\\_address=:5000
      - NEO4J\*causal\*\*clustering\*transaction\_\*listen\\*\\_address=:6000
      - NEO4J\*causal\*\*clustering\*raft\_\*listen\\*\\_address=:7000
      - NEO4J\*dbms\*connector\*bolt\*listen\\*\\*address=:7687
      - NEO4J\*dbms\*connector\*http\*listen\\*\\*address=:7474
      - NEO4J\*dbms\*memory\*heap\*initial\\*\\*size=4G
      - NEO4J\*dbms\*memory\*heap\*max\\*\\*size=8G
      - NEO4J\*dbms\*memory\*pagecache\*size=4G

  # 核心节点3,配置与core1类似,仅端口映射不同
  core3:
    image: neo4j:5.14.0-enterprise
    container\_name: neo4j-core3
    ports:
      - "7476:7474"
      - "7689:7687"
      - "5002:5000"
      - "6002:6000"
      - "7002:7000"
    volumes:
      - ./data/core3:/data
      - ./logs/core3:/logs
      - ./conf/core3:/var/lib/neo4j/conf
    environment:
      - NEO4J\*ACCEPT\*LICENSE\_AGREEMENT=yes
      - NEO4J\_AUTH=neo4j/password
      - NEO4J\*dbms\*mode=CORE
      - NEO4J\*causal\*\*clustering\*initial\_\*discovery\\*\\_members=core1:5000,core2:5000,core3:5000
      - NEO4J\*causal\*\*clustering\*discovery\_\*listen\\*\\_address=:5000
      - NEO4J\*causal\*\*clustering\*transaction\_\*listen\\*\\_address=:6000
      - NEO4J\*causal\*\*clustering\*raft\_\*listen\\*\\_address=:7000
      - NEO4J\*dbms\*connector\*bolt\*listen\\*\\*address=:7687
      - NEO4J\*dbms\*connector\*http\*listen\\*\\*address=:7474
      - NEO4J\*dbms\*memory\*heap\*initial\\*\\*size=4G
      - NEO4J\*dbms\*memory\*heap\*max\\*\\*size=8G
      - NEO4J\*dbms\*memory\*pagecache\*size=4G

  # 只读副本1,负责处理只读查询,配置相对简单
  read1:
    image: neo4j:5.14.0-enterprise
    container\_name: neo4j-read1
    ports:
      - "7477:7474"
      - "7690:7687"
      - "5003:5000"
    volumes:
      - ./data/read1:/data
      - ./logs/read1:/logs
      - ./conf/read1:/var/lib/neo4j/conf
    environment:
      - NEO4J\*ACCEPT\*LICENSE\_AGREEMENT=yes
      - NEO4J\_AUTH=neo4j/password
      - NEO4J\*dbms\*mode=READ\_REPLICA  # 设置为只读副本模式
      - NEO4J\*causal\*\*clustering\*initial\_\*discovery\\*\\_members=core1:5000,core2:5000,core3:5000
      - NEO4J\*causal\*\*clustering\*discovery\_\*listen\\*\\_address=:5000
      - NEO4J\*dbms\*connector\*bolt\*listen\\*\\*address=:7687
      - NEO4J\*dbms\*connector\*http\*listen\\*\\*address=:7474
      - NEO4J\*dbms\*memory\*heap\*initial\\*\\*size=4G
      - NEO4J\*dbms\*memory\*heap\*max\\*\\*size=8G
      - NEO4J\*dbms\*memory\*pagecache\*size=4G

启动集群

在创建好docker-compose.yml文件后,执行以下命令来启动集群:

bash
# 创建数据和配置目录,为每个节点准备独立的存储空间
mkdir -p data/{core1,core2,core3,read1} logs/{core1,core2,core3,read1} conf/{core1,core2,core3,read1}

# 启动集群(后台运行),使用-d参数让集群在后台运行
docker-compose up -d

# 查看集群状态,实时查看日志,了解集群启动情况
docker-compose logs -f

注意事项

  • 首次启动集群可能需要几分钟时间,等待所有节点完成初始化和集群形成
  • 确保系统有足够的资源(CPU、内存、磁盘)运行4个Neo4j节点,建议至少16GB内存
  • 集群启动后,核心节点会通过Raft协议选举出一个领导者(Leader),负责处理写请求,其他核心节点作为跟随者(Follower)
  • 只读副本会从核心节点同步数据,提供只读查询服务

验证集群

集群启动后,可以通过以下方式验证集群状态,确保所有节点正常运行:

bash
# 连接到core1节点的Cypher Shell,这是Neo4j的命令行工具
cypher-shell -u neo4j -p password -a bolt://localhost:7687

# 检查集群状态,列出所有集群成员的详细信息
neo4j@neo4j> CALL dbms.cluster.overview();

执行上述命令后,会返回集群中所有节点的信息,包括节点ID、角色、地址等。正常情况下,应该看到3个核心节点和1个只读副本节点,所有节点状态正常。

Kubernetes 单实例部署

Kubernetes是生产环境中容器编排的标准平台,提供了强大的资源管理、服务发现、自动扩缩容等功能。在Kubernetes中部署Neo4j,可以充分利用这些特性,实现高可用、可扩展的图数据库服务,适合大规模生产环境使用。

使用 YAML 文件部署

创建命名空间

首先创建一个专门的命名空间用于部署Neo4j,便于资源隔离和管理,避免与其他应用冲突:

bash
# 创建名为neo4j的命名空间
kubectl create namespace neo4j

创建持久卷声明

在Kubernetes中,使用持久卷声明(PersistentVolumeClaim,PVC)来请求存储资源,确保数据持久化。PVC是用户对存储资源的请求,Kubernetes会自动匹配或创建合适的持久卷(PersistentVolume,PV):

yaml
# neo4j-pvc.yaml - 定义Neo4j的数据存储需求
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: neo4j-pvc  # PVC名称
  namespace: neo4j  # 所属命名空间
spec:
  accessModes:
    - ReadWriteOnce  # 存储访问模式:只允许一个节点读写挂载
  resources:
    requests:
      storage: 50Gi  # 请求50GB存储空间
  storageClassName: standard  # 使用默认存储类
bash
# 应用PVC配置
kubectl apply -f neo4j-pvc.yaml

参数说明

  • accessModes: ReadWriteOnce:存储卷只能被一个节点以读写方式挂载,适合单实例部署
  • resources.requests.storage: 50Gi:请求50GB的存储空间,根据实际数据量调整
  • storageClassName: standard:使用集群默认的存储类,不同云服务商可能有不同的默认存储类

执行命令后,Kubernetes会自动创建一个持久卷(PersistentVolume,PV)并绑定到该PVC,为Neo4j提供持久化存储。

创建 Neo4j 部署

使用Deployment资源来部署Neo4j单实例,定义容器的镜像、端口、环境变量和存储卷等配置:

yaml
# neo4j-deployment.yaml - 定义Neo4j单实例部署
apiVersion: apps/v1
kind: Deployment
metadata:
  name: neo4j  # Deployment名称
  namespace: neo4j  # 所属命名空间
spec:
  replicas: 1  # 部署副本数,单实例部署设置为1
  selector:
    matchLabels:
      app: neo4j  # 标签选择器,匹配带有app=neo4j标签的Pod
  template:
    metadata:
      labels:
        app: neo4j  # Pod标签,用于Service发现
    spec:
      containers:
      - name: neo4j  # 容器名称
        image: neo4j:5.14.0-enterprise  # 使用Neo4j 5.14.0企业版镜像
        ports:
        - containerPort: 7474
          name: http  # HTTP端口,用于访问Neo4j Browser
        - containerPort: 7687
          name: bolt  # Bolt端口,用于应用程序连接
        env:
        - name: NEO4J_AUTH
          value: neo4j/password  # 设置认证信息,格式为用户名/密码
        - name: NEO4J*dbms*memory*heap*initial_size
          value: 4G  # 初始堆内存大小
        - name: NEO4J*dbms*memory*heap*max_size
          value: 8G  # 最大堆内存大小
        - name: NEO4J*dbms*memory*pagecache*size
          value: 4G  # 页面缓存大小
        volumeMounts:
        - name: neo4j-data
          mountPath: /data  # 挂载数据目录
        - name: neo4j-logs
          mountPath: /logs  # 挂载日志目录
        - name: neo4j-import
          mountPath: /var/lib/neo4j/import  # 挂载导入目录
        - name: neo4j-plugins
          mountPath: /var/lib/neo4j/plugins  # 挂载插件目录
        - name: neo4j-conf
          mountPath: /var/lib/neo4j/conf  # 挂载配置目录
      volumes:
      - name: neo4j-data
        persistentVolumeClaim:
          claimName: neo4j-pvc  # 引用前面创建的PVC
      - name: neo4j-logs
        emptyDir: {}  # 临时日志目录,重启后数据会丢失
      - name: neo4j-import
        emptyDir: {}  # 临时导入目录
      - name: neo4j-plugins
        emptyDir: {}  # 临时插件目录
      - name: neo4j-conf
        emptyDir: {}  # 临时配置目录
bash
# 应用Deployment配置
kubectl apply -f neo4j-deployment.yaml

关键配置说明

  • replicas: 1:部署1个副本,实现单实例部署
  • image: neo4j:5.14.0-enterprise:使用指定版本的Neo4j企业版镜像,确保环境一致性
  • volumeMounts:将容器内的目录挂载到对应的存储卷
  • volumes:定义存储卷,包括持久卷声明和临时目录(emptyDir)

创建服务

创建Service资源来暴露Neo4j的访问端口,这里使用NodePort类型,允许通过节点IP和固定端口访问Neo4j服务:

yaml
# neo4j-service.yaml - 定义Neo4j服务访问方式
apiVersion: v1
kind: Service
metadata:
  name: neo4j  # Service名称
  namespace: neo4j  # 所属命名空间
spec:
  selector:
    app: neo4j  # 匹配带有app=neo4j标签的Pod
  ports:
  - name: http
    port: 7474  # Service端口
    targetPort: 7474  # 目标容器端口
    nodePort: 30474  # 节点暴露端口,范围30000-32767
  - name: bolt
    port: 7687  # Service端口
    targetPort: 7687  # 目标容器端口
    nodePort: 30687  # 节点暴露端口
  type: NodePort  # 服务类型:NodePort
bash
# 应用Service配置
kubectl apply -f neo4j-service.yaml

Service类型说明

  • NodePort:在每个节点上开放一个固定端口,通过节点IP:NodePort访问服务,适合测试和小型部署
  • ClusterIP:默认类型,只允许集群内部访问,适合集群内部应用访问
  • LoadBalancer:使用云服务商的负载均衡器,对外暴露服务,适合生产环境

执行命令后,可以通过http://<节点IP>:30474访问Neo4j Browser管理界面,使用前面设置的用户名和密码登录。

访问 Neo4j

部署完成后,可以通过以下方式访问Neo4j:

  • Neo4j Browser:通过浏览器访问 http://`<node-ip>`:30474,使用设置的用户名和密码登录
  • Bolt 连接:应用程序通过bolt://&lt;node-ip&gt;:30687连接Neo4j数据库

其中&lt;node-ip&gt;是Kubernetes集群中任意节点的IP地址。

Kubernetes 集群部署

对于生产环境,Kubernetes集群部署是最佳选择,可以充分利用Kubernetes的编排能力,实现高可用性和自动扩缩容。Neo4j提供了官方的Helm Chart,简化了集群部署过程。

使用 Neo4j 官方 Helm Chart 部署

Helm是Kubernetes的包管理工具,可以快速部署和管理复杂的应用。Neo4j提供了官方的Helm Chart,支持一键部署因果集群。

添加 Neo4j Helm 仓库

首先添加Neo4j官方的Helm仓库:

bash
helm repo add neo4j https://helm.neo4j.com/neo4j
helm repo update

安装 Neo4j 集群

创建values.yaml文件,自定义集群配置,然后使用Helm安装Neo4j集群:

bash
# 创建 values.yaml 文件
cat > values.yaml << EOF
neo4j:
  name: neo4j-cluster
  edition: enterprise
  auth:
    username: neo4j
    password: password
  resources:
    core:
      cpu: "2"
      memory: "8Gi"
    readReplica:
      cpu: "2"
      memory: "8Gi"
  cores:
    numberOfServers: 3
  readReplicas:
    numberOfServers: 2
  persistence:
    enabled: true
    storageClassName: "standard"
    size: 50Gi
  config:
    dbms:
      memory:
        heap:
          initial\_size: "4G"
          max\_size: "8G"
        pagecache:
          size: "4G"
EOF

# 安装 Helm Chart
helm install neo4j-cluster neo4j/neo4j -n neo4j -f values.yaml --create-namespace

关键配置说明

  • edition: enterprise:使用企业版
  • cores.numberOfServers: 3:部署3个核心节点
  • readReplicas.numberOfServers: 2:部署2个只读副本
  • persistence.enabled: true:启用持久化存储
  • config.dbms.memory:配置内存参数

执行命令后,Helm会自动创建所有必要的资源,包括StatefulSet、Service、PVC等。

验证集群部署

集群部署完成后,可以通过以下方式验证:

bash
# 查看 Pod 状态
kubectl get pods -n neo4j

# 查看服务状态
kubectl get services -n neo4j

# 连接到集群中的第一个核心节点
kubectl exec -it neo4j-cluster-core-0 -n neo4j -- cypher-shell -u neo4j -p password

# 检查集群状态,列出所有节点
neo4j@neo4j> CALL dbms.cluster.overview();

正常情况下,应该看到3个核心节点和2个只读副本节点,状态均为正常。

自定义 Kubernetes 集群部署

创建 StatefulSet

yaml
# neo4j-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: neo4j-core
  namespace: neo4j
spec:
  serviceName: neo4j
  replicas: 3
  selector:
    matchLabels:
      app: neo4j
      role: core
  template:
    metadata:
      labels:
        app: neo4j
        role: core
    spec:
      containers:
      - name: neo4j
        image: neo4j:5.14.0-enterprise
        ports:
        - containerPort: 7474
          name: http
        - containerPort: 7687
          name: bolt
        - containerPort: 5000
          name: discovery
        - containerPort: 6000
          name: transaction
        - containerPort: 7000
          name: raft
        env:
        - name: NEO4J\*ACCEPT\*LICENSE\_AGREEMENT
          value: "yes"
        - name: NEO4J\_AUTH
          value: neo4j/password
        - name: NEO4J\*dbms\*mode
          value: CORE
        - name: NEO4J\*causal\*\*clustering\*initial\_\*discovery\*\_members
          value: neo4j-core-0.neo4j.neo4j.svc.cluster.local:5000,neo4j-core-1.neo4j.neo4j.svc.cluster.local:5000,neo4j-core-2.neo4j.neo4j.svc.cluster.local:5000
        - name: NEO4J\*causal\*\*clustering\*discovery\_\*listen\*\_address
          value: ":5000"
        - name: NEO4J\*causal\*\*clustering\*transaction\_\*listen\*\_address
          value: ":6000"
        - name: NEO4J\*causal\*\*clustering\*raft\_\*listen\*\_address
          value: ":7000"
        - name: NEO4J\*dbms\*connector\*bolt\*listen**address
          value: ":7687"
        - name: NEO4J\*dbms\*connector\*http\*listen**address
          value: ":7474"
        - name: NEO4J\*dbms\*memory\*heap\*initial**size
          value: 4G
        - name: NEO4J\*dbms\*memory\*heap\*max**size
          value: 8G
        - name: NEO4J\*dbms\*memory\*pagecache\*size
          value: 4G
        volumeMounts:
        - name: neo4j-data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: neo4j-data
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 50Gi
      storageClassName: standard
bash
kubectl apply -f neo4j-statefulset.yaml

创建 Headless Service

yaml
# neo4j-headless-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: neo4j
  namespace: neo4j
spec:
  clusterIP: None
  selector:
    app: neo4j
  ports:
  - name: http
    port: 7474
    targetPort: 7474
  - name: bolt
    port: 7687
    targetPort: 7687
  - name: discovery
    port: 5000
    targetPort: 5000
  - name: transaction
    port: 6000
    targetPort: 6000
  - name: raft
    port: 7000
    targetPort: 7000
bash
kubectl apply -f neo4j-headless-service.yaml

创建 LoadBalancer Service

yaml
# neo4j-loadbalancer-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: neo4j-lb
  namespace: neo4j
spec:
  selector:
    app: neo4j
  ports:
  - name: http
    port: 7474
    targetPort: 7474
  - name: bolt
    port: 7687
    targetPort: 7687
  type: LoadBalancer
bash
kubectl apply -f neo4j-loadbalancer-service.yaml

持久化存储配置

持久化存储是容器化部署的关键,确保数据不会因为容器重启或删除而丢失。Neo4j提供了多种持久化存储选项,适用于不同的部署环境。

Docker 持久化存储

主机目录挂载

主机目录挂载是最直接的持久化方式,将Neo4j的数据目录映射到主机上的某个目录:

bash
docker run --name neo4j \
  -p 7474:7474 -p 7687:7687 \
  -v /path/on/host/data:/data \
  -v /path/on/host/logs:/logs \
  -v /path/on/host/conf:/var/lib/neo4j/conf \
  -d neo4j:enterprise

优点

  • 简单直观,易于管理
  • 数据直接存储在主机上,便于备份和恢复

缺点

  • 依赖主机文件系统,可移植性较差
  • 不同主机间的目录结构可能不一致

Docker Volume 挂载

Docker Volume是Docker管理的存储卷,提供了更好的可移植性和性能:

bash
# 创建 Docker Volume
docker volume create neo4j-data
docker volume create neo4j-logs

# 使用 Docker Volume 运行容器
docker run --name neo4j \
  -p 7474:7474 -p 7687:7687 \
  -v neo4j-data:/data \
  -v neo4j-logs:/logs \
  -d neo4j:enterprise

优点

  • 由Docker管理,与主机文件系统解耦
  • 支持多种存储驱动,适应不同的存储后端
  • 更好的性能和可靠性

缺点

  • 数据存储位置不直观,需要通过Docker命令管理

Kubernetes 持久化存储

在Kubernetes中,持久化存储通过PersistentVolume(PV)和PersistentVolumeClaim(PVC)实现,提供了灵活的存储管理机制。

持久卷声明(PVC)

PVC是用户对存储资源的请求,类似于Pod对CPU和内存的请求:

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: neo4j-pvc
  namespace: neo4j
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi
  storageClassName: standard

accessModes说明

  • ReadWriteOnce (RWO):存储卷只能被一个节点以读写方式挂载
  • ReadOnlyMany (ROX):存储卷可以被多个节点以只读方式挂载
  • ReadWriteMany (RWX):存储卷可以被多个节点以读写方式挂载

StatefulSet 持久化

对于集群部署,StatefulSet是最佳选择,它为每个Pod提供稳定的网络标识和持久化存储。通过volumeClaimTemplates,可以为每个Pod自动创建PVC:

yaml
# StatefulSet 中的 volumeClaimTemplates
volumeClaimTemplates:
- metadata:
    name: neo4j-data
  spec:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 50Gi
    storageClassName: standard

优点

  • 为每个Pod创建独立的PVC,避免数据冲突
  • Pod重建时,自动挂载原来的PVC,保持数据一致性
  • 支持有序的扩缩容和滚动更新

这种方式特别适合Neo4j集群部署,每个节点都有自己独立的数据存储。

配置管理

Docker 配置管理

环境变量配置

bash
docker run --name neo4j \
  -e NEO4J\*dbms\*memory\*heap\*initial\\*\\*size=4G \
  -e NEO4J\*dbms\*memory\*heap\*max\\*\\*size=8G \
  -e NEO4J\*dbms\*memory\*pagecache\*size=4G \
  -d neo4j:enterprise

配置文件挂载

bash
# 将自定义配置文件挂载到容器
docker run --name neo4j \
  -v /path/on/host/neo4j.conf:/var/lib/neo4j/conf/neo4j.conf \
  -d neo4j:enterprise

Kubernetes 配置管理

ConfigMap 配置

yaml
# neo4j-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: neo4j-config
  namespace: neo4j
data:
  neo4j.conf: |
    # Neo4j 配置
    dbms.memory.heap.initial\_size=4G
    dbms.memory.heap.max\_size=8G
    dbms.memory.pagecache.size=4G
    dbms.connector.bolt.enabled=true
    dbms.connector.http.enabled=true
bash
kubectl apply -f neo4j-configmap.yaml

使用 ConfigMap

yaml
# 在 Deployment 或 StatefulSet 中使用 ConfigMap
volumes:
- name: neo4j-conf
  configMap:
    name: neo4j-config

监控与日志

Docker 监控与日志

查看容器日志

bash
# 查看所有日志
docker logs neo4j

# 实时查看日志
docker logs -f neo4j

# 查看特定数量的日志行
docker logs --tail 100 neo4j

监控容器资源

bash
# 查看容器资源使用率
docker stats neo4j

Kubernetes 监控与日志

查看 Pod 日志

bash
# 查看特定 Pod 的日志
kubectl logs neo4j-core-0 -n neo4j

# 实时查看日志
kubectl logs -f neo4j-core-0 -n neo4j

监控 Pod 资源

bash
# 查看所有 Pod 的资源使用率
kubectl top pod -n neo4j

# 查看特定 Pod 的资源使用率
kubectl top pod neo4j-core-0 -n neo4j

集成 Prometheus 和 Grafana

yaml
# 在 Deployment 或 StatefulSet 中添加监控端口
ports:
- containerPort: 2004
  name: metrics

# 配置 Prometheus 监控
env:
- name: NEO4J\*metrics\*prometheus\_enabled
  value: "true"
- name: NEO4J\*metrics\*prometheus\_port
  value: "2004"

备份与恢复

Docker 备份与恢复

备份数据

bash
# 从运行中的容器备份数据
docker exec -it neo4j neo4j-admin backup --backup-dir=/backup --name=neo4j-backup

# 将备份数据复制到主机
docker cp neo4j:/backup/neo4j-backup /path/on/host/backup

恢复数据

bash
# 停止并删除现有容器
docker stop neo4j
docker rm neo4j

# 恢复数据
docker run --name neo4j \
  -v /path/on/host/backup:/backup \
  -v /path/on/host/data:/data \
  -d neo4j:enterprise neo4j-admin restore --from=/backup/neo4j-backup --database=neo4j --force

Kubernetes 备份与恢复

备份数据

bash
# 从运行中的 Pod 备份数据
kubectl exec -it neo4j-core-0 -n neo4j -- neo4j-admin backup --backup-dir=/backup --name=neo4j-backup

# 将备份数据复制到本地
kubectl cp neo4j/neo4j-core-0:/backup/neo4j-backup /path/on/host/backup

恢复数据

bash
# 删除现有 StatefulSet
kubectl delete statefulset neo4j-core -n neo4j

# 删除现有 PVC
kubectl delete pvc -l app=neo4j -n neo4j

# 重新创建 StatefulSet
kubectl apply -f neo4j-statefulset.yaml

# 恢复数据到第一个 Pod
kubectl exec -it neo4j-core-0 -n neo4j -- neo4j-admin restore --from=/backup/neo4j-backup --database=neo4j --force

# 重启 Pod
kubectl delete pod neo4j-core-0 -n neo4j

容器化部署最佳实践

1. 资源配置

  • CPU:根据工作负载调整,推荐 2-8 核
  • 内存:根据数据大小调整,推荐 8-32GB
  • 存储:使用 SSD 存储,推荐 50GB 以上

2. 安全配置

  • 认证:启用强密码认证
  • TLS/SSL:启用 TLS/SSL 加密
  • 网络隔离:使用命名空间和网络策略
  • 最小权限:使用非 root 用户运行容器

3. 高可用性

  • Docker 集群:使用至少 3 个核心节点
  • Kubernetes 集群:使用 StatefulSet 确保稳定的网络标识和持久化存储
  • 健康检查:配置 livenessProbe 和 readinessProbe

4. 监控与告警

  • 启用 Prometheus 监控
  • 配置 Grafana 仪表盘
  • 设置资源使用率告警
  • 监控集群健康状态

5. 备份策略

  • 定期备份数据
  • 测试恢复流程
  • 存储备份数据到安全位置
  • 配置备份自动化

6. 升级策略

  • 使用滚动升级方式
  • 测试升级过程
  • 准备回滚计划
  • 监控升级过程

版本差异

Neo4j 4.x 与 5.x Docker 镜像差异

  • 镜像标签:5.x 镜像标签更简洁,例如 neo4j:5.14.0-enterprise
  • 配置参数:5.x 配置参数前缀从 dbms 改为 server
  • 默认端口:4.x 和 5.x 的默认端口相同(7474、7687)
  • 集群配置:5.x 增强了集群配置选项

Docker 与 Kubernetes 部署差异

特性DockerKubernetes
部署方式简单,适合开发和测试复杂,适合生产环境
高可用性需要手动配置内置高可用性支持
自动扩缩容手动支持自动扩缩容
资源管理基本资源管理高级资源管理和调度
网络管理基本网络管理高级网络管理和服务发现
持久化存储主机目录或 Docker VolumePVC 和 PV

常见问题(FAQ)

Q1: 如何选择 Neo4j Docker 镜像版本?

A1: 选择镜像版本的建议:

  • 生产环境:使用特定版本的企业版镜像,例如 neo4j:5.14.0-enterprise
  • 开发环境:可以使用最新版社区版镜像,例如 neo4j:latest-community
  • 稳定性优先:选择 LTS(长期支持)版本

Q2: 如何配置 Neo4j 容器的资源限制?

A2: 配置资源限制的方法:

  • Docker:使用 --cpus--memory 参数
    bash
    docker run --name neo4j --cpus=2 --memory=16g neo4j:enterprise
  • Kubernetes:在 Deployment 或 StatefulSet 中配置 resources 字段
    yaml
    resources:
      requests:
        cpu: "2"
        memory: "8Gi"
      limits:
        cpu: "4"
        memory: "16Gi"

Q3: 如何在 Kubernetes 中实现 Neo4j 集群的自动扩缩容?

A3: 实现自动扩缩容的方法:

  • 使用 Horizontal Pod Autoscaler (HPA)
  • 基于 CPU 或内存使用率自动调整副本数
  • 仅适用于只读副本,核心节点需要手动调整

Q4: 如何处理 Neo4j 容器中的数据持久化?

A4: 数据持久化的方法:

  • Docker:使用主机目录挂载或 Docker Volume
  • Kubernetes:使用 Persistent Volume Claim (PVC)
  • 确保备份数据,定期测试恢复流程

Q5: 如何监控 Neo4j 容器的性能?

A5: 监控性能的方法:

  • 启用 Prometheus 监控
  • 配置 Grafana 仪表盘
  • 监控容器资源使用率
  • 查看 Neo4j 日志和指标

Q6: 如何升级 Neo4j 容器版本?

A6: 升级容器版本的步骤:

  1. 备份数据
  2. 停止并删除现有容器/Pod
  3. 拉取新版本镜像
  4. 使用新版本镜像重新部署
  5. 验证升级成功

Q7: 如何在 Docker Compose 中配置 Neo4j 集群?

A7: 在 Docker Compose 中配置集群的要点:

  • 至少配置 3 个核心节点
  • 配置正确的初始发现成员列表
  • 映射所有必要的端口
  • 配置适当的资源限制
  • 使用持久化存储

Q8: 如何解决 Neo4j 容器启动失败的问题?

A8: 解决启动失败的方法:

  • 查看容器日志:docker logs neo4jkubectl logs neo4j-core-0 -n neo4j
  • 检查配置文件:确保配置参数正确
  • 检查资源限制:确保资源充足
  • 检查持久化存储:确保存储可访问

Q9: 如何在 Kubernetes 中配置 Neo4j 的网络策略?

A9: 配置网络策略的示例:

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: neo4j-network-policy
  namespace: neo4j
spec:
  podSelector:
    matchLabels:
      app: neo4j
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: neo4j
    ports:
    - protocol: TCP
      port: 5000  # discovery
    - protocol: TCP
      port: 6000  # transaction
    - protocol: TCP
      port: 7000  # raft
  - from:
    - namespaceSelector:
        matchLabels:
          name: default
    ports:
    - protocol: TCP
      port: 7474  # http
    - protocol: TCP
      port: 7687  # bolt

Q10: 如何在 Docker 中启用 Neo4j 的 APOC 插件?

A10: 启用 APOC 插件的方法:

bash
docker run --name neo4j \
  -v /path/on/host/plugins:/var/lib/neo4j/plugins \
  -e NEO4JLABS\_PLUGINS='["apoc"]' \
  -e NEO4J\*dbms\*security\*procedures\*unrestricted='apoc.*' \
  -d neo4j:enterprise