Существует ли "встроенная СУБД" для поддержки нескольких приложений (процессов) для записи в одном файле db?

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

ОБНОВЛЕНИЕ:

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

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

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

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

Ответы

Ответ 1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 2

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

Обновленная информация ниже:

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

    -------------     -------------           -------------  
    |           |     |           |           |           |  
    | 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

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

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

Ответ 4

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

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

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

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

Ответ 6

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

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

В режиме Client/Server (или даже Embedded Server) можно разрешить несколько подключений.

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

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

Ответ 8

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

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

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

Ответ 9

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

Ответ 10

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

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

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

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