存储服务:分布式键值存储工具

3,486 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天,点击查看活动详情

简介

什么是etcd?

etcd 是一个一致的分布式键值存储。在分布式系统中主要用作单独的协调服务。

并设计用于保存可完全放入内存中的少量数据

2 安装和基础使用

     git clone -b v3.5.0 https://github.com/etcd-io/etcd.git
 2005  ls
 2006  cd etcd/
 2007  ls
 2008  ./build.sh
 2009  ls 
 2019  export PATH="$PATH:/data/etcds/etcd/bin"
 2020  etcd --version

安装后,需要启动它

    nohup etcd >etcd.log 2>&1 &

指定客户端连接本服务时,需要键入的主机地址:

   nohup etcd --listen-client-urls http://192.168.30.131:2379 --advertise-client-urls http://192.168.30.131:2379 >etcds.log 2>&1 &

设置键值:

    etcdctl --endpoints=127.0.0.1:2379 put foo "hello bar."

获取键值:

    etcdctl --endpoints=127.0.0.1:2379 --write-out="json" get foo

其他客户端可以通过外网ip连接

    etcdctl --endpoints=192.168.30.131:2379 endpoint health

2.1 如何设置演示 etcd 集群,访问etcd

直接通过ip端口号访问:

设置键值:

    etcdctl --endpoints=127.0.0.1:2379 put foo "hello bar."

获取键值:

etcdctl --endpoints=127.0.0.1:2379 --write-out="json" get foo
 

2.3 如何通过前缀获取键

大量相似的键,存储的值,可以通过其共同的前缀 一次性获取,比如设置 web1 web2 web3 后,通过web可以全部获取

    root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 put web1 "hello web1"
	OK
	root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 put web2 "hello web2"
	OK
	root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 put web3 "hello web3"
	OK
	root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 get web --prefix
	web1
	hello web1
	web2
	hello web2
	web3
	hello web3

结果写入json:

  etcdctl --endpoints=127.0.0.1:2379 --write-out="json" get web --prefix
    
    {"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":6,"raft_term":2},
    "kvs":[{"key":"d2ViMQ==","create_revision":4,"mod_revision":4,"version":1,"value":"aGVsbG8gd2ViMQ=="},
        {"key":"d2ViMg==","create_revision":5,"mod_revision":5,"version":1,"value":"aGVsbG8gd2ViMg=="},
        {"key":"d2ViMw==","create_revision":6,"mod_revision":6,"version":1,"value":"aGVsbG8gd2ViMw=="}],
     "count":3}

2.4 如何删除键

只删除一个

按前缀批量删除

	root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 del web1
	1
	root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 del web --prefix
	2

2.5 如何在事务中进行多次写入 multiple writes in a transaction

设置一个新值

  etcdctl --endpoints=127.0.0.1:2379 user1 bad

创建事务

  etcdctl --endpoints=127.0.0.1:2379 txn --interactive

修改这个设置的值

   etcdctl --endpoints=127.0.0.1:2379 txn --interactive
	compares:
	value("user1") = "bad"

	success requests (get, put, del):
	del user1

	failure requests (get, put, del):
	put user1 good

	SUCCESS

2.6 如何监控键值更改 watch key

启动监听键值服务

     etcdctl --endpoints=127.0.0.1:2379 watch stock --prefix

在另一个进程设置这个 stock前缀的任何值,将在此处反应

     etcdctl --endpoints=127.0.0.1:2379 put stock1 100

监控台将实时反应:

 etcdctl --endpoints=127.0.0.1:2379 watch stock --prefix
	PUT
	stock1
	100

2.7 如何创建租约 lease

创建一个租约

etcdctl --endpoints=127.0.0.1:2379 lease  grant 300
lease 694d85bfb1026b25 granted with TTL(300s)
    

保持租约合法

root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 lease keep-alive 694d85bfb1026b25
lease 694d85bfb1026b25 keepalived with TTL(300)
 

在此指定租约中 创建 键值,(如果此时你的键值监听仍然在线,那么将会看到这个操作)

root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 put stock2 2000 --lease=694d85bfb1026b1f

OK

获取键值信息

root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 get stock2

root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 lease revoke 694d85bfb1026b25

注意,即使创建了租约,但是在设置键值的时候,没有指定租约id,那么键值是不会受到租约的影响的。

2.8 如何创建锁

