导语

为了满足用户日益增长的日志存储大小,不影响用户的写入和查询性能。满足不同用户写入流量。同时用户日志长期保存,日志存储比较占用空间和成本。ES集群规格配置高,消耗资源和成本。我们基于Go语言设计了一个多用户多ES集群,日志备份到cos节省成本的方案。本篇实践基于Go语言编程。

索引设计

为了防止单个索引不断增加。影响ES集群查询写入性能,ES 集群的索引设计主要采取如下方式:

  1. 租户分离:将索引按照租户进行分离,避免不同租户之间的数据混淆,提高 ES 集群的数据安全性和隔离性。
  2. 按月分割:将索引按照每个月进行分割,避免单个索引过大,提高 ES 集群的查询性能。
  3. 按大小固定rollover:将索引按照固定大小进行rollover,自动分索引,避免单个索引过大,进行索引管理,提升集群性能,便于集群运维。

ES集群设计

为了避免 ES 集群出现单点问题,以及配置不断增加带来的运维风险, ES 集群设计时主要通过将不同规格的用户日志写入不同配置的ES集群,并且使用自动扩容技术来实现集群的可扩展性。

具体来说,可以将用户日志按照不同的规格(例如不同的数据量、访问频率等)进行分类,然后将不同规格的用户日志写入不同配置的ES集群中。例如,可以使用较小的ES集群来处理低频访问的用户日志,而使用较大的ES集群来处理高频访问的用户日志。

ES数据备份到COS

创建备份流程

在 ES 备份流程中,为了保证备份的正确性和完整性,可以按照如下步骤执行:

创建一个仓库来存储备份数据。

创建一个快照任务,将ES中的数据备份到指定的仓库中。在创建快照任务时,需要指定备份的索引、仓库、快照名称等参数,并设置备份的间隔时间和保留时间等策略。

查询快照任务是否完成。ES提供了API接口来查询快照的状态和进度,可以根据查询结果来判断备份是否已经完成。

调用 COS 提供的压缩函数对备份数据进行压缩,以减小备份数据所占用的存储空间。

通过备份和压缩到 COS 可以将 ES 存储的数据缩小到 1/4 的大小,并且通过 COS 的海量分布式存储服务,可以提供低成本、弹性的云存储服务。

各项步骤对应的代码逻辑如下:

1.创建仓库

func CreateRepository(Repository string, cosappid uint64, appId uint64, accessKeyId string, AccessKeySecret string, buckets string, region string) error {
service := Client.SnapshotCreateRepository(Repository)
service = service.Type("cos").Settings(map[string]interface{}{
"app_id": strconv.FormatUint(cosappid, 10),
"access_key_id": accessKeyId,
"access_key_secret": AccessKeySecret,
"bucket": buckets,
"region": region,
"compress": true,
"chunk_size": "500mb",
"base_path": "backup/" + strconv.FormatUint(appId, 10) + "/" + Repository,
})
if err := service.Validate(); err != nil {
logger.Errorf("SnapshotCreateRepository failed,app_id=%v,Repository=%s ", appId, Repository)
return err
}
_, err := service.Do(context.Background())
if err != nil {
logger.Errorf("SnapshotGetRepository do failed,app_id=%v,Repository=%s ", appId, Repository)
}
return nil
}

2.创建快照

func SnapshotCreate(Repository string, Snapshot string, appId uint64, indexname string) error {
type IndicesSetting struct {
Indices string `json:"indices"`
}
e1 := IndicesSetting{indexname}
_, err := Client.SnapshotCreate(Repository, Snapshot).WaitForCompletion(false).BodyJson(e1).Pretty(true).Do(context.Background())
if err != nil {
logger.Errorf("SnapshotCreate failed,app_id=%v,Repository=%s Snapshot=%s ", appId, Repository, Snapshot)
return err
}
return nil
}

3.查询快照状态

func SnapshotGet(Repository string, Snapshot string, appId uint64) (*elastic.SnapshotGetResponse, error) {
service, err := Client.SnapshotGet(Repository).
Snapshot(Snapshot).
IgnoreUnavailable(true).
Verbose(true).Pretty(true).Do(context.Background())
if err != nil {
logger.Errorf("SnapshotGet failed,app_id=%v,Repository=%s Snapshot=%s ", appId, Repository, Snapshot)
return nil, err
} /*
判断任务是否完成
if service.Snapshots[0].State != "true" { }*/
return service, nil
}

4.创建压缩任务

压缩任务是腾讯云对象存储 COS 提供的压缩API,需要先创建好压缩函数:

创建压缩函数参考如下:

https://cloud.tencent.com/document/product/436/58578

首先获取压缩文件,然后调用压缩函数进行压缩。获取压缩文件代码逻辑如下:

