docker基本使用
docker
docker是什么
Docker 是一个应用打包、分发、部署的工具
你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要
而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件
跟普通虚拟机的对比
特性 | 普通虚拟机 | Docker |
---|---|---|
跨平台 | 通常只能在桌面级系统运行,例如 Windows/Mac,无法在不带图形界面的服务器上运行 | 支持的系统非常多,各类 windows 和 Linux 都支持 |
性能 | 性能损耗大,内存占用高,因为是把整个完整系统都虚拟出来了 | 性能好,只虚拟软件所需运行环境,最大化减少没用的配置 |
自动化 | 需要手动安装所有东西 | 一个命令就可以自动部署好所需环境 |
稳定性 | 稳定性不高,不同系统差异大 | 稳定性好,不同系统都一样部署方式 |
打包、分发、部署
打包:就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包
分发:你可以把你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装
部署:拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一摸一样的运行环境,不管是在 Windows/Mac/Linux
docker安装
容器是由镜像实例化而来,简单来说,镜像是文件,容器是进程
容器是基于镜像创建的,即容器中的进程依赖于镜像中的文件
docker 的镜像概念类似虚拟机的镜像。是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器
镜像运行起来就是容器,容器服务运行的过程中,基于原始镜像做了改变,比如安装了程序,添加了文件,也可以提交回去 (commit)成为镜像
docker安装分为安装包和命令行两种
下载docker安装包,按照指示安装即可
windows需要打开启用或关闭Windows功能
下的Hyper-V
、容器
和适用于Linux的Windows子系统
选项
安装完要打开Docker Desktop
软件,打开会启动引擎,这样才能使用docker
重要:打开Docker Desktop
软件,打开Settings
下的Resources
,选择Advanced
下的Disk image location
,选择合适的文件夹存放docker的镜像和容器,注意后期容器多的话,这个文件夹很占空间的
1 | curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun |
配置镜像加速
进入阿里云,登陆后点击左侧的镜像加速,生成自己的镜像加速地址
执行阿里云推荐的终端命令,即可更新docker的镜像源为阿里云镜像
1 | sudo mkdir -p /etc/docker |
代理配置
为docker服务创建一个内嵌的systemd目录
1
mkdir -p /etc/systemd/system/docker.service.d
创建
/etc/systemd/system/docker.service.d/http-proxy.conf
文件,并添加HTTP_PROXY环境变量,其中[proxy-addr]和[proxy-port]分别改成实际情况的代理地址和端口1
2[Service]
Environment="HTTP_PROXY=http://192.168.4.xx:xx" "HTTPS_PROXY=http://192.168.4.xx:xx"如果还有内部的不需要使用代理来访问的Docker registries,那么还需要制定NO_PROXY环境变量
1
2[Service]
Environment="HTTP_PROXY=http://192.168.4.xx:xx" "HTTPS_PROXY=http://192.168.4.xx:xx" "NO_PROXY=localhost,127.0.0.1,docker-registry.somecorporation.com"更新配置并重启Docker服务
1
2systemctl daemon-reload
systemctl restart docker
下载docker安装包,按照如下指令安装即可
1 | # 下载 Docker 二进制文件的压缩包 |
一键安装脚本(未测试,参考别人的)
创建 Docker 和 Docker-Compose 一键安装脚本 install.sh:
1 |
|
一键卸载脚本
创建 Docker 和 Docker-Compose 一键安装脚本 uninstall.sh:
1 | #!/bin/sh |
加速格式:”registry-mirrors”: [“https://registry.docker-cn.com“]
镜像加速器 | 镜像加速器地址 |
---|---|
Docker 中国官方镜像 | https://registry.docker-cn.com |
DaoCloud 镜像站 | http://f1361db2.m.daocloud.io |
Azure 中国镜像 | https://dockerhub.azk8s.cn |
科大镜像站 | https://docker.mirrors.ustc.edu.cn |
阿里云 | https://ud6340vz.mirror.aliyuncs.com |
七牛云 | https://reg-mirror.qiniu.com |
网易云 | https://hub-mirror.c.163.com |
腾讯云 | https://mirror.ccs.tencentyun.com |
命令学习
基本命令
1 | # 查看版本号 |
镜像
Docker默认拉取的架构是与主机的架构相同,当你在一个特定的架构上运行Docker命令时,Docker将自动尝试拉取与该架构匹配的镜像。例如,如果你在x86架构的主机上运行Docker命令,Docker将尝试拉取x86架构的镜像
这意味着Docker会自动适配主机的架构,并拉取相应的镜像供使用。如果需要指定架构,可以加上--platform=arm64
参数
1 | # 查看本地镜像 |
容器
1 | # 创建一个全新的容器,不会立即运行 |
镜像打包工具 Buildpacks、Dockerfile
Docker, Dockerfile, 和Docker Compose区别 | Baeldung
Docker Compose允许我们定义容器共享的共同对象。例如,我们可以一次性定义一个卷,然后把它挂在每个容器里,这样它们就可以共享一个共同的文件系统。或者,我们可以定义一个或多个容器用来通信的网络。
Docker Compose只是一个协调多个容器的工具。其他选择包括Kubernetes、Openshift和Apache Mesos
Docker容器迁移到其他服务器的5种方法详解_docker
目录挂载
- 使用 Docker 运行后,我们改了项目代码不会立刻生效,需要重新
build
和run
,很是麻烦 - 容器里面产生的数据,例如 log 文件,数据库备份文件,容器删除后就丢失了
目录挂载解决以上问题
bind mount
直接把宿主机目录映射到容器内,适合挂代码目录和配置文件。可挂到多个容器上volume
由容器创建和管理,创建在宿主机,所以删除容器不会丢失,官方推荐,更高效,Linux 文件系统,适合存储数据库数据。可挂到多个容器上tmpfs mount
适合存储临时文件,存宿主机内存中。不可多容器共享
演示
1 | # bind mount 方式 |
Docker Compose管理
安装
1 | # 下载 |
定义docker-compose.yaml
文件
1 | version: '3.3' # 指定 Docker Compose 文件的版本 |
基本指令学习
1 | # 启动服务 |
多容器通信
虚拟网络
要想多容器之间互通,从 Web 容器访问 Redis 容器,我们只需要把他们放到同个网络中就可以了
创建一个名为test-net
的网络:
1 | docker network create test-net |
运行 Redis 在 test-net
网络中,别名redis
1 | # network-alias指的是网络的别名 |
使用时url填写redis://redis:6379
运行 Web 项目,使用同个网络
1 | docker run -p 8080:8080 --name test -v D:/test:/app --network redis-net -d test:v0 |
Docker-Compose
假设运行了两个容器:Web 项目 + Redis
如果项目依赖更多的第三方软件,我们需要管理的容器就更加多,每个都要单独配置运行,指定网络
我们可以使用 docker-compose 把项目的多个服务集合到一起,一键运行
安装 Docker Compose
- 如果你是安装的桌面版 Docker,不需要额外安装,已经包含了
- 如果是没图形界面的服务器版 Docker,你需要单独安装 安装文档
- 运行
docker-compose
检查是否安装成功
要把项目依赖的多个服务集合到一起,我们需要编写一个docker-compose.yml
文件,描述依赖哪些服务
容器默认时间不是北京时间,增加 TZ=Asia/Shanghai 可以改为北京时间
1 | version: "3.7" |
在docker-compose.yml
文件所在目录,执行:docker-compose up
就可以跑起来了,文档在这
在后台运行只需要加一个 -d 参数docker-compose up -d
动作 | 命令 |
---|---|
查看运行状态 | docker-compose ps |
停止运行 | docker-compose stop |
重启 | docker-compose restart |
重启单个服务 | docker-compose restart service-name |
进入容器命令行 | docker-compose exec service-name sh |
查看容器运行log | docker-compose logs [service-name] |
hello world
创建dockfile,新建一个
Dockerfile
文件
1 | # 使用基础镜像,选择适合您的环境 |
构建镜像,在
Dockerfile
目录下,执行以下命令,-t后面跟的是镜像名和版本,这里会构建一个fastchat
镜像,版本号为v0
,
1 | docker build -t fastchat:v0 . |
如果出现网络问题,需要配置代理,可以带上--build-arg
参数
1 | docker build -t fastchat:v0 --build-arg http_proxy=http://192.168.0.xx:xx --build-arg https_proxy=http://192.168.0.xx:xx . |
如果需要指定dockfile文件,可以使用-f
参数
1 | docker build -f Q:\pyCharmWS\chatgpts\dockfiles\Dockerfile-ubuntu -t ubuntu:v0 . |
除了自己写dockfile,还可以使用docker pull
拉取现成的镜像
查看镜像列表
1 | docker images |
启动镜像
1 | docker run -itd -p 8080:80 --name ubuntu-test fastchat:v0 |
docker run -itd
表示在后台运行容器,并允许与容器进行交互,同时为容器分配一个伪终端
将容器的80端口映射到主机的8080端口
--name ubuntu-test
用于指定容器的名称为`ubuntu-test,返回一个容器id
如果已执行就退出’Exit(0)’,可以加上参数--entrypoint=/bin/bash
,这里会自动退出是因为Docker容器后台运行,就必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail)就是会自动退出的
查看容器列表
1 | docker ps |
CONTAINER ID
指的是容器ID
进入容器
1 | docker exec -it ubuntu-test bash |
输入exit
退出,container是不会被关闭的
1 | docker attach ubuntu-test |
使用快捷键退出:按下键盘上的Ctrl + P
,然后按下Ctrl + Q
,container是不会被关闭的
或者输入exit
退出,container是会被关闭的
这个组合键可以分离终端与容器的连接,但不会停止容器的运行,将返回到宿主机的终端,而容器会继续在后台运行
停止容器
1 | docker stop ubuntu-test |
当您执行docker stop
命令停止容器后,容器的名称可能仍然保留在Docker中。如果您尝试使用相同的容器名称再次运行容器,会出现”重名”的错误
1 | Q:\pyCharmWS\chatgpts\dockfiles>docker run -itd --name ubuntu-test fastchat:v0 |
这是因为Docker要求容器名称在给定的命名空间中必须是唯一的。当您停止容器时,该容器的名称不会立即从Docker中删除,以便您可以查看已停止容器的状态和日志等信息
这时候可以更改原来容器的名称
或删除已停止的容器
docker rename ubuntu-old ubuntu-test
1
2
3Q:\pyCharmWS\chatgpts\dockfiles>docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
918a3b2ccc42 fastchat:v0 "/bin/bash" 41 minutes ago Exited (130) 11 minutes ago ubuntu-testdocker rm ubuntu-test
重启容器
1 | docker restart ubuntu-test |
将容器保存为镜像,以便稍后再次使用或与其他人共享
要将容器保存为镜像,可以使用docker commit
命令。以下是保存容器为镜像的步骤:
确保您的容器处于停止状态。如果容器正在运行,请先停止它:
1
docker stop <container_name_or_id>
使用
docker commit
命令将容器保存为镜像。在命令中指定容器的名称或ID以及要为新镜像指定的名称和标签:1
docker commit <container_name_or_id> <new_image_name:tag>
例如:
1
docker commit mycontainer myimage:v1
这将创建一个名为
myimage
,标签为v1
的新镜像等待
docker commit
命令完成,它会将容器的文件系统和元数据保存为新的镜像。一旦完成,您可以使用docker images
命令查看新创建的镜像
现在,您已经将容器保存为新的镜像。您可以使用该镜像创建新的容器,或将其推送到镜像仓库以供其他人使用
请注意,使用docker commit
命令保存容器为镜像时,镜像将包含容器中当前的文件系统状态和配置。这意味着如果容器中有任何不必要的文件或敏感信息,它们也会包含在保存的镜像中。因此,在保存容器之前,最好确保容器中不包含不必要的文件,并遵循最佳实践来保护敏感信息
值得一提的是,docker commit
命令是将容器的状态保存为镜像,而不是推荐的方法
更好的做法是使用 Dockerfile 来定义容器的配置和状态,并使用 docker build
命令构建镜像。这样可以更好地跟踪和管理镜像的变更
dockfile
构建一个基于ubuntu的anaconda环境
1 | # 使用基础镜像,选择适合您的环境 |
除了SHELL ["/bin/bash", "-c"]
,还可以每次指定bash环境,CMD /bin/bash -c "source activate chat38"
发布和部署
要将镜像发布到 Docker Hub 上,需要按照以下步骤进行操作:
注册 Docker Hub 账号,如果你还没有 Docker Hub 账号,首先需要在Docker Hub的官方网站上进行注册
登录 Docker Hub,使用以下命令在终端中登录到 Docker Hub
1 | Q:\pyCharmWS\chatgpts\dockfiles>docker login -u narutohyc |
标记镜像,在发布到 Docker Hub 之前,需要为镜像添加一个适当的标签,以便将其与你的 Docker Hub 用户名和存储库关联起来,使用以下命令为镜像添加标签
1 | docker tag <IMAGE_ID> <DOCKER_HUB_USERNAME>/<REPOSITORY_NAME>:<TAG> |
其中,<IMAGE_ID>
是你要发布的镜像的 ID,<DOCKER_HUB_USERNAME>
是你的 Docker Hub 用户名,<REPOSITORY_NAME>
是你想要为镜像设置的存储库名称,<TAG>
是一个可选的标签,用于标识镜像的版本号
发布镜像,使用以下命令将标记后的镜像发布到 Docker Hub
1 | docker push <DOCKER_HUB_USERNAME>/<REPOSITORY_NAME>:<TAG> |
这将把镜像推送到 Docker Hub 上的指定存储库中
确认发布,登录到 Docker Hub 的网站,访问你的 Docker Hub 账号,你应该能够在相应的存储库中看到已发布的镜像
请注意,发布到 Docker Hub 的镜像将成为公开可访问的,任何人都可以从 Docker Hub 上获取并使用该镜像。如果你希望限制访问权限,可以考虑使用私有仓库,或者在 Docker Hub 上创建一个私有的组织来管理镜像的访问权限
示例
安装redis
演示 Docker 安装 Redis
一个命令跑起来:docker run -d -p 6379:6379 --name redis redis:latest
命令参考:https://docs.docker.com/engine/reference/commandline/run/
安装wordpress
定义docker-compose.yml
文件
1 | version: '3.1' |
执行docker-compose up -d
docker镜像打包部署
基于基础的python镜像,构建出符合项目的镜像,并打包上传至服务器,然后基于这个镜像,运行项目服务
版本支持(20版本不支持,会抛异常
RuntimeError: can't start new thread
,目前测试通过的有24.0.5、27.2.0)
准备dockfile文件和requirements.sh文件
1
2
3
4
5
6
7
8
9
10
11# 使用官方 Python 3.11 slim 版本镜像作为基础镜像
FROM python:3.11-slim
# 设置工作目录
WORKDIR /app
# 复制当前目录所有文件到容器的工作目录中
COPY ./requirements.sh .
# 更新包管理器并安装依赖
RUN sh requirements.shrequirements.sh
示例如下:1
2
3
4
5
6
pip install --progress-bar off aiohappyeyeballs==2.4.0
pip install --progress-bar off aiohttp==3.10.5
pip install --progress-bar off aiolimiter==1.1.0
pip install --progress-bar off aiosignal==1.3.1基于dockfile文件执行build命令(要在当前路径下,有
Dockerfile
和requirements.sh
脚本)1
docker build -f "D:\work\coding\Dockerfile" -t py311_bilu:v0 .
创建完镜像,可以用命令查看是否创建成功
1
2
3(base) PS D:\work\coding\pycharm\bilu\新建文件夹> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
py311_bilu v0 de6dbadb4ea4 47 minutes ago 498MB将镜像保存成文件
1
docker save -o py311_bilu.tar py311_bilu:v0
将镜像文件发送到服务器,并加载到docker
1
docker load -i py311_bilu.tar
加载完镜像,可以用命令查看是否加载成功
1
2
3docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
py311_bilu v0 de6dbadb4ea4 47 minutes ago 498MB运行服务(需要在
docker-compose
文件的路径下)docker-compose方式(推荐)
1
2
3
4
5# 基于docker-compose.yml文件
docker-compose up -d
# 查看运行日志
docker-compose logs py311_bilu_env旧的方式
1
2
3
4
5
6
7
8
9
10
11
12docker ps | grep py311_bilu_env
# 如果容器已经在运行,先关闭
docker stop py311_bilu_env
# 如果容器已存在,先删除
docker rm py311_bilu_env
# 创建并启动容器 -p为端口映射 -v为路径映射 py311_bilu_env是容器名 py311_bilu:v0是镜像名
# sh -c 后面跟的是运行命令
# -e HTTP_PROXY、-e HTTPS_PROXY为代理(不一定需要)
docker run -d -p 6007:6007 --network bridge --ulimit nproc=1024:2048 -e OMP_NUM_THREADS=4 -e OPENBLAS_NUM_THREADS=4 -v /home/ai:/app/ai --name py311_bilu_env py311_bilu:v0 sh -c "cd /app/ai/scripts/services && python main_service_script.py"重启服务(文件有更新时需要)
1
2# 重新启动服务
docker-compose restartdocker-compose文件配置有更新时,需要先关闭服务
1
2
3
4
5
6# 关闭服务
docker-compose down
# 启动服务
docker-compose -f noup_docker-compose.yml up -d
# 查看日志
docker-compose logs py311_bilu_env其他命令
1
2# 创建容器,并进入交互式
docker exec -it py311_bilu_env /bin/sh
实战neo4j
安装neo4j
拉取neo4j镜像
从docker官方镜像中找合适的镜像
1
docker search neo4j
拉取镜像源
1
docker pull neo4j(:版本号) # 缺省 ":版本号" 时默认安装latest版本的
查看本地镜像,检验是否拉取成功
1
docker images
图算法插件
neo4j提供了一系列常用的图算法,该算法库需要单独安装,注意版本对应关系
点击上方官网链接,下载
Neo4j Graph Data Science
下的文件,放到$NEO4J_HOME/plugins
目录中将以下内容添加到您的
$NEO4J_HOME/conf/neo4j.conf
文件中,参考这里1
dbms.security.procedures.unrestricted=apoc.*,gds.*
此配置条目是必需的,因为 GDS 库访问 Neo4j 的低级组件以最大化性能
重启 Neo4j,在docker下就是重启
为了验证您的安装,可以输入以下命令
1 | RETURN gds.version() |
要列出所有已安装的算法,请运行以下gds.list()
过程
1 | CALL gds.list() |
启动neo4j
找一个目录存放docker的各镜像运行目录,比如我这里选的是/home/huangyc/docker
然后再在这个目录新建具体的镜像对应的文件夹/home/huangyc/docker/neo4j,在下面新建四个文件夹(实际上好像不需要手动建,执行命令时自动会新建)
- data: 数据存放的文件夹
- logs: 运行的日志文件夹
- conf: 数据库配置文件夹(在配置文件neo4j.conf中配置包括开放远程连接、设置默认激活的数据库)
- import: 为了大批量导入csv来构建数据库,需要导入的节点文件nodes.csv和关系文件rel.csv需要放到这个文件夹下
- plugins: 存放jar插件
启动命令格式如下
1 | docker run -d --name container_name \ //-d表示容器后台运行 --name指定容器名字 |
也可以写成单行命令
1 | docker run -d --name neo4j_hyc -p 7474:7474 -p 7687:7687 -v /home/huangyc/docker/neo4j/data:/data -v /home/huangyc/docker/neo4j/logs:/logs -v /home/huangyc/docker/neo4j/conf:/var/lib/neo4j/conf -v /home/huangyc/docker/neo4j/import:/var/lib/neo4j/import -v /home/huangyc/docker/neo4j/plugins:/var/lib/neo4j/plugins --env NEO4J_AUTH=neo4j/hyc neo4j |
py库
使用Python访问图数据库,主要使用的库时py2neo
和neo4j
,
- py2neo通过操作python变量,达到操作neo4j的目的,同时也支持
cypher
语法 - neo4j主要时执行CQL(cypher)语句
安装
1 | pip install py2neo |
使用例子
1 | # coding:utf-8 |
安装
1 | pip install neo4j |
使用例子
1 | from neo4j import GraphDatabase |
实战nebula
基本介绍
NebulaGraph 由三种服务构成:Graph 服务、Meta 服务和 Storage 服务,是一种存储与计算分离的架构
Meta 服务
Meta 服务是由 nebula-metad 进程
提供的,用户可以根据场景配置 nebula-metad 进程数量:
- 测试环境中,用户可以在 NebulaGraph 集群中部署 1 个或 3 个 nebula-metad 进程。如果要部署 3 个,用户可以将它们部署在 1 台机器上,或者分别部署在不同的机器上。
- 生产环境中,建议在 NebulaGraph 集群中部署 3 个 nebula-metad 进程。请将这些进程部署在不同的机器上以保证高可用。
所有 nebula-metad 进程构成了基于 Raft 协议的集群,其中一个进程是 leader,其他进程都是 follower。
leader 是由多数派选举出来,只有 leader 能够对客户端或其他组件提供服务,其他 follower 作为候补,如果 leader 出现故障,会在所有 follower 中选举出新的 leader。
Graph 服务
Graph 服务是由nebula-graphd 进程
提供,服务主要负责处理查询请求,包括解析查询语句、校验语句、生成执行计划以及按照执行计划执行四个大步骤,查询请求发送到 Graph 服务后,会由如下模块依次处理:
- Parser:词法语法解析模块。
- Validator:语义校验模块。
- Planner:执行计划与优化器模块。
- Executor:执行引擎模块。
Storage 服务
NebulaGraph 的存储包含两个部分,一个是 Meta 相关的存储,称为 Meta 服务,在前文已有介绍。
另一个是具体数据相关的存储,称为 Storage 服务。其运行在 nebula-storaged 进程
中
环境搭建
以nebula 3.2.1为例
下载并安装NebulaGraph
1 | wget https://oss-cdn.nebula-graph.com.cn/package/3.2.1/nebula-graph-3.2.1.el7.x86_64.rpm |
--prefix
为可选项,用于指定安装路径
如不设置,系统会将 NebulaGraph 安装到默认路径/usr/local/nebula/
集群配置
集群配置需要保证集群机器配置ssh免密
修改每个服务器上的 NebulaGraph 配置文件
NebulaGraph 的所有配置文件均位于安装目录的etc
目录内,包括nebula-graphd.conf
、nebula-metad.conf
和nebula-storaged.conf
,用户可以只修改所需服务的配置文件。各个机器需要修改的配置文件如下。
机器名称 | 待修改配置文件 |
---|---|
A | nebula-graphd.conf 、nebula-storaged.conf 、nebula-metad.conf |
B | nebula-graphd.conf 、nebula-storaged.conf 、nebula-metad.conf |
C | nebula-graphd.conf 、nebula-storaged.conf 、nebula-metad.conf |
D | nebula-graphd.conf 、nebula-storaged.conf |
E | nebula-graphd.conf 、nebula-storaged.conf |
机器 A 配置
nebula-graphd.conf
1
2
3
4
5
6
7
8
9
10
11########## networking ##########
# Comma separated Meta Server Addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
# Local IP used to identify the nebula-graphd process.
# Change it to an address other than loopback if the service is distributed or
# will be accessed remotely.
--local_ip=192.168.10.111
# Network device to listen on
--listen_netdev=any
# Port to listen on
--port=9669nebula-storaged.conf
1
2
3
4
5
6
7
8
9########## networking ##########
# Comma separated Meta server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
# Local IP used to identify the nebula-storaged process.
# Change it to an address other than loopback if the service is distributed or
# will be accessed remotely.
--local_ip=192.168.10.111
# Storage daemon listening port
--port=9779nebula-metad.conf
1
2
3
4
5
6
7
8
9########## networking ##########
# Comma separated Meta Server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
# Local IP used to identify the nebula-metad process.
# Change it to an address other than loopback if the service is distributed or
# will be accessed remotely.
--local_ip=192.168.10.111
# Meta daemon listening port
--port=9559机器 D 配置
nebula-graphd.conf
1
2
3
4
5
6
7
8
9
10
11########## networking ##########
# Comma separated Meta Server Addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
# Local IP used to identify the nebula-graphd process.
# Change it to an address other than loopback if the service is distributed or
# will be accessed remotely.
--local_ip=192.168.10.114
# Network device to listen on
--listen_netdev=any
# Port to listen on
--port=9669nebula-storaged.conf
1
2
3
4
5
6
7
8
9########## networking ##########
# Comma separated Meta server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
# Local IP used to identify the nebula-storaged process.
# Change it to an address other than loopback if the service is distributed or
# will be accessed remotely.
--local_ip=192.168.10.114
# Storage daemon listening port
--port=9779ABC三台配置除了
local_ip
,其他都一致,DE两台配置除了local_ip
,其他都一致
启动服务
命令学习
使用脚本nebula.service
管理服务,包括启动、停止、重启、中止和查看
nebula.service
的默认路径是/usr/local/nebula/scripts
,如果修改过安装路径,请使用实际路径
语法
1 | sudo /usr/local/nebula/scripts/nebula.service |
比如对于非容器部署的 NebulaGraph,执行如下命令启动服务:
1 | sudo /usr/local/nebula/scripts/nebula.service start all |
执行如下命令查看 NebulaGraph 服务状态
1 | sudo /usr/local/nebula/scripts/nebula.service status all |
如果返回如下结果,表示 NebulaGraph 服务正常运行
1 | [INFO] nebula-metad(33fd35e): Running as 29020, Listening on 9559 |
正常启动 NebulaGraph 后,nebula-storaged
进程的端口显示红色。这是因为nebula-storaged
在启动流程中会等待nebula-metad
添加当前 Storage 服务,当前 Storage 服务收到 Ready 信号后才会正式启动服务。从 3.0.0 版本开始,在配置文件中添加的 Storage 节点无法直接读写,配置文件的作用仅仅是将 Storage 节点注册至 Meta 服务中。必须使用ADD HOSTS
命令后,才能正常读写 Storage 节点。
注册
具体是通过nebula-console命令行或者studio页面执行,用 java client 也可以的, 底层逻辑都是通过客户端发送一条 add hosts xxxxx
query
1 | ADD HOSTS 192.168.40.39:9779, 192.168.40.40:9779, 192.168.40.41:9779; |
比如使用python客户端
1 | from nebula3.gclient.net import ConnectionPool |
等待20s后,重新查看服务状态,发现警告没有就说明成功了
1 | [root@localhost nebula]# sudo scripts/nebula.service status all |
清空图
数据清除后,如无备份,无法恢复。使用该功能务必谨慎
CLEAR SPACE
不是原子性操作。如果执行出错,请重新执行,避免残留数据图空间中的数据量越大,
CLEAR SPACE
消耗的时间越长如果
CLEAR SPACE
的执行因客户端连接超时而失败,可以增大 Graph 服务配置中storage_client_timeout_ms
参数的值在
CLEAR SPACE
的执行过程中,向该图空间写入数据的行为不会被自动禁止这样的写入行为可能导致
CLEAR SPACE
清除数据不完全,残留的数据也可能受到损坏
1 | CLEAR SPACE [IF EXISTS] <space_name>; |
保留的数据¶
图空间中,CLEAR SPACE
不会删除的数据包括:
- Tag 信息
- Edge type 信息
- 原生索引和全文索引的元数据
DROP SPACE
语句用于删除指定图空间以及其中的所有信息
1 | DROP SPACE [IF EXISTS] <graph_space_name>; |
客户端
NebulaGraph 支持多种类型的客户端,包括命令行客户端、可视化界面客户端和流行编程语言客户端
详情参见客户端列表
前提条件¶
NebulaGraph 服务已启动
运行 NebulaGraph Console 的机器和运行 NebulaGraph 的服务器网络互通
NebulaGraph Console 的版本兼容 NebulaGraph 的版本
使用命令arch
,查看系统结构,去官网下载安装包,重命名文件为nebula_console
为用户授予 nebula-console 文件的执行权限
1
chmod 111 nebula-console
在命令行界面中,切换工作目录至 nebula-console 文件所在目录,执行如下命令连接 NebulaGraph
1
./nebula-console -addr <ip> -port <port> -u <username> -p <password> [-t 120] [-e "nGQL_statement" | -f filename.nGQL]
例如,要连接到部署在 192.168.10.8 上的 Graph 服务,运行以下命令
1
./nebula_console -addr 192.168.10.8 -port 9669 -u root -p nebula
已安装 Python,版本为 3.6 及以上,版本对照表¶
NebulaGraph 版本 | NebulaGraph Python 版本 |
---|---|
3.2.1 | 3.1.0 |
2.6.x | 2.6.0 |
pip安装
1 | $ pip install nebula3-python==<version> |
初始化一些数据
执行如下语句创建名为
basketballplayer
的图空间1
CREATE SPACE basketballplayer(partition_num=15, replica_factor=1, vid_type=fixed_string(32));
执行命令
SHOW HOSTS
检查分片的分布情况,确保平衡分布1
2
3
4
5
6
7
8nebula> SHOW HOSTS;
+-------------+-----------+-----------+-----------+--------------+----------------------------------+------------------------+---------+
| Host | Port | HTTP port | Status | Leader count | Leader distribution | Partition distribution | Version |
+-------------+-----------+-----------+-----------+--------------+----------------------------------+------------------------+---------+
| "storaged0" | 9779 | 19669 | "ONLINE" | 5 | "basketballplayer:5" | "basketballplayer:5" | "3.1.0" |
| "storaged1" | 9779 | 19669 | "ONLINE" | 5 | "basketballplayer:5" | "basketballplayer:5" | "3.1.0" |
| "storaged2" | 9779 | 19669 | "ONLINE" | 5 | "basketballplayer:5" | "basketballplayer:5" | "3.1.0" |
+-------------+-----------+-----------+-----------+--------------+----------------------------------+------------------------+---------+选择图空间
basketballplayer
1
nebula[(none)]> USE basketballplayer;
用户可以执行命令
SHOW SPACES
查看创建的图空间1
2
3
4
5
6nebula> SHOW SPACES;
+--------------------+
| Name |
+--------------------+
| "basketballplayer" |
+--------------------+创建 Tag 和 Edge type
语法:
1
2
3
4
5
6
7
8CREATE {TAG | EDGE} [IF NOT EXISTS] {<tag_name> | <edge_type_name>}
(
<prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']
[{, <prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']} ...]
)
[TTL_DURATION = <ttl_duration>]
[TTL_COL = <prop_name>]
[COMMENT = '<comment>'];创建 Tag:
player
和team
,以及 Edge type:follow
和serve
。说明如下表。| 名称 | 类型 | 属性 |
| ——— | ————- | ———————————————— |
| player | Tag | name (string), age (int) |
| team | Tag | name (string) |
| follow | Edge type | degree (int) |
| serve | Edge type | start_year (int), end_year (int) |1
2
3
4CREATE TAG player(name string, age int);
CREATE TAG team(name string);
CREATE EDGE follow(degree int);
CREATE EDGE serve(start_year int, end_year int);插入点和边
插入点
1
2
3
4
5
6
7
8INSERT VERTEX [IF NOT EXISTS] [tag_props, [tag_props] ...]
VALUES <vid>: ([prop_value_list])
tag_props:
tag_name ([prop_name_list])
prop_name_list: [prop_name [, prop_name] ...]
prop_value_list: [prop_value [, prop_value] ...]vid
是 Vertex ID 的缩写,vid
在一个图空间中是唯一的。参数详情请参见 INSERT VERTEX插入边
1
2
3
4
5
6INSERT EDGE [IF NOT EXISTS] <edge_type> ( <prop_name_list> ) VALUES
<src_vid> -> <dst_vid>[@<rank>] : ( <prop_value_list> )
[, <src_vid> -> <dst_vid>[@<rank>] : ( <prop_value_list> ), ...];
<prop_name_list> ::= [ <prop_name> [, <prop_name> ] ...]
<prop_value_list> ::= [ <prop_value> [, <prop_value> ] ...]
参数详情请参见 INSERT EDGE
插入代表球员和球队的点
1
2
3
4nebula> INSERT VERTEX player(name, age) VALUES "player100":("Tim Duncan", 42);
nebula> INSERT VERTEX player(name, age) VALUES "player101":("Tony Parker", 36);
nebula> INSERT VERTEX player(name, age) VALUES "player102":("LaMarcus Aldridge", 33);
nebula> INSERT VERTEX team(name) VALUES "team203":("Trail Blazers"), "team204":("Spurs");插入代表球员和球队之间关系的边
1
2
3
4nebula> INSERT EDGE follow(degree) VALUES "player101" -> "player100":(95);
nebula> INSERT EDGE follow(degree) VALUES "player101" -> "player102":(90);
nebula> INSERT EDGE follow(degree) VALUES "player102" -> "player100":(75);
nebula> INSERT EDGE serve(start_year, end_year) VALUES "player101" -> "team204":(1999, 2018),"player102" -> "team203":(2006, 2015);
查询数据¶
🌶注意
无属性索引的时候,在没有指定条件的时候,可以通过数据扫描的sample下推去扫得 limit 的数据
而带有filter
条件时,需要全扫才行,这个情况在nebula里是被禁止的,需要创建这个tag上的索引才能查询
1 | # 在 Tag player 的 name 属性和 Edge type belong_to 上创建索引 |
图模式
模式(pattern)和图模式匹配,是图查询语言的核心功能
单点模式
1 | (a) |
示例为一个简单的模式,描述了单个点,并使用变量a
命名该点
多点关联模式
多个点通过边相连是常见的结构,模式用箭头来描述两个点之间的边。例如:
1 | (a)-[]->(b) |
示例为一个简单的数据结构:两个点和一条连接两个点的边,两个点分别为a
和b
,边是有方向的,从a
到b
这种描述点和边的方式可以扩展到任意数量的点和边,例如:
1 | (a)-[]->(b)<-[]-(c) |
这样的一系列点和边称为路径
(path)
只有在涉及某个点时,才需要命名这个点。如果不涉及这个点,则可以省略名称,例如:
1 | (a)-[]->()<-[]-(c) |
Tag模式
nGQL 中的Tag
概念与 openCypher 中的Label
有一些不同。例如,必须创建一个Tag
之后才能使用它,而且Tag
还定义了属性的类型
模式除了简单地描述图中的点之外,还可以描述点的 Tag。例如:
1 | (a:User)-[]->(b) |
模式也可以描述有多个 Tag 的点,例如:
1 | (a:User:Admin)-[]->(b) |
属性模式
点和边是图的基本结构。nGQL 在这两种结构上都可以增加属性,方便实现更丰富的模型。
在模式中,属性的表示方式为:用花括号括起一些键值对,用英文逗号分隔。例如一个点有两个属性:
1 | (a {name: 'Andres', sport: 'Brazilian Ju-Jitsu'}) |
在这个点上可以有一条边是:
1 | (a)-[{blocked: false}]->(b) |
边模式
描述一条边最简单的方法是使用箭头连接两个点。
可以用以下方式描述边以及它的方向性。如果不关心边的方向,可以省略箭头,例如:
1 | (a)-[]-(b) |
和点一样,边也可以命名。一对方括号用于分隔箭头,变量放在两者之间。例如:
1 | (a)-[r]->(b) |
和点上的 Tag 一样,边也可以有类型。描述边的类型,例如:
1 | (a)-[r:REL_TYPE]->(b) |
和点上的 Tag 不同,一条边只能有一种 Edge type。但是如果我们想描述多个可选 Edge type,可以用管道符号(|)将可选值分开,例如:
1 | (a)-[r:TYPE1|TYPE2]->(b) |
和点一样,边的名称可以省略,例如:
1 | (a)-[:REL_TYPE]->(b) |
变长模式
在图中指定边的长度来描述多条边(以及中间的点)组成的一条长路径,不需要使用多个点和边来描述。例如:
1 | (a)-[*2]->(b) |
该模式描述了 3 点 2 边组成的图,它们都在一条路径上(长度为 2),等价于:
1 | (a)-[]->()-[]->(b) |
也可以指定长度范围,这样的边模式称为variable-length edges
,例如:
1 | (a)-[*3..5]->(b) |
*3..5
表示最小长度为 3,最大长度为 5。
该模式描述了 4 点 3 边、5 点 4 边或 6 点 5 边组成的图。
也可以忽略最小长度,只指定最大长度,例如:
1 | (a)-[*..5]->(b) |
必须指定最大长度,不支持仅指定最小长度((a)-[*3..]->(b)
)或都不指定((a)-[*]->(b)
)。
路径变量
一系列连接的点和边称为路径
。nGQL 允许使用变量来命名路径,例如:
1 | p = (a)-[*3..5]->(b) |
可以在 MATCH 语句中使用路径变量
注释
支持四种注释方式:#
、//
、/* */
nGQL 语句中的反斜线(\)代表换行
数据类型
字符串的表示方式为用双引号或单引号包裹,例如"Hello, Cooper"
或'Hello, Cooper'
日期和时间的类型,包括DATE
、TIME
、DATETIME
、TIMESTAMP
和DURATION
1 | nebula> RETURN DATE({year:-123, month:12, day:3}); |
date()
支持的属性名称包括year
、month
和day
。date()
支持输入YYYY
、YYYY-MM
或YYYY-MM-DD
,未输入的月份或日期默认为01
time()
支持的属性名称包括hour
、minute
和second
datetime()
支持的属性名称包括year
、month
、day
、hour
、minute
和second
列表(List)是复合数据类型,一个列表是一组元素的序列,可以通过元素在序列中的位置访问列表中的元素
nGQL 的下标支持从前往后查询,从 0 开始,0 表示第一个元素,1 表示第二个元素,以此类推;也支持从后往前查询,从-1 开始,-1 表示最后一个元素,-2 表示倒数第二个元素,以此类推。
- [M]:表示下标为 M 的元素。
- [M..N]:表示
M ≤ 下标 < N
的元素。N
为 0 时,返回为空。 - [M..]:表示
M ≤ 下标
的元素。 - [..N]:表示
下标 < N
的元素。N
为 0 时,返回为空。
可视化
NebulaGraph Studio(简称 Studio)是一款可以通过 Web 访问的开源图数据库可视化工具,搭配 NebulaGraph 内核使用,提供构图、数据导入、编写 nGQL 查询等一站式服务。
前提条件¶
在部署 RPM 版 Studio 之前,用户需要确认以下信息:
NebulaGraph 服务已经部署并启动。详细信息,参考 NebulaGraph 安装部署
使用的 Linux 发行版为 CentOS ,已安装 lsof
确保以下端口未被占用,
7001
是Studio 提供 web 服务使用的
从官网下载nebula-graph-studio-3.4.1.x86_64.rpm,使用以下命令安装到指定路径
1 | sudo rpm -i nebula-graph-studio-3.4.1.x86_64.rpm --prefix=<path> |
安装完,自动会启动,当屏幕返回以下信息时,表示 PRM 版 Studio 已经成功启动。
1 | Start installing NebulaGraph Studio now... |
启动成功后,在浏览器地址栏输入 http://<ip address>:7001
注意: host处填写为 ip:port
格式
用户名和密码:根据 Nebula Graph 的身份验证设置填写登录账号和密码
- 如果未启用身份验证,可以填写默认用户名
root
和任意密码。 - 如果已启用身份验证,但是未创建账号信息,用户只能以 GOD 角色登录,必须填写
root
及对应的密码nebula
。 - 如果已启用身份验证,同时又创建了不同的用户并分配了角色,不同角色的用户使用自己的账号和密码登录。
如果在浏览器窗口中能看到以下登录界面,表示已经成功部署并启动 Studio
异常处理¶
如果在安装过程中自动启动失败或是需要手动启动或停止服务,请使用以下命令:
手动启动服务
1
bash /usr/local/nebula-graph-studio/scripts/rpm/start.sh
手动停止服务
1
bash /usr/local/nebula-graph-studio/scripts/rpm/stop.sh
如果启动服务时遇到报错报错 ERROR: bind EADDRINUSE 0.0.0.0:7001
,用户可以通过以下命令查看端口 7001 是否被占用。
1 | lsof -i:7001 |
如果端口被占用,且无法结束该端口上进程,用户可以通过以下命令修改 Studio 服务启动端口,并重新启动服务。
1 | //修改 studio 服务启动端口 |
集群监控
NebulaGraph Dashboard
(简称Dashboard)是一款用于监控NebulaGraph集群中机器和服务状态的可视化工具
数据导入
Nebula 目前作为较为成熟的产品,已经有着很丰富的生态。数据导入的维度而言就已经提供了多种选择。有大而全的Nebula Exchange,小而精简的Nebula Importer, 还有为 Spark / Flink 引擎提供的Nebula Spark Connector 和 Nebula Flink Connector。
使用场景介绍:
Nebula Exchange
- 需要将来自 Kafka、Pulsar 平台的流式数据, 导入 Nebula Graph 数据库
- 需要从关系型数据库(如 MySQL)或者分布式文件系统(如 HDFS)中读取批式数据
- 需要将大批量数据生成 Nebula Graph 能识别的 SST 文件
Nebula Importer
- Importer 适用于将本地 CSV 文件的内容导入至 Nebula Graph 中
Nebula Spark Connector:
- 在不同的 Nebula Graph 集群之间迁移数据
- 在同一个 Nebula Graph 集群内不同图空间之间迁移数据
- Nebula Graph 与其他数据源之间迁移数据
- 结合 Nebula Algorithm 进行图计算
Nebula Flink Connector
- 在不同的 Nebula Graph 集群之间迁移数据
- 在同一个 Nebula Graph 集群内不同图空间之间迁移数据
- Nebula Graph 与其他数据源之间迁移数据
总体来说,Exchange 大而全,可以和大部分的存储引擎结合,导入到 Nebula 中,但是需要部署Spark 环境。
Importer 使用简单,所需依赖较少,但需要自己提前生成数据文件,配置好 schema 一劳永逸,但是不支持断点续传,适合数据量中等。
Spark / Flink Connector 需要和流数据结合。
不同的场景选择不同的工具,如果作为新人使用 Nebula 在导入数据时,建议使用 Nebula Importer 工具,简单快速上手。
k8s
简介
Kubernetes (K8S) 是什么
它是一个为 容器化 应用提供集群部署和管理的开源工具,由 Google 开发
Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目
主要特性:
- 高可用,不宕机,自动灾难恢复
- 灰度更新,不影响业务正常运转
- 一键回滚到历史版本
- 方便的伸缩扩展(应用伸缩,机器加减)、提供负载均衡
- 有一个完善的生态
部署方案
- 传统部署方式:
应用直接在物理机上部署,机器资源分配不好控制,出现Bug时,可能机器的大部分资源被某个应用占用,导致其他应用无法正常运行,无法做到应用隔离
- 虚拟机部署
在单个物理机上运行多个虚拟机,每个虚拟机都是完整独立的系统,性能损耗大
- 容器部署
所有容器共享主机的系统,轻量级的虚拟机,性能损耗小,资源隔离,CPU和内存可按需分配
Kubernetes 可以为你提供集中式的管理集群机器和应用,加机器、版本升级、版本回滚,那都是一个命令就搞定的事,不停机的灰度更新,确保高可用、高性能、高扩展
重要概念 Pod
豆荚,K8S 调度、管理的最小单位,一个 Pod 可以包含一个或多个容器,每个 Pod 有自己的虚拟IP。一个工作节点可以有多个 pod,主节点会考量负载自动调度 pod 到哪个节点运行
Kubernetes 组件
Kubernetes 是一个开源的容器编排和管理平台,由多个组件组成。下面是 Kubernetes 的一些核心组件:
- kube-apiserver:作为 Kubernetes API 的前端组件,处理来自用户、kubectl 命令行工具以及其他组件的 API 请求,并将其存储在 etcd 中
- etcd:是一个高度可用且一致性的分布式键值存储,用于保存 Kubernetes 集群的配置数据、元数据和状态信息
- kube-scheduler:负责监视新创建的 Pod,并根据可用的计算资源、硬件和软件要求选择合适的节点进行调度
- kube-controller-manager:包含多个控制器,用于管理集群中的各种资源,例如节点控制器、副本控制器、服务控制器等。它负责保持期望状态和实际状态之间的一致性
- kubelet:在每个节点上运行的代理组件,负责管理节点上的容器,与容器运行时进行交互,接收来自 kube-apiserver 的指令,并确保容器按照期望状态运行
- kube-proxy:负责为 Service 对象提供网络代理和负载均衡功能,将网络流量路由到正确的容器上
- Container Runtime:Kubernetes 支持多种容器运行时,如 Docker、containerd、CRI-O 等,用于创建和管理容器
- kube-dns/coredns:提供集群内 DNS 服务,用于解析 Kubernetes 集群中的服务名称
- Dashboard:提供可视化的 Kubernetes 集群管理界面,用于查看和操作集群中的资源
除了这些核心组件之外,还有其他的辅助组件和插件,如Ingress Controller(用于管理入口流量)、Heapster(用于集群监控和性能分析)、Prometheus(用于指标收集和监控)、Fluentd(用于日志收集和聚合)等,这些组件可以根据具体需求选择安装和配置
安装和部署
占位…