etcd之日志和快照管理

2023-11-14

系列文章目录

浅谈分布式系统与一致性协议(一)
浅谈分布式系统与一致性协议(二)
浅谈分布式系统与一致性协议(三)
深入浅出之etcd
深入浅出之etcd(二)
etcd版本之v3
etcd之安全性阐述
etcd的多版本并发控制


概述

etcd对数据的持久化采用的是binlog(日志,也称为WAL,即Write-Ahead-Log)加Snapshot(快照)的方式

在计算机科学中,预写式日志(Write-Ahead-Log,WAL)是关系数据库系统中用于提供原子性和持久性(ACID中的两个特性)的一系列技术。在使用WAL系统中,所有修改在提交之前都要写入log文件中

log文件中通常包括redo信息和undo信息。假设一个程序在执行某些操作过程中机器掉电了。在重新启动时,程序可能需要直到当时执行得操作是完全成功了还是部分成功或者完全失败。如果使用了WAL,那么程序就可以检查log文件,并对突然掉电时计划执行的操作内容与实际上执行的操作内容进行比较。在这个比较的基础上,程序就可以决定是撤销已做的还是继续完成已做的操作,或者保持原样

WAL允许用in-space的方式更新数据库。另一种用来实现原子更新的方法是shadow paging,它并不是一种in-place方式。用in-place方式进行更新的主要有点是减少索引和块列表的修改。ARIES是WAL系列技术常用的算法。在文件系统中,WAL通常称为journaling。PostgreSQL也是用WAL来提供oint-in-time恢复和数据库复制特性的

etcd数据库的所有更新操作都需要先写入到binlog中,而binlog是实时写到磁盘上的,因此这样就可以保证不会丢失数据,即使机器断电,重新启动以后etcd也能通过读取并重放binlog里面的操作记录来重新建立数据库

etcd数据的高可用性和一致性是通过Raft算法实现的,Master节点会通过Raft协议向Slave节点复制binlog,Slave节点根据binlog对操作进行重放,以维持数据的多个副本的一致性。也就是说binlog不仅仅是实现数据库持久化的一种手段,其实还是实现不同副本间一致性协议的重要手段。客户端对数据库发起所有写操作都会记录在binlog中,待主节点将更新日志在集群多数节点之间完成同步后,以便内存中的数据库中应用该日志项的内容,进而完成一次客户端的写请求

数据的持久化和复制

先看个例子。例如,通过以下命令向etcd中插入一个键值对

etcdctl set /foo bar

etcd会在默认的工作目录下生成两个子目录:snap和wal。两个目录的作用说明如下:

  • snap:用于存放快照数据。etcd为了防止WAL文件过多就会创建快照,snap用于存储etcd的快照数据状态
  • wal:用于存放预写式日志,其最大的作用是记录整个数据变化的全部历程。在etcd中,所有数据的修改在提交之前,都要写入WAL中。使用WAL进行数据的存储使得etcd拥有故障快速恢复和数据回滚两个重要的功能

故障快速恢复:如果你的数据遭到颇快,就可以通过执行所有WAL中记录的修改操作,快速从原始的数据恢复到数据损坏之前的状态

数据回滚(undo)/重做(redo):因为所有的修改操作都被记录在WAL中,所以进行回滚或者重做时,只需要反响或者正向执行日志即可

etcd的日志管理

etcd提供了一个WAL日志库,日志追加等功能均有该库完成。下面让我们先看一下WAL数据结构定义

WAL数据结构

WAL数据结构定义如下:

type WAL struct{
	dir string
	dirFile *os.File
	metadata []byte
	state raftpb.HardState
	start walpb.Snapshot
	decoder *decoder
	readClose func() error
	mu sync.Mutex
	enti uint64
	encoder *encoder
	locks []*fileutil.LockedFile
	fp *filePipeline
}

WAL管理所有的更新日志,主要处理日志的追加,日志文件的切换,日志的回放等操作

