Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ С\С++ _ Стратегия сетевого приложения.

Автор: dzyk 14.9.2008, 17:57

Имеется приложение. Ядро - база данных SQLite(информация в таблицах изменяется 20-30 раз в день). Сейчас необходимо реализовать одновременное использование БД на нескольких компьюетрах "сети"(постоянных соединений нет, кто-то подключается, кто-то отключатеся, IP динамические, всего 5-6 машин).

Вот мои варианты.

1. Связать приложения по UDP и отсылать каждые х-минут контрольную сумму файла БД SQLite. Если не совпадает то коннект по TCP и клонирование самого свежего файла БД SQLite.

2. Поставить сервер MySQL|PostgreSQL|other (нереально, нет выделенного сервера)

3. Ваше предложение

Автор: AD 14.9.2008, 18:00

Цитата(dzyk @ 14.9.2008, 18:57) *
2. Поставить сервер MySQL|PostgreSQL|other (нереально, нет выделенного сервера)

3. Ваше предложение

Вопрос (сорри, если тупой): нельзя одну машину сделать серверной?

Автор: dzyk 14.9.2008, 18:06

Цитата(AD @ 14.9.2008, 19:00) *
Вопрос (сорри, если тупой): нельзя одну машину сделать серверной?


к сожалению нет, т.к.

1. Нет администраторов
2. Компьютеров в сети максимум 6-7. Ни один из них постоянно работать не будет.

Автор: Novak 14.9.2008, 18:19

Может, стоит реализовать синхронизацию копий БД, которые хранятся на каждом компе, путём оповещения при каждом изменении?

Ещё вариант - попробовать реализовать своеобразный динамический сервер, то есть данную роль передавать при отключении. Для этого выстроить определённый порядок обращений (с начала по этому ip, потом по другому и т.д.).
В любом случае при этом крайне желательны статические IP

Но лучше всего было бы поставить на один компьютер нормальную СУБД, решается много проблем разом.

Автор: dzyk 14.9.2008, 18:55

Цитата(Novak @ 14.9.2008, 19:19) *
попробовать реализовать своеобразный динамический сервер


Это самый интересный вариант, но сложно. :crazy:

Развивая Вашу идею:

1 Программы, живущие в настоящее время в сети, вещают в сеть свой IP+контр сумму файла БД+время жизни в онлайн
2 Если контр сумма не совпадает, то кешировавшиеся ранее SQL запросы передаются по TCP тем, кто был в оффлайне ?от программы, которая дольше всех живет в сети.

Самое сложное - создать кэш запросов к БД SQLite, так как в программе используется в основном QSQLTableModel.

Автор: Litkevich Yuriy 14.9.2008, 19:08

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

Мой вариант такой - ставим на все тачки Git, у каждого своя копия файла БД и при необходимости работать с БД сначало обновляем свою копию БД, средствами Git, он в отличие от Subversion может работать с децентрализованой средой. Но пускать его видимо нодо будет руками, либо выдрать часть кода из QGit - Qt'явая оболчка для Git'а.

Автор: Novak 14.9.2008, 19:26

Всё же стоит выделить один комп для постоянной работы СУБД, пусть он даже и не будет чистым сервером))
Просто как представишь себе все проблемы работы в подобной децентрализованной среде..

Автор: ViGOur 14.9.2008, 20:06

dzyk, мне кажется, что ты предложил самое оптимальное решение.
Только вот я не думаю, что целесобразно копировать весь файл бд, лучше просто передавать новые, изменившиеся или удаленные записи.
Так как не понятно до каких размеров вырастет бд, и какая связь у клиентов с тобой. Например те же 10-20Gb постоянно передавать по сети 20-30 раз в день это не мало... :)

Автор: dzyk 14.9.2008, 20:41

Цитата(Litkevich Yuriy @ 14.9.2008, 20:08) *
SQLite не поддерживает транзакции, т.е. к БД одновременно сможет подключатся только одно приложение/компьютер/пользователь


не согласен.
SQLite is a software library that implements a ... transactional SQL database engine.

Цитата(ViGOur @ 14.9.2008, 21:06) *
я не думаю, что целесобразно копировать весь файл бд


Справедливое замечание.

Но я не знаю как кэшировать SQL запросы, я ведь использую класс QSQLTableModel

Автор: ViGOur 14.9.2008, 22:21

Цитата(dzyk @ 14.9.2008, 21:41) *
Но я не знаю как кэшировать SQL запросы, я ведь использую класс QSQLTableModel
Нужно подумать как обойти класс QSQLTableModel...

Например у той же Berkeley DB аля логирование, файлы логов, которые создаются при добавлении новой записи, изменении или удалении. Но это как вариант стороны в которую капать...

Автор: dzyk 15.9.2008, 0:48

Цитата(ViGOur @ 14.9.2008, 23:21) *
Нужно подумать как обойти класс QSQLTableModel


Если унаследовать QSQLTableModel и переопределить setData, в котором создать кэширование запросов.

Неужели нет другого способа?

Цитата(Litkevich Yuriy @ 14.9.2008, 20:08) *
Мой вариант такой - ставим на все тачки Git


