Форум » LetoDB, HbNetio. » Leto DB Server (продолжение) » Ответить

Leto DB Server (продолжение)

alkresin: Только что открыл на Sourceforge новый проект - Leto DB Server - https://sourceforge.net/projects/letodb Это мультиплатформенный ( Windows, Unix/Linux ) сервер баз данных, предоставляющий клиентским программам доступ к dbf/cdx файлам, находящимся на удаленном сервере ( можно и на локальном компьютере запускать - в отладочных целях ). В общем, как ADS :). Проект - на стадии разработки, не все даже базовые функции еще реализованы, до оптимизации дело еще не дошло. Но работает :). Крутится у меня на сервере несколько дней, подключал до 15 клиентов, пока не падает. Мои программы работают с ним нормально. Преимущества по сравнению с обычным файл-сервером: 1) Безопасность - базы могут быть в каталоге, недоступном для клиентских компьютеров - никто их случайно не удалит и не повредит. 2) Поскольку базы открываются серверной программой, а не клиентской, ее целостности ничего не грозит при случайном отключении клиентского компьютера. 3) значительное уменьшение сетевого траффика. 4) Должен быть, по идее, выигрыш в скорости. 5) Возможность контроля за пользователями с помощью утилиты manage ( можно придумать и другие формы контроля ). 6) Можно будет сделать транзакции, stored procedures на Харборе, ... и вообще все в наших руках :). Кто хочет участвовать в разработке, тестировании - пишите.

Ответов - 316, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 All

Pasha: Andrey пишет: А как тогда добавлять свои функции на хХарборе в СЕРВЕР leto_db ? Переписывать на Харборе ? Так по синтаксису Harbour и xHarbour практически идентичны. Свои функции добавлять надо так же, как и с xHarbour

Andrey: Pasha пишет: Так по синтаксису Harbour и xHarbour практически идентичны. Свои функции добавлять надо так же, как и с xHarbour Так это почти понятно.... Что так сильно различается в лучшую сторону Харбор ? Если будет лучше СЕРВЕР, то смиримся с отсутствием хХарбора. Главное потом чтоб не жалеть, что нет совместимости клиента на хХарборе и сервера на Харборе !

alx_on: alkresin Суммируя вышесказанное Александр, беремся переписать? Со своей стороны предлагаю активное тестирование и помощь в реализации Текущая ситуация похожа на поиск черной кошки в темной комнате. Непредсказуемость поведения библиотек, не расчитанных на MT-режим и невозможность расширения функционала без костылей. А хочется летать! :) Если да, то 1. Переход на Harbour последней версии 2. Возможность запуска нескольких потоков для обработки запросов и(или) обработки таблиц 3. Запуск потоков для встраиваемых функций (plugins? SQL-запросы? Аппетиты растут во время еды...) 4. Асихронная передача сообщений или отдельный поток для этого 5. Корректная обработка падения отдельного потока, не затрагивающая остальные потоки и (или) клиентские соединения (ну это уже так, мечты) 6. И т.д. и т.п.


alkresin: Суммируя вышесказанное Александр, беремся переписать? Со своей стороны предлагаю активное тестирование и помощь в реализации Только не так резво :). Для начала надо как следует разобраться с моделью mt в Harbour, с возможностью ее использования на С уровне, с тем, какие ограничения она наложит на возможную реализацию. После беглого просмотра некоторых материалов меня особенно напрягло вот это: Workareas are fully thread separated. Each threads uses it's own workareas so there is not need to synchronize access to WA. The same if for SETs (so _SET_DELETED, and similar switches are local to thread and does not effect other threads) and some RDD attributes like default RDD driver, current WA, neterr flag, etc. Each thread has it's own table for ALIASes and aliases are not shared between threads. Just like memvars. Only RDD nodes and RDD settings (rddInfo()) are global to application. > Are there public wa for all MT and private wa for one MT? private for MT. > Will it be possible to close all private wa of a single MT? dbCloseAll() - it closes all workareas open by thread which executes it. When you terminate thread then all open by this thread WA are closed automatically. И учтите, что реализация mt приложений достаточно сложна, и при переходе к Harbour модели нам наверняка встретится еще не одна "черная кошка в темной комнате" :). Так что я предпочел бы продолжить искать свою кошку параллельно с исследованием Harbour mt ( полностью согласен, что его использование, если удастся успешно обойти/учесть его ограничения, очень заманчиво ).

