我们有一个firehose将记录发送到Elasticsearch Service集群。我们的集群已经填满,一些记录未通过S3。 https://docs.aws.amazon.com/firehose/latest/dev/basic-deliver.html#retry处的文档表明失败的记录可用于回填:"跳过的文档将传递到elasticsearch_failed /文件夹中的S3存储桶,您可以将其用于手动回填"但我还没有找到任何关于如何实现这一目标的文件。
查看记录,它们似乎是包含JSON blob的文本文件的gzip文件,其中包含" rawData"包含我们发送给firehose的原始记录的base64编码字符串的字段。
是否有现有工具可以处理这些来自S3的gzip文件,将其分解并重新提交记录?文档暗示您可以手动回填"它是一个非常标准化的流程,所以我的假设是有人之前做过这个,但我还没有找到方法。
答案 0 :(得分:1)
遇到相同的问题,修改了上面的脚本以将失败的文档(使用403)回填到现有的Elasticsearch实例
import boto3
import json
import base64
import logger
import requests
s3_client = boto3.client('s3', region_name="xx-xx-x", aws_access_key_id="xxxx", aws_secret_access_key="xxxx")
s3keys = s3_client.list_objects(Bucket="bucketname", Prefix='path/to/folder/file')
for s3key in s3keys['Contents']:
print(s3key['Key'])
file = s3_client.get_object(Bucket="bucketname", Key=s3key['Key'])
text = file['Body'].read().decode("utf-8")
failure_cases = list(map(lambda x: json.loads(x), filter(None, text.split('\n'))))
for case in failure_cases:
data = base64.b64decode(case['rawData'])
esid = case['esDocumentId']
esIndexName = case['esIndexName']
doc = data.decode('utf-8')
url = ("https://es-domain-name/%s/_doc/%s" %(esIndexName, esid ))
headers = {"content-type": "application/json", "Accept-Charset": "UTF-8"}
if case['errorCode'] == '403':
try:
print(case['errorCode'])
r = requests.post(url, data=doc, headers=headers, auth=('user', 'password'))
response = r.json()
print(response)
except:
pass
答案 1 :(得分:0)
我想手动回填意味着使用一个AWS开发工具包将文档再次发送到Elasticsearch中。 python中的一个示例(使用boto3),该示例从S3读取故障文件并将其中的文档发送到Elasticsearch:
es_client = boto3.client('es', region_name=REGION, aws_access_key_id=ACCESS_KEY_ID, aws_secret_access_key=SECRET_ACCESS_KEY)
s3_client = boto3.client('s3', region_name=REGION, aws_access_key_id=ACCESS_KEY_ID, aws_secret_access_key=SECRET_ACCESS_KEY)
file = s3_client.get_object(Bucket=bucket, Key=key)
text = file['Body'].read().decode("utf-8")
failure_cases = list(map(lambda x: json.loads(x), filter(None, text.split('\n'))))
for case in failure_cases:
try:
data = base64.b64decode(case['rawData'])
es_instance.create(index=case['esIndexName'], id=case['esDocumentId'], body=data)
logger.debug("Successfully sent {}".format(case['esDocumentId']))
except RequestError:
logger.info("Retry failed for Document ID {}\nReason: {}"
.format(case['esDocumentId'], case['errorMessage']))