etcd的锁是 阻塞锁,如果一个客户端创建了锁,那么这个客户端将干不了其他事情

  etcdctl --endpoints=127.0.0.1:2379 lock mutex1
  mutex1/694d85bfb1026b2e

这时,客户端2 如果尝试创建同样的锁,将不被响应

   etcdctl --endpoints=127.0.0.1:2379 lock mutex1

锁可以没有时长限制。

2.9 etcd集群如何进行leader选举

集群选举可以指定

   etcdctl --endpoints=127.0.0.1:2379 elect one p1
      one/694d85bfb1026b41
      p1

或者

   etcdctl --endpoints=127.0.0.1:2379 elect one p2
      one/694d85bfb1026b48
      p2

2.10 如何检查集群状态

状态检查,为每台机器指定初始集群配置:

  etcdctl --write-out=table --endpoints=127.0.0.1:2379 endpoint status

健康检查

  etcdctl --endpoints=127.0.0.1:2379 endpoint health

例子:

    etcdctl --endpoints=$ENDPOINTS endpoint health
root@fk:/data/etcds#    etcdctl --write-out=table --endpoints=127.0.0.1:2379 endpoint status
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|    ENDPOINT    |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 127.0.0.1:2379 | 8e9e05c52164694d |   3.5.0 |   29 kB |      true |      false |         2 |         46 |                 46 |        |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
root@fk:/data/etcds# etcdctl --endpoints=127.0.0.1:2379 endpoint health
127.0.0.1:2379 is healthy: successfully committed proposal: took = 4.369833ms

2.12 如何保存数据库

etcd 数据库快照指南,snapshot保存 etcd 数据库的时间点快照:

只能从一个 etcd 节点请求快照,因此--endpoints标志应仅包含一个端点

etcdctl --endpoints=127.0.0.1:2379 snapshot save my.db

etcdctl --endpoints=127.0.0.1:2379 snapshot save my.db
	{"level":"info","ts":1673961180.7177243,"caller":"snapshot/v3_snapshot.go:68","msg":"created temporary db file","path":"my.db.part"}
	{"level":"info","ts":1673961180.720011,"logger":"client","caller":"v3/maintenance.go:211","msg":"opened snapshot stream; downloading"}
	{"level":"info","ts":1673961180.7207196,"caller":"snapshot/v3_snapshot.go:76","msg":"fetching snapshot","endpoint":"127.0.0.1:2379"}
	{"level":"info","ts":1673961180.72545,"logger":"client","caller":"v3/maintenance.go:219","msg":"completed snapshot read; closing"}
	{"level":"info","ts":1673961180.7287757,"caller":"snapshot/v3_snapshot.go:91","msg":"fetched snapshot","endpoint":"127.0.0.1:2379","size":"29 kB","took":"now"}
	{"level":"info","ts":1673961180.728973,"caller":"snapshot/v3_snapshot.go:100","msg":"saved","path":"my.db"}
	Snapshot saved at my.db

2.13 支持模块

有以下常用模块:

	go.etcd.io/etcd/api/v3 - 包含定义 etcd 客户端和服务器之间通信协议的 API 定义(如原型和原型生成的库)。

	go.etcd.io/etcd/pkg/v3 - etcd 使用的实用程序包集合,不特定于 etcd 本身。一个包只有在将来可能被移出到它自己的存储库中时才属于这里。请避免在此处添加自身有很多依赖项的代码,因为它们会自动成为客户端库的依赖项(我们希望保持轻量级)。

	go.etcd.io/etcd/client/v3 - 用于通过网络 (grpc) 联系 etcd 的客户端库。推荐用于 etcd 的所有新用法。

	go.etcd.io/etcd/client/v2 - 用于通过 HTTP 协议联系 etcd 的旧版客户端库。已弃用。所有新用法都应依赖于 /v3 库。

	go.etcd.io/etcd/raft/v3 - 分布式共识协议的实现。应该没有 etcd 特定代码。

	go.etcd.io/etcd/server/v3 - etcd 实现。这个包中的代码是 etcd 内部的,不应该被外部项目使用。包布局和 API 可以在次要版本中更改。

	go.etcd.io/etcd/etcdctl/v3 - 一个用于访问和管理 etcd 的命令行工具。

	go.etcd.io/etcd/tests/v3 - 一个包含 etcd 所有集成测试的模块。注意:所有单元测试(快速且不需要跨模块依赖)都应保存在本地模块中以供测试代码使用。

	go.etcd.io/bbolt - 持久 b 树的实现。托管在单独的存储库中:https ://github.com/etcd-io/bbolt 。

