深入了解etc(一)

先做一个etcd 的backup小实验
启动etcd集群

nohup etcd --name infra0 \
--data-dir=/tmp/etcd/infra0 \
--listen-peer-urls https://127.0.0.1:3380 \
--initial-advertise-peer-urls https://127.0.0.1:3380 \
--listen-client-urls https://127.0.0.1:3379 \
--advertise-client-urls https://127.0.0.1:3379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=https://127.0.0.1:3380,infra1=https://127.0.0.1:4380,infra2=https://127.0.0.1:5380 \
--initial-cluster-state new \
--client-cert-auth --trusted-ca-file=/tmp/etcd-certs/certs/ca.pem \
--cert-file=/tmp/etcd-certs/certs/127.0.0.1.pem \
--key-file=/tmp/etcd-certs/certs/127.0.0.1-key.pem \
--peer-client-cert-auth --peer-trusted-ca-file=/tmp/etcd-certs/certs/ca.pem \
--peer-cert-file=/tmp/etcd-certs/certs/127.0.0.1.pem \
--peer-key-file=/tmp/etcd-certs/certs/127.0.0.1-key.pem 2>&1 > /var/log/infra0.log &

nohup etcd --name infra1 \
--data-dir=/tmp/etcd/infra1 \
--listen-peer-urls https://127.0.0.1:4380 \
--initial-advertise-peer-urls https://127.0.0.1:4380 \
--listen-client-urls https://127.0.0.1:4379 \
--advertise-client-urls https://127.0.0.1:4379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=https://127.0.0.1:3380,infra1=https://127.0.0.1:4380,infra2=https://127.0.0.1:5380 \
--initial-cluster-state new \
--client-cert-auth --trusted-ca-file=/tmp/etcd-certs/certs/ca.pem \
--cert-file=/tmp/etcd-certs/certs/127.0.0.1.pem \
--key-file=/tmp/etcd-certs/certs/127.0.0.1-key.pem \
--peer-client-cert-auth --peer-trusted-ca-file=/tmp/etcd-certs/certs/ca.pem \
--peer-cert-file=/tmp/etcd-certs/certs/127.0.0.1.pem \
--peer-key-file=/tmp/etcd-certs/certs/127.0.0.1-key.pem 2>&1 > /var/log/infra1.log &

nohup etcd --name infra2 \
--data-dir=/tmp/etcd/infra2 \
--listen-peer-urls https://127.0.0.1:5380 \
--initial-advertise-peer-urls https://127.0.0.1:5380 \
--listen-client-urls https://127.0.0.1:5379 \
--advertise-client-urls https://127.0.0.1:5379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=https://127.0.0.1:3380,infra1=https://127.0.0.1:4380,infra2=https://127.0.0.1:5380 \
--initial-cluster-state new \
--client-cert-auth --trusted-ca-file=/tmp/etcd-certs/certs/ca.pem \
--cert-file=/tmp/etcd-certs/certs/127.0.0.1.pem \
--key-file=/tmp/etcd-certs/certs/127.0.0.1-key.pem \
--peer-client-cert-auth --peer-trusted-ca-file=/tmp/etcd-certs/certs/ca.pem \
--peer-cert-file=/tmp/etcd-certs/certs/127.0.0.1.pem \
--peer-key-file=/tmp/etcd-certs/certs/127.0.0.1-key.pem 2>&1 > /var/log/infra2.log &

备份文件

etcdctl --endpoints https://127.0.0.1:3379 \
--cert /tmp/etcd-certs/certs/127.0.0.1.pem \
--key /tmp/etcd-certs/certs/127.0.0.1-key.pem \
--cacert /tmp/etcd-certs/certs/ca.pem snapshot save snapshot.db

我们把/tmp/etcd 数据目录删除,然后备份恢复

export ETCDCTL_API=3
etcdctl snapshot restore snapshot.db \
  --name infra0 \
  --data-dir=/tmp/etcd/infra0 \
  --initial-cluster infra0=https://127.0.0.1:3380,infra1=https://127.0.0.1:4380,infra2=https://127.0.0.1:5380 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-advertise-peer-urls https://127.0.0.1:3380

etcdctl snapshot restore snapshot.db \
    --name infra1 \
    --data-dir=/tmp/etcd/infra1 \
    --initial-cluster infra0=https://127.0.0.1:3380,infra1=https://127.0.0.1:4380,infra2=https://127.0.0.1:5380 \
    --initial-cluster-token etcd-cluster-1 \
    --initial-advertise-peer-urls https://127.0.0.1:4380

etcdctl snapshot restore snapshot.db \
  --name infra2 \
  --data-dir=/tmp/etcd/infra2 \
  --initial-cluster infra0=https://127.0.0.1:3380,infra1=https://127.0.0.1:4380,infra2=https://127.0.0.1:5380 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-advertise-peer-urls https://127.0.0.1:5380

