информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Страшный баг в WindowsВсе любят медСетевые кракеры и правда о деле Левина
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
 Умер Никлаус Вирт 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Oracle Berkeley DB btree/hash performance 05.08.08 06:36  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
На одно-процессорном компьютере, тестировалась производительность «map» контейнера на основе Oracle Berkeley DB с доступом DB_BTREE/DB_HASH. Производительность оказалась не очень высокой: для 1 writer и 4 readers производительность в ~30-40 раз ниже чем для обычной std::map с простейшей синхронизацией на критической секции. Кстати, это не плохой результат (~50000 w/r в секунду) для многих практических задач. Но вопрос в том, можно ли повысить скорость DB_BTREE/DB_HASH?

Вероятно, наибольшее влияние оказывает DB_BTREE/DB_HASH страничный механизм блокировок (page-level locking) на замедление скорости w/r. Напротив, для DB_QUEUE (по-элементная блокировка, record-level locking), производительность не намного уступает stl-based queue коgнтейнерам с простейшей синхронизацией на semaphore и критической секции.
Просто ремайндер 06.08.08 15:28  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
Из других постов я понял, что нужно это тебе для коммерческого проекта. Так вот Oracle BDB ни фига не бесплатная для коммерческих проектов. Там цена такая, что они ее даже в открытую стесняются на сайте выкладывать.
Хм... меня чуть кандратий не схватил. Я быстенько написал в... 07.08.08 07:25  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
> Из других постов я понял, что нужно это тебе для
> коммерческого проекта. Так вот Oracle BDB ни фига не
> бесплатная для коммерческих проектов. Там цена такая, что
> они ее даже в открытую стесняются на сайте выкладывать.
Хм... меня чуть кандратий не схватил. Я быстенько написал в Oracle. Прояснилось следующее - мы можем использовать BDB в коммерческих целях фо фри, если не будет передавать ПО третьим лицам. Самое главное, чтобы не было "redistribution":

The following are not redistribution:

Building an application for use internal to your organization, deployed and managed on your company servers.
Off-site backups or other software archival procedures.


http://www.oracle.com/technology/software/products/berkeley-db/htdocs/licensing.html
При инициализации окружения используем только нужные подсистемы? 05.08.08 08:53  
Автор: HandleX <Александр М.> Статус: The Elderman
Отредактировано 05.08.08 08:56  Количество правок: 1
<"чистая" ссылка>
> На одно-процессорном компьютере, тестировалась
> производительность «map» контейнера на основе Oracle
> Berkeley DB с доступом DB_BTREE/DB_HASH. Производительность
> оказалась не очень высокой: для 1 writer и 4 readers
> производительность в ~30-40 раз ниже чем для обычной
> std::map с простейшей синхронизацией на критической секции.
> Кстати, это не плохой результат (~50000 w/r в секунду) для
> многих практических задач. Но вопрос в том, можно ли
> повысить скорость DB_BTREE/DB_HASH?
Ценность БДБ не только в скорости, но и в хранении данных (Durability), и в быстром поиске для большого кол-ва данных, и во вторичных индексах, и в транзакциях, и в журналировании ;-) Внутри код достаточно «ветвистый» для поддержки всего этого, хотя бы проверка тех же условий, как в данный момент произвести то или иное действие в зависимости от опций DB_ENV.

В тестах использовалась stand-alone DB или создавалась сперва DB_ENV, а потом уже открывалась DB? Я просто не помню, какие подсистемы юзает stand-alone DB, может она подключает что-то лишнее...
При открытии среды нужно указывать (в твоём случае) только DB_INIT_LOCK | DB_INIT_MPOOL | DB_THREAD флаги.
Если нужна какая-то ультраскорость :) попробуй убрать флаг DB_INIT_LOCK и сам занимайся синхронизацией.
С флагами памяти ещё можно поиграться... Только наврядли это что-то даст.
Больше мыслей нет.
Я не спорю. Но ведь если перформанс был бы выше, так это... 06.08.08 04:47  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
> Ценность БДБ не только в скорости, но и в хранении данных
> (Durability), и в быстром поиске для большого кол-ва
> данных, и во вторичных индексах, и в транзакциях, и в
> журналировании ;-) Внутри код достаточно «ветвистый» для
> поддержки всего этого, хотя бы проверка тех же условий, как
> в данный момент произвести то или иное действие в
> зависимости от опций DB_ENV.

