etcd

Краткая выжимка из описаний etcd - распределённой системы хранения данных

  • Где взять
  • etcd latest Documentation
  • etcd API
  • Etcd на CPAN
  • jq - is a lightweight and flexible command-line JSON processor. Удобно им форматировать тестовые выводы etcd - см. ниже
  • [Getting Started][https://coreos.com/etcd/docs/latest/getting-started-with-etcd.html] - простые эффектные примеры

Недавно (20.06.2016) вышла версия 3. Сейчас (начало июля 2016) везде используется версия 2.

Несколько примеров из etcd API. etcd API всё равно надо читать, так как там много информации более подробной, частные случаи и она обновляется:

jq

jq умеет форматировать JSON и он есть в debian jessie - apt-get install jq. Ниже два примера, первый без форматирования, второй с форматированием.

~/etcd$ curl -s -L http://127.0.0.1:4001/v2/keys/message -XPUT -d value="Hello world"

{"action":"set","node":{"key":"/message","value":"Hello world","modifiedIndex":17,"createdIndex":17},
"prevNode":{"key":"/message","value":"Hello world","modifiedIndex":16,"createdIndex":16}}

~/etcd$ curl -s -L http://127.0.0.1:4001/v2/keys/message -XPUT -d value="Hello world" |jq .

{
  "action": "set",
  "node": {
    "key": "/message",
    "value": "Hello world",
    "modifiedIndex": 18,
    "createdIndex": 18
  },
  "prevNode": {
    "key": "/message",
    "value": "Hello world",
    "modifiedIndex": 17,
    "createdIndex": 17
  }
}

Etcd на CPAN

CPAN модуль представляет простой интерфейс. Так как модуль имеет странную версию (сейчас 0.004), надо проверять всё что он делает.

Обработка ошибок (получение несуществующих ключей, создание существующих директорий и т.д.) рекомендовано в Etcd::Error делать так:

use Etcd;
my $etcd = Etcd->new;

use Try::Tiny;
try {
    $etcd->get("/message");
}
catch {
    print $_;
};

Не худший вариант.

запуск тестового кластера на одном хосте

/usr/local/bin/etcd -data-dir `hostname`-1 -name `hostname`-1 --debug

в текущей директории создаст директорию с данными и будет выводить отладочные сообщения при каждом запросе

curl

curl выполняет HTTP запрос.

Флаги:

-d <data> - помещаем <data> в POST часть запроса.
-X - указание типа запроса 

Запись значения

В оригинальной документации написано "Setting the value of a key" - буквально "Установка значения ключа". Я пишу просто "Запись значения" и далее в том же духе.

curl -L http://127.0.0.1:4001/v2/keys/message1 -XPUT -d value="`date`"

Можно сделать значение с указанием времени жизни:

curl -L http://127.0.0.1:4001/v2/keys/message2 -XPUT -d value="`date`" -d ttl=5

Perl:

my $etcd = Etcd->new;
$etcd->set("message2", time(), ttl=>5);

Через 5 секунд значение будет удалено. Но есть важное замечание:

NOTE: Keys can only be expired by a cluster leader, so if a machine gets disconnected from the cluster, its keys will not expire until it rejoins.

то есть пока наша копия etcd не будет снова в кластере, значение не удалится.

Если надо отменить время жизни, делаем так:

curl -L http://127.0.0.1:4001/v2/keys/message2 -XPUT -d value="`date`" -d ttl= -d prevExist=true

Запись значения из файла

echo "Hello\nWorld" > afile.txt
curl http://127.0.0.1:2379/v2/keys/afile -XPUT --data-urlencode value@afile.txt

{
    "action": "get",
    "node": {
        "createdIndex": 2,
        "key": "/afile",
        "modifiedIndex": 2,
        "value": "Hello\nWorld\n"
    }
}

Чтение значения

curl -L http://127.0.0.1:4001/v2/keys/message1

Изменение значения

curl -L http://127.0.0.1:4001/v2/keys/message1 -XPUT -d value="`date`"

Удаление значения

curl -L http://127.0.0.1:4001/v2/keys/message1 -XDELETE

Perl:

my $etcd = Etcd->new;
$etcd->delete("/message1");

Директории

Директория - это ключ без значений, но с подключами.

Создание директории

curl -L http://127.0.0.1:4001/v2/keys/dir1 -XPUT -d dir=true
etcdctl mkdir /dir1

Perl:

my $etcd = Etcd->new;
unless($etcd->exists($key)){
    $etcd->create_dir($key);
}

Запись значения в директорию 'dir1'

curl -s -L http://127.0.0.1:4001/v2/keys/dir1/message1 -XPUT -d value="`date`"
curl -s -L http://127.0.0.1:4001/v2/keys/dir1/message2 -XPUT -d value="`date`"

Если имя ключа или имя директории начинается с символа подчёркивания '_', то это значение/директория не будет высвечиваться в листинге директории.

curl -s -L http://127.0.0.1:4001/v2/keys/dir1/_message3 -XPUT -d value="`date`"

Чтение значения всей директории (листинг)

~/etcd$ curl -s -L http://127.0.0.1:4001/v2/keys/dir1 |jq .
{
  "action": "get",
  "node": {
    "key": "/dir1",
    "dir": true,
    "nodes": [
      {
        "key": "/dir1/message1",
        "value": "Sun Mar 13 13:34:24 UTC 2016",
        "modifiedIndex": 55,
        "createdIndex": 55
      },
      {
        "key": "/dir1/message2",
        "value": "Sun Mar 13 13:34:24 UTC 2016",
        "modifiedIndex": 56,
        "createdIndex": 56
      }
    ],
    "modifiedIndex": 54,
    "createdIndex": 54
  }
}

curl -s -L http://127.0.0.1:4001/v2/keys/dir1/_message3

curl -s -L http://127.0.0.1:4001/v2/keys/dir1/_message3 |jq .
{
  "action": "get",
  "node": {
    "key": "/dir1/_message3",
    "value": "Sun Mar 13 13:46:15 UTC 2016",
    "modifiedIndex": 63,
    "createdIndex": 63
  }
}

Директория с поддиректориями

curl -L http://127.0.0.1:4001/v2/keys/dir1/dir2 -XPUT -d dir=true
curl -s -L http://127.0.0.1:4001/v2/keys/dir1/dir2/message3 -XPUT -d value="`date`"
curl -s -L http://127.0.0.1:4001/v2/keys/dir1/dir2/message4 -XPUT -d value="`date`"

Читаем так же как директорию, но добавляем параметр recursive=true

curl -s -L http://127.0.0.1:4001/v2/keys?recursive=true
curl -s -L http://127.0.0.1:4001/v2/keys/dir1?recursive=true

{
  "action": "get",
  "node": {
    "key": "/dir1",
    "dir": true,
    "nodes": [
      {
        "key": "/dir1/message1",
        "value": "Sun Mar 13 13:34:24 UTC 2016",
        "modifiedIndex": 55,
        "createdIndex": 55
      },
      {
        "key": "/dir1/message2",
        "value": "Sun Mar 13 13:34:24 UTC 2016",
        "modifiedIndex": 56,
        "createdIndex": 56
      },
      {
        "key": "/dir1/dir2",
        "dir": true,
        "nodes": [
          {
            "key": "/dir1/dir2/message3",
            "value": "Sun Mar 13 13:37:04 UTC 2016",
            "modifiedIndex": 58,
            "createdIndex": 58
          },
          {
            "key": "/dir1/dir2/message4",
            "value": "Sun Mar 13 13:37:04 UTC 2016",
            "modifiedIndex": 59,
            "createdIndex": 59
          }
        ],
        "modifiedIndex": 57,
        "createdIndex": 57
      }
    ],
    "modifiedIndex": 54,
    "createdIndex": 54
  }
}

Удаление директории

curl -L 'http://127.0.0.1:4001/v2/keys/dir1?dir=true' -XDELETE

Если в директории есть значения, то удаляем рекурсивно:

curl -L 'http://127.0.0.1:4001/v2/keys/dir1?recursive=true' -XDELETE

1 comment to etcd

  • # !/bin/bash
    
    # Скрипт создаёт локальный кластер из пяти узлов
    
    killall etcd
    sleep 3
    
    mkdir logs
    mkdir datadir
    
    
    for E in e1 e2 e3 e4 e5; do
        rm -Rf datadir/$E.etcd
        rm -Rf logs/$E.log
    done
    
    ETCD_INITIAL_CLUSTER_TOKEN=etcd_cluster_1
    ETCD_INITIAL_CLUSTER_NAME=e1
    ETCD_INITIAL_SERVER=http://127.0.0.1:7001
    
    ETCD_CLIENT=http://127.0.0.1:4001
    ETCD_SERVER=http://127.0.0.1:7001
    ETCD_NAME=e1
    
    ETCD_INITIAL_CLUSTER=$ETCD_NAME=$ETCD_SERVER
    ETCD_ENDPOINTS=$ETCD_CLIENT
    
    nohup etcd --data-dir datadir/$ETCD_NAME.etcd --name $ETCD_NAME \
        --initial-advertise-peer-urls $ETCD_SERVER \
        --listen-peer-urls $ETCD_SERVER \
        --listen-client-urls $ETCD_CLIENT \
        --advertise-client-urls $ETCD_CLIENT \
        --initial-cluster-token $ETCD_INITIAL_CLUSTER_TOKEN \
        --initial-cluster $ETCD_INITIAL_CLUSTER \
        --initial-cluster-state new \
        >logs/$ETCD_NAME.log &
    
    sleep 2 
    
    for ID in 2 3 4 5 ; do
    
    sleep 2 
    
    ETCD_CLIENT=http://127.0.0.1:400$ID
    ETCD_SERVER=http://127.0.0.1:700$ID
    ETCD_NAME=e$ID
    ETCD_INITIAL_CLUSTER=$ETCD_INITIAL_CLUSTER,$ETCD_NAME=$ETCD_SERVER
    
    ./etcdctl --endpoints $ETCD_ENDPOINTS member add $ETCD_NAME $ETCD_SERVER
    ETCD_ENDPOINTS=$ETCD_ENDPOINTS,$ETCD_CLIENT
    
    echo \#\!/bin/bash >$ETCD_NAME.sh
    echo \#./etcdctl --endpoints $ETCD_ENDPOINTS member add $ETCD_NAME $ETCD_SERVER  >>$ETCD_NAME.sh 
    echo nohup etcd --data-dir datadir/$ETCD_NAME.etcd --name $ETCD_NAME \
        --initial-advertise-peer-urls $ETCD_SERVER \
        --listen-peer-urls $ETCD_SERVER \
        --listen-client-urls $ETCD_CLIENT \
        --advertise-client-urls $ETCD_CLIENT \
        --initial-cluster-token $ETCD_INITIAL_CLUSTER_TOKEN \
        --initial-cluster $ETCD_INITIAL_CLUSTER \
        --initial-cluster-state existing \
        \>logs/$ETCD_NAME.log \& \
        >>$ETCD_NAME.sh
    
    chmod 755 $ETCD_NAME.sh
    
    bash ./$ETCD_NAME.sh
    
    
    done
    
    sleep 1
    ./etcdctl member list
    ./etcdctl cluster-health
    

Leave a Reply