Существует ли «встроенная СУБД» для поддержки нескольких приложений (процессов) записи в одних и тех же файлах БД? - PullRequest
14 голосов
/ 18 января 2010

Мне нужно знать, существует ли какая-либо встроенная СУБД (предпочтительно на Java и не обязательно реляционная), которая поддерживает несколько приложений (процессов) записи в одном и том же наборе файлов БД. BerkeleyDB поддерживает несколько читателей, но только один писатель. Мне нужно несколько писателей и несколько читателей.

ОБНОВЛЕНИЕ:

Это не проблема с несколькими подключениями. Я имею в виду, что мне не нужно несколько подключений к работающему приложению (процессу) СУБД для записи данных. Мне нужно несколько приложений (процессов) СУБД для фиксации в одних и тех же файлах хранения.

HSQLDB, H2, JavaDB (Derby) и MongoDB не поддерживают эту функцию.

Я думаю, что могут быть некоторые ограничения файловой системы, которые запрещают это. Если да, существует ли файловая система, которая позволяет нескольким авторам записывать один файл?

Вариант использования: Вариант использования - это кластерная система с высокой пропускной способностью, которая намеревается хранить свои записи большого объема бизнес-журнала в хранилище SAN . Хранение бизнес-журналов в отдельных файлах для каждого сервера не подходит, поскольку для всех журналов biz необходимы возможности запросов и индексации.

Поскольку «SAN, как правило, представляет собой собственную сеть устройств хранения данных, которые, как правило, не доступны через обычную сеть с помощью обычных устройств» , я хочу использовать пропускную способность сети SAN для ведения журнала, когда пропускная способность кластерной локальной сети LAN используется для связи другого сервера с сервером и клиента с сервером.

Ответы [ 10 ]

12 голосов
/ 21 января 2010

Вам в основном не повезло, если вы как-то не изменили свои требования.

Во-первых, особенно в системах Unix, ничто не мешает нескольким процессам записывать в одни и те же файлы. В ОДНОЙ СИСТЕМЕ это не будет проблемой, у вас просто будет типичное состояние гонки, если две или более записи конфликтуют в одном и том же пространстве файла, в которое будет записана запись. Поскольку он работает в одной системе, он имеет идеальное разрешение на уровне байтов.

Итак, игра с точки зрения наличия нескольких процессов, записывающих в один файл, как эти процессы координируются? Как обеспечить, чтобы они не ходили друг на друга? В Unix, опять же, есть механизм блокировки на основе ОС, который можно использовать для предотвращения этого, но обычно большинство систем реализуют центральный сервер и координируют всю свою запись через эту систему, а затем записывает на диск, одновременно смягчая и обработка любых конфликтов.

Ваша проблема в два раза.

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

Во-вторых, вы предлагаете, чтобы не только несколько процессов писали на один и тот же том, но и тот, на который они пишут, был разделен через SAN. Это еще один гаечный ключ.

В отличие от NFS, сети SAN не поддерживают «файловые системы». Скорее они поддерживают «хранение». В основном устройства уровня блока. SAN, как только вы прошли кучу махинаций по управлению томами, на самом деле довольно «глупы» с точки зрения ОС.

Я почти уверен, что на самом деле вы можете смонтировать том на нескольких машинах, но я не уверен, что на устройстве можно больше одного. Для этого есть веские причины.

Проще говоря, SAN - это хранилище на уровне блоков. Блок, скажем, 4K байтов. Это «атомная» единица работы для SAN. Хотите изменить один байт данных? Считайте блок 4K из SAN, измените свой байт и запишите обратно блок 4k.

Если у вас есть несколько машин, считающих, что у них есть «универсальный» доступ к хранилищу SAN, и вы рассматриваете его как файловую систему, значит у вас поврежденная файловая система. Это так просто. Машины напишут, как они думают, как должны выглядеть блоки, в то время как другие машины и разбивают его своей локальной версией. Катастрофа. Руина. Не счастлив.

