分布式系统
文章平均质量分 80
分布式系统(distributed system)是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。
肥叔菌
本博客主要用于记录学习过程中的笔记,每隔一段时间,博主将会将精华内容整合发到知乎、简书上。欢迎关注博主肥叔菌在其他平台上的账号,谢谢。
B站:https://space.bilibili.com/456254145
segmentfault:https://segmentfault.com/u/feishujun/articles
简书:https://www.jianshu.com/u/67bab078551a
展开
-
分布式原子提交协议——2PC
2PC says nothing about this behavior - it’s outside of the system model defined by the protocol. The read behavior isn’t defined by the protocol but rather the deployment configuration. 对于数据库,读取请求在提交之前到达。可以想象,一个邪恶的用户操作一个特制的协调器,故意让事务处于“停滞状态”,从而耗尽参与者的资源。翻译 2023-10-17 00:00:00 · 126 阅读 · 0 评论 -
ETCD数据库源码分析——gRPC 拦截器
RPC响应要流经后置处理阶段。在前置处理阶段之后,则可以调用StreamHandler来完成远程方法的RPC执行,而且通过已实现grpc.ServerStream接口的包装器流接口,可以拦截流RPC的消息。server 收到 client 的 Range RPC 请求后,根据 ServiceName 和 RPC Method 将请求转发到对应的 handler 实现,handler 首先会将上面描述的一系列拦截器串联成一个执行,在拦截器逻辑中,通过调用 KVServer 模块的 Range 接口获取数据。.原创 2022-08-16 00:00:00 · 494 阅读 · 0 评论 -
ETCD数据库源码分析——客户服务端通信API层
最后我们看到election和lock服务都是通过server/etcdserver/api/v3election和v3lock文件提供了相应的实现结构体,从图中定义可以看出,这两个归为一类是因为其结构体成员都是clientv3.Client,也就是通过客户端Client结构体来实现相应的接口函数功能,实际上和watchServer、authMaintenanceServer、ClusterServer接口函数实现逻辑是不同的。...原创 2022-08-13 17:13:06 · 321 阅读 · 0 评论 -
ETCD数据库源码分析——Cluster membership changes日志
leader节点收到日志后,需要存储该日志的索引为未完成的集群配置变更索引,像其它正常日志一样处理先写本地的日志,再广播给集群的其他节点,半数应答则认为日志达成一致可以提交了。集群配置变更日志提交之后,对照新旧的集群变更数据,该添加到集群的添加到集群,该删除的节点停机。所谓的联合共识,就是将新旧配置的节点一起做为一个节点集合,只有该节点集合达成半数一致,才能认为日志可以提交,由于新旧两个集合做了合并,那么就不会出现多leader的情况了。注意,这时候的日志,需要提交到C_{old,new}中的所有节点。..原创 2022-07-26 02:00:00 · 400 阅读 · 0 评论 -
ETCD数据库源码分析——EtcdServer run apply流程
这里通过调用Wait.Trigger方法,将id小于etcdProgress.appliedi的Entry对应的通道全部关闭,以通知其他监听通道的goroutine。其后,run协程会监听raftNode.applyc通道,并调用applyAll方法处理从其中读取到的apply实例。等待raftNodestart协程完成写盘,或者appliedindex大于raftstorage中最后的index,下面截图中的代码就是raftNodestart协程向notifyc通道中写入。...原创 2022-07-19 03:15:00 · 305 阅读 · 0 评论 -
ETCD数据库源码分析——ServerV2接口实现
我们知道EtcdServer实现了Server接口、ServerV2接口和ServerV3接口,这里我们首先介绍一下ServerV2接口(ServerV2接口是用于操作v2store的API)。如上图中的ServerV2代码所示,其提供了Leader()、Do()和ClientCertAuthEnabled()函数定义。EtcdServer结构体需要实现ServerV2接口,以提供操作v2store的能力。...原创 2022-07-18 00:00:00 · 455 阅读 · 0 评论 -
ETCD数据库源码分析——初始化EtcdServer结构体
我们知道上面提到的ETCD数据库源码分析——etcdserver bootstrap初始化存储和ETCD数据库源码分析——etcdserver bootstrap初始化cluster和raft其实都是在bootstrap函数中调用的,而bootstrap函数是由NewServer函数调用的。NewServer函数进行bootstrap初始化存储和初始化cluster和raft之后会对EtcdServer结构体进行初始化。EtcdServer结构体中的很多成员都是依赖于bootstrap函数产生的boots原创 2022-07-16 23:42:40 · 410 阅读 · 0 评论 -
ETCD数据库源码分析——etcdserver bootstrap从快照中恢复store
v2存储的恢复其实就是加载快照文件中的JSON数据。从静态存储系统恢复它需要恢复节点的父字段。RecoverSnapshotBackend函数定义在server/storage/backend.go文件中,其会检测前面创建的Backend实例是否可用(即包含了快照数据所包含的全部Entry记录),如果可用则继续使用该Backend实例,如果不可用则根据快照的元数据查找可用的BoltDB数据库文件,并创建新的Backend实例。其持久化方式是将整个存储的数据序列化成JSON格式的数据,并写入磁盘文件中。...原创 2022-07-16 22:36:11 · 1020 阅读 · 0 评论 -
ETCD数据库源码分析——etcdserver bootstrap去除v2store
bootstrapBackend需要修改,其实就是修改recoverSnapshot函数,删除其stv2store.Store,删除v2store.Store恢复流程。,同样也需要删除RaftCluster结构体中的v2store成员。针对RaftCluster的Recover函数,需要去掉从v2store中提出数据的代码,bootstrapStorage函数中删除st,也就是将bootstrappedStorage中的st成员删除。bootstrap函数中需要删除v2store创建函数。...原创 2022-07-16 01:27:12 · 370 阅读 · 0 评论 -
ETCD数据库源码分析——etcdserver bootstrap初始化cluster和raft
bootstrapCluster函数用于初始化bootstrapedCluster结构体,分为三种情况1.没有wal文件且未指明是新建集群的情况下,调用bootstrapExistingClusterNoWAL从peer节点获取集群信息并初始化bootstrapedCluster结构体2.没有wal文件且指明是新建集群的情况下直接初始化空的bootstrapedCluster结构体3.有wal文件,从WAL文件中提取集群信息并初始化bootstrapedCluster结构体。...原创 2022-07-16 01:26:42 · 559 阅读 · 0 评论 -
ETCD数据库源码分析——三大主流程启动流程
raft.Node的run协程在StartNode和RestartNode中执行(raft/node.go),而StartNode和RestartNode函数是在server/etcdserver/bootstrap.go文件中的newRaftNode函数中调用的。newRaftNode函数在server/etcdserver/server.go的NewServer函数中创建EtcdServer结构体时调用,并赋值给EtcdServer.r成员,也就是RaftNode类型的变量。...原创 2022-07-14 21:09:30 · 669 阅读 · 0 评论 -
ETCD数据库源码分析——ProgressTracker
tracker是etcd数据库raft使用的单独一个包(raft/tracker),其核心类是ProgressTracker。从类名上看是Progress的Tracker,所以Progresstracker是用来跟踪Progress的,理解了什么是Progress才能明白ProgressTracker的是干什么的,但是这里先介绍一些简单的函数来看看ProgressTracker提供的功能。Progress代表了Leader视角的Follower进度,Leader拥有所有Follower的进度,并根据其进原创 2022-07-12 02:45:00 · 642 阅读 · 0 评论 -
ETCD数据库源码分析——服务端NewAuthServer
NewAuthServer函数定义在server/etcdserver/api/v3rpc/auth.go文件中,其定义如下,输入参数为EtcdServer类型,返回值为AuthServer结构体。将输入参数EtcdServer作为AuthServer结构体的authenticator成员。Authenticator接口定义在server/etcdserver/v3_server.go文件中,如下为其提供的接口函数。server/etcdserver/api/v3rpc/auth.go文件中AuthSe原创 2022-07-07 13:18:29 · 367 阅读 · 0 评论 -
使用etcd的proto文件生成编译etcd client v3的c++客户端代码
下载安装protobuf下载源码,下载地址:https://github.com/protocolbuffers/protobuf添加环境变量vim /etc/profile,添加: export PATH=$PATH:/usr/local/protobuf/bin/,然后source /etc/profile3. 整理etcd的proto文件生成c++代码1)下载etcd的源码,找出etcd中的proto文件放到单独的文件夹pb下2)查看proto文件中的import依赖项,将依赖项全拷贝到原创 2022-07-13 00:00:00 · 438 阅读 · 0 评论 -
ETCD数据库源码分析——Message
ETCD Raft模块是一个复杂的状态机,驱动该状态机就是传令Message(相当于古代传令兵所携带的军情命令等消息),可以说Raft模块所有的动作都基于传令Message。首先我们先看一下传令Message分为19种类型(定义在raft/raftpb/raft.pb.go)。如下就是上述类型消息所使用的通用消息结构体,From就是从哪个节点发出,To就是发向哪个节点,Term就是当前任期,logTerm表示Raft logs所包含的任期,Index就是raft log index,Entries就是多个r原创 2022-07-11 00:00:00 · 265 阅读 · 0 评论 -
ETCD数据库源码分析——rawnode简单封装
在etcd 3.6.0之前是没有rawnode模块,现在出现的rawnode.go仅仅是raft模块的简单封装,并将raft.Node run协程中每轮循环需要保存的raft的前一次硬软状态prevSoftSt和prevHardSt保存到rawnode结构体中。如下为rawnode结构体的定义:rawnode提供的接口如下所示,粗体的函数会被其他模块调用,从这些接口函数我们可以看到作为raft模块的封装需要提供哪些接口:NewRawNode实例化给定配置中的RawNode。有关引导初始状态的信息,请参阅原创 2022-07-05 13:09:40 · 406 阅读 · 0 评论 -
ETCD数据库源码分析——从raftNode的start函数说起
如上图所示,raftNode是真正操纵ETCD RAFT API的模块,充当etcd-raft模块与上层模块之间交互的桥梁,其定义了如下成员。其中msgSnapC通道用于接收和发送快照、applyc通道用于发送待应用的Entry记录、readStateC用于向上层模块发送ReadState、ticker用于向raft模块发送定时脉冲tick、td用于检测发往同一节点的两次心跳消息是否超时。raftNodeConfig后续再说,该篇主要说明ticker模块。初始化raftNode结构体的函数是newRaft原创 2022-07-07 00:00:00 · 217 阅读 · 0 评论 -
ETCD数据库源码分析——处理Entry记录简要流程
(1)当客户端向etcd集群发送了一次请求之后,请求中的封装Entry记录会先被提交给etcd-raft模块进行处理,其中,etcd-raft模块会先将Entry记录保存到raftLog.unstable中。我们以ETCD数据库源码分析——服务端PUT流程为例,kvServer结构体Put函数处理流程如下:首先会对请求消息进行各方面的检查,检查完之后会将所有的请求交给其内封装的RaftKV接口进行处理,待处理完成得到响应消息之后,会通过header.fill()方法填充响应的头信息,最后将完整的响应消息返原创 2022-07-04 13:05:25 · 298 阅读 · 0 评论 -
ETCD数据库源码分析——etcdserver bootstrap初始化存储
etcdserver.NewServer函数第一步就是调用bootstrap函数(定义在server/etcdserver/bootstrap.go文件中),其输入参数是config.ServerConfig,输出参数是bootstrappedServer,其主要作用是对存储Storage、集群信息Cluster和一致性模块信息Raft进行初始化和恢复。etcd 3.6.0和之前版本不同是将需要恢复的模块都集中到bootstrappedServer结构体中,以简化代码逻辑。bootstrapSnapsho原创 2022-07-06 00:00:00 · 575 阅读 · 1 评论 -
ETCD数据库源码分析——集群间网络层客户端peerRt
peerRt(RoundTripper类型)主要负责实现etcdserver的网络请求等功能,用于向集群其他节点发送version或lease服务请求。我们知道其是在ETCD数据库源码分析——etcdserver bootstrap初始化中的第二步进行初始化的。如何使用它呢?如server/etcdserver/cluster_util.go的promoteMemberHTTP所示,使用peerRt创建http客户端,然后构造请求Url和指定请求方法为POST,创建http Request结构体,调用ht原创 2022-07-05 00:00:00 · 167 阅读 · 0 评论 -
ETCD数据库源码分析——初始化总览
本篇文章将讲解ETCD数据库初始化整体流程,主要是对前期的博客进行总结。ETCD源码分析——EtcdServer初始化文章主要介绍server/etcdmain/main.go Main函数总入口函数,主要是通过启动命令行参数来判定执行流程:如果输入参数是gateway或grpc-proxy则执行rootCmd.Execute;其他情况执行startEtcdOrProxyV2(args)。startEtcdOrProxyV2(server/etcdmain/etcd.go)函数先调用newConfig函数(原创 2022-07-04 00:00:00 · 750 阅读 · 0 评论 -
ETCD数据库源码分析——服务端PUT流程
在ETCD数据库源码分析——etcd gRPC 服务 API注册服务小节,有如下grpc服务注册代码,包含了服务端PUT流程所属的KVServer。RegisterKVServer函数定义在/api/etcdserverpb/rpc.pb.go文件中,这里中的s指的就是ETCD数据库中的最重要的etcdserver结构体。在/api/etcdserverpb/rpc.pb.go里面,可以看到上面定义的ServiceName和MethodName,可以找到Put方法对应的函数_KV_Put_Handle原创 2022-06-29 13:15:18 · 575 阅读 · 0 评论 -
ETCD数据库源码分析——集群间网络层服务端RaftHandler
在ETCD数据库源码分析——集群间网络层服务端接口文章中,启动http.Server时会通过rafthttp.Transporter.Handler()方法为指定的URL路径添加相应Handler实例,如下图所示。streamHandler负责处理Stream消息通道上的请求。pipelineHandler负责处理Pipeline通道上的请求,snapHandler负责处理Pipeline通道上的请求。pipelineHandler用于集群间网络层服务端负责处理Pipeline通道上的请求,tr为当前pi原创 2022-06-27 08:00:00 · 562 阅读 · 0 评论 -
ETCD数据库源码分析——集群间网络层服务端接口
从上一篇文章ETCD数据库源码分析——集群通信初始化我们知道:这篇文章我们来学习一下函数和pipelineHandler、streamHandler、snapHandler。Listener的初始化代码如下所示,transport.NewListenerWithOpts函数代码位于client/pkg/transport/listener.go文件中,作为transport包内export到外部的函数。client/pkg/transport/listener.go文件export两个函数给其他代码调用。原创 2022-06-25 16:54:35 · 562 阅读 · 0 评论 -
ETCD数据库源码分析——集群通信初始化
消息入口一个etcd节点运行以后,有3个通道接收外界消息,以kv数据的增删改查请求处理为例,介绍这3个通道的工作机制。初始化集群内部通信服务端通信所需的peerListenerconfigurePeerListeners函数定义在server/embed/etcd.go文件中,为配置Config中LPUrls每个url创建一个peerListener,如上图中的peerListener结构体所示,该函数为初始化peerListener结构体会调用函数创建net.Listener,将close函数初始原创 2022-06-25 15:13:00 · 348 阅读 · 0 评论 -
ETCD数据库源码分析——etcd gRPC 服务 API
本文将会开始介绍 etcd3 API 的核心设计,主要针对常见的 API 接口服务。对于理解 etcd 基本思想有很大的帮助。所有 etcd3 API 均在 gRPC 服务中定义,该服务对 etcd 服务器可以理解的远程过程调用(RPC)进行分类。发送到etcd服务器的每个API请求都是一个gRPC远程过程调用。etcd3 中的 RPC 接口定义根据功能分类到服务中。处理 etcd 键值的重要服务包括:api/etcdserverpb/rpc.proto文件定义了KV服务,其中定义了五个客户端最基本、最常用原创 2022-06-19 15:31:41 · 529 阅读 · 0 评论 -
ETCD数据库源码分析——客户服务端通信serveCtx
在etcd.go文件中的StartEtcd函数负责启动etcd的服务端,每个节点都会对外提供两组URL地址,一组是与集群中其他节点交互的URL地址(Peer URL),另一组是与客户端交互的URL地址(Client URL)。本篇博客就是讲解客户服务端通信,首先介绍一下服务端通信建立流程。为每个Client URL创建相应的Listener实例函数会为每个Client URL地址创建相应的serveCtx实例,也就是该函数返回的sctxs map。在serveCtx实例中记录了相应的Listener实例原创 2022-06-18 16:26:28 · 357 阅读 · 0 评论 -
ETCD数据库源码分析——protobuf bingdings
该篇博客的目标就是从scripts/genproto.sh脚本中看出ETCD数据库有哪些地方需要protobuf环境变量配置与grpc和protobuf相关GO环境变量GOFAST_BIN=$(tool_get_bin github.com/gogo/protobuf/protoc-gen-gofast)GRPC_GATEWAY_BIN=$(tool_get_bin github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway)SWA原创 2022-03-28 23:03:35 · 874 阅读 · 0 评论 -
分布式时钟同步:逻辑时钟、向量时钟、混合逻辑时钟
中心授时节点TSO(Timestamp Oracle) TiDB(PD)混合逻辑时钟HLC(Hybird Logical Clock) Yugabyte Cockroach TBASE(GTM)Cockroach通过NTP来同步集群节点之间的时钟,获得不太精确的全局Timestamp逻辑时钟的性质逻辑时钟首次在Lamport于1978年发表的《Time, clocks, and the ordering of events in a distributed system》中被提出,引用量过万,可谓原创 2022-02-24 23:35:12 · 459 阅读 · 0 评论 -
ETCD源码分析——snap.New函数简介
Snapshotter结构体代码位于server/etcdserver/api/snap/snapshotter.go文件中,其定义如下所示,New函数就是将形参填充到Snapshotter函数的成员中。type Snapshotter struct { lg *zap.Logger dir string}func New(lg *zap.Logger, dir string) *Snapshotter { if lg == nil { lg = zap.NewNop() } return原创 2022-01-20 12:52:52 · 829 阅读 · 0 评论 -
ETCD源码分析——openBackend函数简介
ci := cindex.NewConsistentIndex(nil) beHooks := &backendHooks{lg: cfg.Logger, indexer: ci} be := openBackend(cfg, beHooks) ci.SetBackend(be) cindex.CreateMetaBucket(be.BatchTx())后续内容欢迎关注公号或者充值CSDN VIP阅读。数据结构backendbackendHooksconsistentIn.原创 2022-01-13 13:02:57 · 352 阅读 · 0 评论 -
ETCD源码分析——创建etcd server总览
e.Server, err = etcdserver.NewServer(srvcfg) // buffer channel so goroutines on closed connections won't wait forever e.errc = make(chan error, len(e.Peers)+len(e.Clients)+2*len(e.sctxs)) ... e.Server.Start()NewServer 根据提供的配置创建一个新的 EtcdServer。 该配置原创 2022-01-11 23:52:06 · 978 阅读 · 0 评论 -
ETCD源码分析——StartEtcd函数
StartEtcd启动etcd服务器和HTTP处理程序以进行客户端/服务器通信。 返回的 Etcd.Server 不保证已加入集群。 等待 Etcd.Server.ReadyNotify() 通道以了解etcd服务何时完成并准备好使用。后续内容欢迎关注公号或者充值CSDN VIP阅读。embed.StartEtcd函数分为三个部分来讲解:构建Etcd结构体,包含server初始化和listener创建通过检测配置文件isMemberInitialized(cfg)来看是否需要初始化(第一次启动).原创 2022-01-11 13:07:59 · 586 阅读 · 0 评论 -
ETCD源码分析——EtcdServer初始化
ETCD二进制文件编译命令如下所示,可以看到ETCD的代码主要集中于server文件夹下。server/main.go代码就是直接调用etcdmain.Main(os.Args)server/etcdmain/main.go Main函数总入口函数如下所示:如果输入参数是gateway或grpc-proxy则执行rootCmd.Execute其他情况执行startEtcdOrProxyV2(args)func Main(args []string) { checkSupportArch()原创 2022-01-10 23:19:43 · 533 阅读 · 0 评论 -
ETCD应用场景——服务发现
前言etcd环境安装与使用文章中介绍了etcd的安装及v3 API使用,本篇将介绍如何使用etcd实现服务发现功能。服务发现介绍服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听 udp 或 tcp 端口,并且通过名字就可以查找和连接。服务发现需要实现一下基本功能:服务注册:同一service的所有节点注册到相同目录下,节点启动后将自己的信息注册到所属服务的目录中。健康检查:转载 2021-12-29 12:22:32 · 1110 阅读 · 0 评论 -
Protocol Buffers官方文档(开发指南)
本文是对官方文档的翻译,然后截取了一篇非常优秀的文章片段来帮助理解,本人英文水平有限,基本都是直译,如果有不理解的地方请参考英文官方文档,参考的文章链接在文章末尾protocol buffers简介protocol buffer是google的一个开源项目,它是用于结构化数据序列化的灵活、高效、自动的方法,例如XML,不过它比xml更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。protocol buff原创 2021-12-20 12:31:02 · 391 阅读 · 0 评论 -
复制状态机简介
读过Paxos等论文的读者,应该对复制状态机(Replicated State Machine)的概念并不陌生。复制状态机在分布式系统中是一个很简单却很强大的模型,也是一种很有价值的思想。模型一句话描述就是:多个节点上,从相同的初始状态开始,执行相同的一串命令,产生相同的最终状态。服务器上的一致性模块负责接收外部命令,然后追加到自己的操作日志中。它与其他服务器上的一致性模块进行通信以保证每一个服务器上的操作日志最终都以相同的顺序包含相同的指令。一旦指令被正确复制,那么每个服务器的状态机都将按照操作日志的原创 2021-11-04 22:54:00 · 2386 阅读 · 0 评论 -
Boltdb源码分析——bolt.Open
Bolt是受LMDB、hyc_symas激发的纯key/value存储。Since Bolt is meant to be used as such a low-level piece of functionality, simplicity is key. The API will be small and only focus on getting values and setting values. That’s it.[hyc_symas]: https://twitter.com/hyc_sym原创 2021-10-26 22:48:50 · 500 阅读 · 0 评论 -
基于MySQL和DynamoDB的强一致性分布式事务实践
在单体应用向微服务架构转型的过程中,本地事务已不再满足系统一致性需求,为了解决这一问题,前人在对性能和数据一致性反复权衡的过程中总结了许多典型的协议和算法,各有优劣。本文我们将深入探讨 Freewheel 如何实现无单点故障的可扩展分布式事务实现模型。为什么需要分布式事务?当应用程序有严格的数据一致性要求时,ACID 事务是必须的,如果一个事务涉及的所有操作能够放在一个服务内部,且共用一个数据库,那么只用在一个方法里同一个事务下操作数据库即可。然而为了提升系统整体的可靠性,方便各个模块独立演化,系统从单转载 2021-10-24 17:21:31 · 184 阅读 · 0 评论 -
Boltdb源码分析——page结构
boltdb是一个纯粹的key Value数据库,其宗旨是提供一个简单,快速,可信的数据库。此数据库广泛应用于各大开源组件中。源码目录为:内存页boltdb 存储概括来讲,boltdb 的存储有如下特点:每个 db 对应一个文件,文件按照 page size(一般为 4096 Bytes) 划分为 page:前2个 page 保存 metadata;特殊的 page 保存 freelist,存放空闲 page 的 id;剩下的 page 构成一个 B+ 树结构。支持 namespace,每对原创 2021-09-13 12:53:57 · 477 阅读 · 0 评论