- PVSM.RU - https://www.pvsm.ru -

zetcd от CoreOS: Заменяя ZooKeeper на… хранилище etcd

На прошлой неделе компания CoreOS порадовала [1] очередным Open Source-проектом — zetcd [2]. На самом деле о нём было известно ещё с прошлого года, но теперь состоялся первый релиз, который перевёл продукт в статус бета-тестирования — заявил о готовности продукта к серьёзным испытаниям перед выпуском в мир production. Авторы позиционируют zetcd как готовую замену для ZooKeeper внутри таких распределённых/кластерных решений, как Mesos, Apache Kafka и Apache Drill. Их настрою не препятствует даже тот факт, что etcd предлагает «плоское» хранение ключей-значений против иерархического подхода своего конкурента. Как они к этому пришли?
zetcd от CoreOS: Заменяя ZooKeeper на… хранилище etcd - 1

Предыстория: Apache ZooKeeper

Вряд ли Apache ZooKeeper [3] нуждается в особом представлении, но тем не менее: это написанное на Java хранилище ключей-значений (KV). Оно отличается иерархическим пространством имён и ориентированностью на применение в распределённых приложениях, где выступает в качестве централизованной службы для хранения конфигураций и другой служебной информации.

Как утверждают авторы ZooKeeper, этот проект появился (изначально, кстати, внутри Hadoop) как ответ на многократные попытки разработчиков распределённых систем создать свои подобные хранилища, что неизменно приводило к новым вызовам и сложностям в поддержке. И надо признать, что за десять лет своего существования ZooKeeper удалось хорошо закрепиться на рынке, став важным компонентом для таких Open Source-проектов, как Apache Drill, Apache Hadoop YARN, Apache HBase, Apache Kafka, Apache Solr, Mesos, Norbert. (Кстати, есть и примеры тех, кто в итоге отказался от ZooKeeper: Juju и Neo4j [4].) Разумеется, ZooKeeper выбрали и некоторые разработчики закрытых систем и приложений, которым требовалось распределённое KV-хранилище. Наконец, это решение стало популярным в мире микросервисов, где используется ещё и как служба обнаружения сервисов [5], хоть тут не обходится без проблем [6].

Причём здесь etcd?

Конечно, Apache ZooKeeper не является единственным решением в своей нише. Есть ещё, например, Consul [7], предлагающий KV-хранилище и делающий особый акцент на упомянутый Service Discovery, а также Doozer [8], ориентированный на высокую доступность (в ущерб масштабируемости и производительности), и главный «персонаж» этой статьи — etcd [9]. (Для интересующихся в разнице этих решений могут быть полезны статьи «Consul vs. ZooKeeper, doozerd, etcd [10]» по версии HashiCorp, «Exploring Performance of etcd, Zookeeper and Consul Consistent Key-value Datastores [11]» по версии CoreOS.)

Хранилище etcd было создано в CoreOS для критически важных данных в распределённых системах, написано на языке Go и стремится обеспечить: а) простоту (простой API, доступный через gRPC), б) безопасность (автоматический TLS), в) производительность (авторы обещают 10000 операций записи в секунду), г) надёжность (благодаря алгоритму конcенсуса Raft [12]). Всё это, приправленное интересами и энтузиазмом CoreOS, позволило новому решению набрать определённый вес: достаточно упомянуть, что etcd стал постоянным хранилищем [13] объектов REST API в Kubernetes.

Дальнейший ход CoreOS не вызывает удивления: если многие в мире пользуются ZooKeeper, а у компании есть интерес продвигать свой конкурирующий продукт, то почему бы не сделать миграцию настолько простой, насколько это вообще возможно… А раз модель данных и клиентский протокол etcd отличаются от используемого в ZooKeeper и не будут изменяться ради этой совместимости, то решение очевидно — выпустить прослойку, которая перенаправит все запросы приложений, обращённые к ZooKeeper, в кластер etcd. Благо, «достаточно выразительный API в etcd v3 позволил эмулировать модель данных ZooKeeper на клиентской стороне с помощью обычного прокси». Удобство для разработчиков заключается в том, что модифицировать приложения вообще не требуется: достаточно заменить инсталляцию ZooKeeper на etcd и добавить перед ней новый прокси-сервер — тот самый zetcd.