Я не спорю. Но ведь если перформанс был бы выше, так это только лучше. Так ведь?

> В тестах использовалась stand-alone DB или создавалась
> сперва DB_ENV, а потом уже открывалась DB?
Конечно DB_ENV.

> При открытии среды нужно указывать (в твоём случае) только
> DB_INIT_LOCK | DB_INIT_MPOOL | DB_THREAD флаги.

В принципе, код инициализации весьма стандартный:
#ifdefIN_MEMORY_DB		m_db_env = new DbEnv(0);
    
		// cache & in-memory logs
		m_db_env->set_cachesize(0,10*1024*1024,1);
		m_db_env->log_set_config(DB_LOG_IN_MEMORY, 1);
		m_db_env->set_lg_bsize(10*1024*1024);

		m_db_env->open(NULLin-memory, DB_PRIVATEin-memory|DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL|DB_THREAD, 0);
		
		m_db = new Db(m_db_env, 0);
		m_db->open(NULL, NULL, db_name_t.c_str(), DB_HASH, DB_CREATE|DB_THREAD, 0);

		/*in-memory cache file*/
		DbMpoolFile* mpf = m_db->get_mpf();
		if (mpf)
		{
			mpf->set_flags(DB_MPOOL_NOFILE, 1);
		}
		else
		{
		}
#else
		m_db_env = new DbEnv(0);
		m_db_env->open(env_name_t.c_str(), DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL|DB_THREAD, 0);
		m_db = new Db(m_db_env, 0);
		m_db->open(NULL, db_name_t.c_str(), NULL, DB_HASH, DB_CREATE|DB_THREAD, 0);
#endif


---

Не уверен, что нужно инициализировать подсистему DB_INIT_LOCK


> Если нужна какая-то ультраскорость :) попробуй убрать флаг
> DB_INIT_LOCK и сам занимайся синхронизацией.
> С флагами памяти ещё можно поиграться... Только наврядли
> это что-то даст.
> Больше мыслей нет.

Основная проблема, как мне кажется - блокировка page-level locking. Например, для DB_QUEUE, где этого нет (там record-level locking) - работает просто ультрасаунд. Поетому, если ключи и данные небольшие, так что всё помещается на нескольких страницах, блокировка страницы душит всю DB. Надо б найти способ уменьшить кол-во записей на страницу.
А, у тебя CDB спользована, отлично! 06.08.08 09:53  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
> В принципе, код инициализации весьма стандартный:
> Не уверен, что нужно инициализировать подсистему
> DB_INIT_LOCK
Ага, я совсем забыл про CDB.

> Основная проблема, как мне кажется - блокировка page-level
> locking. Например, для DB_QUEUE, где этого нет (там
> record-level locking) - работает просто ультрасаунд.
> Поетому, если ключи и данные небольшие, так что всё
> помещается на нескольких страницах, блокировка страницы
> душит всю DB. Надо б найти способ уменьшить кол-во записей
> на страницу.
Есть DB->set_pagesize и DB->set_h_ffactor попробуй с ними поиграться. Одна записьна страницу... Готично :-)
Но вот мне интересно, БД у тебя in-memory, ради одного хешированного индекса стоит ли городить огород, чего вы там в С++ используете для словарей std::map вроде, вот его может и использовать + своя синхронизация?
DB->set_pagesize мало что даёт. Я тестировал page_size =... 07.08.08 07:19  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
> Есть DB->set_pagesize и DB->set_h_ffactor попробуй с
> ними поиграться. Одна записьна страницу... Готично :-)