alx_on: alkresin пишет: особенно напрягло Ничего плохого не вижу. Если, например, будем переделывать REALTIONS в сторону выполнения на сервере, тогда да, есть сложные моменты, связанные с передачей в поток сразу нескольких таблиц. На текущей реализации никаких ограничений я не увидел. Каждый поток будет обрабатывать свой набор таблиц. Или будет запрашивать (если это не сильно накладно по времени) у главного держателя таблиц. Так что я предпочел бы продолжить искать свою кошку параллельно с исследованием Harbour mt Развивать поиск кошек на данный момент некуда. На вин и маке падают по разному и отловить можно только случайно ценой потери минимум дня тестов. Я считаю, что мы уже уперлись в ограничения. Давайте выделим отдельную ветку для перехода. Старую можно использовать для работы и косметических доработок, на новой версии обкатывать MT

Pasha: alkresin пишет: Workareas are fully thread separated. Я не копался в Harbour mt, а надо бы :) Из прочитанного можно понять, что надо для каждого потока создавать отдельную WA для одной и той же таблицы. А ведь в leto WA для таблицы, открываемой несколькими пользователями, одна. А при создании потока уже открытые WA ему доступны ? Конечно, надо решить несколько таких принциальных моментов. Например (это пока только для обсуждения), можно создавать отдельную WA для каждой команды USE, поступающей с клиента. Харбор в этом случае (как ни удивительно) работать будет. Но тогда таблицы прийдется открывать в shared-режиме, что нежелательно. Да и надо продумать, что в этом случае будет, к примеру, с транзакциями. Хоты в leto они выполняются на клиента. Может быть еще есть какие-то мели и подводные камни. Или оставить существующую схему работы с WA, но тогда прийдется блокировать таблицы для разрешения конфликта с разными потоками. PS Я к вам конечно присоединюсь :)

Andrey: alx_on пишет: Давайте выделим отдельную ветку для перехода. Старую можно использовать для работы и косметических доработок, на новой версии обкатывать MT Давайте не так быстро... Может после изучения и проработки на бумаге технологии перехода ?

alkresin: Каждый поток будет обрабатывать свой набор таблиц А как быть с транзакциями ? Или будет запрашивать (если это не сильно накладно по времени) у главного держателя таблиц. Вот именно - если это не сильно накладно по времени. Т.е. главный поток будет анализировать команды; если это открытие таблицы, то проверит, открыта ли она уже для других клиентов и, если нет, вызывает специальный поток - держатель таблиц для ее открытия, а если да - то другой поток для ее DBREQUEST и т.п. ... Я это все к тому, что архитектура требует тщательнейшего продумывания на предмет согласованности работы потоков и достижения приемлемой производительности. Развивать поиск кошек на данный момент некуда. На вин и маке падают по разному и отловить можно только случайно ценой потери минимум дня тестов. Я считаю, что мы уже уперлись в ограничения. Есть еще варианты и появятся другие. Первое, что я попробую - это сделать c iprecv то же, что сделали с ipaccept, - проверять не только по hb_iperrorcode(), но и по возвращаемому функцией значению. Если бы вы все-таки попробовали перекомпилировать сервер на старой версии Harbour и потестировали бы его, это было бы существенное продвижение - было бы яснее, куда смотреть. У меня-то все сейчас работает ( даже без последних корректировок ) - 14-ый день без проблем... Давайте выделим отдельную ветку для перехода. Ветку CVS ? Я бы предпочел просто создать новый каталог - так мне кажется проще и удобнее. В этих средствах CVS, связанных с ветвлением, я не очень ориентируюсь и боюсь запутаться.