Основы zetcd

Разобраться в его устройстве поможет анонс проекта [2] и небольшие практические эксперименты. Итак, zetcd создан для того, чтобы получать запросы приложений, отправленные в ZooKeeper, и преобразовывать их в операции, соответствующие модели данных etcd и исполняемые в этом хранилище.
zetcd от CoreOS: Заменяя ZooKeeper на… хранилище etcd - 2

Для запуска zetcd требуется лишь наличие компилятора Go. Установка etcd и zetcd:

$ go get github.com/coreos/etcd/cmd/etcd
$ go get github.com/coreos/zetcd/cmd/zetcd

Примечание: по опыту инсталляций на разных версиях Ubuntu — лучше всего (для установки последних версий всех приложений из Git-репозиториев CoreOS) иметь установленным Go 1.8, который для 16.04 можно взять из ppa:longsleep/golang-backports.

Запуск etcd (по умолчанию биндится к localhost:2379) и zetcd:

$ etcd &
$ zetcd -zkaddr localhost:2181 -endpoints localhost:2379 &

Установка zkctl (CLI-утилита для выполнения простых операций в ZooKeeper) и пробные команды:

$ go install github.com/coreos/zetcd/cmd/zkctl
$ zkctl watch / &
$ zkctl create /abc "test"
$ zkctl get /abc
2017/05/23 21:57:44 Connected to 127.0.0.1:2181
2017/05/23 21:57:44 Authenticated: id=7587822333160445481, timeout=1000
[116 101 115 116]
Stat:
&{Czxid:3 Mzxid:14 Ctime:1495550621626193 Mtime:1495551461984432 Version:1 Cversion:1 Aversion:0 EphemeralOwner:0 DataLength:4 NumChildren:1 Pzxid:7}

Очевидно, был создан новый узел в корне дерева ZooKeeper (abc), с которым ассоциировали строку test (116 101 115 116 — номера юникодных символов, подтверждающие случившееся). Но это терминология ZooKeeper, а что произошло в etcd?

Внутреннее устройство zetcd

Для ответа на этот вопрос надо лучше разобраться в том, как же zetcd преобразует иерархическую модель данных ZooKeeper в формат, понятный для etcd. Древовидная структура ZooKeeper укладывается в плоское KV-пространство таким образом, что на каждую запись создаются KV-пары с метаданными, ключами которых является полный путь, содержащий также название параметра и уровень вложенности: /zk/[param]/[depth]/[full path]. Таким образом, просмотру ключей по директориям в ZooKeeper (getChildren) соответствует просмотр списка ключей по интервалу в etcd (Range), а внутри самой etcd хранятся дополнительные сведения, формирующие полное представление ZNode:

zetcd от CoreOS: Заменяя ZooKeeper на… хранилище etcd - 3

То есть для каждого ключа из ZooKeeper хранятся метаданные о его ревизии, версии и правах доступа. Они упрощены по сравнению с оригинальным ZNode из-за специфики etcd (отсутствие директорий в дереве как таковых, ролевая аутентификация вместо ACL и т.п.), однако полностью описывают узел. Например:

  • /zk/key/001/abc — хранит значение ключа /abc (первый уровень вложенности в дереве ZooKeeper);
  • /zk/mtime/002/abc/xyz — время модификации ключа /abc/xyz (второй уровень вложенности).

Проверить физическую организацию данных в действии можно с помощью консольного клиента etcdctl:

$ go get github.com/coreos/etcd/etcdctl
$ export ETCDCTL_API=3
$ etcdctl get --prefix /zk
/zk/acl/001/abc
������-��ACL��PermsScheme
                         ID
                           ��>worldanyone
/zk/count/001/abc

/zk/ctime/001/abc
ބ�����
/zk/cver/001/

/zk/cver/001/abc

/zk/err-node
1
/zk/key/001/abc
test
/zk/mtime/001/abc
ބ�����
/zk/ver/001/abc

