7

我正在尝试使用从脚本调用的 Python 客户端https://github.com/elastic/elasticsearch-py(也在容器中运行)来索引容器化的 Elasticsearch 数据库。

通过查看现有的代码,这似乎docker-compose是一个有用的工具,可以用于我的目的。我的目录结构是

docker-compose.yml
indexer/
- Dockerfile
- indexer.py
- requirements.txt
elasticsearch/
- Dockerfile

我的docker-compose.yml阅读

version: '3'

services:
  elasticsearch:
    build: elasticsearch/
    ports: 
      - 9200:9200
    networks:
      - deploy_network
    container_name: elasticsearch

  indexer:
    build: indexer/
    depends_on:
      - elasticsearch
    networks:
      - deploy_network
    container_name: indexer
  
networks:
  deploy_network:
    driver: bridge

indexer.py

from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
    
es = Elasticsearch(hosts=[{"host":'elasticsearch'}]) # what should I put here?

actions = [
    {
    '_index' : 'test',
    '_type' : 'content',
    '_id' : str(item['id']),
    '_source' : item,
    }
for item in [{'id': 1, 'foo': 'bar'}, {'id': 2, 'foo': 'spam'}]
]
    
# create index
print("Indexing Elasticsearch db... (please hold on)")
bulk(es, actions)
print("...done indexing :-)")

elasticsearch 服务的 Dockerfile 是

FROM docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.3
EXPOSE 9200
EXPOSE 9300

而对于索引器是

FROM python:3.6-slim
WORKDIR /app
ADD . /app
RUN pip install -r requirements.txt
ENTRYPOINT [ "python" ]
CMD [ "indexer.py" ]

包含requirements.txt只能elasticsearch用 pip 下载。

运行在https://pastebin.com/6U8maxGX ( )docker-compose run indexer处给我错误消息。就我所见,elasticsearch 已启动或运行.ConnectionRefusedError: [Errno 111] Connection refusedcurl -XGET 'http://localhost:9200/' docker ps -a

如何修改我的docker-compose.ymlindexer.py解决问题?

为了完整起见,可以在此处找到代码的 PS A(工作)版本(由以下答案通知):https ://github.com/davidefiocco/dockerized-elasticsearch-indexer 。

4

3 回答 3

11

问题是同步错误:尝试连接elasticsearch时尚未完全启动。indexer您必须添加一些重试逻辑,以确保elasticsearch在尝试对其运行查询之前它已启动并运行。像es.ping()在循环中运行直到它以指数退避成功为止的东西应该可以解决问题。

更新: Docker指令可用于实现类似的结果(即在尝试对其运行查询之前HEALTHCHECK确保它已启动并运行)。elasticsearch

于 2018-02-09T18:59:05.767 回答
2

进行更明确的@Mihai_Todor 更新,我们可以使用HEALTHCHECK(docker 1.12+),例如使用如下命令:

curl -fsSL "http://$(hostname --ip-address):9200/_cat/health?h=status" | grep -E '^green'

要使用 using 回答这个问题HEALTHCHECK

FROM python:3.6-slim

WORKDIR /app
ADD . /app
RUN pip install -r requirements.txt

HEALTHCHECK CMD curl -fsSL "http://$(hostname --ip-address):9200/_cat/health?h=status" | grep -E '^green'

ENTRYPOINT [ "python" ]
CMD [ "indexer.py" ]
于 2019-03-28T22:15:16.253 回答
0

retry用来确保 Elasticsearch 已准备好接受连接:

from retrying import retry

client = Elasticsearch()


class IndexerService:

    @staticmethod
    @retry(wait_exponential_multiplier=500, wait_exponential_max=100000)
    def init():
        MyDocumentIndex.init()

# Here we will wait until ES is ready, or 100 sec passed.
IndexerService.init()

它会尝试 500 毫秒、1 秒、2 秒、4 秒,直到 100 秒。

参考:https ://github.com/rholder/retrying

于 2019-11-30T10:06:51.937 回答