ETCD教程-3.ETCD体验

简介: 以MAC系统为例,讲述2种按照方法,第一种很简单,是Mac自带的

3.1 ETCD安装


3.1.1 直接安装

以MAC系统为例,讲述2种按照方法,第一种很简单,是Mac自带的:

#用brew安装非常方便,没安装的自行安装Homebrew,通过下面命令可以查看安装包brew search etcd#安装brew install etcd#查看版本etcd --version#启动,如果没有--enable-v2=true,就不用使用v2的接口etcd --enable-v2=true


不过这种方式可能会安装失败,我这把失败时提示日志目前没有权限,根据提示执行相关命令即可,我这边的提示如下:

sudo chown -R $(whoami) /usr/local/var/log


3.1.2 源码安装

我个人更推荐下面这种安装方式:

ETCD_VER=v3.4.14
# choose either URLGOOGLE_URL=https://storage.googleapis.com/etcdGITHUB_URL=https://github.com/etcd-io/etcd/releases/downloadDOWNLOAD_URL=${GOOGLE_URL}
rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.ziprm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-darwin-amd64.zip -o /tmp/etcd-${ETCD_VER}-darwin-amd64.zipunzip /tmp/etcd-${ETCD_VER}-darwin-amd64.zip -d /tmp && rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zipmv /tmp/etcd-${ETCD_VER}-darwin-amd64/* /tmp/etcd-download-test && rm -rf mv /tmp/etcd-${ETCD_VER}-darwin-amd64
#输出etcd版本/tmp/etcd-download-test/etcd --version/tmp/etcd-download-test/etcdctl version
#这里是把etcd和etcdctl copy到bin目录下面cp /tmp/etcd-download-test/etcd /usr/local/bincp /tmp/etcd-download-test/etcdctl /usr/local/bin


然后执行:

#安装etcdsh etcd_install.sh#查看版本etcd --version#启动,如果没有--enable-v2=true,就不用使用v2的接口etcd --enable-v2=true


3.2 集群部署


3.2.1 部署流程

下面我们可以部署一个etcd集群,我把代码还是写到文件中,第一个脚本为不支持在 Docs 外粘贴 block,内容如下(启动etcd需要很多参数,这些参数我都已经注释说明,更多参数详见:https://www.cnblogs.com/linuxws/p/11194403.html):

TOKEN=token-01CLUSTER_STATE=newNAME_1=etcd-01NAME_2=etcd-02NAME_3=etcd-03HOST_1=127.0.0.1HOST_2=127.0.0.1HOST_3=127.0.0.1PORT_API_1=2379PORT_PEER_1=2380PORT_API_2=2479PORT_PEER_2=2480PORT_API_3=2579PORT_PEER_3=2580
CLUSTER=${NAME_1}=http://${HOST_1}:${PORT_PEER_1},${NAME_2}=http://${HOST_2}:${PORT_PEER_2},${NAME_3}=http://${HOST_3}:${PORT_PEER_3}
# For every machineTHIS_NAME=${NAME_1}THIS_IP=${HOST_1}THIS_PORT_API=${PORT_API_1}THIS_PORT_PEER=${PORT_PEER_1}# 用于杀死进程lsof -i:2379 | awk '{print $2}' | grep -v "PID" | uniq | xargs kill -9
# --enable-v2 支持v2接口,可以省略# --data-dir 数据存储目录,可以省略# --name 节点名称,必须# --initial-advertise-peer-urls  数据在集群内进行交互的url,必须# --listen-peer-urls  集群节点之间通信监听的url,必须# --advertise-client-urls 客户通过该地址与本member交互信息,可以省略# --listen-client-urls 监听客户端请求的url,必须# --initial-cluster 初始启动的集群配置,必须# --initial-cluster-state 初始化集群状态,取值为new和existing,可以省略# --initial-cluster-token 集群初始化token,可以省略etcd --enable-v2=true --data-dir=data.${THIS_NAME} --name ${THIS_NAME} \        --initial-advertise-peer-urls http://${THIS_IP}:${THIS_PORT_PEER} --listen-peer-urls http://${THIS_IP}:${THIS_PORT_PEER} \        --advertise-client-urls http://${THIS_IP}:${THIS_PORT_API} --listen-client-urls http://${THIS_IP}:${THIS_PORT_API} \        --initial-cluster ${CLUSTER} \        --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}


第二个脚本,需要把里面的内容替换如下:

# For every machineTHIS_NAME=${NAME_2}THIS_IP=${HOST_2}THIS_PORT_API=${PORT_API_2}THIS_PORT_PEER=${PORT_PEER_2}# 用于杀死进程lsof -i:2479 | awk '{print $2}' | grep -v "PID" | uniq | xargs kill -9


第三个脚本,需要把里面的内容替换如下:

# For every machineTHIS_NAME=${NAME_3}THIS_IP=${HOST_3}THIS_PORT_API=${PORT_API_3}THIS_PORT_PEER=${PORT_PEER_3}# 用于杀死进程lsof -i:2579 | awk '{print $2}' | grep -v "PID" | uniq | xargs kill -9


有了这3个脚本,分别开3个窗口,分别执行,服务启动截图如下:

image.gif_LEIBYSHRK)H5ROHH7$)CNS.png


当这3个脚本全部启动后,集群部署完毕,我们检查一下3个节点的健康状态:

curl http://127.0.0.1:2379/healthcurl http://127.0.0.1:2479/healthcurl http://127.0.0.1:2579/health


返回结果如下,其中peerURLs是节点互相通信访问的url,clientURLs是对外访问的url:

{"members":[        {"id":"264ae6bc59e99892","name":"etcd-01","peerURLs":["http://127.0.0.1:2380"            ],"clientURLs":["http://127.0.0.1:2379"            ]        },        {"id":"dbafe5ad6b652eda","name":"etcd-02","peerURLs":["http://127.0.0.1:2480"            ],"clientURLs":["http://127.0.0.1:2479"            ]        },        {"id":"f570ae41f524bdcb","name":"etcd-03","peerURLs":["http://127.0.0.1:2580"            ],"clientURLs":["http://127.0.0.1:2579"            ]        }    ]}


3.2.2 遇到问题

问题1:服务启动后,不能使用v2接口,比如执行

“curl http://127.0.0.1:2379/v2/members”,提示“404 page not found”

问题原因:因为V3.4版本默认是V3接口,不支持V2

解决方案:需要在启动etcd时,加上“--enable-v2=true”,强制使用V2接口


问题2:服务启动失败,提示“conflicting environment variable "ETCD_ENABLE_V2" is shadowed by corresponding command-line flag (either unset environment variable or disable flag)”

问题原因:因为启动etcd时,参数“--enable-v2=true”导致,因为V3.4版本会读取该配置,所以提示配置重复。

解决方案:不能删除该参数,否则会引入其它问题,我是关闭所有窗口,然后重新启动etcd即可。


问题3:启动某个节点时,提示member已经存在

问题原因:因为之前启动过该节点,该member已经存在,不能初始化,只能加入已经存在的member

解决方案:需要将启动脚本中的“CLUSTER_STATE=new”改为“CLUSTER_STATE=existing”


3.3 常规操作


3.3.1 集群管理

我们在部署集群时,用到一些方法,这里我简单汇总一下:

// 版本检查,输出{"etcdserver":"3.4.14","etcdcluster":"3.4.0"}curl http://127.0.0.1:2379/version// 健康检查,输出{"health":"true"}curl http://127.0.0.1:2379/health// 查看集群节点curl http://127.0.0.1:2379/v2/members


3.3.2 键值操作

设置键的值:

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="hello world"


返回结果:

{"action":"set","node":{"key":"/message","value":"hello world","modifiedIndex":43,"createdIndex":43    }}


读取键的值:

curl http://127.0.0.1:2379/v2/keys/message


返回结果:

{"action":"get","node":{"key":"/message","value":"hello world","modifiedIndex":43,"createdIndex":43    }}


给键设置10s的超时时间:

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="hello world" -d ttl=10


返回结果(prevNode是旧值):

{"action":"set","node":{"key":"/message","value":"hello world","expiration":"2021-01-21T00:16:13.777434Z","ttl":10,"modifiedIndex":44,"createdIndex":44    },"prevNode":{"key":"/message","value":"hello world","modifiedIndex":43,"createdIndex":43    }}

获取该键值,超时后,就提示“key not found”:

image.gifQCU5LDA[VEL6{]98W$@NS{N.png

3.3.3 watch通知

可以对key设置监听,当key的值有变化时,会通知监听的客户端,我们先在客户端A监听key:

curl http://127.0.0.1:2379/v2/keys/message?wait=true


然后在客户端B,修改该key的值:

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="hello world2"


客户端A返回并退出,返回结果:

{"action":"set","node":{"key":"/message","value":"hello world2","modifiedIndex":48,"createdIndex":48    }}


如果希望客户端A能持续监听,不退出,可以通过增加stream=true参数:

curl "http://127.0.0.1:2379/v2/keys/message?wait=true&stream=true"


当在客户端B执行如下时:

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="hello world" -d ttl=1

客户端A会实时监听返回,比如当给key设置值,或者当key过期时,客户端A都会监听到:

HXZAIGGYY8$K~PFLP}LYBZD.pngimage.gif

3.3.4 目录操作

这个可用于配置管理,因为etcd数据结构是颗目录树,所以我们也可以PUT一个目录,目录里存放我们的服务的配置数据:

curl http://127.0.0.1:2379/v2/keys/animal -XPUT -d dir=true


返回结果:

{"action":"set","node":{"key":"/animal","dir":true,"modifiedIndex":80,"createdIndex":80    }}


可以获取目录中的数据,如果增加参数recursive=true,可以递归罗列:

curl http://127.0.0.1:2379/v2/keys?recursive=true


返回结果:

{"action":"get","node":{"dir":true,"nodes":[            {"key":"/animal","dir":true,"modifiedIndex":80,"createdIndex":80            }        ]    }}


下面我们举一个稍微复杂的示例,创建2个目录:

curl http://127.0.0.1:2379/v2/keys/animal -XPUT -d dir=truecurl http://127.0.0.1:2379/v2/keys/animal/cat -XPUT -d value="a little cat"curl http://127.0.0.1:2379/v2/keys/animal/dog -XPUT -d value="a big dog"curl http://127.0.0.1:2379/v2/keys/tool -XPUT -d dir=truecurl http://127.0.0.1:2379/v2/keys/tool/car -XPUT -d value="a small car"curl http://127.0.0.1:2379/v2/keys/tool/ship -XPUT -d value="a big ship"


然后递归获取里面的数据:

curl http://127.0.0.1:2379/v2/keys?recursive=true


返回结果:

{"action":"get","node":{"dir":true,"nodes":[            {"key":"/tool","dir":true,"nodes":[                    {"key":"/tool/car","value":"a small car","modifiedIndex":84,"createdIndex":84                    },                    {"key":"/tool/ship","value":"a big ship","modifiedIndex":85,"createdIndex":85                    }                ],"modifiedIndex":83,"createdIndex":83            },            {"key":"/animal","dir":true,"nodes":[                    {"key":"/animal/cat","value":"a little cat","modifiedIndex":81,"createdIndex":81                    },                    {"key":"/animal/dog","value":"a big dog","modifiedIndex":82,"createdIndex":82                    }                ],"modifiedIndex":80,"createdIndex":80            }        ]    }}


我们也可以通过下面方式删除animal目录:

curl http://127.0.0.1:2379/v2/keys/animal?recursive=true -XDELETE


返回结果:

{"action":"delete","node":{"key":"/animal","dir":true,"modifiedIndex":86,"createdIndex":80    },"prevNode":{"key":"/animal","dir":true,"modifiedIndex":80,"createdIndex":80    }}


3.3.5 自动创建有序key

通过对一个目录发起POST请求,我们能够让创建的key的名字是有序的。自动创建有序key的这个功能在许多场景下都很有用,例如,用于实现一个对处理顺序有严格要求的队列等。

curl http://127.0.0.1:2379/v2/keys/queue -XPOST -d value=Jobl


返回结果:

{"action":"create","node":{"key":"/queue/00000000000000000088","value":"Jobl","modifiedIndex":88,"createdIndex":88    }}

如果我们多执行几次,会发现key中的值是递增关系,但如果在并发情况下,就不一定每次都是递增1,看一下执行结果:

D$G}@G0[TKB)3}IY6OQ9{TL.jpgimage.gif

我们可以列举这个目录下所有的key,并排序输出:

curl -s "http://127.0.0.1:2379/v2/keys/queue?recursive=true&sort=true"


输出结果:

{"action":"get","node":{"key":"/queue","dir":true,"nodes":[            {"key":"/queue/00000000000000000088","value":"Jobl","modifiedIndex":88,"createdIndex":88            },            {"key":"/queue/00000000000000000089","value":"Jobl","modifiedIndex":89,"createdIndex":89            },            {"key":"/queue/00000000000000000090","value":"Jobl","modifiedIndex":90,"createdIndex":90            },            {"key":"/queue/00000000000000000091","value":"Jobl","modifiedIndex":91,"createdIndex":91            },            {"key":"/queue/00000000000000000092","value":"Jobl","modifiedIndex":92,"createdIndex":92            },            {"key":"/queue/00000000000000000093","value":"Jobl","modifiedIndex":93,"createdIndex":93            }        ],"modifiedIndex":88,"createdIndex":88    }}
相关文章
|
存储 JSON NoSQL
ETCD教程-4.深入ETCD
目前etcd主要经历了3个大的版本,分别为etcd 0.4版本、etcd 2.0版本和etcd 3.0版本。
877 0
ETCD教程-4.深入ETCD
|
存储 域名解析 缓存
|
运维
ETCD系列之一:简介
本文介绍etcd使用场景,工作原理。
76737 3
|
3月前
|
存储 监控 算法
[etcd]简介与安装
[etcd]简介与安装
|
6月前
|
存储 算法 开发者
etcd入门指南
etcd入门指南
382 4
etcd入门指南
|
6月前
|
存储 消息中间件 算法
ETCD(一)简介
ETCD(一)简介
96 0
|
数据可视化 Ubuntu Go
etcd源码分析 - 0.搭建学习etcd的环境
如果要更深入地研究etcd,就需要我们涉及到源码、并结合实践进行学习。那么,接下来,我将基于`v3.4`这个版本,做一期深入的环境搭建。
96 0
|
存储 设计模式 缓存
etcd 实战基础篇(一)
etcd 实战基础篇(一)
366 0
etcd 实战基础篇(一)
|
NoSQL 安全 Redis
etcd 实战基础篇(二)
etcd 实战基础篇(二)
257 0
etcd 实战基础篇(二)
|
存储 API DataX
netcdf入门(转)
一、概述  NetCDF全称为network Common Data Format,中文译法为“网络通用数据格式”,对程序员来说,它和zip、jpeg、bmp文件格式类似,都是一种文件格式的标准。netcdf文件开始的目的是用于存储气象科学中的数据,现在已经成为许多数据采集软件的生成文件的格式。
1533 0