什么是etcd?

etcd 发音为/ˈɛtsiːdiː/,名字的由来,“distributed etc directory.”,意思是“分布式etc目录”,说明它存的是大型分布式系统的配置信息。
官网的一句话
A distributed, reliable key-value store for the most critical data of a distributed system.
翻译并理解过来就是:一个用于存储分布式系统中最关键的数据的仓库,它是分布式的、可靠的键值对仓库。首先它是个数据存储仓库,它的特性是分布式的、可靠性的,数据存储格式是键值对存储,它主要用于存储分布式系统中的关键数据。

etcd的应用场景

etcd的应用场景:服务发现和服务注册、配置中心、分布式锁。

1、服务发现
服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听 udp 或 tcp 端口,并且通过名字就可以查找和连接。
控制时序,即所有想要获得锁的用户都会被安排执行,但是获得锁的顺序也是全局唯一的,同时决定了执行顺序。
2、配置中心
将一些配置信息放到 etcd 上进行集中管理。
这类场景的使用方式通常是这样:应用在启动的时候主动从 etcd 获取一次配置信息,同时,在 etcd 节点上注册一个 Watcher 并等待,以后每次配置有更新的时候,etcd 都会实时通知订阅者,以此达到获取最新配置信息的目的。
3、分布式锁
因为 etcd 使用 Raft 算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。

  • 保持独占即所有获取锁的用户最终只有一个可以得到。etcd 为此提供了一套实现分布式锁原子操作 CAS(CompareAndSwap)的API。通过设置prevExist值,可以保证在多个节点同时去创建某个目录时,只有一个成功。而创建成功的用户就可以认为是获得了锁。
  • 控制时序,即所有想要获得锁的用户都会被安排执行,但是获得锁的顺序也是全局唯一的,同时决定了执行顺序。etcd 为此也提供了一套API(自动创建有序键),对一个目录建值时指定为POST动作,这样 etcd会自动在目录下生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可以使用 API按顺序列出所有当前目录下的键值。此时这些键的值就是客户端的时序,而这些键中存储的值可以是代表客户端的编号。

为什么用etcd而不用zookeeper?

  • etcd简单,使用Go语言编写部署简单,支持HTTP/JSON API,使用简单:使用Raft算法保证强一致性,让用户易于理解。
  • etcd默认数据一更新就进行持久化。
  • etcd支持SSL客户端安全认证。
  • zookeeper部署维护复杂,其使用的PAXOS强一致性算法难懂。官方只提供了JAVA和C两种语言的接口。
  • zookeeper 使用JAVA编写引入大量依赖。运维人员维护起来比较麻烦。

下面开始实战

安装etcd

  1. 所谓安装ectd,实际上就是下载etcd文件,然后解压即可。

etcd下载目录:https://github.com/etcd-io/etcd/releases

