我想在我的Cassandra容器的开头创建键空间和列族。
我在docker-compose.yml
文件中尝试了以下内容:
# shortened for clarity
cassandra:
hostname: my-cassandra
image: my/cassandra:latest
command: "cqlsh -f init-database.cql"
图片my/cassandra:latest
在init-database.cql
中包含/
。但这似乎不起作用。
有没有办法让这种情况发生?
答案 0 :(得分:8)
我们最近试图解决Cassandra参考应用程序KillrVideo中的类似问题。我们正在使用Docker Compose来启动包含DataStax Enterprise(即Cassandra)节点的应用程序所需的环境。我们希望该节点在第一次开始安装CQL架构时进行一些引导(使用cqlsh
来运行.cql
文件中的语句,就像您尝试这样做一样)。基本上我们采用的方法是为Docker入口点编写一个shell脚本:
cqlsh -f
运行一些CQL语句并初始化架构。我们只是使用文件的存在来指示节点是否已经被引导并在启动时检查以确定我们是否需要执行上述逻辑或者只是正常启动它。您可以在killrvideo-dse-docker repository on GitHub。
中查看结果这种方法有一点需要注意。这对我们很有用,因为在我们的参考应用程序中,我们只是在单个节点上旋转(即我们不创建具有多个节点的集群)。如果您正在运行多个节点,那么您可能希望确保只有一个节点执行引导以创建架构,因为同时修改架构的多个客户端可能会导致某些节点群集问题。 (这is a known issue并希望在某些时候得到解决。)
答案 1 :(得分:4)
我也在寻找这个问题的解决方案,这就是我实现该问题的方法。
在这里,Cassandra的第二个实例具有一个带有 schema.cql 的卷,并运行CQLSH命令
我的版本 ,这样我们就可以摆脱 sleep 命令
version: '2.2'
services:
cassandra:
image: cassandra:3.11.2
container_name: cassandra
ports:
- "9042:9042"
environment:
- "MAX_HEAP_SIZE=256M"
- "HEAP_NEWSIZE=128M"
restart: always
volumes:
- ./out/cassandra_data:/var/lib/cassandra
healthcheck:
test: ["CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces"]
interval: 15s
timeout: 10s
retries: 10
cassandra-load-keyspace:
container_name: cassandra-load-keyspace
image: cassandra:3.11.2
depends_on:
cassandra:
condition: service_healthy
volumes:
- ./src/main/resources/cassandra_schema.cql:/schema.cql
command: /bin/bash -c "echo loading cassandra keyspace && cqlsh cassandra -f /schema.cql"
NetFlix 使用 sleep
的版本version: '3.5'
services:
cassandra:
image: cassandra:latest
container_name: cassandra
ports:
- "9042:9042"
environment:
- "MAX_HEAP_SIZE=256M"
- "HEAP_NEWSIZE=128M"
restart: always
volumes:
- ./out/cassandra_data:/var/lib/cassandra
cassandra-load-keyspace:
container_name: cassandra-load-keyspace
image: cassandra:latest
depends_on:
- cassandra
volumes:
- ./src/main/resources/cassandra_schema.cql:/schema.cql
command: /bin/bash -c "sleep 60 && echo loading cassandra keyspace && cqlsh cassandra -f /schema.cql"
我在Netflix Repos之一的
处找到了这种方式答案 2 :(得分:2)
我通过修补cassandra的docker-entrypoint.sh
解决了这个问题,因此它将在启动时执行sh
中的cql
和/docker-entrypoint-initdb.d
文件。这类似于MySQL docker容器的工作方式。
基本上,我在docker-entrypoint.sh
的末尾(紧接在最后一行exec "$@"
的前面)添加了一个小脚本,一旦cassandra启动,它将运行cql脚本。简化的版本是:
INIT_DIR=docker-entrypoint-initdb.d
# this whole block will execute in the background
(
cd $INIT_DIR
# wait for cassandra to be ready
while ! cqlsh -e 'describe cluster' > /dev/null 2>&1; do sleep 6; done
echo "$0: Cassandra cluster ready: executing cql scripts found in $INIT_DIR"
# find and execute cql scripts, in name order
for f in $(find . -type f -name "*.cql" -print | sort); do
echo "$0: running $f"
cqlsh -f "$f"
echo "$0: $f executed"
done
) &
此解决方案适用于所有cassandra版本(至少在撰写本文时为3.11)。
因此,您只需要构建并使用此cassandra映像版本,然后使用docker-compose卷将适当的初始化脚本添加到容器中即可。
具有更强大入口点修补程序(和示例)的完整要领可用。here。