Datahub 安装失败记录

背景介绍

参考链接: https://blog.csdn.net/ddxygq/article/details/123437072

DataHub是由LinkedIn的数据团队开源的一款提供元数据搜索与发现的工具。

提到LinkedIn,不得不想到大名鼎鼎的Kafka,Kafka就是LinkedIn开源的。LinkedIn开源的Kafka直接影响了整个实时计算领域的发展,而LinkedIn的数据团队也一直在探索数据治理的问题,不断努力扩展其基础架构,以满足不断增长的大数据生态系统的需求。随着数据的数量和丰富性的增长,数据科学家和工程师要发现可用的数据资产,了解其出处并根据见解采取适当的行动变得越来越具有挑战性。为了帮助增长的同时继续扩大生产力和数据创新,创建了通用的元数据搜索和发现工具DataHub。

Datahub作为新一代的元数据管理平台,大有取代老牌元数据管理工具Atlas之势。首先,阿里云也有一款名为DataHub的产品,是一个流式处理平台,本文所述DataHub与其无关。

市面上常见的元数据管理系统有如下几个:

笔者之前白嫖了亚马逊的EC2服务器,在链接文章的教程下尝试安装datahub, 系统默认环境python2.7、python3.7;

安装datahub过程

1、笔者尝试安装了 python3.8,本来开始没有安装3.8,但是在安装完datahub的时候,尝试验证版本号时抱如下第一个错误

python3 -m datahub version
DataHub CLI version: 0.10.0.1
Python version: 3.7.16 (default, Dec 15 2022, 23:24:54) 
[GCC 7.3.1 20180712 (Red Hat 7.3.1-15)]
Exception ignored in: <generator object configure_logging at 0x7f8fcca5a050>
Traceback (most recent call last):
  File "/home/ec2-user/.local/lib/python3.7/site-packages/datahub/utilities/logging_manager.py", line 187, in configure_logging
  File "/usr/lib64/python3.7/contextlib.py", line 486, in __exit__
AttributeError: 'NoneType' object has no attribute 'exc_info'

2、上边的错误出现后没有找到合适的解决方案,就直接升级python版本到3.8了,以后就有了一系列的坑,如下第二个错误,发生在对python3.8编译的过程中。

    wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz

    tar zxvf Python-3.8.3.tgz

    ./configure --prefix=/usr/lib/python3.8
    checking build system type... x86_64-pc-linux-gnu
    checking host system type... x86_64-pc-linux-gnu
    checking for python3.8... no
    checking for python3... python3
    checking for --enable-universalsdk... no
    checking for --with-universal-archs... no
    checking MACHDEP... "linux"
    checking for gcc... no
    checking for cc... no
    checking for cl.exe... no
    configure: error: in `/home/ec2-user/Python-3.8.3':
    configure: error: no acceptable C compiler found in $PATH
    See `config.log' for more details

通过安装 gcc 解决了上边的问题; 因为ec2有权限限制,非root用户执行命令时尽可能带上sudo

    sudo yum -y install gcc-c++

    sudo make && sudo make install

3、然后make install的时候遇到问题三,如下提示,通过安装zlib-devel解决

zipimport.ZipImportError: can't decompress data; zlib not available

    sudo yum install zlib-devel

编译完并通过ln -s 命令修改了python3的软链之后,执行pip3的操作开始报如下的错误,通过安装openssl 和 openssl-devel解决,但是还得从新编译python3.8,从.config开始从新执行之前的命令

python3 -m pip install --upgrade pip wheel setuptools

WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/pip/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/pip/
    sudo yum -y install openssl openssl-devel

    python3 -m pip install --upgrade acryl-datahub