alkresin: А при создании потока уже открытые WA ему доступны ? Насколько я понял - нет. Например (это пока только для обсуждения), можно создавать отдельную WA для каждой команды USE, поступающей с клиента. Харбор в этом случае (как ни удивительно) работать будет. Но тогда таблицы прийдется открывать в shared-режиме, что нежелательно. А в letodb и сейчас есть такой режим работы - NO_SAVE_WA = 1 в letodb.ini, я, правда, его толком не тестировал, поэтому и в readme не упомянул, только в Changelog. Да и надо продумать, что в этом случае будет, к примеру, с транзакциями. Мда... Это особенная тема. Сейчас одно из главных свойств транзакций ( целостность, что ли - забыл уже, как называется ) гарантируется именно тем, что все они выполняются в одном потоке, т.е. строго одна за другой. Может быть еще есть какие-то мели и подводные камни. :):) Я, помню, немало помучился, прежде чем нормально заработала нынешняя mt схема - то производительность резко падала, то вообще глухо все висло.

alx_on: Pasha пишет: Но тогда таблицы прийдется открывать в shared-режиме, что нежелательно Если использовать один или оба варианта 1. Для каждого потока свой набор таблиц. Т.е. какая то определенная таблица будет использоваться всеми пользователями (открывается лето в exclusive-режиме) и только этот поток ее обрабатывает. 2. Между потоками передаем таблицу (например, для leto_sum в отдельном потоке) с помощью стандартных функций харбора то проблемы, как таковой, вообще не существует! (скорость передачи таблицы окупится общей скоростью выполнения и общим увеличением отзывчивости сервера) Для транзакций на стороне сервера нужно будет придумать хорошее решение, но! Главное начать, а там само пойдет :) В текущем варианте транзакций даже менять ничего не надо для клиента. Для сервера можно запускать поток, который будет выступать в роли клиента для остальных потоков с таблицами (т.е. он последовательно отдает команды на обновление таблиц, раскиданных по потокам)

alkresin: Для транзакций на стороне сервера нужно будет придумать хорошее решение, но! Главное начать, а там само пойдет :) Вы эти горбачевские штучки бросьте :). Он вот так именно и говорил - и как оно "пошло" и к чему пришло мы все свидетели. Впрочем, это тема для другого форума... Начать можно, я не против. Просто надо сначала поизучать, как организовывать mt в Harbour на С уровне. Я этого еще не знаю.

alkresin: Кстати, нет ли у кого в загашнике теста производительности RDD, а то я свои растерял ? Написать-то недолго, конечно, но ...

КСС: Всем привет. Помнится, в молодости, когда я работал в КБ на военном радиозаводе и разрабатывал кой-какую аппаратуру, бывало на полпути понимал, что сама идея имеет недостатки, которые не позволят реализовать все задачи. Тогда я шёл к руководителю проекта и предлагал новые решения и убедительно доказывал, что прежняя никуда не годится. Его ответ я запомнил и руководствуюсь всю жизнь. Он сказал: "Лучшее - враг хорошего. Сделай хорошее, а потом займёшься лучшим". Кстати, в производство пошёл именно "хороший" вариант, а до лучшего руки так и не дошли. Предлагаю довести до совершенства и максимально возможной стабильности существующий вариант, а затем спокойно делать что-то новое на старых ошибках. Если, к тому времени, кому то это ещё будет нужно.

alkresin: Предлагаю довести до совершенства и максимально возможной стабильности существующий вариант, а затем спокойно делать что-то новое на старых ошибках. Если, к тому времени, кому то это ещё будет нужно. Ни в коем случае не собираюсь бросать действующий вариант. Он вполне удовлетворяет нужды предприятия, где я работаю ( а это, кстати, не маленькое предприятие - около 1100 человек ). Но было бы интересно попробовать и новую схему. Для меня это не главный приоритет, но кого-то заинтересует всерьез. Возможно, удастся сохранить большую часть кода, переписав только ядро

Pasha: Александр, посмотрите пожалуйста такой случай Перед транзакцией запись удалена Делаем: leto_BeginTransaction() ... dbRecall() ... leto_CommitTransaction() ? Deleted() // true, т.е. запись остается удаленной, хотя фактически recall сработал. Если сделать skip -1 skip 1 ? Deleted() то возвращается false