下面我们了解一下etcd的全景图
在这里插入图片描述
整个etcd可以分为client层,api网络层,raft算法层,功能逻辑层,和存储层,client层提供了v2和v3版本,提供了简洁的api,api网络层v3版本支持grpc也支持http,主从之间的数据复制和leader选举都是走的http,raft算法层有leader选举,日志复制,readindex,功能逻辑层包括,kvserver,mvcc,auth鉴权,lease租约,compactor压缩模块,存储层包括,wal,snaoshot,boltdb,

etcdctl --endpoint=http://127.0.0.1:2379 get a

当我们使用上面的命名执行一个读请求的时候,我们看看会发生什么
etcdctl 创建一个clientv3库对象,使用kvserver模块的api来访问etcd server,一般etcd都是多节点的,当我们使用etcdctl访问后端的时候会采用负载均衡算法round-robin,访问到后端,选择好etcd server之后,client调用kvserver模块的range rpc方法,把请求发送给etcd server,

etcd提供了metrics,日志,请求行为检查等机制,它们都是通过拦截器非侵入式实现的,server收到client的range rpc请求后,会把请求转发到handler,然后通过kvserver的range借口获取数据

进入kvserver后,读包括穿行读,和线性读,状态机更新数据变慢的话,会出现读到旧数据,所谓的串行读,就是直接读取状态机,无需通过raft协议,它有低延时,高吞吐,适合对数据一致性不高的场景,反只就是线性读,readindex就是确保数据读取一致而存在的,它主要就是比较索引,直到状态机已经应用的索引大于等于leader已经提交的索引的时候才会通知读请求,然后访问数据,

mvcc模块,包括boltdb和treeindex两部分,boltdb是基于B+ tree实现的key-value的健值库,boltdb的key是版本号,value是用户的key,value等字段组合成的结构体,通过treeindex保存key和版本号的映射关系,treeindex基于btree实现的,treeindex只包含用户的key个相关的版本信息,用户的key和value存储在boltdb中,不是所有的请求都要到boltdb,etcd使用了buffer缓存,如果命中直接返回,没有命中就需要向boltdb中访问数据了,boltdb使用bucket来隔离数据,通过boltdb的游标cursor快速的在B+tree找到key对应的value返回给client

下面我们看看在etcd中一个写请求是怎样执行的,首先client通过负载均衡算法选择一个etcd节点,然后etcd节点收到请求后,经过grpc拦截器,quota模块,进入kvserver模块,kvserver模块向raft模块提交一个写入请求的提案,quota模块的作用就是检查这次提交加上db剩余的容量是否超过了etcd的配额大小,默认是2G,社区建议不超过8G,所以配置合理的压缩历史版本很重要,我们可以通过compact压缩历史版本,一旦超过了配额,会出现no space告警,这个时候集群就会变成只读,不能在写,可以增加配额,然后要清除告警 etctl alarm disarm 配额(quota-backend-bytes) 默认0就是默认的2GB,不建议设置成负数也就是禁用配额

kvserver会把put信息打包成提案信息交给raft模块,在提交之前会做一些预检查,任何提交到raft模块的请求都会先做一些限速处理,如果日志索性超过了5000会报出一个 too many requests的错误,然后做鉴权,最后检查这个包的大小是否超过了1.5MB,如果超过了,会报requests is too large

kvserver向raft模块提交提案会有一个7秒的超时时间,超过时间会报,requests timeed out 所有的写请求都会先到leader处理,etcdserver从raft模块获得消息后,会通过广播告诉其他节点,把信息写入到wal日志,它包含,crc校验码,data wal记录内容,和type wal记录类型,raft中的input结构包含下面信息,term是任期号,index是日志条目的索引,单调递增,然后是type可以是普通日志,和集群配置变更日志,data里面是提案的内容

超过半数以上的节点写入请求后,etcdserver模块从channel中取出提案内容添加到一个先进先出FIFO对列中,然后通过apply模块按入队,异步依次执行提案内容,如果此时etcd crash掉了,会从wal解析出raft日志条目内容,追加到raft日志的存储中,通过index解决幂等性的问题,apply模块在执行提案内容前,先判断当前提案是否已经执行过了,如果执行过了直接返回,若未执行同时db.配额没有告警,会进入mvcc模块

mvcc模块包含treeindex和boltdb,treeindex保存key的历史信息,boltdb用来持久化存储key-value数据,etcd持久化以下信息,key名称,key创建的版本号,最后一次修改时的版本号,key自身修改的次数,value值,和租约信息,不是每次都要执行事务提交的,etcd采取的是合并合并再合并,通过bucket buffer实现读写性能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值