2009-08-13 3 views
2

Мне нужно хранить десятки или даже сотни миллионов данных на диске. Каждая часть данных содержит информацию, как:Как перенести данные на диск и как произвольно обновлять его, так и эффективно передавать его обратно в ОЗУ?

id=23425 
browser=firefox 
ip-address=10.1.1.1 
outcome=1.0 

Новые элементы данных могут быть добавлены в размере до 1-к за миллисекунды.

Таким образом, это относительно простой набор пар ключ-значение, где значения могут быть строками, целыми числами или поплавками. Иногда мне может потребоваться обновить кусок данных с определенным идентификатором, изменив поле флага от 0 до 1. Другими словами, мне нужно иметь возможность выполнять поиск случайных ключей по id и изменять данные (на самом деле только плавающие точечный «результат» - так что мне никогда не понадобится изменять размер значения).

Другим требованием является то, что я должен иметь возможность передавать эти данные с диска (порядок не особенно важен) эффективно. Это означает, что голова жесткого диска не должна перемещаться по диску для чтения данных, а должна читаться в последовательных блоках диска.

Я пишу это на Java.

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

У кого-нибудь есть идеи? Могу ли я создать собственное решение для этого (где я имею дело непосредственно с ByteBuffers и обрабатываю идентификатор)?

+0

«DB4O не является вариантом, так как это GPL, а остальная часть моего кода не является» - это имеет значение только в том случае, если вы планируете распространять свой код. –

+0

Я планирую распространять свой код – sanity

ответ

0

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

0

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

Я понимаю, что при использовании этого метода небольшое увеличение ввода-вывода, но если вы говорите о миллионах записей, я думаю, что все равно будет быстрее, потому что любой алгоритм поиска, который вы создаете, будет значительно превосходить полноценный механизм базы данных ,

0

Вы можете попробовать , который теперь принадлежит Oracle. У них есть Open Source и Коммерческие лицензии. Он использует модель Key/Value (с возможностью создания индексов, если требуются другие формы запросов). Существует чистая Java-версия и родная версия с привязками Java.

+0

Надеюсь, я могу найти что-то бесплатное, к сожалению, Berkeley DB нет, если я не хочу GPL мой код, что не является вариантом. – sanity

0

http://www.zentus.com/sqlitejdbc/

SQLite база данные (общественное достояние), JDBC разъем с лицензией BSD, произрастающие на целую кучу платформ (OSX, Linux, Windows), эмуляции для остальные.

2

Как насчет H2? License должен работать на вас.

  • Вы можете использовать H2 бесплатно. Вы можете интегрировать его в ваше приложение (включая коммерческие приложения), и его можно распространять.
  • Файлы , содержащие только ваш код, не являются , на которые распространяется эта лицензия (это «коммерчески приемлемый»).
  • Изменения к исходному коду H2 должно быть опубликовано.
  • Вам не нужно указывать Исходный код H2, если вы не сделали ничего не измените.

я получаю

1000000 вставки в 22492ms (44460,252534234394 строк/сек)

100000 обновления в 9565ms (+10454,783063251438 строк/сек)

от

import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.SQLException; 
import java.util.Random; 


/** 
* @author clint 
* 
*/ 
public class H2Test { 

    static int testrounds = 1000000; 

    public static void main(String[] args) { 
    try { 
     Class.forName("org.h2.Driver"); 

    Connection conn = DriverManager. 
     getConnection("jdbc:h2:/tmp/test.h2", "sa", ""); 
    // add application code here 
    conn.createStatement().execute("DROP TABLE IF EXISTS TEST"); 
    conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TEST(id INT PRIMARY KEY, browser VARCHAR(64),ip varchar(16), outcome real)"); 
    //conn.createStatement().execute("CREATE INDEX IDXall ON TEST(id,browser,ip,outcome"); 


    PreparedStatement ps = conn.prepareStatement("insert into TEST (id, browser, ip, outcome) values (?,?,?,?)"); 
    long time = System.currentTimeMillis(); 
    for (int i = 0; i < testrounds; i++) { 
     ps.setInt(1,i); 
     ps.setString(2,"firefox"); 
     ps.setString(3,"000.000.000.000"); 
     ps.setFloat(4,0); 
     ps.execute(); 
    } 
    long last = System.currentTimeMillis() ; 
    System.out.println(testrounds + " insert in " + (last - time) + "ms (" + ((testrounds)/((last - time)/1000d)) + " row/sec)"); 

    ps.close(); 
    ps = conn.prepareStatement("update TEST set outcome = 1 where id=?"); 
    Random random = new Random(); 
    time = System.currentTimeMillis(); 

    /// randomly updadte 10% of the entries 
    for (int i = 0; i < testrounds/10; i++) { 
     ps.setInt(1,random.nextInt(testrounds)); 
     ps.execute(); 
    } 

    last = System.currentTimeMillis(); 
    System.out.println((testrounds/10) + " updates in " + (last - time) + "ms (" + ((testrounds/10)/((last - time)/1000d)) + " row/sec)"); 

    conn.close(); 

    } catch (ClassNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (SQLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    } 

} 
-1

Я бы так что посмотрите, есть ли что-нибудь существующее на основе EHCache или JCS, которые могут помочь.

0

Вы можете использовать Apache Derby (или JavaDB), который поставляется вместе с JDK. Однако, если СУБД не обеспечивает требуемую скорость, вы можете реализовать определенную файловую структуру самостоятельно. Если требуется только точный поиск ключа, вы можете использовать хэш-файл для его реализации. Хэш-файл является самой быстрой файловой структурой для таких требований (намного быстрее, чем файловые структуры общего назначения, такие как B-деревья и сетки, которые используются в БД). Он также обеспечивает приемлемую эффективность потоковой передачи.

1

JDBM - отличная встроенная база данных для Java (а не как обремененная лицензированием в качестве версии Java Berkley). Было бы полезно попробовать. Если вам не нужны гарантии ACID (т. Е. Вы в порядке с повреждением базы данных в случае сбоя), выключите диспетчер транзакций (значительно увеличивает скорость).

0

Вы ознакомились с базой данных Oracle «TimesTen»? Его встроенная память db, которая должна быть очень высокой. Не знаете о расходах/лицензиях и т. Д., Но посмотрите сайт Oracles и найдите его. Загрузка Eval должна быть доступна.