基于SCF实现批量备份Elasticsearch索引到COS

在采用ELK架构的日志应用场景中,通常我们会按天或者按小时创建索引,从而避免单个索引的数据量太大。如果我们需要对过去一段时间的老索引进行冷备份,比如通过快照备份到S3或者腾讯云的对象存储服务COS中,然后降低索引的副本数量或者直接从ES删除索引,可以采取的方式有多种。一种是手动调用ES的API,一次性备份所有的老索引到COS中,但是如果数据量较大时只使用一个快照可能因为数据传输中断而导致快照执行失败;另外一种方式是自己编写脚本,通过crontab定时执行脚本对过去某一天或几天的索引打快照,执行成功后再对其它的索引打快照;本文尝试使用SCF(腾讯云无服务器云函数)对按小时新建的索引,持续批量的打快照到COS。

实施步骤

1. 创建COS仓库

我们把快照保存到腾讯云的COS对象存储中,首先需要调用ES的API创建一个COS repository:

PUT _snapshot/cos-repo
{
    "type": "cos",
    "settings": {
        "app_id": "xxxxxxx",
        "access_key_id": "xxxxxx",
        "access_key_secret": "xxxxxxx",
        "bucket": "xxxxxx",
        "region": "ap-guangzhou",
        "compress": true,
        "chunk_size": "500mb",
        "base_path": "/"
    }
}

更详细的基于COS备份和恢复ES数据的步骤可以参考使用 COS 进行备份及恢复.

2. 创建SCF云函数

如图,基于名为"ES写入函数"的模板,创建一个新的函数:


image

点击"下一步"进入函数编辑界面,直接复制如下函数代码粘贴到编辑框,修改ES的vip和用户名密码,以及索引前缀名称等信息:

# -*- coding: utf8 -*-
import datetime
from elasticsearch import Elasticsearch

# ES集群的用户名密码信息
ESServer = Elasticsearch(["xxxx:9200"],http_auth=('elastic', 'xx'))
# 索引前缀
esPrefix = "my-index-"
# 从过去哪一天的索引开始打快照
beforeOfDay = 60

# COS仓库名称
cosRepository = "cos-repo"
# 快照名称前缀
cosSnapshotPrefix = "snapshot-"

# 临时索引名称,不需要修改
snapshotTempIndex = "temp-snapshot"
currentDate = ""

def check_or_create_snapshot():
    existed = ESServer.indices.exists(snapshotTempIndex)
    if existed == True:
        getTempDoc = ESServer.get(snapshotTempIndex, doc_type="_doc", id="1")
        print getTempDoc
        currentDate = getTempDoc["_source"]["currentDate"]
        print "current date: " + currentDate
    else:
        today = datetime.datetime.now()
        offset = datetime.timedelta(days=-beforeOfDay)
        re_date = (today + offset).strftime('%Y.%m.%d')
        currentDate = re_date

    currentSnapshot = cosSnapshotPrefix + currentDate
    params = {}
    params["ignore_unavailable"] = "true"
    getResult = ESServer.snapshot.get(cosRepository, currentSnapshot, params = params)
    snapshots = getResult["snapshots"]
    if len(snapshots) != 0:
        if snapshots[0]["state"] == "SUCCESS":
            print currentSnapshot +" executed finished!"
            newDate = getNewDate(currentDate)
            createSnapshot(newDate)
        else:
            print currentSnapshot +" is running!"
    else:
        createSnapshot(currentDate)

def createSnapshot(currentDate):
    currentSnapshot = cosSnapshotPrefix + currentDate
    body = {}
    body["indices"] = esPrefix + currentDate + "-*"
    body["ignore_unavailable"] = "true"
    body["include_global_state"] = "false"
    createResult = ESServer.snapshot.create(cosRepository, currentSnapshot,body)
    if createResult["accepted"] == True:
        print "create [" + currentSnapshot + "] success!"
        indexTempDate(currentDate)
        return
    else:
        print "create [" + currentSnapshot +"] failed!" + str(createResult)


def getNewDate(currentDate):
    dateTime_p = datetime.datetime.strptime(currentDate,'%Y.%m.%d')
    offset = datetime.timedelta(days=+1)
    re_date = (dateTime_p + offset).strftime('%Y.%m.%d')
    print "new date: "+ re_date
    return re_date

def indexTempDate(currentDate):
    indexBody ={}
    indexBody["currentDate"] = currentDate
    headers= {}
    headers["Content-Type"] = "application/json"
    indexResult = ESServer.index(index=snapshotTempIndex, doc_type="_doc", body=indexBody,id="1")
    print "index temp date success!"

def main_handler(event,context):
    check_or_create_snapshot()

image

点击"完成"即可完成云函数的创建。

上述代码的主要逻辑为:

  1. 第一次执行函数时,根据指定的beforeOfDay,确定从哪一天开始打快照,如示例中从60天前的索引开始,创建一个名为snapshot-2020.xx.xx的快照,备份的索引为my-index-2020.xx.xx-*, 也即60天前的当天创建的所有索引;同时创建一个名为temp-snapshot的临时索引,记录下"2020.xx.xx"
  2. 之后每次执行函数时会先从temp-snapshot索引中获取到当前正在执行哪一天的快照,判断快照是否执行成功,如果执行成功则进行对下一天的索引打快照,同时更新temp-snapshot索引

3. 配置云函数

创建完云函数后,需要进行配置才能使用,如下图,可以配置函数的私有网络VPC和Subnet(选择和ES相同的VPC和Subnet):


image

4. 测试云函数

配置完云函数后,可以对函数代码进行测试,保证能够正常运行;如果需要进行编辑,可以直接编辑然后点击"保存并测试":


image

5. 配置触发器

配置触发器,每5分钟执行一次函数:


image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266