在 Docker 上运行 Cassandra 并进行一些 Python 操作会返回 NoHostAvailable、ConnectionRefusedError

问题描述 投票:0回答:1

我想使用 docker 在本地创建 cassandra 数据库,并使用 python 脚本插入一些数据并打印它

有文件:

  • Dockerfile
FROM python:3.10-slim

WORKDIR /app

RUN pip install cassandra-driver

COPY init-db.cql /init-db.cql

COPY app.py /app/app.py

CMD ["python", "app.py"]

  • docker-compose.yml
version: '3'
services:
  cassandra:
    image: cassandra:latest
    container_name: cassandra
    ports:
      - "9042:9042"
    volumes:
      - ./init-db.cql:/init-db.cql
    command: ["cassandra", "-f"]

  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: app
    depends_on:
      - cassandra
    links:
      - cassandra
    volumes:
      - ./app.py:/app/app.py
  • init-db.cql
CREATE KEYSPACE IF NOT EXISTS mykeyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'};

CREATE TABLE IF NOT EXISTS mytable (
    id UUID PRIMARY KEY,
    message TEXT
);

INSERT INTO mytable (id, message) VALUES ('1',"hello i am the first");
INSERT INTO mytable (id, message) VALUES ('2',"hello i am the second");
  • 应用程序.py
from cassandra.cluster import Cluster

cluster = Cluster(['cassandra'])
session = cluster.connect('mykeyspace')

session.execute("INSERT INTO mytable (id, message) VALUES (uuid(), 'ciao mondo sono il terzo')")
session.execute("INSERT INTO mytable (id, message) VALUES (uuid(), 'ciao mondo sono il quarto')")
result = session.execute("SELECT * FROM mytable")

for row in result:
    print(row.id, row.message)

cluster.shutdown()

我执行这个命令:

  • docker 撰写构建
  • docker 组成 当我执行 compose up 时,出现以下错误:
    cassandra.cluster.NoHostAvailable: ('Unable to connect to any servers', {'172.23.0.2:9042': ConnectionRefusedError(111, "Tried connecting to [('172.23.0.2', 9042)]. Last error: Connection refused")}) 

我尝试查看文档

python docker docker-compose cassandra dockerfile
1个回答
0
投票

数据库离线

您的设置存在一些问题,但主要的一个是您的应用程序在有机会出现之前尝试连接到 Cassandra,因为主机尚不可用


当 Docker 启动一个容器时,它几乎会立即进入“运行”状态,因为容器本身正在运行,但应用程序本身仍在启动。就 Cassandra 而言,它必须像任何其他数据库一样经历初始化过程,并且可能需要几秒钟到一两分钟的时间,具体取决于您机器的规格。

Cassandra 启动需要几个步骤,包括加载配置、初始化服务器组件和健全性检查等。当所有先决步骤完成并通过后,Cassandra 最终启动在 CQL 端口上侦听客户端的服务。

您应该

添加

NoHostAvailable命令

,以便您可以确定 Cassandra 的状态以及也可以使用的依赖服务。确定 Cassandra 是否准备就绪的最简单方法是检查它是否正在使用 
healthcheck:
 监听端口 
9042
(默认)
netstat

然后可以将依赖服务配置为显式等待 Cassandra 在“健康”条件下上线:

healthcheck: test: ["CMD-SHELL", "netstat -ltn | grep -q 9042"]

无效使用
depends_on: cassandra: condition: service_healthy

对 Cassandra 容器运行 

command

无效,因为您不应该在容器的前台启动 Cassandra。

虽然看起来可行,但这并不是在 Docker 中运行 Cassandra 的正确方法。当您指定 

cassandra -f

时,它将覆盖默认启动过程,因此在这种情况下没有必要,应该从您的撰写中删除。

缺少架构

我看不到使用或访问

command

文件的任何地方,这意味着永远不会创建键空间和表。因此,当您的应用程序尝试将数据插入表中时,它将会失败,因为它不存在。

我将在下一节中推荐一个解决方案。

不需要应用程序

构建一个仅插入几行并从表中读取的应用程序是没有必要的。一个简单的选择是简单地运行 cqlsh 并执行 CQL 文件。

例如,当 Cassandra 通过 cqlsh 服务使用图像

nuvo/docker-cqlsh

在线时,让我们创建架构(在文件

init-db.cql
中)。我们希望将 CQL 文件放在 schema.cql 目录中,以便
/scripts
会自动运行它。这是一个服务定义示例:
docker-cqlsh

Cassandra 上线后 (
cqlsh: container_name: cqlsh image: nuvo/docker-cqlsh depends_on: cassandra: condition: service_healthy environment: CQLVERSION: 3.4.6 CQLSH_HOST: cassandra CQLSH_PORT: 9042 volumes: - "/path/to/schema_directory:/scripts"

),Docker 将启动

condition: service_healthy
服务,该服务执行
cqlsh
自动创建架构。
就其价值而言,大部分信息都位于 

Apache Cassandra 官方网站

上的快速入门指南中。干杯!

© www.soinside.com 2019 - 2024. All rights reserved.