Мне кажется, это очень сложно. Git очень серьезная вещь (хотя с ней не знаком, но судя по описаниям). В моем случае это кАщунство.

Автор: DmP 15.9.2008, 3:48

Цитата(ViGOur @ 14.9.2008, 23:21) *
Неужели нет другого способа?

SQLite поддерживает простые триггеры, поставте перехват на INSERT, DELETE и UPDATE:
http://sqlite.org/lang_createtrigger.html

Автор: dzyk 15.9.2008, 23:05

Цитата(DmP @ 15.9.2008, 4:48) *
SQLite поддерживает простые триггеры


Спасибо. Теоретически все срастается. Осталось реализовать.

Автор: Litkevich Yuriy 16.9.2008, 5:13

Цитата(DmP @ 15.9.2008, 7:48) *
SQLite поддерживает простые триггеры, поставте перехват на INSERT, DELETE и UPDATE:
и что вам в этой децентрализованой среде дадут тригеры?
Давайте рассуждать над механизмом:
Вот пользователь № 1 (П1) вставил данные в свою копию БД (Б1), дальше что происходит?

Автор: ViGOur 16.9.2008, 8:09

Цитата(Litkevich Yuriy @ 16.9.2008, 6:13) *
Вот пользователь № 1 (П1) вставил данные в свою копию БД (Б1), дальше что происходит?
Дальше срабатывает тригер на добавление записи, в котором можно эту запись сохранить например в файл. Тоже самое при изменении и удалении записей.

Автор: Litkevich Yuriy 16.9.2008, 8:17

Цитата(ViGOur @ 16.9.2008, 12:09) *
в котором можно эту запись сохранить например в файл
разве есть такая возможность в БД, в частности в SQLite?
Если есть, то пример тригера в студию!

Автор: Litkevich Yuriy 16.9.2008, 8:54

Цитата(ViGOur @ 16.9.2008, 12:09) *
можно эту запись сохранить например в файл
тут тригер даже и не нужен, данные меняются с помощью программы она сохранит в файл.

Итак, П1 вставил данные в Б1, копия вставленых данных (Ин1.1) сохранилась в файл, дальше что происходит?

Автор: dzyk 16.9.2008, 21:40

Цитата(Litkevich Yuriy @ 16.9.2008, 9:17) *
разве есть такая возможность в БД, в частности в SQLite?


Ну в файл то точно НЕТ.

Вот пример триггера SQLite ( при каждом инсерте в таблицу people поля id,fio сохраняются в таблицу Log_table)
CREATE TRIGGER LogRSChanges INSERT   ON people
  BEGIN
    INSERT INTO Log_table (id,fio) VALUES (new.id,new.fio);
  END;


Осталось только включить фанатазию и написать алгоритм синхронизации между программами.

Покритикуйте такой вариант:

Запускается 1П, обращается в сеть. Если не находит другой П2 или Пх. То открывает свою БД и работает с ней как с "верной" БД.

После этого запускается П2. видит П1 и запрашивает у нее "данные для синхронизации БД". Приводит свою БД2 в соответсвии с БД1. И спокойно работает. При этом все изменения в своей БД2 отсылаются в БД1. А изменения в БД1 (1П соотв) копируются в БД2.

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

Это конечно самый ненадежный способ. А если кто-то работал в оффлайне и изменял свою БД? :) Алгоритм намного усложняется.

Автор: ViGOur 17.9.2008, 12:00

Еще есть вариант того, что 1П и 2П работают в офлайне, оба изменяют одну и ту же запись, что ты будешь делать(значения записи разные)? :)

Автор: AD 17.9.2008, 12:06

Цитата
Еще есть вариант того, что 1П и 2П работают в офлайне, оба изменяют одну и ту же запись, что ты будешь делать(значения записи разные)? :)

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

Автор: Litkevich Yuriy 17.9.2008, 13:28

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

dzyk, а как устроены таблицы БД заранее известно?

Автор: dzyk 17.9.2008, 17:55

Цитата(ViGOur @ 17.9.2008, 13:00) *
Еще есть вариант того, что 1П и 2П работают в офлайне, оба изменяют одну и ту же запись, что ты будешь делать(значения записи разные)?


Если синхронизовать ОС(либо приложения) по времени, то апдейтится последний вариант из "стека триггеров"

Автор: Andrew Selivanov 18.9.2008, 12:52

Цитата(dzyk @ 14.9.2008, 18:57) *
Имеется приложение. Ядро - база данных SQLite(информация в таблицах изменяется 20-30 раз в день). Сейчас необходимо реализовать одновременное использование БД на нескольких компьюетрах "сети"(постоянных соединений нет, кто-то подключается, кто-то отключатеся, IP динамические, всего 5-6 машин).

Вот мои варианты.

1. Связать приложения по UDP и отсылать каждые х-минут контрольную сумму файла БД SQLite. Если не совпадает то коннект по TCP и клонирование самого свежего файла БД SQLite.

2. Поставить сервер MySQL|PostgreSQL|other (нереально, нет выделенного сервера)

3. Ваше предложение