Примечание: если вы хотите повторить последнюю операцию, чтобы своими глазами увидеть, как данные ZNode хранятся в etcd, то собирать zetcd необходимо с -tags path_debug (т.е. go get -u -v -tags path_debug github.com/coreos/zetcd/cmd/zetcd), а также вам потребуется версия из Git-репозитория, вобравшая в себя свежий Pull Request #54 [14], созданный в результате моего любопытства в Issue #52 [15]).

Производительность zetcd

Считая производительность не первой необходимостью, но важной составляющей успеха для zetcd, разработчики позаботились о создании простой benchmark-утилиты — zkboom [16]. С ней в CoreOS сравнили показатели ZooKeeper 3.4.10 и dev-ветви etcd при записи и чтении 128-байтных KV-пар, ограничивая число запросов до 2500 в секунду и наращивая количество одновременных клиентов. Всё это производилось на «двух современных Linux-машинах, соединённых гигабитным свитчем; на одной были запущены прокси и серверный софт, а другая генерировала клиентские запросы».

zetcd от CoreOS: Заменяя ZooKeeper на… хранилище etcd - 4

Как видно, в создании ключей задержка zetcd достигает в ~2—3 раза худших значений, чем у ZooKeeper, а в чтении — в ~1,5 раза. Нельзя сказать, что это грандиозные результаты (скорее — вполне объяснимые, учитывая необходимость работать со множеством дополнительных ключей для эмуляции метаданных ZNode), но и совсем плохими, учитывая специфику назначения прокси-сервера, их не назовёшь.

К слову, со связкой etcd и zetcd уже должны работать и другие утилиты, созданные для тестирования производительности самого ZooKeeper, что открывает большое поле для самостоятельных экспериментов и выводов.

Заключение

Первый публичный релиз zetcd — v0.0.1 — состоялся на прошлой неделе. По мнению авторов, даже при том, что остаётся место для улучшений в производительности zetcd, в скором времени продукт сможет стать готовой заменой для ZooKeeper в различных применениях, к которым помимо известных проектов можно отнести и разработки категории in-house, авторы которых желают по каким-либо причинам уйти с ZooKeeper и сделать это «малой кровью». Наконец, интересная особенность такой замены появляется в контексте применения etcd Operator для Kubernetes [17], добавляющего этому хранилищу, совместимому с ZooKeeper, автоматизированные обновления, бэкапы и другие возможности.

Автор: Флант

Источник [18]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/open-source/256050

Ссылки в тексте:

[1] порадовала: https://www.nixp.ru/news/14040.html

[2] zetcd: https://coreos.com/blog/introducing-zetcd

[3] Apache ZooKeeper: https://zookeeper.apache.org/

[4] Neo4j: http://www.rene-pickhardt.de/michael-hunger-talks-about-high-availability-of-neo4j-built-on-paxos-in-the-graphdevroom-fosdem/

[5] служба обнаружения сервисов: http://blog.arungupta.me/zookeeper-microservice-registration-discovery/

[6] не обходится без проблем: https://tech.knewton.com/blog/2014/12/eureka-shouldnt-use-zookeeper-service-discovery/

[7] Consul: https://www.consul.io/

[8] Doozer: https://github.com/ha/doozerd

[9] etcd: https://coreos.com/etcd

[10] Consul vs. ZooKeeper, doozerd, etcd: https://www.consul.io/intro/vs/zookeeper.html

[11] Exploring Performance of etcd, Zookeeper and Consul Consistent Key-value Datastores: https://coreos.com/blog/performance-of-etcd.html

[12] Raft: https://raft.github.io/

[13] постоянным хранилищем: https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/

[14] Pull Request #54: https://github.com/coreos/zetcd/pull/54

[15] Issue #52: https://github.com/coreos/zetcd/issues/52

[16] zkboom: https://github.com/coreos/zetcd/tree/master/cmd/zkboom

[17] etcd Operator для Kubernetes: https://habrahabr.ru/company/flant/blog/326414/

[18] Источник: https://habrahabr.ru/post/329224/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best