2.14 库和工具

etcd 工具和客户端库的列表

	etcdctl - etcd 的命令行客户端
	etcd-dump - 用于转储/恢复 etcd 的命令行实用程序。
	etcd-fs - 用于 etcd 的 FUSE 文件系统
	etcddir - 实时同步 etcd 和本地目录。使用 Windows 和 Linux。
	etcd-browser - 使用 AngularJS 的基于 Web 的 etcd 键/值编辑器
	etcd-lock - Master election & distributed r/w lock implementation using etcd - 支持 v2
	etcd-console - 使用 PHP 的 etcd 的基于 Web 的键/值编辑器
	etcd-viewer - 用 Ja​​va 编写的 etcd 键值存储编辑器/查看器
	etcdtool - 将 etcd 目录导出/导入/编辑为 JSON/YAML/TOML 并使用 JSON 模式验证目录
	etcdloadtest - 用于 etcd 3.0 及更高版本的命令行负载测试客户端。
	lucas - 用于 kubernetes etcd3.0+ 集群的基于 Web 的键值查看器。
	etcd-manager - 现代、高效、多平台且免费的 etcd 3.x GUI 和客户端工具。适用于 Windows、Linux 和 Mac。
	etcd-backup-restore - 定期增量备份和恢复 etcd 的实用程序。
	etcdadm - 用于操作 etcd 集群的命令行工具。
	图书馆
	以下部分按语言列出了 etcd 客户端库。

Go

	etcd/client/v3 - 官方维护的 v3 客户端
	etcd/client/v2 - 官方维护的 v2 客户端
	go-etcd - 已弃用的官方客户端。可能对旧版本 (<2.0.0) 的 etcd 有用。
	encWrapper -encWrapper 是 etcd 客户端密钥 API/KV 的加密包装器.
	  
Python

	kragniz/python-etcd3 - v3 客户端
	jplana/python-etcd - 支持 v2
	russellhaering/txetcd - 一个扭曲的 Python 库
	cholcombe973/autodock - 一个 docker 部署自动化工具
	lisael/aioetcd - (Python 3.4+) Asyncio 协程客户端(支持 v2)
	txaio-etcd - 用于 Twisted(今天)和 asyncio(未来)的异步 etcd v3-only 客户端库
	dims/etcd3-gateway - 使用 HTTP grpc 网关的 etcd v3 API 库
	aioetcd3 -(Python 3.6+)用于异步的 etcd v3 API
	Revolution1/etcd3-py -(python2.7 和 python3.5+)用于 etcd v3 的 Python 客户端,使用 gRPC-JSON-Gateway
	 

使用 etcd 的项目

spf13/viper - Go 配置库,使用可选加密从 ENV、pflags、文件和 etcd 中读取值
go-discover - Go 中的服务发现
gleicon/goreman - 支持 etcd 的 Go Foreman 克隆的分支
garethr/hiera-etcd - 使用 etcd 的 Puppet hiera 后端
mattn/etcd-vim - vim 内部的 SET 和 GET 键

小结

资源 如何添加和删除成员,处理 etcd 集群成员资格的步骤. member添加、删除、更新会员资格:

      https://etcd.io/docs/v3.5/tutorials/how-to-deal-with-membership/
      
      https://etcd.io/docs/v3.5/faq/

是否全部客户端的请求都发往了 etcd leader

 是基于领导者的;领导者处理所有需要集群共识的客户端请求。
 
 但是,客户端不需要知道哪个节点是领导者。
 
 发送给跟随者的任何需要达成共识的请求都会自动转发给领导者。不需要共识的请求(例如,序列化读取)可以由任何集群成员处理

配置资源:

listen-<client,peer>-urls、advertise-client-urls 或 initial-advertise-peer-urls 之间有什么区别

listen-client-urls并listen-peer-urls指定 etcd 服务器绑定到的本地地址以接受传入连接。

要侦听所有接口的端口,请指定0.0.0.0为侦听 IP 地址。

advertise-client-urls并initial-advertise-peer-urls指定 etcd 客户端。

其他 etcd 成员应该用来联系 etcd 服务器的地址。

对外地址必须可以从远程计算机访问。

不要为生产设置发布诸如localhost或之类0.0.0.0的地址,因为这些地址无法从远程计算机访问。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天,点击查看活动详情