Skip to content

Repository files navigation

tgdb

CICDGitHub ReleaseWakatimeLinescodecov

РСУБД поверх Telegram.

pip install tgdb
docker pull n255/tgdb:0.1.0-slim

Caution

Не используйте этот проект с большим количеством ботов, так как он нарушает правила Telegram и создаёт паразитическую нагрузку на его инфраструктуру.

В противном случае ваши данные могут быть удалены, а аккаунты — заблокированы.

Запуск

Для запуска сервера укажите путь к YAML-конфигу через переменную окружения CONFIG_PATH.

Пример конфигурации:

conf:
uvicorn:
host: "0.0.0.0"port: 8000api:
id: 23598539hash: "6d9d7305ffc6f148dab120d24541b127"clients:
bots: "/etc/tgdb/clients/bots"userbots: "/etc/tgdb/clients/userbots"horizon:
max_len: 800transaction:
max_age_seconds: 30message_cache:
max_len: 100_000heap:
chat: -1000000000000page:
max_fullness: 0.8relations:
chat: -1000000000000buffer:
chat: -1000000000000overflow:
len: 5000timeout_seconds: 0.1

Important

С данной конфигурацией один сервер потребляет не более 200 МБ памяти (без учёта обработки входящих запросов).

Обзор

tgdb — это СУБД, хранящая данные в Telegram-чатах и предоставляющая доступ к ним через реляционную модель с поддержкой ACID-транзакций.

Взаимодействие с Telegram происходит через ботов/юзерботов, имеющих фиксированные лимиты на количество запросов в определённый промежуток времени. Фактически они представляют собой аренду небольшой части инфраструктуры Telegram, поэтому считаются ресурсами ввода-вывода (аналогично пропускной способности сети).

Из-за специфики лимитов операции с сообщениями имеют существенно разную стоимость по сравнению с операциями в памяти/на диске:

  • Все операции выполняются за константное время (200–400 мс), но чтение значительно дороже записи, так как доступно только через юзерботов. Для регистрации юзербота требуется отдельный номер (по закону РФ физическое лицо может иметь не более 20 номеров), тогда как для обычных ботов достаточно регистрации у BotFather.
  • Несмотря на сложность создания юзерботов, за один запрос можно прочитать множество сообщений. Запись новых сообщений требует отдельного запроса для каждого сообщения.
  • Обновление сообщений требует предварительного поиска целевого сообщения.
  • Удаление поддерживает пакетную обработку, но также требует поиска сообщений.

Отношения

Текущая реализация позволяет создавать отношения без поддержки миграций. Ограничения включают только доменные ограничения на размер данных.

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

Операции

На данный момент можно читать кортежи только до записи, а сама запись возможна только через bulk-запрос в рамках коммита.

tgdb не использует MVCC, поэтому невозможно сделать Repeatable Read в том виде, что бы он был легче Serializable. В этом случае может быть только три уровня изоляции:

n — количество транзакций уровня изоляции.

Уровень изоляцииОсобенностиСтартКоммитОткатПамять
SerializableТребует повторения транзакций при ошибках сериализацииO(n)O(n)O(n)O(n²)
Read CommittedВ разработке. Операции чтения могут выполняться в 3 раза дольшеO(1)O(1)O(1)O(n)
Read UncommittedO(1)O(1)O(1)O(n)

Important

При параллельном выполнении транзакций с разными уровнями изоляции вся группа получает гарантии минимального уровня из группы.

Чтение кортежей вне транзакций эквивалентно уровню Read Uncommitted, но создаёт меньшую нагрузку.

Коммиты буферизируются и хранятся в отдельном чате перед конкурентной записью в кучу. При достаточном количестве ботов задержка транзакции (10 чтений + 10 записей) составляет ~3 обращения к Telegram (~0.75 с).

Буфер хранится на сервере и сохраняется в чате только при переполнении. Это гарантирует восстановление консистентного состояния после сбоев и не ограничивает сервер пропускной способностью в одно обращение к Telegram.

Этапы выполнения транзакции:

  1. Старт транзакции — сетевая задержка до сервера tgdb
  2. Чтение из кучи — сетевая задержка до telegram
  3. Начало коммита — сетевая задержка до сервера tgdb
  4. Ожидание переполнения буфера — conf.buffer.overflow.timeout_seconds (макс.)
  5. Сохранение буфера в чате — сетевая задержка до telegram
  6. Запись в кучу — сетевая задержка до telegram
  7. Подтверждение коммита — сетевая задержка до сервера tgdb

Масштабирование

На данный момент все данные хранятся в одной куче, которая может вмещать только 1 млн сообщений (после 1 млн Telegram будет удалять сообщения до 500 тыс.), что даже в случае полного заполнения страниц ~16 ГБ (включая метаданные) и сам по себе сервер однопоточный.

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

About

РСУБД поверх Telegram

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages

Generated from emptybutton/library