惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
T
Threatpost
Latest news
Latest news
N
News | PayPal Newsroom
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
TaoSecurity Blog
TaoSecurity Blog
The Last Watchdog
The Last Watchdog
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
T
Threat Research - Cisco Blogs
O
OpenAI News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
The Exploit Database - CXSecurity.com
NISL@THU
NISL@THU
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
Securelist
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Martin Fowler
Martin Fowler
S
SegmentFault 最新的问题
Cisco Talos Blog
Cisco Talos Blog
云风的 BLOG
云风的 BLOG
AWS News Blog
AWS News Blog
GbyAI
GbyAI
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
美团技术团队
Engineering at Meta
Engineering at Meta
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
S
Schneier on Security
博客园 - 聂微东
V2EX - 技术
V2EX - 技术
T
Troy Hunt's Blog
SecWiki News
SecWiki News
S
Secure Thoughts
B
Blog RSS Feed
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
腾讯CDC
H
Heimdal Security Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed

Spaceack's Blog

使用简单算法两小时实现猎杀乌姆帕斯(Hunt the Wumpus)Python小游戏 使用Mysql实现消息队列 使用docker模拟双机环境测试mysql双机互为主备 天池大数据竞赛 Spaceack带你利用Pandas,趋势图与桑基图分析美国选民候选人喜好度 Python利用matplotlib万花尺画月饼 情人节遥寄 靠近爱人 牵着你的手 七夕收到的礼物
搭建etcd分布式kv数据库集群并使用python操作
Spaceack · 2021-05-27 · via Spaceack's Blog

介绍

etcd 是一个分布式、可靠的键值存储数据库,用于收集分布式系统中最关键的数据。是k8s的组件之一,使用Raft一致性算法,为分布式系统而生。常用做服务发现和配置共享等应用场景。

可以使用protobuf定义的接口来进行开发,这里使用更易测试验证的第三方python库etcd3举例。

这里需要注意的一点是:“ raft算法写入时需要半数以上的节点写入成功才返回,宕机节点不超过半数则数据不丢失。” 即: 3个节点的集群,1个节点宕机无妨。但两个节点宕机后,即使另一个节点存活也无法读取数据!。四个节点集群也是两个节点宕机后,无法工作。5个节点则允许两个节点宕机。满足公式quorum=(n+1)/2。所以建议奇数的集群节点。因为奇数和偶数的可靠性一样,单可以节省1个节点的资源。

下载与安装

etcd 下载 etcd v3.4 文档

简单测试

1
2
3
4
5
6
7
8
# 运行
./etcd
# etcd put 命令用于设置给定 key 的值。如果 key 已经存储其他值, put 就覆写旧值.
./etcdctl put greeting "Hello, etcd"
# 通过key获取value
./etcdctl get greeting
# 删除 kv
./etcdctl del greeting

使用docker-compose组建4节点集群。

docker-compose.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
version: '2'
networks:
  byfn:

services:
  etcd1:
    image: quay.io/coreos/etcd
    container_name: etcd1
    command: etcd -name etcd1 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380,etcd4=http://etcd4:2380" -initial-cluster-state new
    ports:
      - 2385:2379
      - 2380
    networks:
      - byfn
 
  etcd2:
    image: quay.io/coreos/etcd
    container_name: etcd2
    command: etcd -name etcd2 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380,etcd4=http://etcd4:2380" -initial-cluster-state new
    ports:
      - 2386:2379
      - 2380
    networks:
      - byfn
  
  etcd3:
    image: quay.io/coreos/etcd
    container_name: etcd3
    command: etcd -name etcd3 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380,etcd4=http://etcd4:2380" -initial-cluster-state new
    ports:
      - 2387:2379
      - 2380
    networks:
      - byfn
      
  etcd4:
    image: quay.io/coreos/etcd
    container_name: etcd4
    command: etcd -name etcd4 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380,etcd4=http://etcd4:2380" -initial-cluster-state new
    ports:
      - 2388:2379
      - 2380
    networks:
      - byfn

运行 docker-compose up 即可

使用虚拟机组建4节点集群。

4个虚拟机分别运行以下命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 虚拟机1 192.168.0.156
./etcd --name infra0 --initial-advertise-peer-urls http://192.168.0.156:2380 \
  --listen-peer-urls http://192.168.0.156:2380 \
  --listen-client-urls http://192.168.0.156:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://192.168.0.156:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster infra0=http://192.168.0.156:2380,infra1=http://192.168.0.157:2380,infra2=http://192.168.0.158:2380,infra3=http://192.168.0.159:2380 \
  --initial-cluster-state new
# 虚拟机2 192.168.0.157
  ./etcd --name infra1 --initial-advertise-peer-urls http://192.168.0.157:2380 \
  --listen-peer-urls http://192.168.0.157:2380 \
  --listen-client-urls http://192.168.0.157:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://192.168.0.157:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster infra0=http://192.168.0.156:2380,infra1=http://192.168.0.157:2380,infra2=http://192.168.0.158:2380,infra3=http://192.168.0.159:2380 \
  --initial-cluster-state new
 # 虚拟机3 192.168.0.158
  etcd --name infra2 --initial-advertise-peer-urls http://192.168.0.158:2380 \
  --listen-peer-urls http://192.168.0.158:2380 \
  --listen-client-urls http://192.168.0.158:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://192.168.0.158:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster infra0=http://192.168.0.156:2380,infra1=http://192.168.0.157:2380,infra2=http://192.168.0.158:2380,infra3=http://192.168.0.159:2380 \
  --initial-cluster-state new
 # 虚拟机4 192.168.0.159
   etcd --name infra3 --initial-advertise-peer-urls http://192.168.0.159:2380 \
  --listen-peer-urls http://192.168.0.159:2380 \
  --listen-client-urls http://192.168.0.159:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://192.168.0.159:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster infra0=http://192.168.0.156:2380,infra1=http://192.168.0.157:2380,infra2=http://192.168.0.158:2380,infra3=http://192.168.0.159:2380 \
  --initial-cluster-state new

python etcd3 库测试

安装 pip3 install etcd3

etcd3文档

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import etcd3
# 建立连接
etcd = etcd3.client(host='127.0.0.1', port=2379)
# 添加 kv
result = etcd.put('greeting', 'hello, world!')
"""
header {
  cluster_id: 14841639068965178418
  member_id: 10276657743932975437
  revision: 16
  raft_term: 5
}
"""
# 根据 key 获得 value
result = etcd.get('greeting')    # 不存在 (None, None); 存在(b'hello, world!', <etcd3.client.KVMetadata object at 0x7ffbf072de80>)
rv = result[0].decode() if result[0] else result[0] # 取解析后的值

# 删除某个 key
result = etcd.delete('greeting') # 成功删除 True, 不存在,删除失败 False

# 返回满足前缀 key 的 value
objs = etcd.get_prefix("server1")
result = [obj[0].decode() if obj[0] else obj[0] for obj in objs]

# 获取所有的 key的 value
objs = etcd.get_all() 
result = [obj[0].decode() if obj[0] else obj[0] for obj in objs]