(如果上面的地址下载不了。就进入这个地址下载:https://studygolang.com/articles/28682)

  1. 下载到本地window,通过scp (或者ftp工具)上传到linux目录即可:

scp -r ./etcd-v3.4.7-linux-amd64.tar.gz root@81.68.81.16:/usr/local

  1. 到linux的环境执行以下操作:
cd /usr/local
tar -xzvf etcd-v3.4.7-linux-amd64.tar.gz

解压成功后能看到下面的文件:

首先,必须开启etcd(需要在etcd的解压目录下执行)

./etcd (后台挂起程序:nohup ./etcd &)

查看etcd默认的端口是否已经开启:netstat -antp | grep 2379

然后就可以在xshell控制台新增和读取key-value(需要在etcd的解压目录下执行)

./etcdctl --endpoints=localhost:2379 put mylove lxz
./etcdctl --endpoints=localhost:2379 get mylove
#删除key:
./etcdctl del /hello


如果没开启etcd,就进行读取或新增key的话,会出现下面的报错:

通过go代码实现etcd的读写操作

  1. 设置key-value
package main
import ("fmt""context"clientv3 "go.etcd.io/etcd/client/v3""time"
)
// 设置etcd的值
func main() {key := "bookname"value := "收敛之道"SetEtcdData(key,value)
}func SetEtcdData(key string,value string) {cli, err := clientv3.New(clientv3.Config{Endpoints:   []string{"127.0.0.1:2379"},DialTimeout: 5 * time.Second,})if err != nil {// handle error!fmt.Printf("connect to etcd failed, err:%v\n", err)return}fmt.Println("connect to etcd success")defer cli.Close()// putctx, cancel := context.WithTimeout(context.Background(), time.Second)_, err = cli.Put(ctx, key, value)cancel()if err != nil {fmt.Printf("put to etcd failed, err:%v\n", err)return}
}
  1. 读取key-value
package main
import ("fmt""context"clientv3 "go.etcd.io/etcd/client/v3""time"
)//获取etcd的值
func main() {fmt.Println("获取etcd的key")//获取单个key// key := "foo"// GetEtcdData(key)// GetEtcdData2(key)//获取多个keykeys := []string{"foo","mylove"}GetEtcdData3(keys...)
}func GetEtcdData(key string) {cli, err := clientv3.New(clientv3.Config{Endpoints:   []string{"127.0.0.1:2379"},DialTimeout: 5 * time.Second,})if err != nil {// handle error!fmt.Printf("connect to etcd failed, err:%v\n", err)return}fmt.Println("connect to etcd success")defer cli.Close()//限制请求时间为1秒ctx, cancel := context.WithTimeout(context.Background(), time.Second)resp, err := cli.Get(ctx, key)cancel()if err != nil {fmt.Printf("get from etcd failed, err:%v\n", err)return}fmt.Println(resp.Kvs) //[key:"foo" create_revision:2 mod_revision:3 version:2 value:"bar" ]fmt.Println(resp.Kvs[0])//key:"foo" create_revision:2 mod_revision:3 version:2 value:"bar"for _, ev := range resp.Kvs {fmt.Printf("获取etcd的key-value为:%s:%s\n", ev.Key, ev.Value)}
}func GetEtcdData2(key string) {var kv clientv3.KVcli, err := clientv3.New(clientv3.Config{Endpoints:   []string{"127.0.0.1:2379"},DialTimeout: 5 * time.Second,})if err != nil {// handle error!fmt.Printf("connect to etcd failed, err:%v\n", err)return}fmt.Println("connect to etcd success")defer cli.Close()//限制请求时间为1秒ctx, cancel := context.WithTimeout(context.Background(), time.Second)kv = clientv3.NewKV(cli)//用newKv的方式获取键值对resp, err := kv.Get(ctx, key)cancel()if err != nil {fmt.Printf("get from etcd failed, err:%v\n", err)return}fmt.Println(resp.Kvs) //[key:"foo" create_revision:2 mod_revision:3 version:2 value:"bar" ]fmt.Println(resp.Kvs[0])//key:"foo" create_revision:2 mod_revision:3 version:2 value:"bar"for _, ev := range resp.Kvs {fmt.Printf("22获取etcd的key-value为:%s:%s\n", ev.Key, ev.Value)}
}//获取多个键值对
func GetEtcdData3(keys...string) {cli, err := clientv3.New(clientv3.Config{Endpoints:   []string{"127.0.0.1:2379"},DialTimeout: 5 * time.Second,})if err != nil {// handle error!fmt.Printf("connect to etcd failed, err:%v\n", err)return}fmt.Println("connect to etcd success")defer cli.Close()ctx := context.TODO()//做法1//限制请求时间为1秒for _,k := range keys {//做法2// ctx, cancel := context.WithTimeout(context.Background(), time.Second)resp, err := cli.Get(ctx, k)// cancel()if err != nil {fmt.Printf("get from etcd failed, err:%v\n", err)return}for _, ev := range resp.Kvs {fmt.Printf("获取etcd的多个key-value为:%s:%s\n", ev.Key, ev.Value)}}
}
  1. 监听key的变化
package mainimport ("context""fmt""time"clientv3 "go.etcd.io/etcd/client/v3"
)// watch demo
//监听某个key的变化
func main() {cli, err := clientv3.New(clientv3.Config{Endpoints:   []string{"127.0.0.1:2379"},DialTimeout: 5 * time.Second,})if err != nil {fmt.Printf("connect to etcd failed, err:%v\n", err)return}fmt.Println("connect to etcd success")defer cli.Close()// watch key:bookname changerch := cli.Watch(context.Background(), "bookname") // <-chan WatchResponsefor wresp := range rch {for _, ev := range wresp.Events {fmt.Printf("Type: %s Key:%s Value:%s\n", ev.Type, ev.Kv.Key, ev.Kv.Value)}}
}

效果:

etcd操作多个key:

#获取某个前缀的key,--keys-only代表不展示value。
./etcdctl --endpoints=localhost:2379 get / --prefix --keys-only #获取所有key,以及对应的value
./etcdctl --endpoints=localhost:2379 get  ""  --prefix#获取所有key
./etcdctl --endpoints=localhost:2379 get  ""  --prefix --keys-only#监听某个前缀的所有key的修改
./etcdctl --endpoints=localhost:2379 watch "/k" --prefix#删除前缀是/hello开头下的所有key:
./etcdctl del /hello --prefix


代码实战:

//获取某个前缀下的所有key
//当pre_key=""的时候,获取全部的key。
func GetEtcdData4(pre_key string) {var kv clientv3.KVcli, err := clientv3.New(clientv3.Config{Endpoints:   []string{"127.0.0.1:2379"},DialTimeout: 5 * time.Second,})if err != nil {// handle error!fmt.Printf("connect to etcd failed, err:%v\n", err)return}fmt.Println("connect to etcd success")defer cli.Close()//限制请求时间为1秒ctx := context.TODO()//做法1kv = clientv3.NewKV(cli)//用newKv的方式获取键值对//获取前缀下面的所有key。当pre_key=""的时候,获取全部的key。resp, err := kv.Get(ctx, pre_key, clientv3.WithPrefix())if err != nil {fmt.Printf("get from etcd failed, err:%v\n", err)return}fmt.Println(resp.Kvs) //[key:"foo" create_revision:2 mod_revision:3 version:2 value:"bar" ]// fmt.Println(resp.Kvs[0])//key:"foo" create_revision:2 mod_revision:3 version:2 value:"bar"for _, ev := range resp.Kvs {fmt.Printf("22获取etcd的key-value为:%s:%s\n", ev.Key, ev.Value)}
}

推荐阅读:
https://blog.csdn.net/wohu1104/article/details/108552649
https://www.topgoer.com/%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C/go%E6%93%8D%E4%BD%9Cetcd/etcd%E4%BB%8B%E7%BB%8D.html

go之etcd读写实战相关推荐

  1. Linux 蓝牙读写,实战Linux Bluetooth编程(三) HCI层编程

    作者:Sam (甄峰) (HCI协议简介,HCI 在BlueZ中的实现以及HCI编程接口) 1. HCI层协议概述: HCI提供一套统一的方法来访问Bluetooth底层.如图所示: 从图上可以看出, ...

  2. C++ 文件读写实战——2进制文件查看器(16进制显示)

    简单的二进制阅读器(或者说16进制查看器) 在学习BMP位图的构成时,对网上的收费16进制查看器很是烦躁,notepad查看时卡到放弃人生 因为只是为了初步学习图片知识,以及查看2进制文件内部构成的话 ...

  3. etcd 笔记(07)— 键值对读写操作过程

    1. 读写总体概述 etcd 各个模块交互的总览,如下图所示: 总体上的请求流程从上至下依次为客户端 → API 接口层 → etcd Server → etcd raft 算法库. 读请求 客户端通 ...

  4. 降低 80% 的读写响应延迟!我们测评了 etcd 3.4 新特性(内含读写发展史)

    作者 | 陈洁(墨封)  阿里云开发工程师 导读:etcd 作为 K8s 集群中的存储组件,读写性能方面会受到很多压力,而 etcd 3.4 中的新特性将有效缓解压力,本文将从 etcd 数据读写机制 ...

  5. etcd 在超大规模数据场景下的性能优化

    2019独角兽企业重金招聘Python工程师标准>>> 作者 | 阿里云智能事业部高级开发工程师 陈星宇(宇慕) 概述 etcd是一个开源的分布式的kv存储系统, 最近刚被cncf列 ...

  6. 独家解读 etcd 3.4版本 |云原生生态周报 Vol. 18

    作者 | 酒祝.墨封.宇慕.衷源 关注"阿里巴巴云原生"公众号,回复关键词 "资料" ,即可获得 2019 全年 meetup 活动 PPT 合集及 K8s 最 ...

  7. 8s pod 查看 的yaml_Kubernetes入门到实战(五)深入浅出详解Pod

    作者:Happy老师 链接:https://blog.51cto.com/happylab/2500457 写在前面 前面的系列文章已介绍kubernetes架构,安装,升级和快速入门,读者通过文章的 ...

  8. python 微服务 etcd_架构之微服务(etcd)

    1. ETCD是什么 ETCD是用于共享配置和服务发现的分布式,一致性的KV存储系统.该项目目前最新稳定版本为2.3.0. 具体信息请参考[项目首页]和[Github].ETCD是CoreOS公司发起 ...

  9. 万级K8s集群背后etcd稳定性及性能优化实践

    作者:唐聪, 腾讯 CSIG 后台开发工程师 本文旨在帮助大家了解 etcd集群场景下稳定性与性能优化经验引的容量,避免给后面留坑. 背景与挑战 随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云 ...

最新文章

  1. 请问,关闭子窗口提示错误,大家遇到这样的问题吗?
  2. 能“预测未来”的AI来了!谷歌DeepMind推Dreamer,训练时间减半
  3. win messenger启动随outlook explorer
  4. 夏日炎炎 数据中心要降温更要注意湿度影响
  5. access无法 dolby_如何解决windows 8无法开启杜比音效的问题
  6. mysql key_block_size_Mysql入门mysql Key_buffer_size参数的优化设置
  7. cont::value_type相关的测试程序
  8. 详解Python序列解包(4)
  9. 多个Wyze 摄像头漏洞可导致攻击者接管设备并访问视频
  10. 关于Aws SNS的使用 小结
  11. java.security.NoSuchAlgorithmException: SHA256WithRSAandMGF1 Signature not available
  12. 计算机课题推荐人意见,课题申请推荐人意见怎么写
  13. 从Dying gasp功能看Linux的响应速度
  14. 基于面部视频的实时心率检测系统 day four
  15. 学习 JSON(入门)
  16. 海洋沉积物样品粒度分析
  17. 基于 Kintex UltraScale 系列 FPGA 的高性能 PXIE 数据预处理载板(KU060 +FMC子卡接口)
  18. 无线充电qi认证全面解读
  19. 2022 CCF中国软件大会(CCF ChinaSoft)“软件工程教育”论坛成功召开
  20. 外贸管理软件CRM、ERP对外贸企业有什么用?

热门文章

  1. 计算机网络自顶向下 利用分组嗅探器Wireshark俘获协议报文并分析IP协议
  2. 电脑硬盘坏道如何屏蔽
  3. Symbian手机 如何取消桌面壁纸?
  4. Google Earth Engine(GEE)——土地分类/覆盖案例分析含各类土地面积统计和精度评定(印度班加罗尔为例)
  5. PHP学习笔记-PHP概述与环境搭建
  6. java字符流的父类_Java基于代码实战的字符流父类、字符转换流、缓冲字符流、过滤流...
  7. 区块链学习笔记:来份P2P
  8. 财经管理中的计算机应用第三版实验报告,管理系统中计算机应用实验报告.doc...
  9. 奇瑞汽车用鸿蒙,奇瑞配鸿蒙,是自我放弃还是独辟蹊径?
  10. 照片拼图软件哪个好?快来看看这几个软件