При подключении посылаем широковещательный пакет смысл которого сводится к фразе "Есть кто главный?"
Если главного нет, становимся главным и начинаем отвечать на подобные запросы.
Если главный есть, открываем с ним постоянное соединение и засасываем изменения к базе (или всю базу)
На каждой машине своя актуальная копия данных, но изменения происходят только через главный сервер (нажатием жирной кнопки ДОБАВИТЬ ИЗМЕНЕНИЯ).
Если сервер умирает - происходят выборы нового на основании например приоритета (не давать пользователям ничего изменять в такие моменты, просто лочить нахрен форму с надписью обрыв связи ждите итп)
Короче смысл такой - динамический главный сервер и все изменения только через него, а иначе секс с внедрением механизма транзакций, причем думаю придется все равно с ним что то придумывать, т.к. сервера могут отвалиться, и в то время как они отваливаются отваливается главный сервер, неожиданный shutdown, итп.

Автор: Novak 18.9.2008, 15:50

Всё равно плохо, ибо ситуация, когда все компы не работают, один включился, потом выключился. потом врубились остальные, приводит к потере данных.
Хотя можно предусмотреть, что запись возможна только при рабочем главном сервере, а передача роли главного сервера возможна только добровольная (т.е. гарантированном копировании данных).
Остальные пусть при отсутствии главного сервака пишут в кеш, или что-то подобное файрберда (Firebird) в плане версионности замутить

Автор: Litkevich Yuriy 18.9.2008, 16:58

Цитата(Novak @ 18.9.2008, 19:50) *
Всё равно плохо
Да!
А идея Мастер-Браузера (главного компа) вообще плохая, намой взгляд. Реализацией арбитража приходилось заниматся в сети из 128 устройств. Отлаживаться долго пришлось.

Надо думать как изменения регестрировать надежно. Тогда можно будет и обмен без блокировок наладить и без главной машины.

Автор: Tonal 19.9.2008, 10:51

Мне всё-таки кажется, что проще/быстрее/дешевле/надёжнее купить машинку под сервер.
Ну или уж поднять честный кластер на этих 5-7 машинках. :D

Автор: Andrew Selivanov 19.9.2008, 12:51

Цитата(Novak @ 18.9.2008, 16:50) *
Всё равно плохо, ибо ситуация, когда все компы не работают, один включился, потом выключился. потом врубились остальные, приводит к потере данных.
Хотя можно предусмотреть, что запись возможна только при рабочем главном сервере, а передача роли главного сервера возможна только добровольная (т.е. гарантированном копировании данных).

Именно это я и имел ввиду под:
но изменения происходят только через главный сервер (нажатием жирной кнопки ДОБАВИТЬ ИЗМЕНЕНИЯ).

Цитата(Litkevich Yuriy @ 18.9.2008, 17:58) *
А идея Мастер-Браузера (главного компа) вообще плохая, намой взгляд. Реализацией арбитража приходилось заниматся в сети из 128 устройств. Отлаживаться долго пришлось.

Для 5-7 машин и редких изменений данных IMHO покатит схема с блокировками. Все же 128 машин это уже в несколько раз больше.

Теперь про идею в целом - да я и не претендовал на самую лучшую идею :) Высказал свои соображения. Вообще мне кажется очень полезно было бы изучить логику работы протоколов Gnutella, eDonkey, DCPP(ADC) даже там используются серверы. Лично мне особенно нравится как написан DCPP (каждый кто озадачится написанием своего протокола - очень рекомендую!)

Автор: Litkevich Yuriy 19.9.2008, 13:01

Есть приборная сеть, в которой реализована идея респределенной БД (название на языке крутится, но вспомнить не могу), узлы могут использовать любые даннын из нее, но там помоему тоже централизованая система.
Реализуется на микроконтроллерах, как следствие не должно требовать ресурсов и т.д. и т.п.

Автор: Novak 19.9.2008, 13:03

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

Автор: Tonal 19.9.2008, 19:13

Да, ещё можно поднять на машинах распределённую БД. Например Mnesia из стандартной поставки Erlang-а такой является.
Т.е. поднимаем на всех машинах Mnesia - если я ничего не путаю, она сама является отдельным Erlang приложением.
Пишем адаптеры для работы с ней и всё готово. :)
Т.е. на конкретной машине Наша прожка коннектится к локальной Erlang-овской ноде на которой крутится Mnesia.
А она уже заботится о всей распределёнке.

По ходу вариант менее бредовый чем мутить собственную распределённую базу.
Тут нужно написать конектор и разобраться с Mnesia. и по тому и по другому хорошая дока и есть примеры. :)

Автор: Litkevich Yuriy 19.9.2008, 19:44

http://Начала%20работы%20с%20Erlang по Erlang'у нашел

Автор: ЙаМайскЫйПчОЛ 23.9.2008, 13:12

dzyk, Варинт оффлайна сродни работы с CVS, перед заливкое в единую БД происходит запрос текущего состояния с учетом времени изменения + предоставляется возможность мержинья локально внесенных изменений или истории SQL запросов...

Может можно завязать базы данных на механизмы контроля версии файлов типа cvs?

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)