var coslist []string
coslist, err = ext.GetCosDirCosKeyList(backupcosfile, cosClient)
if err != nil {
logger.Errorx("GetCosDirCosKeyList error", err)
return err
}
scfClient, err := ext.GetScfClient(config.One.Backup.Region, true)
if err != nil {
logger.Errorx("GetScfClient error", err)
return err
}
var invokeRequestId string
invokeRequestId, err = ext.ScfCompression(scfClient, coslist, backupcosfilezip, config.One.Backup.ZipFunctionName)
if err != nil {
logger.Errorx("GetScfClient error", err)
return err
}

压缩函数模版如下:

func ScfCompression(scfCleint *scf.Client, cosKeyList []string, compressKey string, functionname string) (functionRequestId string, err error) {
request := scf.NewInvokeRequest() request.FunctionName = common.StringPtr(functionname)
scfSourceList := make([]ScfCompressionSource, 0, 1)
for _, cosKey := range cosKeyList {
scfSource := ScfCompressionSource{
Url: fmt.Sprintf("https://%s.cos-internal.%s.tencentcos.cn/%s", config.One.Cos.GuangzhouCosBucket, config.One.Cos.CosRegion, cosKey),
}
scfSourceList = append(scfSourceList, scfSource)
}
scfClientContext := ScfCompressionClientContext{
Bucket: config.One.Cos.GuangzhouCosBucket,
Region: config.One.Cos.CosRegion,
Key: compressKey,
Flatten: false,
SourceList: scfSourceList,
}
clientContext, err := json.Marshal(scfClientContext)
if err != nil {
logger.Errorx("ScfCompression Marshal", err)
return "", err
}
request.ClientContext = common.StringPtr(string(clientContext))
//fmt.Println(string(clientContext)) response, err := scfCleint.Invoke(request)
if _, ok := err.(*tencentError.TencentCloudSDKError); ok {
logger.Errorx("An API error has returned:", err)
return "", err
}
if err != nil {
logger.Errorx("scfCleint.Invoke", err)
return "", err
}
logger.Debugf("%s", response.ToJsonString())
return *response.Response.Result.FunctionRequestId, nil
}

COS数据恢复到ES

创建恢复流程

恢复流程是备份流程的逆向流程,主要包括如下步骤:

创建COS解压缩函数

创建恢复任务

查询恢复任务是否完成

完成恢复

  1. COS 解压缩任务

    解压缩任务是腾讯云对象存储 COS 提供的解压缩函数模板,需要先创建好解压缩函数:

创建解压函数参考如下:

https://cloud.tencent.com/document/product/436/67101

解压缩函数模板如下:

func ScfDecompression(scfCleint *scf.Client, compressKey string, cosTargetPrefix string, functionname string) (functionRequestId string, err error) {
logger.Debug("ScfDecompression" + compressKey)
request := scf.NewInvokeRequest() request.FunctionName = common.StringPtr(functionname)
//key := fmt.Sprintf("https://%s.cos-internal.ap-guangzhou.myqcloud.com/%s", config.One.Cos.GuangzhouCosBucket, compressKey)
scfClientContext := ScfDecompressionClientContext{
Bucket: config.One.Cos.GuangzhouCosBucket,
Region: config.One.Cos.CosRegion,
Key: compressKey,
TargetBucket: config.One.Cos.GuangzhouCosBucket,
TargetRegion: config.One.Cos.CosRegion,
TargetPrefix: cosTargetPrefix,
}
clientContext, err := json.Marshal(scfClientContext)
if err != nil {
logger.Errorx("ScfCompression Marshal", err)
return "", err
}
request.ClientContext = common.StringPtr(string(clientContext))
//fmt.Println(string(clientContext)) response, err := scfCleint.Invoke(request)
if _, ok := err.(*tencentError.TencentCloudSDKError); ok {
logger.Errorx("An API error has returned:", err)
return "", err
}
if err != nil {
logger.Errorx("scfCleint.Invoke", err)
return "", err
}
logger.Debugf("%s", response.ToJsonString())
return *response.Response.Result.FunctionRequestId, nil
}
  1. 完成解压缩后,创建恢复任务
func SnapshotRestore(Repository string, Snapshot string, appId uint64, oldIndexName string, newIndexName string) error {
_, err := Client.SnapshotRestore(Repository, Snapshot).RenamePattern(oldIndexName).
RenameReplacement(newIndexName).Indices(oldIndexName).WaitForCompletion(false).Pretty(true).Do(context.Background())
if err != nil {
logger.Errorf("SnapshotRestore failed,app_id=%v,Repository=%s Snapshot=%s ", appId, Repository, Snapshot)
return err
}
return nil
}

