English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
rocksDB è unEmbeddabileKey-value storage persistente
Di seguito è descritto dal sito web cinese ufficiale di RocksDB
https://rocksdb.org.cn/
Ha le seguenti quattro caratteristiche
1 Prestazioni elevate: RocksDB utilizza un motore di database a struttura di log, scritto in C++ per ottenere prestazioni migliori. Le chiavi e i valori sono flussi di byte di qualsiasi dimensione.
2 Ottimizzato per il rapido archiviazione: RocksDB è particolarmente ottimizzato per dispositivi di archiviazione veloci e a bassa latenza (ad esempio, SSD o hard disk a alta velocità). RocksDB massimizza le prestazioni di lettura e scrittura ad alta frequenza di memoria flash e RAM.
3 Adattabilità: RocksDB è adatto a vari tipi di lavoro. Dalla storage engine come MyRocks, all'applicazione della cache dati, fino a alcune attività embedded, RocksDB può affrontare con facilità queste diverse esigenze di lavoro sui dati.
4 Operazioni di base e avanzate del database: RocksDB offre alcune operazioni di base, come l'apertura e la chiusura del database. Per operazioni avanzate come la fusione e la compressione dei filtri, è fornito anche supporto per la lettura e la scrittura.
Installazione e utilizzo di RockDB
Ci sono diversi modi per installare rocksDB. Poiché l'ufficio non fornisce librerie binarie per la piattaforma corrente, è necessario compilare e utilizzare manualmente.
L'installazione di rocksDB è semplice, ma è necessario cambiare la percezione di rocksDB. Non è un database a livello enterprise, ma un sistema di archiviazione key-value embedded. Questo significa che puoi aggiungere la dipendenza rocksDB nel tuo progetto Maven e provarlo in ambiente di sviluppo. Se non hai capito questo punto, potresti cadere nelle seguenti due modalità di installazione non raccomandate.
Metodo uno: visitare il sito web ufficiale di rocksDB e scoprire che è necessario scrivere un programma C++ (non raccomandato)
#include <assert> #include "rocksdb/db.h" rocksdb::DB* db; rocksdb::Options options; options.create_if_missing = true; rocksdb::Status status = rocksdb::DB::Open(options, "/tmp/testdb", &db); assert(status.ok());
Creare un database????? Come è diverso da MySQL o MongoDB che ho usato prima, perché non c'è uno script come start.sh o start.bat. Devo scriverlo? Dopo averlo scritto e compilato, non so come collegarlo alla libreria rocksDB, cosa devo fare? Ho dimenticato tutto il C++.
Metodo due: utilizzare pyrocksDB (non raccomandato)
http://pyrocksdb.readthedocs.io/en/latest/installation.html
Documentazione dettagliata dell'installazione è disponibile nel documento di installazione ufficiale di pyrocksDB.
Questi due metodi sono molto amichevoli per sviluppatori familiarizzati con C++ o Python, ma non così amichevoli per sviluppatori Java.
In seguito, presenteremo il terzo metodo.
Metodo tre: utilizzare Maven (raccomandato)
Nuovo progetto Maven, modifica il dipendenze nel file pom.xml aggiungendo
<dependency> <groupId>org.rocksdb</groupId> <artifactId>rocksdbjni</artifactId> <version>5.8.6</version> </dependency>
Puoi scegliere la versione che preferisci.
Poi un livello di linguaggio Maven più alto, qui ho impostato globalmente su 1.8
<profiles> <profile> <id>jdk18</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile> </profiles>
Arrivati qui, l'ambiente è stato configurato, non è tornato al familiare mondo Java?
Poi copia una classe dal pacchetto del codice sorgente, modifica la configurazione di esecuzione nell'IDE, aggiungi un percorso di archiviazione del database durante l'esecuzione del programma, e puoi eseguire il test. Darò questo esempio alla fine dell'articolo.
Il console di esecuzione produrrà output di log, e appariranno anche nuovi file nel file.
Seguiranno aggiornamenti su API di sviluppo di rockDB, nonché su applicazioni in produzione, spero che tutti li seguano.
// Copyright (c) 2011-present, Facebook, Inc. Tutti i diritti riservati. // Questo codice sorgente è licenziato sia sotto GPLv2 (trovato nel // file COPYING nella directory principale) e licenza Apache 2.0 // (trovato nel file LICENSE.Apache nella directory principale). import org.rocksdb.*; import org.rocksdb.util.SizeUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; public class RocksDBSample { static { RocksDB.loadLibrary(); {} public static void main(final String[] args) { if (args.length < 1) { System.out.println("uso: RocksDBSample db_path"); System.exit(-1); {} final String db_path = args[0]; final String db_path_not_found = db_path + "_not_found"; System.out.println("RocksDBSample"); try (final Opzioni options = new Opzioni(); final FiltroBloom bloomFilter = new BloomFilter(10); final OpzioniLettura readOptions = new OpzioniLettura() .setFillCache(false); final Statistics stats = new Statistics(); final LimitatoreVelocita limitatoreVelocita = new LimitatoreVelocita(10000000, 10000, 10)) { try (final RocksDB db = RocksDB.open(options, db_path_not_found)) { assert (false); } catch (final RocksDBException e) { System.out.format("Catturato l'eccezione attesa -- %s\n", e); {} try { options.setCreateIfMissing(true) .setStatistics(stats) .setWriteBufferSize(8 * UnitDimension.KB) .setMaxWriteBufferNumber(3) .setMaxBackgroundCompactions(10) .setCompressionType(TipoCompressione.SNAPPY_COMPRESSION) .setCompactionStyle(CompactionStyle.UNIVERSAL); } catch (final IllegalArgumentException e) { assert (false); {} assert (options.createIfMissing() == true); assert (options.writeBufferSize() == 8 * SizeUnit.KB); assert (options.maxWriteBufferNumber() == 3); assert (options.maxBackgroundCompactions() == 10); assert (options.compressionType() == CompressionType.SNAPPY_COMPRESSION); assert (options.compactionStyle() == CompactionStyle.UNIVERSAL); assert(options.memTableFactoryName().equals("SkipListFactory")); options.setMemTableConfig( new HashSkipListMemTableConfig() .setHeight(4) .setBranchingFactor(4) .setBucketCount(2000000)); assert (options.memTableFactoryName().equals("HashSkipListRepFactory")); options.setMemTableConfig( new HashLinkedListMemTableConfig() .setBucketCount(100000)); assert (options.memTableFactoryName().equals("HashLinkedListRepFactory")); options.setMemTableConfig( new VectorMemTableConfig().setReservedSize(10000)); assert (options.memTableFactoryName().equals("VectorRepFactory")); options.setMemTableConfig(new SkipListMemTableConfig()); assert(options.memTableFactoryName().equals("SkipListFactory")); options.setTableFormatConfig(new PlainTableConfig()); // Plain-Table richiede lettura mmap options.setAllowMmapReads(true); assert(options.tableFactoryName().equals("PlainTable")); options.setRateLimiter(rateLimiter); final BlockBasedTableConfig table_options = new BlockBasedTableConfig(); table_options.setBlockCacheSize(64 * SizeUnit.KB) .setFilter(bloomFilter) .setCacheNumShardBits(6) .setBlockSizeDeviation(5) .setBlockRestartInterval(10) .setCacheIndexAndFilterBlocks(true) .setHashIndexAllowCollision(false) .setBlockCacheCompressedSize(64 * SizeUnit.KB) .setBlockCacheCompressedNumShardBits(10); assert(table_options.blockCacheSize() == 64 * SizeUnit.KB); assert(table_options.cacheNumShardBits() == 6); assert(table_options.blockSizeDeviation() == 5); assert(table_options.blockRestartInterval() == 10); assert(table_options.cacheIndexAndFilterBlocks() == true); assert (table_options.hashIndexAllowCollision() == false); assert (table_options.blockCacheCompressedSize() == 64 * SizeUnit.KB); assert (table_options.blockCacheCompressedNumShardBits() == 10); options.setTableFormatConfig(table_options); assert (options.tableFactoryName().equals("BlockBasedTable")); try (final RocksDB db = RocksDB.open(options, db_path)) { db.put("hello".getBytes(), "world".getBytes()); final byte[] value = db.get("hello".getBytes()); assert ("world".equals(new String(value))); final String str = db.getProperty("rocksdb.stats"); assert (str != null && !str.equals("")); } catch (final RocksDBException e) { System.out.format("[ERROR] caught the unexpected exception -- %s\n", e); assert (false); {} try (final RocksDB db = RocksDB.open(options, db_path)) { db.put("hello".getBytes(), "world".getBytes()); byte[] value = db.get("hello".getBytes()); System.out.format("Get('hello') = %s\n", new String(value)); for (int i = 1; i <= 9; ++i) { for (int j = 1; j <= 9; ++j) { db.put(String.format("%dx%d", i, j).getBytes(), String.format("%d", i * j).getBytes()); {} {} for (int i = 1; i <= 9; ++i) { for (int j = 1; j <= 9; ++j) { System.out.format("%s ", new String(db.get( String.format("%dx%d", i, j).getBytes()))); {} System.out.println(""); {} // scrittura batch di test try (final WriteOptions writeOpt = new WriteOptions()) { for (int i = 10; i <= 19; ++i) { try (final WriteBatch batch = new WriteBatch()) { for (int j = 10; j <= 19; ++j) { batch.put(String.format("%dx%d", i, j).getBytes(), String.format("%d", i * j).getBytes()); {} db.write(writeOpt, batch); {} {} {} for (int i = 10; i <= 19; ++i) { for (int j = 10; j <= 19; ++j) { assert (new String( db.get(String.format("%dx%d", i, j).getBytes())).equals( String.format("%d", i * j))); System.out.format("%s ", new String(db.get( String.format("%dx%d", i, j).getBytes()))); {} System.out.println(""); {} value = db.get("1x1".getBytes()); assert (value != null); value = db.get("world".getBytes()); assert (value == null); value = db.get(readOptions, "world".getBytes()); assert (value == null); final byte[] testKey = "asdf".getBytes(); final byte[] testValue = "asdfghjkl;'<>{+}_)(*&^%$#@".getBytes(); db.put(testKey, testValue); byte[] testResult = db.get(testKey); assert (testResult != null); assert (Arrays.equals(testValue, testResult)); assert (new String(testValue).equals(new String(testResult))); testResult = db.get(readOptions, testKey); assert (testResult != null); assert (Arrays.equals(testValue, testResult)); assert (new String(testValue).equals(new String(testResult))); final byte[] insufficientArray = new byte[10]; final byte[] enoughArray = new byte[50]; int len; len = db.get(testKey, insufficientArray); assert (len > insufficientArray.length); len = db.get("asdfjkl;".getBytes(), enoughArray); assert (len == RocksDB.NOT_FOUND); len = db.get(testKey, enoughArray); assert (len == testValue.length); len = db.get(readOptions, testKey, insufficientArray); assert (len > insufficientArray.length); len = db.get(readOptions, "asdfjkl;".getBytes(), enoughArray); assert (len == RocksDB.NOT_FOUND); len = db.get(readOptions, testKey, enoughArray); assert (len == testValue.length); db.remove(testKey); len = db.get(testKey, enoughArray); assert (len == RocksDB.NOT_FOUND); // repeat the test with WriteOptions try (final WriteOptions writeOpts = new WriteOptions()) { writeOpts.setSync(true); writeOpts.setDisableWAL(true); db.put(writeOpts, testKey, testValue); len = db.get(testKey, enoughArray); assert (len == testValue.length); assert (new String(testValue).equals( new String(enoughArray, 0, len)); {} try { for (final TickerType statsType : TickerType.values()) { if (statsType != TickerType.TICKER_ENUM_MAX) { stats.getTickerCount(statsType); {} {} System.out.println("getTickerCount() passed."); } catch (final Exception e) { System.out.println("Failed in call to getTickerCount()"); assert (false); //Should never reach here. {} try { for (final HistogramType histogramType : HistogramType.values()) { if (histogramType != HistogramType.HISTOGRAM_ENUM_MAX) { HistogramData data = stats.getHistogramData(histogramType); {} {} System.out.println("getHistogramData() passed."); } catch (final Exception e) { System.out.println("Failed in call to getHistogramData()"); assert (false); //Should never reach here. {} try (final RocksIterator iterator = db.newIterator()) { boolean seekToFirstPassed = false; for (iterator.seekToFirst(); iterator.isValid(); iterator.next()) { iterator.status(); assert (iterator.key() != null); assert (iterator.value() != null); seekToFirstPassed = true; {} if (seekToFirstPassed) { System.out.println("iterator seekToFirst tests passed."); {} boolean seekToLastPassed = false; for (iterator.seekToLast(); iterator.isValid(); iterator.prev()) { iterator.status(); assert (iterator.key() != null); assert (iterator.value() != null); seekToLastPassed = true; {} if (seekToLastPassed) { System.out.println("iterator seekToLastPassed tests passed."); {} iterator.seekToFirst(); iterator.seek(iterator.key()); assert (iterator.key() != null); assert (iterator.value() != null); System.out.println("iterator seek test passed."); {} System.out.println("iterator tests passed."); final List<byte[]> keys = new ArrayList<>(); try (final RocksIterator iterator = db.newIterator()) { for (iterator.seekToLast(); iterator.isValid(); iterator.prev()) { keys.add(iterator.key()); {} {} Map<byte[], byte[]> values = db.multiGet(keys); assert (values.size() == keys.size()); for (final byte[] value1 : values.values()) { assert (value1 != null); {} values = db.multiGet(new ReadOptions(), keys); assert (values.size() == keys.size()); for (final byte[] value1 : values.values()) { assert (value1 != null); {} } catch (final RocksDBException e) { System.err.println(e); {} {} {} {}
Questo è tutto il contenuto che vi ho introdotto oggi sull'installazione e l'applicazione di RocksDB in Java. Se avete domande o dubbi dopo aver studiato, potete discuterli nella sezione dei commenti qui sotto. Grazie per il supporto al tutorial di urla.