4、之后再次执行datahub的安装,入到如下问题, 通过安装 libffi-devel 解决

 File "/usr/lib/python3.8/lib/python3.8/ctypes/__init__.py", line 7, in 
      from _ctypes import Union, Structure, Array
  ModuleNotFoundError: No module named '_ctypes'
  [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for avro

  File "/usr/lib/python3.8/lib/python3.8/ctypes/__init__.py", line 7, in 
      from _ctypes import Union, Structure, Array
  ModuleNotFoundError: No module named '_ctypes'
  [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for click-default-group

    sudo yum install libffi-devel

5、继续执行datahub的安装,遇到如下问题, 通过安装bzip2-devel 同时从新编译解决(如果不从新编译还会报错)

    File "/usr/lib/python3.8/lib/python3.8/bz2.py", line 19, in 
    from _bz2 import BZ2Compressor, BZ2Decompressor

ModuleNotFoundError: No module named '_bz2'
    sudo yum install bzip2-devel 

    sudo make && sudo make install

直到此时解决以上的问题,才算是把datahub安装好了。

启动datahub

6、如果docker服务没有启动会可能有如下问题;启动服务失败,报标题中的错误,试试启动服务命令前加上 sudo。

The name org.freedesktop.PolicyKit1 was not provided by any .service files See system logs and 'systemctl status docker.service' for details.

7、docker出现的问题如下

ERROR: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/info": dial unix /var/run/docker.sock: connect: permission denied

通过修改docker 组来处理

Try adding your user to the docker group:

    Run usermod -aG docker "${USER}", then
    either log out and log back in, or run newgrp docker.
    After this you have to restart your docker daemon: sudo service docker restart.

到现在所有的坑基本上踩完了,直接执行如下启动datahub的命令并得到如下提示,GAME OVER!

python3 -m datahub docker quickstart

Total Docker memory configured 0.96GB is below the minimum threshold 3.8GB. You can increase the memory allocated to Docker in the Docker settings.

是的,这是一次全程失败的实验过程,但是笔者认为除了最后设备硬件不够用之外,主要的安装踩坑过程基本上就差不多了。

docker compose 入门随笔

some 配置文件

Docker Compose是Docker编排服务的一部分,Compose可以让用户在集群中部署分布式应用。 Docker Compose是一个属于“应用层”的服务,用户可以定义哪个容器组运行哪个应用,它支持动态改变应用,并在需要时扩展。
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

.dockerignore

.dockerignore 文件的作用类似于 git 工程中的 .gitignore 。不同的是 .dockerignore 应用于 docker 镜像的构建,它存在于 docker 构建上下文的根目录,用来排除不需要上传到 docker 服务端的文件或目录。

docker 在构建镜像时首先从构建上下文找有没有 .dockerignore 文件,如果有的话则在上传上下文到 docker 服务端时忽略掉 .dockerignore 里面的文件列表

  • 每行为一个条目;
  • 以 # 开头的行为注释;
  • 空行被忽略;
  • 构建上下文路径为所有文件的根路径;
规则 含义
*/temp* 匹配根路径下一级目录下所有以 temp 开头的文件或目录
*/*/temp* row 2 col 2
temp? 匹配根路径下以 temp 开头,任意一个字符结尾的文件或目录
**/*.go 匹配所有路径下以 .go 结尾的文件或目录,即递归搜索所有路径
*.md !README.md 匹配根路径下所有以 .md 结尾的文件或目录,但 README.md 除外

两个匹配语法规则有包含或者重叠关系,那么以后面的匹配规则为准

.readthedocs.yaml

.env

The .env file feature only works when you use the docker-compose up command and does not work with docker stack deploy.

  1. Compose支持在名为.env的环境文件中声明默认环境变量,该文件放置在执行docker-compose命令的文件夹(当前工作目录)中即可生效
  2. 可以将不同的.env放置在不同的目录下,在哪个目录执行docker-compose命令,哪个目录下的.env文件就会生效。
  3. 定义在.env中的环境变量主要用于Compose配置文件中的变量替换,特别是当多个Compose配置文件都用到同一个环境变量时,可以将该环境变量定义在.env中,当环境变量的值改变了也不必修改所有Compose配置文件,只需修改.env文件中的环境变量值即可,很方便维护。
  4. 也可以用于定义以下Docker Compose CLI环境变量
  5. env文件中的每一行都采用VAR=VAL格式。
  6. 以#开头的行将作为注释处理并被忽略。
  7. 忽略空白行。
  8. 引号不会被特殊处理,意味着它们是VAL的一部分。
  9. .env文件中定义的环境变量在容器内部不会自动显示

.pre-commit-config.yaml

在提交代码审查之前,Git钩子脚本可用于识别简单问题。我们在每次提交时运行我们的钩子,以自动指出代码中的问题,例如缺少分号、尾随空格和调试语句。通过在代码审查之前指出这些问题,这允许代码审查者专注于变更的体系结构,同时不会浪费时间与琐碎的样式挑剔。

.prettierignore

https://prettier.io/docs/en/index.html

代码自动格式化

.editorconfig

. EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs. The EditorConfig project consists of a file format for defining coding styles and a collection of text editor plugins that enable editors to read the file format and adhere to defined styles. EditorConfig files are easily readable and they work nicely with version control systems.
. https://editorconfig.org/#file-location

  • EditorConfig 有助于为跨各种编辑器和 IDE 处理同一项目的多个开发人员保持一致的编码风格,例如下边的demo,Python 和 JavaScript 文件设置行尾和缩进样式的示例文件
  • 文件放在项目的跟目录下,很多的ide都默认支持,不默认支持的也有对应的插件
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8

# 4 space indentation
[*.py]
indent_style = space
indent_size = 4

# Tab indentation (no size specified)
[Makefile]
indent_style = tab

# Indentation override for all JS under lib directory
[lib/**.js]
indent_style = space
indent_size = 2

# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2

配置参数说明

version: '3.7' # 指定 compose 文件的版本
services: # 定义所有的 service 信息, services 下面的第一级别的 key 既是一个 service 的名称
  aaa: #服务aaa
    build: # 与image二选一,指定包含构建上下文的路径, 或作为一个对象,该对象具有 context 和指定的 dockerfile 文件以及 args 参数值
      context: .               # context: 指定 Dockerfile 文件所在的路径
      dockerfile: Dockerfile            # dockerfile: 指定 context 指定的目录下面的 Dockerfile 的名称(默认为 Dockerfile)
      args: # args: Dockerfile 在 build 过程中需要的参数 (等同于 docker container build --build-arg 的作用)
        JAR_FILE: service.jar
      cache_from:            # v3.2中新增的参数, 指定缓存的镜像列表 (等同于 docker container build --cache_from 的作用)
      labels:                # v3.3中新增的参数, 设置镜像的元数据 (等同于 docker container build --labels 的作用)
      shm_size:              # v3.5中新增的参数, 设置容器 /dev/shm 分区的大小 (等同于 docker container build --shm-size 的作用)
    #ports:
    #  - "80:80"
    #  - "443:443"
    ports: # 建立宿主机与容器间的端口映射关系,上面是短语法写法,下面是长语法写法
      - target: 80     # 容器端口
        published: 80  # 宿主机端口
        protocol: tcp  # 协议类型
        mode: host     # host在每个节点上发布主机端口,ingress 对于集群模式端口进行负载均衡
      - target: 443
        published: 443
        protocol: tcp
        mode: host
    command:               # 覆盖容器启动后默认执行的命令, 支持 shell 格式和 [] 格式
    configs:               # 不知道怎么用
    cgroup_parent:         # 为容器指定父 cgroup 组,意味着将继承该组的资源限制。
    container_name:        # 指定容器的名称 (等同于 docker run --name 的作用)
    deploy: # v3 版本以上, 指定与部署和运行服务相关的配置, deploy 部分是 docker stack 使用的, docker stack 依赖 docker swarm
      endpoint_mode: vip      # v3.3 版本中新增的功能, 指定服务暴露的方式
      #      vip                  # Docker 为该服务分配了一个虚拟 IP(VIP), 作为客户端的访问服务的地址
      #      dnsrr               # DNS轮询, Docker 为该服务设置 DNS 条目, 使得服务名称的 DNS 查询返回一个 IP 地址列表, 客户端直接访问其中的一个地址
      labels:                # 指定服务的标签,这些标签仅在服务上设置
      mode: replicated                  # 指定 deploy 的模式
      #      global              # 每个集群节点都只有一个容器
      #      replicated           # 用户可以指定集群中容器的数量(默认)
      placement:
        constraints:
          - node.role==manager             # 不知道怎么用
      replicas: 1              # deploy 的 mode 为 replicated 时, 指定容器副本的数量
      resources: # 资源限制
        limits: # 设置容器的资源限制
          cpus: "0.5"           # 设置该容器最多只能使用 50% 的 CPU
          memory: 50M           # 设置该容器最多只能使用 50M 的内存空间
        reservations: # 设置为容器预留的系统资源(随时可用)
          cpus: "0.2"           # 为该容器保留 20% 的 CPU
          memory: 20M           # 为该容器保留 20M 的内存空间
      restart_policy: # 定义容器重启策略, 用于代替 restart 参数
        condition: on-failure             # 定义容器重启策略(接受三个参数)
        #          none:                    # 不尝试重启
        #          on-failure:              # 只有当容器内部应用程序出现问题才会重启
        #          any  :                   # 无论如何都会尝试重启(默认)
        delay: 10s                  # 尝试重启的间隔时间(默认为 0s)
        max_attempts: 6           # 尝试重启次数(默认一直尝试重启)
        window: 120s              # 检查重启是否成功之前的等待时间(即如果容器启动了, 隔多少秒之后去检测容器是否正常, 默认 0s)
      update_config: # 用于配置滚动更新配置
        parallelism: 1          # 一次性更新的容器数量
        delay: 10s                 # 更新一组容器之间的间隔时间
        order: stop-first                 # v3.4 版本中新增的参数, 回滚期间的操作顺序
        #      stop-first            #旧任务在启动新任务之前停止(默认)
        #      start-first           #首先启动新任务, 并且正在运行的任务暂时重叠
        failure_action: continue       # 定义更新失败的策略
        #      continue              # 继续更新
        #      rollback              # 回滚更新
        #      pause                 # 暂停更新(默认)
        #      monitor               # 每次更新后的持续时间以监视更新是否失败(单位: ns|us|ms|s|m|h) (默认为0)
        max_failure_ratio: 0     # 回滚期间容忍的失败率(默认值为0)
      rollback_config: # v3.7 版本中新增的参数, 用于定义在 update_config 更新失败的回滚策略
        parallelism: 1         # 一次回滚的容器数, 如果设置为0, 则所有容器同时回滚
        delay: 0           # 每个组回滚之间的时间间隔(默认为0)
        failure_action: continue # 定义回滚失败的策略
        #          continue             # 继续回滚
        #          pause             # 暂停回滚
        monitor: 10s           # 每次回滚任务后的持续时间以监视失败(单位: ns|us|ms|s|m|h) (默认为0)
        max_failure_ratio: 0     # 回滚期间容忍的失败率(默认值0)
        order: stop-first            # 回滚期间的操作顺序
    #          stop-first            # 旧任务在启动新任务之前停止(默认)
    #          start-first            # 首先启动新任务, 并且正在运行的任务暂时重叠
    devices:             # 指定设备映射列表 (等同于 docker run --device 的作用)
    depends_on: #依赖容器
      - db
      - redis
    dns:                 # 设置 DNS 地址(等同于 docker run --dns 的作用)
    dns_search:           # 设置 DNS 搜索域(等同于 docker run --dns-search 的作用)
    tmpfs:               # v2 版本以上, 挂载目录到容器中, 作为容器的临时文件系统(等同于 docker run --tmpfs 的作用, 在使用 swarm 部署时将忽略该选项)
    entrypoint:          # 覆盖容器的默认 entrypoint 指令 (等同于 docker run --entrypoint 的作用)
    env_file: # 从指定文件中读取变量设置为容器中的环境变量, 可以是单个值或者一个文件列表, 如果多个文件中的变量重名则后面的变量覆盖前面的变量, environment 的值覆盖 env_file 的值
      RACK_ENV=development
    volumes: #  定义容器和宿主机的数据卷映射关系
      - "/u01:/u01"   # 映射容器内的 /u01 到宿主机的 /u01目录
    environment: # 设置环境变量, environment 的值可以覆盖 env_file 的值 (等同于 docker run --env 的作用)
      - TZ=Asia/Shanghai
      - PORT_TO_EXPOSE=80
      - LOG_PATH=/opt/proj/logs
      - PROFILES_ACTIVE=prod

    expose:              # 暴露端口, 但是不能和宿主机建立映射关系, 类似于 Dockerfile 的 EXPOSE 指令
    external_links:      # 连接不在 docker-compose.yml 中定义的容器或者不在 compose 管理的容器(docker run 启动的容器, 在 v3 版本中使用 swarm 部署时将忽略该选项)
    extra_hosts:         # 添加 host 记录到容器中的 /etc/hosts 中 (等同于 docker run --add-host 的作用)
    healthcheck: # v2.1 以上版本, 定义容器健康状态检查, 类似于 Dockerfile 的 HEALTHCHECK 指令
      test: NONE # 检查容器检查状态的命令, 该选项必须是一个字符串或者列表, 第一项必须是 NONE, CMD 或 CMD-SHELL, 如果其是一个字符串则相当于 CMD-SHELL 加该字符串
      #        NONE                  # 禁用容器的健康状态检测
      #        CMD                   # test: ["CMD", "curl", "-f", "http://localhost"]
      #        CMD-SHELL             # test: ["CMD-SHELL", "curl -f http://localhost || exit 1"] 或者 test: curl -f https://localhost || exit 1
      interval: 1m30s       # 每次检查之间的间隔时间
      timeout: 10s          # 运行命令的超时时间
      retries: 3            # 重试次数
      start_period: 40s     # v3.4 以上新增的选项, 定义容器启动时间间隔
      disable: true         # true 或 false, 表示是否禁用健康状态检测和 test: NONE 相同
    image:              # 指定 docker 镜像, 可以是远程仓库镜像、本地镜像
    init:               # v3.7 中新增的参数, true 或 false 表示是否在容器中运行一个 init, 它接收信号并传递给进程
    isolation:            # 隔离容器技术, 在 Linux 中仅支持 default 值
    labels:             # 使用 Docker 标签将元数据添加到容器, 与 Dockerfile 中的 LABELS 类似
    links:              # 链接到其它服务中的容器, 该选项是 docker 历史遗留的选项, 目前已被用户自定义网络名称空间取代, 最终有可能被废弃 (在使用 swarm 部署时将忽略该选项)
    logging: # 设置容器日志服务
      driver:              # 指定日志记录驱动程序, 默认 json-file (等同于 docker run --log-driver 的作用)
      options: # 指定日志的相关参数 (等同于 docker run --log-opt 的作用)
        max-size:             # 设置单个日志文件的大小, 当到达这个值后会进行日志滚动操作
        max-file:            # 日志文件保留的数量
    network_mode:       # 指定网络模式 (等同于 docker run --net 的作用, 在使用 swarm 部署时将忽略该选项)
networks: # 将容器加入指定网络 (等同于 docker network connect 的作用), networks 可以位于 compose 文件顶级键和 services 键的二级键
  aliases:              # 同一网络上的容器可以使用服务名称或别名连接到其中一个服务的容器
  ipv4_address          # IP V4 格式
  ipv6_address          # IP V6 格式

实例配置1

version: '3.9'
services:
  pms-tsssd-service:
    build:
      context: .
      args:
        JAR_FILE: servsssisce.jar
      dockerfile: Dockerfile
    image: pms-td-ssssservice:1.0.0
    restart: always
    ports:
      - "9199:80"
    environment:
      - TZ=Asia/Shanghai
      - PORT_TO_EXPOSE=80
      - LOG_PATH=/opt/proj/logs
      - PROFILES_ACTIVE=test
    volumes:
     ## - /opt/pro/pms-td-service.jar:/home/admin/service.jar
      - /Users/yuan/Desktop/nc/pms-td-service.jar:/home/admin/service.jar
      - /Users/yuan/Desktop/nc/logs:/opt/proj/logs
     # - /opt/pe/data/logs:/opt/proj/logs
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.role==manager
      resources:
        limits:
          cpus: '2'
          memory: 4096M
        # reservations:
        #   cpus: '2'
        #   memory: 1024M
      update_config:
        parallelism: 1
        delay: 10s
        order: stop-first
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 6
        window: 120s
# networks:
#   host:
#     external: true
#   default:
#     external:
#       name: pldds_nctransfer

实例配置2


version: '3.7'   # 版本必须3.0及以上,否则无法使用docker-stack 运行
services: # 定义 service 信息
  emcs-nginx:
    image: "***/nginx:test"   # 使用指定的 docker 镜像
    #ports:
    #  - "80:80"
    #  - "443:443"
    ports: # 建立宿主机与容器间的端口映射关系,上面是短语法写法,下面是长语法写法
      - target: 80     # 容器端口
        published: 80  # 宿主机端口
        protocol: tcp  # 协议类型
        mode: host     # host在每个节点上发布主机端口,ingress 对于集群模式端口进行负载均衡
      - target: 443
        published: 443
        protocol: tcp
        mode: host
    volumes: #  定义容器和宿主机的数据卷映射关系
      - "/u01:/u01"   # 映射容器内的 /u01 到宿主机的 /u01目录
    environment: # 设置环境变量
      TZ: Asia/Shanghai   #  设置时区为上海
    deploy: # 指定与部署和运行服务相关的配置, deploy部分是docker stack使用的, docker stack依赖docker swarm
      mode: replicated  # 指定模式:global每个集群节点都只有一个容器,
      # replicated用户可以指定集群中容器的数量(默认)
      replicas: 1  # deploy的mode为 replicated 时, 指定容器副本的数量
      update_config: #  用于配置滚动更新的配置
        parallelism: 1 # 一次性更新的容器数量
        delay: 10s     # 更新一组容器之间的间隔10s
        order: stop-first  # 指定回滚期间的操作顺序:stop-first旧任务在启动新任务之前停止(默认),
        # start-first首先启动新任务, 并且正在运行的任务暂时重叠
      restart_policy: # 定义容器重启策略, 用于代替 restart 参数
        condition: on-failure   # 定义容器重启策略(接受三个参数):
        # none不尝试重启;any无论如何都会尝试重启(默认)
        # on-failure只有当容器内部应用程序出现问题才会重启

  emcs-front: #  第二个服务
    image: "***/front"
    volumes:
      - "/u01/log:/u01/log"
    environment:
      TZ: Asia/Shanghai
    deploy:
      mode: replicated
      replicas: 1
      update_config:
        parallelism: 1
        delay: 20s
        order: stop-first
      restart_policy:
        condition: on-failure