Даже заставить одну машину писать в SAN, в то время как другая читает с нее, сложно. Это также медленно, так как читатель может сделать несколько предположений о содержимом диска, поэтому ему нужно читать и перечитывать блоки (он не может ничего кэшировать, например, оглавления файловой системы и т. Д., Так как они ' Из-за активности писателя меняем его обратно, поэтому читайте снова ... и снова ...).

Такие вещи, как NFS, «решают» эту проблему, потому что вы больше не работаете с необработанным хранилищем. Скорее вы работаете с реальной файловой системой.

Наконец, нет ничего плохого в том, что независимые файлы журналов транслируются с ваших серверов. Они все еще могут быть запрошены. Вам просто нужно повторить запросы и объединить результаты.

Если у вас есть 5 потоковых машин, и вы хотите «всю активность между 12:00 и 12:05», то сделайте 5 запросов, по одному в каждое хранилище журналов, и объедините результаты. Что касается того, как эффективно запрашивать данные вашего журнала, это проблема индексации, и она не является непреодолимой в зависимости от того, как вы запрашиваете. Если вы запрашиваете время, то создаете файлы по времени (каждую минуту, каждый час и т. Д.) И сканируете их. Если ваша система «редко читается», это не имеет большого значения. Если вам нужна более сложная индексация, вам нужно придумать что-то еще.

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

CouchDB может работать или что-то в этом роде из-за его специфического, устойчивого к сбоям, всегда согласованного формата базы данных.Этот файл данных всегда читается экземпляром базы данных.Это может быть вариант для вас.

Но я все равно буду делать несколько запросов и объединять их.

7 голосов
/ 24 января 2010

Отдельные процессы направляют свои журналы в отдельные файлы / БД, чтобы избежать повреждения.Тогда у вас может быть процесс-демон, который асинхронно читает из всех этих файлов / БД и записывает в один консолидированный файл / БД.Когда вам нужно проиндексировать или запросить журналы, сделайте это в консолидированном файле / БД.Единственная проблема заключается в том, что у вас не будет доступа к вашим журналам в режиме реального времени.Будет некоторое отставание, пока журналы не будут объединены.

Обновлены подробности ниже:

  • Процесс-1 в Процесс-N записывает в журнал-1 в журналN
  • Асинхронно Process-X считывает из log-1 в log-N и объединяет его в один log-X (весь журнал biz)
  • Дополнительно Process-X может удалить log-1log-N, пока он заполняет log-X, чтобы освободить место
  • Log Reader использует log-X (весь журнал biz) с возможностями запросов и индексирования


    -------------     -------------           -------------  
    |           |     |           |           |           |  
    | Process-1 |     | Process-2 |    ...    | Process-N |  
    |           |     |           |           |           |  
    -------------     -------------           -------------  
          |                 |                       |        
          |                 |                       |        
          V                 V                       V        
      ( log-1 )         ( log-2 )      ...      ( log-N )    
            \                \                    /          
             \                \                  /           
              - - - -  \      |         / - - - -            
                        \     |        /                     
                          \   |     -                        
                            \ |  /                           
                             |||                             
                             VVV                             
                       -------------                         
                       |           |                         
                       | Process-X |                         
                       |           |                         
                       -------------                         
                             |                               
                             V                               
                             V               --------------  
                             V               |            |  
                         ( log-X )  ------>>>| Log Reader |  
                                             |            |  
                                             --------------  

3 голосов
/ 18 января 2010

Попробуйте FirebirdSQL (ранее Borland Interbase). Имеет режимы «Суперсервер» и «Классик». Первый - это обычный многопоточный сервер баз данных, а второй - классическая модель «один процесс на соединение». Различные процессы координируются в основном с помощью блокировки файлов данных на уровне ОС. Насколько я знаю, вы можете встроить классический сервер в свой собственный код. Ваша заявка станет еще одним классическим процессом.

http://www.firebirdfaq.org/faq25/
http://www.firebirdfaq.org/Firebird-Embedded-Linux-HOWTO.html

Обновление: не читал часть Java. В этом случае вам, вероятно, лучше с любыми другими ответами.

Обновление: когда я говорю "блокировка", я не имею в виду, что она блокирует всю базу данных одновременно. Даже в классическом режиме это все еще полноценная RDBMS. Однако я недостаточно хорошо знаю программное обеспечение, чтобы понять, что на самом деле происходит под капотом.

3 голосов
/ 18 января 2010

HSQLDB - это полнофункциональная база данных, которая поддерживает несколько соединений и уровень изоляции транзакций READ_UNCOMMITTED. Если это вас устраивает, дерзайте.

См. здесь о способах запуска БД.

2 голосов
/ 23 января 2010
2 голосов
/ 18 января 2010

Java DB является поддерживаемым Sun дистрибутивом 100% базы данных технологии Java с открытым исходным кодом Apache Derby. Это полностью транзакционный, безопасный, простой в использовании, основанный на стандартах - SQL, JDBC API и Java EE - но небольшой, всего 2,5 МБ.

Java DB входит в Java SE JDK и является базой данных для разработчика Sun GlassFish Enterprise Server.

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

Обновление: Небольшая ошибка, Java DB не является частью Java SE, как я писал изначально, а JDK.

Обновление 2: Теперь, когда вопрос прояснен, я понимаю, что OP на самом деле ищет что-то вроде «серверов баз данных общего хранилища» (и встраиваемых), и я на самом деле не думаю, что Java БД относится к этой категории. Если честно, мне интересно, существует ли это вообще. Я знаю, что некоторые решения для кластеризации баз данных используют общее хранилище ( Oracle RAC , DB2), но я не понимаю вопроса о кластеризации баз данных. Плюс такие решения, насколько мне известно, не являются встраиваемыми. Но я буду копать это немного больше (и буду пристально следить за этим вопросом).

2 голосов
/ 18 января 2010
1 голос
/ 21 марта 2010

2Gregg - Нет, Berkeley DB - это как раз то, что встроено.
2Amir - Как сказал Аликс Аксель, SQlite стоит попробовать.

Я недавно протестировал несколько из вышеупомянутых механизмов БД во встроенном режиме с использованием Java и SQLite. Это очень быстро для довольно больших объемов данных, вставленных / обновленных в транзакции. Не читайте эти старые вопросы.

Поэтому, если блокировка и параллелизм SQLite вас устраивают, попробуйте один. И ИМХО модель с несколькими журналами / записывающими устройствами с одним асинхронным считывателем / консолидатором является единственным разумным решением.

0 голосов
/ 19 марта 2017

Многопроцессный доступ (каждый процесс одинаков и может как читать, так и записывать) - это убийственная особенность Chronicle Map . При создании Chronicle Maps из разных процессов вы должны просто указать один и тот же файл постоянства:

ChronicleMap<Key, Value> map = ChronicleMap
    .of(Key.class, Value.class)
    .entries(...)
    ...
    .createPersistedFile(sharedDbFile); // <- here

Если у вас нет персистентности как таковой, вы должны поместить этот файл в каталог tmpfs или /dev/shm/ в Linux. На параллелизм / межпроцессный доступ это не влияет.

Помимо поддержки многопроцессорного доступа, Chronicle Map обычно имеет очень хорошие свойства параллелизма, поскольку использует чередование блокировок и многоуровневые блокировки.

0 голосов
/ 19 января 2010

Исправление: MongoDB поддерживает multiwriter как напрямую, так и через mongos

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...