etcd简单入门

发布时间 2023-09-02 21:49:08作者: strongmore

介绍

etcd 是 CoreOS 团队发起的一个开源项目,实现了分布式键值存储和服务发现,etcd 和 ZooKeeper/Consul 非常相似,都提供了类似的功能,以及 REST API 的访问操作,具有以下特点:

  • 简单:安装和使用简单,提供了 REST API 进行操作交互
  • 安全:支持 HTTPS SSL 证书
  • 快速:支持并发 10 k/s 的读写操作
  • 可靠:采用 raft 算法,实现分布式系统数据的可用性和一致性

在k8s中的使用

Etcd 是 Kubernetes 集群中的一个十分重要的组件,用于保存集群所有的网络配置和对象的状态信息。

和Redis的比较

  • etcd 的红火来源于 k8s 用 etcd 做服务发现,而 redis 的兴起则来源于 memcache 缓存本身的局限性。
  • etcd 的重点是利用 raft 算法做分布式一致性,强调各个节点之间的通信、同步,确保各节点数据和事务的一致性,使得服务发现工作更稳定;
  • redis 也可以做主从同步和读写分离,但节点一致性强调的是数据,不是事务。redis 的注册和发现只能通过 pub 和 sub 实现,安全性不能保证(断线重连之后不会将历史信息推送给客户端,需要自己做一个定时轮询),延时也比 etcd v3 高。
  • etcd v3 的底层采用 boltdb 做存储,value 直接持久化;redis 是一个内存数据库,它的持久化方案有 aof 和 rdb,在宕机时都或多或少会丢失数据。
  • etcd v3 只能通过 gRPC 访问,而 redis 可以通过 http 访问,因此 etcd 的客户端开发工作量高很多。
  • redis 的性能比 etcd 强。
  • redis 的 value 支持多种数据类型。
  • etcd 是用 go 开发的,和 k8s 在同一个生态下

使用docker安装

version: '2'

networks:
  app-tier:
    driver: bridge

services:
  Etcd:
    image: 'bitnami/etcd:3.5.1'
    environment:
      - ALLOW_NONE_AUTHENTICATION=yes
      - ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
    ports:
      - 2379:2379
      - 2380:2380
    networks:
      - app-tier

创建 docker-compose.yml 文件,镜像版本为3.5.1,默认不支持http访问

docker-compose up -d 

启动容器

通过http请求访问

注意开启防火墙对端口2379的访问

http://ip:2379/version

查询版本,3.5.1

http://ip:2379/v2/keys

默认不支持http访问,返回404 page not found

开启http访问

version: '2'

networks:
  app-tier:
    driver: bridge

services:
  Etcd:
    image: 'bitnami/etcd:3.5.1'
    environment:
      - ALLOW_NONE_AUTHENTICATION=yes
      - ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
      - ETCD_ENABLE_V2=true
    ports:
      - 2379:2379
      - 2380:2380
    networks:
      - app-tier

增加ETCD_ENABLE_V2=true的环境变量,重新启动

docker-compose down
docker-compose up -d

添加删除及查询

设置键值
image
删除键值
image
查询键值
image

客户端访问

下载地址

.\etcdctl.exe --endpoints=http://ip:2379 get age

获取值

.\etcdctl.exe --endpoints=http://ip:2379 put name lisi2

设置键值

注意,v2和v3的数据是相互隔离的

java客户端访问

<dependency>
  <groupId>io.etcd</groupId>
  <artifactId>jetcd-core</artifactId>
  <version>0.5.11</version>
</dependency>
import io.etcd.jetcd.ByteSequence;
import io.etcd.jetcd.Client;
import io.etcd.jetcd.KV;
import io.etcd.jetcd.KeyValue;
import io.etcd.jetcd.kv.GetResponse;

import java.util.Date;
import java.util.concurrent.CompletableFuture;

public class TestEtcdClient {
    public static void main(String[] args) throws Exception {
        testGetValue();
//        testPutKey();
    }

    private static void testPutKey() {
        KV kvClient = createClient().getKVClient();
        ByteSequence key = ByteSequence.from("date".getBytes());
        ByteSequence value = ByteSequence.from(new Date().toString().getBytes());
        kvClient.put(key, value);
    }

    private static void testGetValue() throws Exception {
        KV kvClient = createClient().getKVClient();
        ByteSequence key = ByteSequence.from("name".getBytes());
        CompletableFuture<GetResponse> getFuture = kvClient.get(key);
        GetResponse response = getFuture.get();
        for (KeyValue keyValue : response.getKvs()) {
            System.out.println(keyValue.getKey().toString() + ":" + keyValue.getValue().toString());//name:lisi2
        }
    }

    private static Client createClient() {
        return Client.builder().endpoints("http://ip:2379").build();
    }

}

v2版本和v3版本的区别

v2

  • 专注于key-value存储,而不是一个完整的数据库;
  • 通过HTTP + JSON的方式暴露给外部API;
  • watch机制提供持续监听某个key变化的功能,以及基于TTL的key的自动过期机制。

v3

  • 二进制取代字符串:通过gRPC进行通信,代替了v2版本的HTTP+JSON格式;
  • 减少TCP连接:使用HTTP/2协议,同一个连接可以同时处理多个请求,摒弃多个请求需要建立多个连接的方式。
  • 实时监听key的更新:解决v2中途key的数据更新,客服端不会感知的问题;
  • 多路复用:这个可以想到select和epool模型,就是一个客户之前需要建立多个TCP连接,现在只需要建立一个即可。
  • 保存历史数据:摈弃v2的“滑动窗口”式设计,通过MVCC机制,保存了所有的历史数据;
  • 数据落磁盘:因为要保存历史数据,数据量态度,不适合全内存存储,使用BoltDB存储;
  • 查询优化:摒弃v2的目录式层级化设计,使用线段树优化查询。

参考

docker 安装 ETCD 及 etcd 使用
Etcd 解析
etcd和redis比较
ETCD系列教程3 - 深入ETCD