Лучший способ предоставить клиент Redis для расширяемых приложений Go - PullRequest
0 голосов
/ 12 ноября 2018

Я использую redigo в приложении и мне интересно, как мои сервисы должны взаимодействовать с Redis.

Википедия может сказать о безопасности потоков:

Потокобезопасность - это концепция компьютерного программирования, применимая к многопоточному коду. Потокобезопасный код управляет общими структурами данных только таким образом, который гарантирует, что все потоки ведут себя правильно и выполняют свои спецификации проекта без непреднамеренного взаимодействия.

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

Из того, что я понял, клиент redigo может использоваться несколькими "программами" (или потоками) одновременно. Это наводит меня на мысль, что достаточно одноэлементной реализации, с которой я знаком в Java.

Я вижу примеры, например, здесь и здесь , где соединения Redis (pool s) просто создаются в методе main и передаются различным функциям redigo. , Это не самый надежный способ добиться цели, хотя они, похоже, следуют шаблону синглтона. (Понятно, что второй пост на самом деле является просто быстрым и грязным API.)

Я бы сделал это так:

  1. При вызове функции main init, который возвращает повтор pool.

  2. Создание функций-обработчиков (контроллеров), которые принимают pool в качестве параметра (своего рода «грязное» внедрение зависимостей).

Это (я думаю) обеспечит создание только одного pool.

В качестве альтернативы, есть ли причина, по которой я не могу создать pool (клиент) каждый раз, когда хочу получить доступ к хранилищу данных? Если клиент завершает работу после завершения транзакции, есть ли проблема с отображением нового pool каждый раз, когда обработчик получает запрос?

1 Ответ

0 голосов
/ 12 ноября 2018

Правильный ответ уже предоставлен в комментариях, хотя я все еще хочу добавить свои 5 центов.

Ваш вопрос смешивает два понятия - параллелизм и пул ресурсов .

Параллельный код обеспечивает безопасную работу нескольких потоков выполнения внутри одного и того же приложения с использованием общей памяти.В нашем примере мы имеем несколько запросов http от наших пользователей и код обработчиков для этих запросов, которые выполняются одновременно.Соединение с БД является частью этого потока и требуется для выполнения запроса.

Параллельный код должен иметь возможность использовать соединение с БД и открывать / закрывать соединение при необходимости.

Хотя параллелизм не имеет ничего общего с правилами, определяющими, сколько соединений следует открывать в любой момент времени и как эти соединения следует повторно использовать / совместно использовать:

  • Кто-то может создать соединение с БДна запрос, и этот код является одновременным.
  • Кто-то может использовать некоторые общие подключения к БД, и этот код выполняется одновременно, если несколько запросов не мешают друг другу.Что обычно достигается с помощью блокировок памяти.

Пул соединений, с другой стороны, - это шаблон, обеспечивающий эффективный способ обработки соединений с БД.Почему важно управлять временем жизни соединений:

  1. Соединение дорого открывать
  2. Соединение дорого поддерживать, не используя его в качестве базы данных, может поддерживать только ограниченное количество открытых соединений.

С помощью пула соединений вы можете контролировать:

  1. Сколько соединений всегда открыто - медленный ресурс разогрева
  2. Максимальное количество открытых соединений - предотвратить открытие слишком большого количества соединений
  3. Тайм-аут соединения - баланс между повторным использованием соединений и высвобождением неиспользуемых ресурсов

Поддержание соединения или пула соединений по запросу не позволяет эффективно повторно использовать соединения.Каждый запрос замедляется из-за открытия соединения, скачок трафика приведет к открытию слишком большого числа соединений и т. Д.

Обычно приложение имеет один пул соединений, общий для всех запросов.

Иногда разработчики создают несколько пулов для разных типов соединений.Например, один пул для транзакционных операций и один для отчетов.

...