WAL文件物理格式

etcd所有的日志项最终都会被追加存储到WAL文件中,日志项有很多类型,具体如下:

  • metadataType :这是一个特殊的日志项,被写在每个WAL文件的头部
  • entryType:应用的更新数据,也是日志中存储的最关键数据
  • stateType:代表日志项中存储的内容时快照
  • crcType:前一个WAL文件里面的数据的crc,也是WAL文件的第一个记录项 snapshotType:当前快照的索引{term,index},即当前快照位于哪个日志记录,不同于stateType,这里只是记录快照的索引,而非快照的数据。

每个日志项都由四部分组成:

  • type:日志项类
  • crc:校验和
  • data:根据日志项类型存储的实际数据也不尽相同,如果snapshotType类型的日志项存储的是快照的日志索引,crcType类型的日志项中则无数据项,其crc字段便充当了数据项
  • padding:为了保持数据项8子节对其而填充的数据

WAL文件的初始化

etcd的WAL库提供了初始化方法,应用需要显示调用初始化方法来完成日志初始化的功能,初始化方法主要包括两个函数Create()与Open()

Create()所做的事情比较简单,具体如下:

  1. 创建WAL目录,用于存储WAL日志文件
  2. 预分配第一个WAL日志文件,默认是64MB,使用预分配机制可以提高写入性能
  3. Open则是在Create完成后被调用,主要是打开WAL目录下的日志文件
  4. Open的主要作用是找到当前快照以后的所有WAL日志,这是因为快照之前的日志我们不再关心,因为日志的内容肯定都已经被更新至快照了,这些日志也是在后面回收日志操作中可以被删除的部分

WAL追加日志项

日志项的追加通过调用etcd的wal库的Save()方法来实现,该函数的核心内容具体如下:

  • 调用saveEntry()将日志项存储到WAL文件中
  • 如果追加后日志文件超过了既定的SegmentSizeBytes大小,则需要调用w.cut()进行WAL文件的切换,即关闭当前WAL日志,创建新的WAL日志,继续用于日志追加
  • cut()的目的用于实现WAL文件切换的功能,每个WAL文件的预设大小均为64MB,一旦超过该大小,便会创建新的WAL文件,这样做的好处便是对旧的WAL文件进行删除

etcd v2的快照管理

etcd v2是一个纯内存数据库,写操作先通过Raft协议复制binlog,复制成功后将数据写入到内存中,整个数据库在内存中是一个简单的树结构,其轻微将数据实时写入到磁盘中,持久化考的是binlog和定期做快照实现的,总的俩讲,etcd v2做快照的方法就是将内存中的整个数据库复制一份,然后序列化成JSON,写入到磁盘中,称为快照。做快照的时候使用的是复制出来的数据库,客户端的读写请求依然会落到原始的数据库,也就是说做快照的操作不会阻塞客户端的读写请求

因为操作系统对内存进行了分页,同时内存的复制操作实际是COW的,所以只有当复制的某一个内存页发生更改时才会发生复制行为,即只有那些被客户端读到的数据也才会在内存中被复制,那些没有读到的压根不会发生复制。

快照数据结构如下:

type ConfState struct{
	Nodes []uint64
}

type SnapshotMetadata struct{
	ConsState ConfState
	Index uint64
	Term uint64
}
type Snapshot struct{
	Data []byte
	Metadata SnapshotMetadata
}

创建快照

创建快照的时机时在请求的处理的流程之中,具体来说,Raft协议每获取到日志项之后,在处理该日志的过程中就会判断是否创建快照。创建快照的具体包含如下几个步骤:

  1. 判断是否传创建快照,该过程有一定的代价,因此不会每次都执行。
  2. 创建快照,由应用实现具体的创建方法
  3. 通过raftStorage创建快照
  4. 存储日志
  5. 进行日志回收(compact)

对于执行快照创建的时机进行判断时,etcd采用较为简单的策略:每处理10000条日志进行一此快照