DB->set_pagesize мало что даёт. Я тестировал page_size = 512 байт, что является минимумом для BDB.
Я бы не стал играть с и density (DB->set_h_ffactor). Это мало относится к числу записей на странице, но скорее влияет на размер bucket-а хеш контейнера. В принципе даже для более простых хэш контейнеров (расштрения stl, stlport и прочее) не рекомендуется этого делать, если нет совершенно ясного понимания к чему это приведёт при разрешении колизий. Для BDB может быть ещё сложнее. Ну и ... это ничего не дало - я всё же протестировал на всякий пожарный влияние DB->set_h_ffactor как ты посоветовал.

> Но вот мне интересно, БД у тебя in-memory, ради одного
> хешированного индекса стоит ли городить огород, чего вы там
> в С++ используете для словарей std::map вроде, вот его
> может и использовать + своя синхронизация?

Использование БД - принципиально важно. В коде, что выше по постингам я намеренно привёлдополнительнуюконфигурацию in-memory, чтобы показать что дисковое IO практически не влияет на перформанс BDB, когда размер DB_BTREE или DB_HASH невелик и полностью помещается в памяти. На самом деле в проекте я хочу использовать именно НЕ in-memory конфинурацию DB (к хорошему привыкаешь быстро;)). Основная идея - приложение может упасть, но после рестарта - всё самозалечится, так как текущие данные будут прочитаны с диска.

Что же до C++ map - здесь может быть не всё так гладко, если использутся тривиальное решение - синхронизация на единственной критической секции, скажем, для 4-5 readers и 1-2 writers и инденсивном обновлении значений мапы.

Скорее, я буду использовать некий симбиоз. Поток данных будет обнослять "быструю" хеш мапу, а отдельный thread будет поддерживать обновленя BDB значеними этой мапы. Гарантий для сохранности актуальных данных гораздо меньше - но это лучше чем ничего.
Ну тогда такие соображения... 07.08.08 08:25  
Автор: HandleX <Александр М.> Статус: The Elderman
Отредактировано 07.08.08 08:25  Количество правок: 1
<"чистая" ссылка>
> Использование БД - принципиально важно. В коде, что выше по
> постингам я намеренно привёлдополнительнуюконфигурацию
> in-memory, чтобы показать что дисковое IO практически не
> влияет на перформанс BDB, когда размер DB_BTREE или DB_HASH
> невелик и полностью помещается в памяти. На самом деле в
> проекте я хочу использовать именно НЕ in-memory
> конфинурацию DB (к хорошему привыкаешь быстро;)). Основная
> идея - приложение может упасть, но после рестарта - всё
> самозалечится, так как текущие данные будут прочитаны с
> диска.
Это прекрасно! Но вот если тебя не устраивает производительность BDB, как тогда база будет успевать сохранять тот поток данных, что успевает зохавать "быстрый" хешмап? + он тоже ресурсы кушает.

> Скорее, я буду использовать некий симбиоз. Поток данных
> будет обнослять "быструю" хеш мапу, а отдельный thread
> будет поддерживать обновленя BDB значеними этой мапы.
> Гарантий для сохранности актуальных данных гораздо меньше -
> но это лучше чем ничего.
Для гарантии сохранности актуальных данных не убежать тебе от DB_INIT_LOG ;-)
ИМХО сделать сперва чисто на BDB, если несколько writers — вместо CDB заюзать DB_INIT_LOCK и посмотреть, что получится.
Или, если важно сохранять данные при пиковых нагрузках, использовать QUEUE, и периодически скармливать основной базе. Очередь в BDB тоже весьма отказоустойчива -)
I agree. 08.08.08 01:33  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
> Или, если важно сохранять данные при пиковых нагрузках,
> использовать QUEUE, и периодически скармливать основной
> базе.

I agree.

> Очередь в BDB тоже весьма отказоустойчива -)

... and very fast. So, it should work.

Thank you!
std::map - это дерево 06.08.08 15:30  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Но вот мне интересно, БД у тебя in-memory, ради одного
> хешированного индекса стоит ли городить огород, чего вы там
> в С++ используете для словарей std::map вроде, вот его
> может и использовать + своя синхронизация?

Хеш-таблица насколько я помню лежит в std::tr1::unordered_map
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach