0 Обзор альбома
etcd является важным базовым компонентом облачной архитектуры, которая инкубируется и размещается CNCF. etcd можно использовать не только для регистрации и обнаружения сервисов в микросервисах и кластерах Kubernetes, но и как промежуточное ПО для хранения ключей и значений.
"Понимание статей серии etcd" познакомит с etcd с точки зрения базовой функциональной практики etcd, интерфейса API, принципа реализации, анализа исходного кода и опыта преодоления ям в реализации. Ожидается, что статей будет около 20, автор будет обновлять каждую неделю, прошу обратить внимание.
1 Обзор API Etcd
В этой статье мы начнем знакомить с основным дизайном API etcd3, в основном для общих служб интерфейса API. Это очень полезно для понимания основной идеи etcd. Все API etcd3 определены в службе gRPC, которая классифицирует удаленные вызовы процедур (RPC), понятные серверу etcd.
2 службы gRPC
Каждый запрос API, отправляемый на сервер etcd, является вызовом удаленной процедуры gRPC. Определения интерфейса RPC в etcd3 подразделяются на службы в зависимости от функциональности.
Важные сервисы для обработки ключей etcd включают в себя:
- KV, создавать, обновлять, получать и удалять пары ключ-значение.
- Следите, следите за ключевыми изменениями.
- Lease, примитив, который использует сообщения проверки активности клиента.
- Lock и т. д. обеспечивают поддержку распределенных общих блокировок.
- Выборы, которые раскрывают механизм выборов на стороне клиента.
2.1 Запросы и ответы
Все RPC в etcd3 имеют одинаковый формат. У каждого RPC есть имя функции, которая принимает NameRequest в качестве параметра и возвращает NameResponse в качестве ответа. Например, вот описание Range RPC:
service KV {
Range(RangeRequest) returns (RangeResponse)
...
}
2.2 Заголовки ответов
Все ответы на API etcd имеют дополнительный заголовок ответа, который включает метаданные кластера для ответа:
message ResponseHeader {
uint64 cluster_id = 1;
uint64 member_id = 2;
int64 revision = 3;
uint64 raft_term = 4;
}
- Cluster_ID — идентификатор кластера, создавшего ответ.
- Member_ID — идентификатор участника, сгенерировавшего ответ.
- Редакция — номер версии хранилища пар "ключ-значение" на момент создания ответа.
- Raft_Term — термин Raft участника на момент создания ответа.
Служба приложений может использовать поля Cluster_ID и Member_ID, чтобы убедиться, что в данный момент она обменивается данными с нужным кластером или участником.
Службы приложений могут использовать поле номера версии, чтобы узнать номер последней версии для текущего хранилища пар "ключ-значение". Эта функция особенно полезна, когда приложение указывает исторические версии для запросов о ходе времени и хочет знать последнюю версию по запросу.
Службы Application Services могут использовать Raft_Term, чтобы определить, когда кластер завершил выборы нового лидера.
3 Служба пары "ключ-значение"
3.1 Определение услуги KV
Большинство запросов к etcd обычно представляют собой запросы типа ключ-значение. Служба KV обеспечивает поддержку операций ключ-значение. В файле rpc.proto служба KV определяется следующим образом:
//rpc.proto
service KV {
rpc Range(RangeRequest) returns (RangeResponse) {}
rpc Put(PutRequest) returns (PutResponse) {}
rpc DeleteRange(DeleteRangeRequest) returns (DeleteRangeResponse) {}
rpc Txn(TxnRequest) returns (TxnResponse) {}
rpc Compact(CompactionRequest) returns (CompactionResponse) {}
}
Введение каждой функции выглядит следующим образом:
- Диапазон, получить ключ в диапазоне из хранилища ключ-значение;
- Put, устанавливает данный ключ в хранилище ключ-значение, запрос на размещение добавляет ревизию хранилища ключ-значение и генерирует событие в истории событий;
- DeleteRange, удаляет заданный диапазон из хранилища "ключ-значение", удаляет запросы на добавление ревизии хранилища "ключ-значение" и генерирует событие удаления для каждого удаленного ключа в истории событий;
- Txn обрабатывает несколько запросов в одной транзакции, запрос txn увеличивает версию хранилища ключей и значений и создает событие с одной и той же версией для каждого завершенного запроса. Не допускается многократное изменение одного и того же ключа в txn;
- Компактный, сжимает историю событий в хранилище ключ-значение etcd. Хранилище ключей и значений должно регулярно уплотняться, иначе история событий будет расти бесконечно.
Ниже мы подробно разберем каждый метод интерфейса.
3.2 Диапазонный метод
Метод Range получает ключи в диапазоне из хранилища ключей и значений и определяется следующим образом:
rpc Range(RangeRequest) returns (RangeResponse) {}
Следует отметить, что не существует метода манипулирования одной клавишей, даже если вы хотите получить доступ к одной клавише, вам нужно использовать метод Range. Тело сообщения RangeRequest запроса выглядит следующим образом:
message RangeRequest {
enum SortOrder {
NONE = 0; // 默认,不排序
ASCEND = 1; // 正序,低的值在前
DESCEND = 2; // 倒序,高的值在前
}
enum SortTarget {
KEY = 0;
VERSION = 1;
CREATE = 2;
MOD = 3;
VALUE = 4;
}
bytes key = 1;
// range_end 是请求范围的上限[key, range_end)
bytes range_end = 2;
// 请求返回的key的数量限制
int64 limit = 3;
int64 revision = 4;
// 指定返回结果的排序顺序
SortOrder sort_order = 5;
// 用于排序的键值字段
SortTarget sort_target = 6;
bool serializable = 7;
// 设置仅返回key而不需要value
bool keys_only = 8;
// 设置仅仅返回范围内key的数量
bool count_only = 9;
}
В определении структуры запроса выше следует отметить, что ключ является первым ключом диапазона. Если range_end не указан, запрос ищет только этот ключ. range_end представляет верхний предел запроса, если range_end равен '\0', диапазон включает все ключи, большие или равные ключу; если range_end на один бит длиннее заданного ключа, то запрос диапазона получает все ключи с префиксом (данный ключ); если и ключ, и диапазон_конца равны '\0', запрос диапазона возвращает все ключи. ревизия Ревизия была сделана на момент сохранения пары ключ-значение диапазона. Если ревизия меньше или равна нулю, область действия находится в последнем хранилище пар "ключ-значение". Возвращает ErrCompacted в качестве ответа, если ревизия была сжата. serializable устанавливает запрос диапазона для локального чтения с использованием сериализованного члена. Запросы диапазона по умолчанию линеаризованы.Линеаризованные запросы имеют большую задержку и меньшую пропускную способность, чем сериализованные запросы, но отражают текущую согласованность кластера. Для повышения производительности сериализованные запросы диапазона обрабатываются локально за счет потенциально грязных чтений без необходимости согласования с другими узлами в кластере.
Тело ответа RangeResponse определяется следующим образом:
message RangeResponse {
ResponseHeader header = 1;
// kvs是匹配范围请求的键值对列表
// 当请求数量时是空的
repeated mvccpb.KeyValue kvs = 2;
// more代表在被请求的范围内是否还有更多的 key
bool more = 3;
// 被请求范围内 key 的数量
int64 count = 4;
}
Заголовок — это общий заголовок ответа, упомянутый в предыдущей сводке. Тело сообщения mvcpb.KeyValue определяется следующим образом:
message KeyValue {
// key 是 bytes 格式的 key。不容许 key 为空
bytes key = 1;
// create_revision 是这个 key 最后创建的修订版本
int64 create_revision = 2;
// mod_revision 是这个 key 最后修改的修订版本
int64 mod_revision = 3;
int64 version = 4;
// value 是 key 持有的值,bytes 格式。
bytes value = 5;
int64 lease = 6;
}
version — это версия ключа. Удаление сбрасывает версию на 0, а любая модификация ключа повышает ее версию. арендный договор — это идентификатор аренды, прикрепленный к ключу. Ключ будет удален по истечении срока действия прилагаемой аренды. Если аренда равна 0, к ключу не привязана аренда.
3.3 Метод пут
Метод put, используемый для хранения данного ключа в базе данных. Метод Put увеличивает версию хранилища ключей и значений и создает событие в истории событий.
rpc Put(PutRequest) returns (PutResponse) {}
Тело сообщения запроса — PutRequest:
message PutRequest {
// byte数组形式的key,用来放置到键值对存储
bytes key = 1;
// byte 数组形式的 value,在键值对存储中和 key 关联
bytes value = 2;
int64 lease = 3;
bool prev_kv = 4;
}
аренда, идентификатор аренды, связанный с ключом в хранилище "ключ-значение", 0 означает отсутствие аренды. Если prev_kv установлен, etcd получает последнюю пару ключ-значение перед изменением. Предыдущая пара ключ-значение будет возвращена в ответе put.
Тело ответа PutResponse определяется следующим образом:
message PutResponse {
ResponseHeader header = 1;
mvccpb.KeyValue prev_kv = 2;
}
Заголовок представляет собой общий заголовок ответа. Если prev_kv в запросе установлен, он вернет предыдущую пару ключ-значение.
3.4 Метод DeleteRange
Метод DeleteRange удаляет указанный диапазон из хранилища ключей и значений. Запросы на удаление добавляют ревизии в хранилище ключей и значений и генерируют событие удаления в истории событий для каждого удаленного ключа.
rpc DeleteRange(DeleteRangeRequest) returns (DeleteRangeResponse)
Тело сообщения запроса DeleteRangeRequest определяется следующим образом:
message DeleteRangeRequest {
bytes key = 1;
bytes range_end = 2;
bool prev_kv = 3;
}
key представляет собой начало диапазона для удаления. range_end — это последний ключ диапазона [key, range_end) для удаления. Если range_end не задан, диапазон определяется как содержащий только ключевой параметр; если range_end равен '\0', диапазон включает все ключи, большие или равные ключу параметра. Если prev_kv установлен, etcd получает последнюю пару ключ-значение перед удалением. Предыдущая пара ключ-значение будет возвращена в ответе на удаление. Тело сообщения DeleteRangeResponse ответа определяется следующим образом:
message DeleteRangeResponse {
ResponseHeader header = 1;
// 被范围删除请求删除的key的数量
int64 deleted = 2;
repeated mvccpb.KeyValue prev_kvs = 3;
}
Если в запросе установлено prev_kv, будет возвращена предыдущая пара ключ-значение.
4 Резюме
В этой статье в основном представлена служба KV, связанная с Etcd API, и содержимое, связанное с ответом на запрос gRPC. Понимание этого является важной предпосылкой для изучения вызовов Etcd RPC. В следующих статьях мы продолжим знакомить вас с этими важными службами и интерфейсами в etcd.
Подписывайтесь на свежие статьи, приглашаю обратить внимание на мой публичный номер
Рекомендуемое чтение
- Сравнение etcd с другими компонентами k-v, такими как Zookeeper и Consul
- Тщательно изучите серию статей etcd (1): первое знакомство с etcd
- Тщательно изучите серию статей etcd (2): различные положения установки etcd
- Тщательно изучите серию статей etcd (3): эксплуатация и обслуживание кластера etcd, развертывание.
- Тщательно изучите серию статей etcd (4): безопасность etcd
- Тщательно изучите серию статей etcd (5): использование etcdctl
- Тщательно изучите серию статей etcd (6): etcd core API v3