alkresin: Сделал небольшой тест для сравнения скорости RDD ( слова Александра о превосходстве ADS меня задели, тем более, что и для меня ADS с самого начала был ориентиром ): #define KOL_ITER 10000 FUNCTION Main( cPathLeto ) PRIVATE cPathAds := "//199.10.11.5:6262/data/" PRIVATE cTable := "test.dbf" PRIVATE aDbf := { { "F1","C",20,0 }, { "F2","L",1,0 }, { "F3","N",12,2 }, ; { "F4","N",8,0 }, { "F5","C",30,0 } } IF Empty( cPathLeto ) cPathLeto := "//199.10.11.5:2814/" ELSE cPathLeto := "//" + cPathLeto ENDIF SET( _SET_FILECASE, 1 ) SET( _SET_DIRCASE, 1 ) SET PRINT ON SET PRINTER TO test_speed.txt ADDITIVE #ifdef RDD_ADS #include "ads.ch" rddSetDefault( "ADS" ) SET FILETYPE TO CDX adsSetServerType( 6 ) adsrightscheck( .F. ) SET AXS LOCKING ON Test( cPathAds ) #endif #ifdef RDD_LETO REQUEST LETO Rddsetdefault( "LETO" ) Test( cPathLeto ) #endif RETURN Nil FUNCTION TEST( cPath ) LOCAL i, n, nSec, sFilter ? "Start", cPath, "iterations: "+Ltrim(Str(KOL_ITER)) ? "---------------------------------------" dbCreate( cPath + cTable, aDbf ) USE ( cPath + cTable ) NEW SHARED nSec := Seconds() FOR i := 1 TO KOL_ITER dbAppend() REPLACE F1 WITH "Test" + Str(i,10), ; F2 WITH ( i%2 == 1 ), ; F3 WITH Seconds(), ; F4 WITH ( KOL_ITER - i ) % 758 + ; Iif( i%3 == 0, 400, Iif( i%3 == 1, 200, 600 ) ), ; F5 WITH Replicate( "m",25 ) NEXT ? "Append", Seconds()-nSec nSec := Seconds() INDEX ON Str(F3+F4,12,2) TAG T1 INDEX ON Str(F4,8)+F1 TAG T2 ? "Indexing", Seconds()-nSec ordSetFocus( "T1" ) nSec := Seconds() GO TOP DO WHILE !Eof() n := F4 dbSkip(1) ENDDO ? "Skipping Forward (I)", Seconds()-nSec nSec := Seconds() DO WHILE !Bof() n := F4 dbSkip(-1) ENDDO ? "Skipping Back (I)", Seconds()-nSec SET ORDER TO 0 nSec := Seconds() GO TOP DO WHILE !Eof() n := F4 dbSkip(1) ENDDO ? "Skipping Forward", Seconds()-nSec nSec := Seconds() DO WHILE !Bof() n := F4 dbSkip(-1) ENDDO ? "Skipping Back", Seconds()-nSec nSec := Seconds() FOR i := 1 TO 30 sFilter := "F4 < " + Ltrim( Str( i * 15 ) ) SET FILTER TO &sFilter GO TOP DO WHILE !Eof() n := F4 dbSkip(1) ENDDO NEXT ? "Filtering-1", Seconds()-nSec nSec := Seconds() FOR i := 1 TO 50 GO TOP DO WHILE !Eof() n := F4 dbSkip(1) ENDDO NEXT ? "Filtering-2", Seconds()-nSec SET FILTER TO nSec := Seconds() FOR i := 1 TO KOL_ITER GO i n := F4 NEXT ? "Go to record", Seconds()-nSec ordSetFocus( "T2" ) nSec := Seconds() FOR i := 1 TO KOL_ITER GO i sFilter := Str(F4,8)+F1 GO TOP SEEK sFilter NEXT ? "Seeking", Seconds()-nSec ? ? CLOSE ALL RETURN Nil Серевер - ASPLinux 11.2, CPU Pentium 4, 3000GHz, ОЗУ 2Gb Вот результаты: Start //199.10.11.5:6262/data/ iterations: 10000 --------------------------------------- Append 7.00 Indexing 0.22 Skipping Forward (I) 0.66 Skipping Back (I) 0.64 Skipping Forward 0.52 Skipping Back 0.52 Filtering-1 2.06 Filtering-2 3.98 Go to record 2.36 Seeking 7.72 Start //199.10.11.5:2814/ iterations: 10000 --------------------------------------- Append 4.59 Indexing 0.16 Skipping Forward (I) 0.55 Skipping Back (I) 0.58 Skipping Forward 0.52 Skipping Back 0.51 Filtering-1 2.95 Filtering-2 7.38 Go to record 2.39 Seeking 9.11 Запустил еще раз: Start //199.10.11.5:6262/data/ iterations: 10000 --------------------------------------- Append 7.25 Indexing 0.22 Skipping Forward (I) 0.66 Skipping Back (I) 0.64 Skipping Forward 0.52 Skipping Back 0.53 Filtering-1 2.09 Filtering-2 4.00 Go to record 2.39 Seeking 7.69 Start //199.10.11.5:2814/ iterations: 10000 --------------------------------------- Append 4.61 Indexing 0.16 Skipping Forward (I) 0.58 Skipping Back (I) 0.59 Skipping Forward 0.56 Skipping Back 0.56 Filtering-1 3.05 Filtering-2 7.09 Go to record 2.38 Seeking 7.64 Цифры для двух запусков чуть отличаются - сервер-то рабочий, загрузка меняется - но основные соотношения между Ads и Leto остаются. По результатам тестов Leto заметно быстрее добавляет записи и индексирует ( быстрая индексация - целиком заслуга dbfcdx ), немного быстрее ( процентов на 15 ) ходит по индексированной базе и практически так же, как ADS - по неиндексированной; примерно одинаковые результаты по go to и seek. Ads заметно быстрее фильтрует - по-видимому, за счет того, что его встроенный движок интерпретации выражений гораздо проще и, соответственно, быстрее, чем у Harbour.

