21-08-08
banq
如果您尝试对正在同步的数据库表中的某些数据进行 CRUD,只需使用docker-compose up -d. 这些更改几乎会立即镜像到 Elastic。
Github存储库中找到完整的示例
本文旨在向您展示如何轻松地在 PostgreSQL 和 ElasticSearch 之间同步数据。通过同步,我的意思是每次在数据库中 CRUD 数据时,这些更改都会立即反映在 Elastic 中。
创建 Elastic 和 Kibana 服务
Kibana 是一个用于 Elastic 数据可视化的开源插件。它提供了各种数据操作工具。它还为我们提供了对 Elastic 实例进行直接查询的控制台。它类似于 GraphQL Playground(如果您曾经使用过)。
因此,我们的 docker-compose 可能如下所示:
version: '3.8' services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.13.4 container_name: elasticsearch environment: - xpack.security.enabled=false - discovery.type=single-node - bootstrap.memory_lock=true - 'ES_JAVA_OPTS=-Xms512m -Xmx512m' ulimits: memlock: soft: -1 hard: -1 ports: - '9200:9200' kibana: image: docker.elastic.co/kibana/kibana:7.13.4 depends_on: - elasticsearch ports: - '5601:5601' environment: - ELASTICSEARCH_HOSTS=http://elasticsearch:9200 |
当然,您可以只创建 Elastic。但是在 Kibana 的帮助下,您可以轻松地向 Elastic 发出请求并通过 UI 查看(也创建)数据。
PostgreSQL 服务
稍后我们需要对其进行自定义,因此无需直接在 docker-compose 文件中使用基本Image镜像。创建PostgresDockerfile并粘贴这个:
FROM postgres:13
然后将其添加到服务下的 docker-compose 文件中:
database: build: context: . dockerfile: PostgresDockerfile container_name: database ports: - '5432:5432' environment: - POSTGRES_PASSWORD=postgres |
同步
PGSync是一个可以帮助我们实现目标的工具!您可以在此处阅读更多相关信息。我们只需要Redis(因为它使用发布-订阅机制)和模式。因此,将此行添加到 docker-compose 文件中:
redis: image: 'redis:alpine' container_name: redis ports: - '6379:6379' |
这个工具是用 Python 编写的,所以我们需要创建一个 Python 容器。正如我们从文档中看到的,我们还应该更改postgresql.conf.
因此,创建目录pgsync,并PgsyncDockerfile在项目的根。
FROM python:3.7-slim WORKDIR /usr/src/app COPY ./pgsync ./ RUN chmod +x ./entrypoint.sh RUN pip install pgsync==2.1.1 RUN apt update \ && apt install -y moreutils \ && apt install -y jq \ && apt install -y wait-for-it ENTRYPOINT ["bash", "./entrypoint.sh"] |
要将额外的配置应用到 postgres 容器,我们只需创建任意数量的 sql 文件,然后将它们复制到/docker-entrypoint-initdb.d我们容器的目录中。好的!它们将在容器初始化时执行。
因此,让我们创建conf.sql以下内容:
ALTER SYSTEM SET wal_level = logical; ALTER SYSTEM SET max_replication_slots = 1; -- set this value to the number of tables you want to load into elastic |
并更改PostgresDockerfile为:
FROM postgres:13 COPY ./pgsync/conf.sql /docker-entrypoint-initdb.d/ COPY ./pgsync/populate.sql /docker-entrypoint-initdb.d/ RUN chmod a+r /docker-entrypoint-initdb.d/conf.sql RUN chmod a+r /docker-entrypoint-initdb.d/populate.sql |
好的,正如你所看到的,我们也应该有entrypoint.shin outpgsync目录。这是主文件,如果我们运行 pgsync 容器,它将被执行。
#!/usr/bin/env bash wait-for-it $PG_HOST:5432 -t 60 wait-for-it $REDIS_HOST:6379 -t 60 wait-for-it $ELASTICSEARCH_HOST:9200 -t 60 jq '.[].database = env.PG_DATABASE' schema.json | sponge schema.json bootstrap --config ./schema.json pgsync --config ./schema.json -d |
我们jq在这里使用实用程序schema根据PG_DATABASE构建阶段的 env 变量在我们的文件中动态设置数据库名称。
我们还使用wait-for-it脚本来等待我们的服务。仅depends_on在 docker-compose 文件中写入并不总是有效,相信我!
Schema文件
在pgsync目录内创建schema.json:
[ { "database": "db_name", "index": "elastic-index-name", "nodes": { "table": "table-name", "schema": "public", "columns": [] } } ] |
服务
将这些添加到 docker-compose 中:
pgsync: build: context: . dockerfile: PgsyncDockerfile container_name: pgsync environment: - PG_USER=postgres - PG_PASSWORD=postgres - PG_DATABASE=postgres - PG_HOST=database - ELASTICSEARCH_HOST=elasticsearch - REDIS_HOST=redis |
运行!
而已。只需使用docker-compose up -d. 现在,如果您尝试对正在同步的数据库表中的某些数据进行 CRUD,这些更改几乎会立即镜像到 Elastic。