博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ETCD实战
阅读量:3962 次
发布时间:2019-05-24

本文共 5714 字,大约阅读时间需要 19 分钟。

简介

etcd介绍

详情见腾讯文档:

etcd是使用Go语言开发的一个开源的、高可用的分布式key-value存储系统,可以用于配置共享和服务的注册和发现。

类似项目有zookeeper和consul。

etcd具有以下特点:

  • 完全复制:集群中的每个节点都可以使用完整的存档
  • 高可用性:Etcd可用于避免硬件的单点故障或网络问题
  • 一致性:每次读取都会返回跨多主机的最新写入
  • 简单:包括一个定义良好、面向用户的API(gRPC)
  • 安全:实现了带有可选的客户端证书身份验证的自动化TLS
  • 快速:每秒10000次写入的基准速度
  • 可靠:使用Raft算法实现了强一致、高可用的服务存储目录

为什么用 etcd 而不用ZooKeeper?

etcd 实现的这些功能,ZooKeeper都能实现。那么为什么要用 etcd 而非直接使用ZooKeeper呢?

为什么不选择ZooKeeper?

  • 部署维护复杂,其使用的Paxos强一致性算法复杂难懂。官方只提供了Java和C两种语言的接口。
  • 使用Java编写引入大量的依赖。运维人员维护起来比较麻烦。
  • 最近几年发展缓慢,不如etcd和consul等后起之秀。

为什么选择etcd?

  • 简单。使用 Go 语言编写部署简单;支持HTTP/JSON API,使用简单;使用 Raft 算法保证强一致性让用户易于理解。
  • etcd 默认数据一更新就进行持久化。
  • etcd 支持 SSL 客户端安全认证。
    最后,etcd 作为一个年轻的项目,正在高速迭代和开发中,这既是一个优点,也是一个缺点。优点是它的未来具有无限的可能性,缺点是无法得到大项目长时间使用的检验。然而,目前 CoreOS、Kubernetes和CloudFoundry等知名项目均在生产环境中使用了etcd,所以总的来说,etcd值得你去尝试。

etcd应用场景

场景一:服务发现(Service Discovery)

在这里插入图片描述

场景二:消息发布与订阅

场景三:负载均衡
场景四:分布式通知与协调
场景五:分布式锁、分布式队列
场景六:集群监控与Leader竞选

使用

etcdctl

etcdctl属于ETCD的客户端,目前V3版本也兼容了V2版本的接口API,故而在使用etcdctl时,必须在命令开头指明所使用的API版本。

ETCDCTL_API=3 etcdctl put key1 "A"  //返回OK表示添加key1:'A'键值对成功ETCDCTL_API=3 etcdctl get key1      //获取key1键的值ETCDCTL_API=3 etcdctl del key1      //删除key1键值对

REST API

curl http://127.0.0.1:2379/version //查看版本 //V2版本 curl http://127.0.0.1:2379/v2/keys/hello -XPUT -d value="world" // 创建键值对(hello:"world") curl http://127.0.0.1:2379/v2/keys/hello //查看hello键的值 curl http://127.0.0.1:2379/v2/keys/hello -X DELETE //删除hello键值对//V3版本,注意在V3版本中所有的key和value都必须转换为base64编码然后才可以存储// foo is 'Zm9v' in Base64// bar is 'YmFy' in Base64curl -L http://127.0.0.1:2379/v3beta/kv/put \	-X POST -d '{"key": "Zm9v", "value": "YmFy"}'// 创建键值对 foo:barcurl -L http://127.0.0.1:2379/v3beta/kv/range \	-X POST -d '{"key": "Zm9v"}' // 查看键值对 foo

版本设置

ETCD v2 和 v3 两个版本不兼容,且 v2 已经停止支持。如果一个系统上同时按照了两个版本,需要通过环境变量来切换:

export ETCDCTL_API=3

读写数据

put 命令写数据:

etcdctl --endpoints=$ENDPOINTS put foo "Hello World!"

get 命令读数据:

etcdctl --endpoints=$ENDPOINTS get fooetcdctl --endpoints=$ENDPOINTS --write-out="json" get foo

通过–write-out="json"选项读数据时,会读包括元数据在内的所有数据,并以 JSON 格式输出。

示例:

func main(){
cli, err := clientv3.New(clientv3.Config{
Endpoints: []string{
"127.0.0.1:2379"}, DialTimeout:time.Second*5, }) if err != nil {
fmt.Printf("connect to etcd failed, err:%v", err) return } defer cli.Close() // put ctx, cancel := context.WithTimeout(context.Background(), time.Second) _, err = cli.Put(ctx, "s4", "真好") if err != nil {
fmt.Printf("put to etcd failed, err:%v", err) return } cancel() // get ctx, cancel = context.WithTimeout(context.Background(), time.Second) gr, err := cli.Get(ctx, "s4") if err != nil {
fmt.Printf("get from etcd failed, err:%v", err) return } for _, ev := range gr.Kvs{
fmt.Printf("key:%s value:%s\n", ev.Key, ev.Value) } cancel()}

通过 prefix 选项读数据

etcdctl --endpoints=$ENDPOINTS put web1 value1etcdctl --endpoints=$ENDPOINTS put web2 value2etcdctl --endpoints=$ENDPOINTS put web3 value3etcdctl --endpoints=$ENDPOINTS get web --prefix

删除数据

etcdctl --endpoints=$ENDPOINTS put key myvalueetcdctl --endpoints=$ENDPOINTS del keyetcdctl --endpoints=$ENDPOINTS put k1 value1etcdctl --endpoints=$ENDPOINTS put k2 value2etcdctl --endpoints=$ENDPOINTS del k --prefix

事务性写入 txn

通过 txn 可以将多个请求放入一个事务:

etcdctl --endpoints=$ENDPOINTS put user1 badetcdctl --endpoints=$ENDPOINTS txn --interactivecompares:value("user1") = "bad"      success requests (get, put, delete):del user1  failure requests (get, put, delete):put user1 good

监控数据变化 watch

通过 watch 选项,可以在将来发生改变时获得通知:

etcdctl --endpoints=$ENDPOINTS watch stock1etcdctl --endpoints=$ENDPOINTS put stock1 1000etcdctl --endpoints=$ENDPOINTS watch stock --prefixetcdctl --endpoints=$ENDPOINTS put stock1 10etcdctl --endpoints=$ENDPOINTS put stock2 20
func main(){
cli, err := clientv3.New(clientv3.Config{
Endpoints: []string{
"127.0.0.1:2379"}, DialTimeout:time.Second*5, }) if err != nil {
fmt.Printf("connect to etcd failed, err:%v", err) return } defer cli.Close() // watch watchCh := cli.Watch(context.Background(), "s4") for wresp := range watchCh{
for _, evt := range wresp.Events{
fmt.Printf("type:%s key:%s value:%s\n", evt.Type, evt.Kv.Key, evt.Kv.Value) } }}

安全写入 lease

lease 选项可以通过 TTL 写入数据:

etcdctl --endpoints=$ENDPOINTS lease grant 300# lease 2be7547fbc6a5afa granted with TTL(300s)etcdctl --endpoints=$ENDPOINTS put sample value --lease=2be7547fbc6a5afaetcdctl --endpoints=$ENDPOINTS get sampleetcdctl --endpoints=$ENDPOINTS lease keep-alive 2be7547fbc6a5afaetcdctl --endpoints=$ENDPOINTS lease revoke 2be7547fbc6a5afa# or after 300 secondsetcdctl --endpoints=$ENDPOINTS get sample

分布式锁 lock

在这里插入图片描述

etcdctl --endpoints=$ENDPOINTS lock mutex1# another client with the same name blocksetcdctl --endpoints=$ENDPOINTS lock mutex1

集群状态

为每台机器指定初始群集配置:

etcdctl --write-out=table --endpoints=$ENDPOINTS endpoint status+------------------+------------------+---------+---------+-----------+-----------+------------+|     ENDPOINT     |        ID        | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |+------------------+------------------+---------+---------+-----------+-----------+------------+| 10.240.0.17:2379 | 4917a7ab173fabe7 | 3.0.0   | 45 kB   | true      |         4 |      16726 || 10.240.0.18:2379 | 59796ba9cd1bcd72 | 3.0.0   | 45 kB   | false     |         4 |      16726 || 10.240.0.19:2379 | 94df724b66343e6c | 3.0.0   | 45 kB   | false     |         4 |      16726 |+------------------+------------------+---------+---------+-----------+-----------+------------+etcdctl --endpoints=$ENDPOINTS endpoint health10.240.0.17:2379 is healthy: successfully committed proposal: took = 3.345431ms10.240.0.19:2379 is healthy: successfully committed proposal: took = 3.767967ms10.240.0.18:2379 is healthy: successfully committed proposal: took = 4.025451ms

转载地址:http://izhzi.baihongyu.com/

你可能感兴趣的文章