ES日志存储以及备份压缩到COS的更多相关文章

  1. Es+kafka搭建日志存储查询系统(设计)

    现在使用的比较常用的日志分析系统有Splunk和Elk,Splunk功能齐全,处理能力强,但是是商用项目,而且收费高.Elk则是Splunk项目的一个开源实现,Elk是ElasticSearch(Es ...

  2. linux下的nginx日志自动备份压缩--日志切割机

    部署完毕nginx之后,发现自己的/var/log/nginx/*log的日志不会压缩,一直都是一个文本写日志, 时间久了,日志文件内存过于增加,将会导致在日志添加过程效率降低,延长时间. 默认安装的 ...

  3. 【RMAN】使用RMAN的 Compressed Backupsets备份压缩技术 (转载)

    1.Oracle参考文档中关于RMAN备份压缩的描述1)关于如何通过调整RMAN参数启用取消备份压缩功能http://download.oracle.com/docs/cd/B19306_01/bac ...

  4. MySQL日志管理、备份、恢复

    目录: 一.MySQL 日志管理 二.数据库备份的重要性与分类 三.常见的备份方法 四.MySQL完全备份 五.数据库完全备份分类 六.MySQL增量备份 七.MySQL数据库增量恢复 八.MySQL ...

  5. MongoDB 如何实现备份压缩

    背景及原理 数据库的备份是灾难恢复的最后一道屏障,不管什么类型的数据库都需要设置数据库备份,MongoDB也不例外.MongoDB 3.0 后 ,数据库可以采用Wiredtiger存储引擎后(3.2 ...

  6. linux系统各种日志存储路径和详细介绍

    Linux常见的日志文件详述如下1./var/log/boot.log(自检过程)2./var/log/cron (crontab守护进程crond所派生的子进程的动作)3./var/log/mail ...

  7. 自定义log4j的appender写es日志

    本篇和大家分享的是自定义log4j的appender,用es来记录日志并且通过kibana浏览es记录:就目前互联网或者一些中大型公司通常会用到第三方组合elk,其主要用写数据到es中,然后通过可视化 ...

  8. 关于拦截器实现日志存储到db的代码调试

    问题是,原来系统有日志操作的代码,但日志最终没有存到数据库. xml中拦截器配置: <mvc:interceptor> <mvc:mapping path="/admin/ ...

  9. Linux下添加shell脚本使得nginx日志每天定时切割压缩

    Linux下添加shell脚本使得nginx日志每天定时切割压缩一 简介 对于nginx的日志文件,特别是access日志,如果我们不做任何处理的话,最后这个文件将会变得非常庞大 这时,无论是出现异常 ...

  10. sql server数据库备份压缩拷贝实例

    --数据库备份压缩拷贝实例:前提要安装RAR压缩软件--声明变量declare @day varchar(10),@dbname varchar(20),@filename varchar(100), ...

随机推荐

  1. C语言中链表与队列

    https://www.cnblogs.com/lanhaicode/p/10432004.html

  2. 掷骰子【普通线性DP】【转移方程可以优化为矩阵快速幂】

    掷骰子 思路 可以先定义一个状态f[i] [j]: 前i个骰子,最后一个面是j的方法数, 肯定超时,然鹅可以混一些分,代码如下 for(int i=1;i<=6;i++) f[0][i]=1; ...

  3. 2.20 Q_Learning 和Sarsa 的区别

    二者都是基于Qtable的算法,其中Qlearning属于off-policy,Sarsa属于on-policy. 算法伪代码: 二者主要区别是更新Qtable的方式不同:

  4. IT工具知识-13: 如何编辑SVG图像文件并转换为ICO图标文件

    使用背景 最近做了个小软件, 但是桌面快捷方式图标不好看, 于是想着找个好看点的图标, 但是网上搜了一圈, 发现好看的几乎都要钱, 常用的话, 付费倒也不反感, 但是, 仅仅只用那么一两次, 为这个付 ...

  5. springboot项目导出excel实现

    参见:https://blog.csdn.net/duli_0105/article/details/102809936

  6. 关于uni-app开发的微信小程序顶部导航条机型适配

    背景: 小程序顶部导航栏那里的样式和功能都是小程序自带的,当我们在pages.json里的pages里新加一条页面配置时,会自动生成一个带顶部导航栏的空白页面,当然也可以再配置里"navig ...

  7. 【Python】validator进行数据校验

    https://pypi.org/project/validator.py/ 校验参数必要性 from validator import Required, In, InstanceOf, Lengt ...

  8. 如果摄像头不支持Web Socket,猿大师播放器还能在网页中播放RTSP流吗?

    问: 我们的情况比较复杂,摄像头设备品牌和数量都比较多,分布在全国各地都有,地点分布比较广泛,有的甚至是比较老的型号,如果摄像头设备不支持Web Socket,猿大师播放器还可以在网页中播放RTSP流 ...

  9. mysql zip安装步骤

    1. 官网下载社区版 https://dev.mysql.com/downloads/mysql/ 版本5.7或者8.0 2. 解压到指定的目录. 3.创建my.ini文件,编辑内容: [mysqld ...

  10. sqli-labs搭建

    今天使用 phpstudy 搭建了 sqli-labs 练习 SQL 注入平台,其中遇到了两个问题. phpstudy phpstudy 中集成了 Apache.Nginx.PHP.Mysql.php ...