суббота, 1 мая 2021 г.

Клиент Go для Elasticsearch

Официальный клиент Go для Elasticsearch - одно из последних дополнений к семейству клиентов, разработанных и поддерживаемых Elastic. Первоначальная версия была опубликована в начале 2019 года и за год получила развитие, получив такие функции, как повторные запросы, обнаружение узлов кластера и различные вспомогательные компоненты. Также предоставлены примеры, чтобы облегчить использование клиента.

В серии постов мы рассмотрим архитектуру и дизайн клиента Go, выделим конкретные детали реализации и предоставим примеры и рекомендации по его использованию.

В этом посте блога мы сосредоточимся на общей архитектуре клиента.

Клиентская архитектура

Каждая клиентская библиотека Elasticsearch содержит в себе множество функций. Поэтому совершенно необходимо правильно разделить проблемы, чтобы упростить обслуживание и разработку. С высоты птичьего полета у клиента Elasticsearch есть две основные проблемы:

  • Предоставление API-интерфейсов Elasticsearch на соответствующем языке программирования
  • Отправка и получение данных из кластера

Естественно, картина более сложна в деталях (Как именно отправляются и принимаются данные? Как данные подвергаются воздействию вызывающего кода?), но общая картина проста.

Пакет elasticsearch делает это разделение проблем прозрачным: он физически разделяет два слоя на разные пакеты с помощью зонтичного пакета, который связывает их вместе. (Этот шаблон также реализуется клиентом Ruby.)

$ go list github.com/elastic/go-elasticsearch/v7/...
github.com/elastic/go-elasticsearch/v7
github.com/elastic/go-elasticsearch/v7/esapi
github.com/elastic/go-elasticsearch/v7/estransport
...

Пакеты esapi и estransport напрямую соответствуют двум упомянутым выше проблемам.

Это имеет серьезные последствия для ремонтопригодности, расширяемости и гибкости клиента. Во-первых, просто разделить код, тесты и другие эксперименты, относящиеся только к одной задаче; если вы посмотрите на модульные и интеграционные тесты estransport, становится очевидным, что они вообще не имеют отношения к Elasticsearch API. Во-вторых, просто использовать изолированно только один пакет: например, только пакет, связанный с API. Распространенный вопрос: "Зачем кому-то это делать?" Правильный ответ - это шаг назад: пакет не хочет принимать решения, которые мешают пользователям достичь определенной цели, независимо от того, насколько они редки или необычны.

Эта траектория мышления иллюстрирует общий подход официальных клиентов Elasticsearch: обеспечить наилучшее готовое решение, но не мешать пользователям непредвиденным образом изменять библиотеки. На протяжении многих лет люди используют различные точки расширения клиентов для достижения определенной цели в эзотерической среде.

Примечание. Вы можете задаться вопросом, почему пакеты не называются просто api и transport. Мотивация состоит в том, чтобы предотвратить "кражу" законного пакета или имени переменной у пользователя - в конце концов, пакет или переменная с именем api встречается довольно часто.

Как же тогда эти пакеты связаны вместе? Это ответственность зонтичного пакета elasticsearch.

$ go doc -short github.com/elastic/go-elasticsearch/v7
...
type Client struct{ ... }
    func NewClient(cfg Config) (*Client, error)
    func NewDefaultClient() (*Client, error)
type Config struct{ ... }

Размер этого пакета намеренно невелик, а его наиболее важными компонентами являются типы Client и Config; последний предоставляет способ настройки клиента, а первый включает API-интерфейсы Elasticsearch и транспорт HTTP.

$ go doc -short github.com/elastic/go-elasticsearch/v7.Client
type Client struct {
  *esapi.API // Встраивает методы API
  Transport  estransport.Interface
}
func NewClient(cfg Config) (*Client, error)
func NewDefaultClient() (*Client, error)
...

Пакет экспортирует методы инициализации клиента: NewDefaultClient() и NewClient().


Читайте также:


Комментариев нет:

Отправить комментарий