创建快照的的操作代码如下,直接将内存中的数据库复制一份转换成JSON即可

func (s *kvstore)getSnapshot()([]byte,error){
	s.mu.Lock()
	defers.mu.Unlock()
	return json.Marshal(s.kvStore)
}

拿到整个数据库快照之后,还要添加一些metadata,比如该快照的版本号等,然后就可以将快照进行持久化了

func (rc *raftNode)saveSnap(snap raftpb.Snapshot) error{
	walSnap:=walpb.Snapshot{
		Index:=snap.Metadata.Index,
		Term:=snap.Metadata.Term,
	}
	if erro:=rc.wal.SaveSnapshot(WalSnap);err!=nil{
		return err
	}
	if err:=rc.snapshotter.SaveSnap(snap);err!=nil{
		return err
	}
	return rc.wal.ReleaseLockTo(snap.Metadata.Index)
}

持久化存储具体包括以下几个内容

  • 快照索引:即当前快照的其实日志项索引信息(term/index),该信息被存储在WAL日志文件所在目录
  • 快照数据:即快照的真正数据
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

etcd之日志和快照管理 的相关文章

  • 【计算机开题报告】图书管理系统

    一 选题依据 简述国内外研究现状 生产需求状况 说明选题目的 意义 列出主要参考文献 国内外研究现状 国外研究现状 在很多发达国家 图书管理系统的应用和技术发展已经相对完善 并且还建立了数字图书馆 各方面的情况也非常成熟 而图书管理的应用价
  • ERROR 5025 (HY000): Insert has filtered data in strict mode, tracking_url=http://IP

    通过http api批量插入数据的时候报Reason null value for not null column column xxx src line 解决方法 检查是否有null值存在 增加数据库字段长度 如下语句更改长度 ALTER
  • Nexus5596交换机支持3层需要的子卡

    3层子卡 nexus5596如果没有这块子卡 无法支持3层特性 TEST Cisco N5596 1 show modu Mod Ports Module Type Model Status 1 48 O2 32X10GBase T 16X
  • python按列写入数据到excel

    要将数据按列写入 Excel 可以使用 Python 的 openpyxl 库 首先 需要安装 openpyxl 库 可以使用以下命令在终端或命令提示符中安装 pip install openpyxl 然后 可以按照以下步骤编写代码 1 导
  • AntDB内存管理之内存上下文之如何使用内存上下文

    5 如何使用内存上下文 使用内存上下文之前 我们需要先对其进行创建 AntDB启动时已经创建并初始化好了部分内存上下文 例如 TopMemoryContext 这个TopMemoryContext是所有内存上下文的父节点或者祖先节点 一般我
  • 6 - 数据备份与恢复|innobackupex

    数据备份与恢复 innobackupex 数据备份与恢复 数据备份相关概念 物理备份与恢复 逻辑备份 推荐 使用binlog日志文件实现对数据的时时备份 使用日志 恢复数据
  • 【计算机毕业设计】出租车管理系统

    现代经济快节奏发展以及不断完善升级的信息化技术 让传统数据信息的管理升级为软件存储 归纳 集中处理数据信息的管理方式 本出租车管理系统就是在这样的大环境下诞生 其可以帮助管理者在短时间内处理完毕庞大的数据信息 使用这种软件工具可以帮助管理人
  • 【计算机毕业设计】Java图书馆智能选座系统

    现代经济快节奏发展以及不断完善升级的信息化技术 让传统数据信息的管理升级为软件存储 归纳 集中处理数据信息的管理方式 本图书馆智能选座系统就是在这样的大环境下诞生 其可以帮助使用者在短时间内处理完毕庞大的数据信息 使用这种软件工具可以帮助管
  • 软件测试/测试开发/全日制/测试管理丨Redis内存数据库

    Redis是一种开源 内存中的数据结构存储系统 它提供了高性能 灵活性和丰富的数据结构 以下是Redis内存数据库的基本介绍 键值存储 Redis基于键值对的存储模型 其中每个键都与一个特定的值相关联 这种简单的数据模型使其易于使用和理解
  • 图解python | 字符串及操作

    1 Python元组 Python的元组与列表类似 不同之处在于元组的元素不能修改 元组使用小括号 列表使用方括号 元组创建很简单 只需要在括号中添加元素 并使用逗号隔开即可 tup1 ByteDance ShowMeAI 1997 202
  • 基于java的饮食分享平台系统设计与实现

    基于java的饮食分享平台系统设计与实现 I 引言 A 研究背景和动机 近年来 随着人们生活水平的提高和健康意识的增强 饮食健康已经成为越来越多人的关注焦点 因此 一个方便快捷的饮食分享平台就显得尤为重要 基于Java的饮食分享平台系统设计
  • 电商数据api接口商品评论接口接入代码演示案例

    电商数据API接口商品评论 接口接入入口 提高用户体验 通过获取用户对商品的评论 商家可以了解用户对商品的满意度和需求 从而优化商品和服务 提高用户体验 提升销售业绩 用户在购买商品前通常会查看其他用户的评论 以了解商品的实际效果和质量 商
  • 深入了解 Python MongoDB 查询:find 和 find_one 方法完全解析

    在 MongoDB 中 我们使用 find 和 find one 方法来在集合中查找数据 就像在MySQL数据库中使用 SELECT 语句来在表中查找数据一样 查找单个文档 要从MongoDB的集合中选择数据 我们可以使用 find one
  • 【计算机毕业设计】趵突泉景区的智慧导游小程序_5ztvv

    当今社会已经步入了科学技术进步和经济社会快速发展的新时期 国际信息和学术交流也不断加强 计算机技术对经济社会发展和人民生活改善的影响也日益突出 人类的生存和思考方式也产生了变化 传统趵突泉景区的智慧导游采取了人工的管理方法 但这种管理方法存
  • 【计算机毕业设计】微信小程序反诈科普平台

    相比于以前的传统手工管理方式 智能化的管理方式可以大幅降低反诈科普平台的运营人员成本 实现了反诈科普平台的标准化 制度化 程序化的管理 有效地防止了反诈科普平台的随意管理 提高了信息的处理速度和精确度 能够及时 准确地查询和修正反诈科普 一
  • 【计算机毕业设计】springbootstone音乐播放器的设计与实现

    随着我国经济的高速发展与人们生活水平的日益提高 人们对生活质量的追求也多种多样 尤其在人们生活节奏不断加快的当下 人们更趋向于足不出户解决生活上的问题 stone音乐播放器展现了其蓬勃生命力和广阔的前景 与此同时 为解决用户需求 stone
  • 温室气体排放更敏感的模型(即更高的平衡气候敏感性(ECS))在数年到数十年时间尺度上也具有更高的温度变化(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Python代码 数据
  • 每日变更的最佳实践

    在优维公司内部 我们采用发布单的方式进行每天的应用变更管理 这里给各位介绍优维的最佳实践 变更是需要多角色合作的 而且他是整体研发流程的一部分 在优维内部 我们坚持每日变更 打通开发环节到最终发布上线的全过程 在保证质量的前提下 尽可能提升
  • Python 使用 NoSQL 数据库的优选方案

    NoSQL 数据库因其高性能 可扩展性和灵活性而风靡一时 然而 对于 Python 程序员而言 选择合适的 NoSQL 数据库可能会令人困惑 因为有多种选择可供选择 那么 哪种 NoSQL 数据库最适合 Python 呢 2 解决方案 根据
  • minikube:无法连接本地部署的 nginx 服务

    我已经在我的 ubuntu 16 04 机器上安装了 minikube 并启动了一个集群 并显示一条消息 Kubernetes is available at https 192 168 99 100 443 接下来 我使用以下命令部署了

随机推荐