Etcd 高可用分布式键值数据库

2019-09-02 15:56:16 浏览数 (1)

Etcd 高可用分布式键值数据库

1, Etcd简介

etcd是CoreOS团队于2016年6月发起的开源项目,他的目标是构建一个高可用的分布式键值(key_value)数据库。Etcd内部采用raft协议作为一致性算法,Etcd是基于Go语言实现的。目前很火的kubernetes等项目都用到etcd组件作为一个高可用分布式键值存储。

etcd作为服务发现系统,有以下特点:

  • 简单: 安装配置简单,而且提供了HTTP API进行交互,使用也很简单
  • 安全: 支持SSL证书验证
  • 快速: 根据官方提供的benchmark数据,单实例支持每秒2k 读操作
  • 可靠: 采用Raft算法,实现分布式系统数据的可用性和一致性

Etcd应用场景

etcd比较多的应用场景适用于服务发现,服务发现(Service Disvocery)要解决的是分布式系统中最常见的问题之一,在同一个分布式集群中的进程或服务如何才能找到对方并建立连接。 服务发现: 就是要了解集群中是否有进程在监听UDP或TCP端口,并通过名字可以进行查找和链接。

解决服务发现的先决条件:

  • 一个强一致性、高可用的服务存储目录 基于Ralf算法的etcd天生的就是这样一个强一致性、高可用的服务存储目录
  • 一种注册服务和健康服务健康状况的机制。 用户可以在etcd中注册服务,并且对注册的服务配置key TTL,定时保持服务的心跳以达到监控健康状态的效果。
  • 一种查找和连接服务的机制。 通过在etcd指定的主题下注册的服务业能在对应的主题下查找到。为了确保连接,我们可以在每个服务机器上都部署一个proxy模式的etcd,这样就可以确保访问etcd集群的服务都能够互相连接。

2,单节点安装etcd

etcd在生产环境中一般推荐集群方式部署。 etcd目前默认使用2379端口提供HTTP API服务,2380端口和peer通信(这两个端口已经被IANA官方预留给etcd);在之前的版本中可能会分别使用4001和7001,在使用的过程中需要注意这个区别。 我们直接yum安装etcd即可

代码语言:javascript复制
yum -y install etcd

启动服务

代码语言:javascript复制
systemctl start  etcd.service && systemctl enable etcd.service

查看服务状态

代码语言:javascript复制
[root@etcd-197 /]# systemctl status etcd
● etcd.service - Etcd Server
   Loaded: loaded (/usr/lib/systemd/system/etcd.service; disabled; vendor preset: disabled)
   Active: active (running) since 四 2019-08-29 15:27:16 CST; 9s ago
 Main PID: 24426 (etcd)
    Tasks: 13
   Memory: 12.7M
   CGroup: /system.slice/etcd.service
           └─24426 /usr/bin/etcd --name=default --data-dir=/var/lib/etcd/default.etcd --listen-client-urls=http://localhost:2379

