Skip to content

emptybutton/tgdb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

97 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tgdb

CI CD GitHub Release Wakatime Lines codecov

РСУБД поверх 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: 8000

  api:
    id: 23598539
    hash: "6d9d7305ffc6f148dab120d24541b127"

  clients:
    bots: "/etc/tgdb/clients/bots"
    userbots: "/etc/tgdb/clients/userbots"

  horizon:
    max_len: 800
    transaction:
      max_age_seconds: 30

  message_cache:
    max_len: 100_000

  heap:
    chat: -1000000000000
    page:
      max_fullness: 0.8

  relations:
    chat: -1000000000000

  buffer:
    chat: -1000000000000
    overflow:
      len: 5000
      timeout_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 Uncommitted O(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

License

Stars

Watchers

Forks

Languages