Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | | |
std::map - это дерево 06.08.08 15:30 Число просмотров: 3614
Автор: amirul <Serge> Статус: The Elderman
|
> Но вот мне интересно, БД у тебя in-memory, ради одного > хешированного индекса стоит ли городить огород, чего вы там > в С++ используете для словарей std::map вроде, вот его > может и использовать + своя синхронизация?
Хеш-таблица насколько я помню лежит в std::tr1::unordered_map
|
<programming>
|
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
|
|
|