You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> **Не используйте этот проект с большим количеством ботов**, так как он нарушает правила Telegram-а и ухудшает его работоспособность из-за создания паразитической нагрузки.
20
+
> **Не используйте этот проект с большим количеством ботов**, так как он нарушает правила Telegram и создаёт паразитическую нагрузку на его инфраструктуру.
21
21
>
22
-
> В противном случае ваши данные могут быть удалены, а аккаунты забанены.
22
+
> В противном случае ваши данные могут быть удалены, а аккаунты — заблокированы.
23
23
24
24
## Запуск
25
25
26
-
Для запуска сервера нужно передать путь yaml конфига через переменную окружения `CONFIG_PATH`.
26
+
Для запуска сервера укажите путь к YAML-конфигу через переменную окружения `CONFIG_PATH`.
27
27
28
-
Пример конфига:
28
+
Пример конфигурации:
29
29
```yaml
30
30
conf:
31
31
uvicorn:
@@ -64,89 +64,85 @@ conf:
64
64
```
65
65
66
66
> [!IMPORTANT]
67
-
> С этой конфигурацией один сервер будет потреблять максимум 200MB памяти без учёта обработки входящих запросов.
67
+
> С данной конфигурацией один сервер потребляет не более 200 МБ памяти (без учёта обработки входящих запросов).
68
68
69
-
## Overview
70
-
`tgdb` - это СУБД хранящая данные в чатах телеграмма и предоставляющая доступ к ним в виде реляционной модели и ACIDтранзакций.
69
+
## Обзор
70
+
`tgdb` — это СУБД, хранящая данные в Telegram-чатах и предоставляющая доступ к ним через реляционную модель с поддержкой ACID-транзакций.
71
71
72
-
Всё взаимодействие с Telegram происходит через ботов/юзерботов, которые имеют фиксированные [лимиты](https://limits.tginfo.me/en) для отправки запросов в некотором промежутке времени и фактически являюстя арендой очень маленького кусочка инфраструктуры Telegram-а, поэтому они считаются IO ресурсами, такими, как например пропусктная способность сети.
72
+
Взаимодействие с Telegram происходит через ботов/юзерботов, имеющих фиксированные [лимиты](https://limits.tginfo.me/ru) на количество запросов в определённый промежуток времени. Фактически они представляют собой аренду небольшой части инфраструктуры Telegram, поэтому считаются ресурсами ввода-вывода (аналогично пропускной способности сети).
73
73
74
-
Из-за специфичных лимитов, операции над сообщениями имеют слишком разную цену, чем у операций, которыми можно обращатся с памятью или дисковым пространством:
75
-
- Все операции можно выполнять за константное время (обычно от 200мс до 400мс), но чтение гораздо дороже операций записи, из-за того что читать сообщения могут только юзерботы. Для регистрации юзерботов нужен отдельный номер (а по закону РФ одно физ. лицо может иметь только 20 номеров любых провайдеров), когда для обычных ботов нужно только регестрация у BotFather.
76
-
- Несмотря на сложность создания юзерботов, можно читать сразу много сообщений за одно обращение, а писать новые сообщения можно только по обращению на каждое новое сообщение.
77
-
Обновления само по себе является записью, но для него первоначально необходимо найти то сообщение, которое нужно обновить.
78
-
Удалять можно сразу много сообщений, которых также необходимо найти, но в отличии от обновления, удалять можно сразу много сообщений за одно обращение.
74
+
Из-за специфики лимитов операции с сообщениями имеют существенно разную стоимость по сравнению с операциями в памяти/на диске:
75
+
- Все операции выполняются за константное время (200–400 мс), но чтение значительно дороже записи, так как доступно только через юзерботов. Для регистрации юзербота требуется отдельный номер (по закону РФ физическое лицо может иметь не более 20 номеров), тогда как для обычных ботов достаточно регистрации у BotFather.
76
+
- Несмотря на сложность создания юзерботов, за один запрос можно прочитать множество сообщений. Запись новых сообщений требует отдельного запроса для каждого сообщения.
77
+
- Обновление сообщений требует предварительного поиска целевого сообщения.
78
+
- Удаление поддерживает пакетную обработку, но также требует поиска сообщений.
79
79
80
80
## Отношения
81
-
На данный момент можно только создавать отношения без возможности миграций. Они не поддерживают ограничения, кроме ограничений доменов на размер данных.
81
+
Текущая реализация позволяет создавать отношения без поддержки миграций. Ограничения включают только доменные ограничения на размер данных.
82
82
83
-
Физически кортежи не хранятся сгруппированными по своим отношениям, а располгаются в едином чате - куче. Каждый кортеж хранится в ровно одном сообщении или странице, которая может вместить всего 4096 символа. Из-за этого нельзя создавать отношения с такими схемами, кортежи которых могут не вместится в одну страницу.
83
+
Физически кортежи не группируются по отношениям, а хранятся в едином чате (куче). Каждый кортеж размещается в отдельном сообщении (странице) размером до 4096 символов. Следовательно, невозможно создать отношение, кортежи которого не помещаются в одну страницу.
84
84
85
85
## Операции
86
-
На данный момент можно читать кортежи только до записи, а сама запись возможна только одним bulk запросом вместе с коммитом. В дальнейшем возможно сделать выполнение операторов таким же, как в обычных СУБД, но пока это не сделано.
86
+
На данный момент можно читать кортежи только до записи, а сама запись возможна только через bulk-запрос в рамках коммита.
87
87
88
-
`tgdb` не использует MVCC, поэтому невозможно сделать Repeatable Read в том виде, что бы он был легче Serializable, поэтому может быть только три уровня изоляции:
88
+
`tgdb` не использует MVCC, поэтому невозможно сделать **Repeatable Read** в том виде, что бы он был легче **Serializable**. В этом случае может быть только три уровня изоляции:
89
89
90
-
> `n` - количество транзакций этого уровня изоляции.
90
+
> `n` — количество транзакций уровня изоляции.
91
91
92
92
<table>
93
93
<tr>
94
94
<th>Уровень изоляции</th>
95
95
<th>Особенности</th>
96
-
<th>Скорость старта</th>
97
-
<th>Скорость коммита</th>
98
-
<th>Скорость роллбека</th>
96
+
<th>Старт</th>
97
+
<th>Коммит</th>
98
+
<th>Откат</th>
99
99
<th>Память</th>
100
-
<th>Главный Bottle Neck</th>
101
100
</tr>
102
101
<tr>
103
102
<td><b>Serializable</b></td>
104
-
<td>В лучшем случае позволяют избежать любых аномалий. Нужно ретраить транзакции по ошибке сериализуемости</td>
103
+
<td>Требует повторения транзакций при ошибках сериализации</td>
105
104
<td>O(n)</td>
106
105
<td>O(n)</td>
107
106
<td>O(n)</td>
108
-
<td>O(n^2)</td>
109
-
<td>CPU и память</td>
107
+
<td>O(n²)</td>
110
108
</tr>
111
109
<tr>
112
-
<td><b>Read Сommited</b></td>
113
-
<td>Пока не существует. Транзакции могут видеть только зафиксированные данные. Любые операции чтения могут выполнятся в 3 раза дольше</td>
110
+
<td><b>Read Committed</b></td>
111
+
<td>В разработке. Операции чтения могут выполняться в 3 раза дольше</td>
114
112
<td>O(1)</td>
115
113
<td>O(1)</td>
116
114
<td>O(1)</td>
117
115
<td>O(n)</td>
118
-
<td>IO</td>
119
116
</tr>
120
117
<tr>
121
-
<td><b>Read Uncommited</b></td>
122
-
<td>Транзакции могут видеть не зафиксированные изменения других транзакций</td>
118
+
<td><b>Read Uncommitted</b></td>
119
+
<td></td>
123
120
<td>O(1)</td>
124
121
<td>O(1)</td>
125
122
<td>O(1)</td>
126
123
<td>O(n)</td>
127
-
<td>IO</td>
128
124
</tr>
129
125
</table>
130
126
131
127
> [!IMPORTANT]
132
-
> Если паралельно выполняются несколько транзакций с разным уровнем изоляции, то у всей группы будут гарантии минимального уровня изоляции из этой группы.
128
+
> При параллельном выполнении транзакций с разными уровнями изоляции вся группа получает гарантии минимального уровня из группы.
133
129
134
-
Дополнительно можно читать кортежи из отношений без транзакций, что по уровню изоляции = **Read Uncommited**, но создаёт меньшую нагрузку на сервер.
130
+
Чтение кортежей вне транзакций эквивалентно уровню **Read Uncommitted**, но создаёт меньшую нагрузку.
135
131
136
-
Коммиты транзакций буфферизируются и хранятся в отдельном чате, перед тем, как они будут конкурентно записаны в кучу. В случае достаточного количества ботов, это значит, что задержка для транзакции, которая посылает 10 конкурентных запросов на чтение, а после коммит с 10 операторами записи, будет равна трём обращением к телеграму, что в среднем ~= 0.75 секунд.
132
+
Коммиты буферизируются и хранятся в отдельном чате перед конкурентной записью в кучу. При достаточном количестве ботовзадержка транзакции (10 чтений + 10 записей) составляет ~3 обращения к Telegram (~0.75 с).
137
133
138
-
Буффер хранится на самом сервере и только при переполнении сохранятся в своём чате. В таком случае изменения записанные в буффер переносятся в кучу только после сохранения в чате буффера, что позволяет востанавливатся серверу в консистетное состояние даже в случае любого сбоя и не ограничевает сервер пропусктной способностью в одно обращению к телеграму.
134
+
Буфер хранится на сервере и сохраняется в чате только при переполнении. Это гарантирует восстановление консистентного состояния после сбоев и не ограничивает сервер пропускной способностью в одно обращение к Telegram.
139
135
140
-
В этом случае скорость выполнения одной транзакции будет ограничена следующими шагами:
141
-
1. Старт транзакции - задержка сети с `tgdb` сервером
142
-
2. Чтение из кучи - задержка сети с `telegram`
143
-
3. Начало коммита - задержка сети с `tgdb` сервером
144
-
4. Ожижание переполнения буфера - `conf.buffer.overflow.timeout_seconds` (в худшем случае)
145
-
5. Сохранение буффера в своём чате - задержка сети с `telegram`
146
-
6. Запись в кучу - задержка сети с `telegram`
147
-
7. Оповещение об успешном коммите - задержка сети с `tgdb` сервером
136
+
Этапы выполнения транзакции:
137
+
1. Старт транзакции — сетевая задержка до сервера `tgdb`
138
+
2. Чтение из кучи — сетевая задержка до `telegram`
139
+
3. Начало коммита — сетевая задержка до сервера `tgdb`
5. Сохранение буфера в чате — сетевая задержка до `telegram`
142
+
6. Запись в кучу — сетевая задержка до `telegram`
143
+
7. Подтверждение коммита — сетевая задержка до сервера `tgdb`
148
144
149
-
## Маштабирование
150
-
На данный момент все данные хранятся в одной куче, которая может вмещать только 1 000 000 сообщений (после 1 000 000 Telegram будет удалять сообщения до 500 000), что даже в случае полного заполнения страниц ~= 16 ГБ (включая метаданные) и сам по себе сервер однопоточный.
145
+
## Масштабирование
146
+
На данный момент все данные хранятся в одной куче, которая может вмещать только 1 млн сообщений (после 1 млн Telegram будет удалять сообщения до 500 тыс.), что даже в случае полного заполнения страниц ~16 ГБ (включая метаданные) и сам по себе сервер однопоточный.
151
147
152
148
В таком случае нужно секционировать данные между несколькими серверами практически всегда, даже в случае одной ноды, но сейчас нет встроенных механизмов для этого.
0 commit comments