8月 29 15:27:16 etcd-197 etcd[24426]: 8e9e05c52164694d received MsgVoteResp from 8e9e05c52164694d at term 2
8月 29 15:27:16 etcd-197 etcd[24426]: 8e9e05c52164694d became leader at term 2
8月 29 15:27:16 etcd-197 etcd[24426]: raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at term 2
8月 29 15:27:16 etcd-197 etcd[24426]: published {Name:default ClientURLs:[http://localhost:2379]} to cluster cdf818194e3a8c32
8月 29 15:27:16 etcd-197 etcd[24426]: ready to serve client requests
8月 29 15:27:16 etcd-197 etcd[24426]: setting up the initial cluster version to 3.3
8月 29 15:27:16 etcd-197 systemd[1]: Started Etcd Server.
8月 29 15:27:16 etcd-197 etcd[24426]: set the initial cluster version to 3.3
8月 29 15:27:16 etcd-197 etcd[24426]: enabled capabilities for version 3.3
8月 29 15:27:16 etcd-197 etcd[24426]: serving insecure client requests on 127.0.0.1:2379, this is strongly discouraged!

3, 安装Etcd集群

Etcd 是 CoreOS 推出的高可用的键值存储系统,主要用于k8s集群的服务发现等,而本身 Etcd 也支持集群模式部署,从而实现自身高可用; Etcd 构建自身高可用集群主要有三种形式:

静态发现: 预先已知 Etcd 集群中有哪些节点,在启动时直接指定好 Etcd 的各个 node 节点地址 Etcd 动态发现: 通过已有的 Etcd 集群作为数据交互点,然后在扩展新的集群时实现通过已有集群进行服务发现的机制 DNS 动态发现: 通过 DNS 查询方式获取其他节点地址信息

3.1, 静态发现搭建Etcd集群

3.1.1, 环境准备

在下面3台机器安装Etcd集群,(注意,Etcd集群节点必须为奇数)

节点/主机名

IP地址

Etcd1

172.16.1.193

Etcd2

172.16.1.195

Etcd3

172.16.1.198

3.1.2 安装Etcd

CentOS 官方提供了 Etcd 的rpm,可通过 yum 直接安装,目前 yum 上最新版本为 3.3.11,比较合适;官方最新版本更新到了 3.3.12,鉴于稳定因素,这里使用 3.3.11 搭建

代码语言:javascript复制
# yum -y install etcd
# etcd --version
etcd Version: 3.3.11
Git SHA: 2cf9e51
Go Version: go1.10.3
Go OS/Arch: linux/amd64
3.1.3 修改配置文件

默认的配置文件

代码语言:javascript复制
[root@Etcd2 /]# cat /etc/etcd/etcd.conf
#[Member]
#ETCD_CORS=""
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
#ETCD_LISTEN_PEER_URLS="http://localhost:2380"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
ETCD_NAME="default"
#ETCD_SNAPSHOT_COUNT="100000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_QUOTA_BACKEND_BYTES="0"
#ETCD_MAX_REQUEST_BYTES="1572864"
#ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"
#ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"
#ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"
#
#[Clustering]
#ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_INITIAL_CLUSTER="default=http://localhost:2380"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_STRICT_RECONFIG_CHECK="true"

#
#[Proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[Security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_AUTO_TLS="false"
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#ETCD_PEER_AUTO_TLS="false"
#
#[Logging]
#ETCD_DEBUG="false"
#ETCD_LOG_PACKAGE_LEVELS=""
#ETCD_LOG_OUTPUT="default"
#
#[Unsafe]
#ETCD_FORCE_NEW_CLUSTER="false"
#
#[Version]
#ETCD_VERSION="false"
#ETCD_AUTO_COMPACTION_RETENTION="0"
#
#[Profiling]
#ETCD_ENABLE_PPROF="false"
#ETCD_METRICS="basic"
#
#[Auth]
#ETCD_AUTH_TOKEN="simple"

修改后的配置文件,另外两台对照更改

代码语言:javascript复制
[root@Etcd1 /]# grep -v "^#" /etc/etcd/etcd.conf
#数据存放的目录
ETCD_DATA_DIR="/var/lib/etcd/etcd1"
#监听的URL,用于与其他节点通讯
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
#对外提供服务的地址,客户端会连接到这里和Etcd进行交互
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
#节点的名称
ETCD_NAME="etcd1"
#改节点的member(同伴)监听的地址,这个值会告诉集群中其他节点
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.1.193:2380"
#对外公告的该节点客户端监听地址,这个值会告诉集群中其他节点
ETCD_ADVERTISE_CLIENT_URLS="http://172.16.1.193:2379"
#集群中所有节点的信息,这里的 etcd1 是节点的 --name 指定的名字;后面的172.16.1.93:2380 是 --initial-advertise-peer-urls 指定的值
ETCD_INITIAL_CLUSTER="etcd1=http://172.16.1.193:2380,etcd2=http://172.16.1.195:2380,etcd3=http://172.16.1.198:2380"
# 创建集群的 token,这个值每个集群保持唯一。这样的话,如果你要重新创建集群,即使配置和之前一样,也会再次生成新的集群和节点 uuid;否则会导致多个集群之间的冲突,造成未知的错误
ETCD_INITIAL_CLUSTER_TOKEN="zsf-etcd-cluster"
#新建集群的时候,这个值为 new ;假如已经存在的集群,这个值为 existing
ETCD_INITIAL_CLUSTER_STATE="new"
3.1.4 启动etcd集群,并查看其状态

启动etcd集群

代码语言:javascript复制
systemctl start etcd.service

集群启动完成之后我们在任意节点执行etcdctl member list 可列出所有集群节点信息,

代码语言:javascript复制
[root@Etcd1 /]# etcdctl member list
729a9a39e059871b: name=etcd2 peerURLs=http://172.16.1.195:2380 clientURLs=http://172.16.1.195:2379 isLeader=false
ce1ac55777b620f9: name=etcd1 peerURLs=http://172.16.1.193:2380 clientURLs=http://172.16.1.193:2379 isLeader=true
e62232af7400cdbe: name=etcd3 peerURLs=http://172.16.1.198:2380 clientURLs=http://172.16.1.198:2379 isLeader=false

使用etcdctl cluster-health检查集群健康状态

代码语言:javascript复制
[root@Etcd1 /]# etcdctl cluster-health
member 729a9a39e059871b is healthy: got healthy result from http://172.16.1.195:2379
member ce1ac55777b620f9 is healthy: got healthy result from http://172.16.1.193:2379
member e62232af7400cdbe is healthy: got healthy result from http://172.16.1.198:2379

4,etcdctl V3版本使用

etcdctl是一个命令行客户端,它能提供一些简洁的命令,供用户直接跟etcd服务打交道,而无需基于 HTTP API方式。可以方便我们在对服务进行测试或者手动修改数据库内容。建议刚刚接触etcd时通过etdctl来熟悉相关操作。这些操作跟HTTP API基本上是对应的。

4.1 设置环境变量

etcd项目二进制发行包中已经包含了etcdctl工具,etcdctl支持的命令大体上分为数据库操作和非数据库操作两类。 因为我们这边使用的是etcd 3.3.11版本,etcdctl默认操作的事etcd 2.X 版本,2和3版本有些命令不一样,所以我们要添加个环境变量,来使其默认操作etcd 3.X版本

代码语言:javascript复制
export ETCDCTL_API=3

或者在`/etc/profile`文件中添加环境变量
vi /etc/profile
...
ETCDCTL_API=3
...
source /etc/profile

4.2 查看当前etcdctl的版本信息

代码语言:javascript复制
[root@etcd-197 ~]# etcdctl version
etcdctl version: 3.3.11
API version: 3.3

4.3 ectd常用命令

4.3.1 增
代码语言:javascript复制
//增
[root@etcd-197 ~]# etcdctl put zsf 'hello world!'
OK
4.3.2 查
代码语言:javascript复制
[root@etcd-197 ~]# etcdctl get zsf
zsf
hello world!

指定为json格式查找

代码语言:javascript复制
[root@etcd-197 ~]# etcdctl get --write-out="json" zsf
{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":6,"raft_term":3},"kvs":[{"key":"enNm","create_revision":6,"mod_revision":6,"version":1,"value":"aGVsbG8gd29ybGQh"}],"count":1}

基于相同前缀查找

代码语言:javascript复制
[root@etcd-197 ~]# etcdctl put zsf1 'one'
OK
[root@etcd-197 ~]# etcdctl put zsf2 'two'
OK
[root@etcd-197 ~]# etcdctl get zsf --prefix
zsf
hello world!
zsf1
one
zsf2
two
4.3.3 改
代码语言:javascript复制
[root@etcd-197 ~]# etcdctl put zsf "test"
OK
[root@etcd-197 ~]# etcdctl get zsf
zsf
test
4.3.4 删
代码语言:javascript复制
[root@etcd-197 ~]# etcdctl del zsf1
1
[root@etcd-197 ~]# etcdctl get zsf1
[root@etcd-197 ~]#
4.3.5 查看集群状态
代码语言:javascript复制
[root@etcd-197 ~]# etcdctl --write-out=table  endpoint status
 ---------------- ------------------ --------- --------- ----------- ----------- ------------ 
|    ENDPOINT    |        ID        | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
 ---------------- ------------------ --------- --------- ----------- ----------- ------------ 
| 127.0.0.1:2379 | 8e9e05c52164694d |  3.3.11 |   20 kB |      true |         3 |         17 |
 ---------------- ------------------ --------- --------- ----------- ----------- ------------ 

4.4 集群操作

代码语言:javascript复制
member add          Adds a member into the cluster
member remove       Removes a member from the cluster
member update       Updates a member in the cluster
member list         Lists all members in the cluster

列出集群成员:

代码语言:javascript复制
[root@Etcd1 ~]# etcdctl member list -w table
 ------------------ --------- ------- -------------------------- -------------------------- 
|        ID        | STATUS  | NAME  |        PEER ADDRS        |       CLIENT ADDRS       |
 ------------------ --------- ------- -------------------------- -------------------------- 
| 729a9a39e059871b | started | etcd2 | http://172.16.1.195:2380 | http://172.16.1.195:2379 |
| ce1ac55777b620f9 | started | etcd1 | http://172.16.1.193:2380 | http://172.16.1.193:2379 |
| e62232af7400cdbe | started | etcd3 | http://172.16.1.198:2380 | http://172.16.1.198:2379 |
 ------------------ --------- ------- -------------------------- -------------------------- 

0 人点赞