alx_on: КСС пишет: Предлагаю довести до совершенства и максимально возможной стабильности существующий вариант Он УЖЕ доведен до предела своих возможностей Стабильность (на данном способе реализации) тоже. Не надо бросаться в другую крайность. Типа работает не трогай. Костыли приделывать. В данном случае предлагается не улучшение, а хорошее решение проблемы падений и скорости работы. Я считаю, что комфортность работы (скорость и отзывчивость системы, надежность) является для данного типа продуктов главным приоритетом. И лишь бы работало (хоть иногда) - это не ответ. Искать ошибки я лично больше не намерен (и так уже на это убил больше недели) Надо начинать переделку (все или не все переделывать - это обсуждаемо)

alx_on: alkresin пишет: Сделал небольшой тест для сравнения скорости RDD ( слова Александра о превосходстве ADS меня задели, тем более, что и для меня ADS с самого начала был ориентиром ) Никого не хотел задеть или каким либо образом обидеть. Как я уже говорил у меня тоже на тестах все отлично. Потому то я и выбрал лето :) На реальном приложении с реальной базой не все так радужно Конечно, можно сказать про проблемы реализации самого приложения, но факт остается фактом - ADS считала быстрее (я потом смог переделкой прилаги достичь скорости ADS до переделки, но и скорость ADS тоже выросла)

alkresin: Я считаю, что комфортность работы (скорость и отзывчивость системы, надежность) является для данного типа продуктов главным приоритетом. И лишь бы работало (хоть иногда) - это не ответ. Согласен. Но как раз "комфортность" работы здесь и сейчас, с моими клиентскими приложениями - в полном порядке. И работает оно не "хоть иногда", а, как и положено, 24 часа в сутки, стабильно и надежно. Я это к тому, что не все так плохо :). Поэкспериментировать с реализацией ядра я не отказываюсь. Никого не хотел задеть или каким либо образом обидеть. Да не обиделся я, Александр, мне уже давно не 20 лет :). "Задели" ваши слова по-хорошему - лень объяснять, надеюсь поймете. Я верю, что в вашем конкретном случае ADS заметно быстрее. Это может быть вызвано или какими-то особенностями ОС, сетевой среды ( с этой точки зрения было бы неплохо, если б вы повторили мой тест у себя ), или тем, что в ваших приложениях наиболее активно используются как раз те операции, где ADS реально быстрее. По результатам моих тестов это фильтрация. Особенно заметна разница при повторных проходах по отфильтрованной базе. По-видимому, ADS использует какие-то механизмы оптимизации, запоминает в буфере номера записей, попадающих в фильтр. В своих клиентских приложениях я это делаю при необходимости сам.

alkresin: Pasha пишет: Перед транзакцией запись удалена ... Посмотрю. Где-то в буфере на клиентской стороне остается этот флаг.



полная версия страницы