The data contains about 1.3 million records(key/value pairs), with total 50 Gb storage. I save it as a RocksDB database on an NFS share file system. In the cluster, I want to use the MPI I/O to read this database using multiple client processes. In each slave node, the client process will open this database and read the part according to the cursor position given by the master process. In this way, there is no need to transfer the actual data via network, and consequently it can decrease the time of data transportation.
Is the RocksDB suitable for this project?
Unfortunately, the answer is No. When I opened the database using two processes, it says "LOCK: Resource temporarily unavailable", just like the LevelDB.
If the database is not being written to when the readers are reading, you can potentially open the database in readonly-mode (https://github.com/facebook/rocksdb/wiki/RocksDB-Basics#readonly-mode). That might allow you to open the same database from multiple processes.
@dhruba , thank you very much for your valuable advice!
Yes, the data is not changable after it is generated. No inserted, no deleted, no modification, just for read. I'll test that.
In fact, I tried the LMDB, but in the NFS share file system, when the disk load is large, the process of reading the LMDB database usually died unexpectedly. And It often shows "No locks available". Thus I'm looking for a database that are suitable in this circumstance.
UPDATE:
Yes, I changed the Open to OpenForReadOnly, it works!
@dhruba Yes, the OpenForReadOnly and Seek can help achieve my goal, I also wish the high efficiency of doing the work as expected.
You save me a lot of time! Thank you very much!
@strongbanker Great to be of any help. If there is anything else that you need from RocksDB, pl do let us know.
@dhruba, if the database was changing, can I keep closing and re-opening it every minute or so ? Would that be a viable strategy if there are the update volume is not high.
@sanjosh How did you end-up dealing with visibility of changes made by write-process in read-only processes ? Is re-opening DB the only way to see changes ?
@unoexperto , yes you have to reopen the DB because the SST files get mapped in per-process memory. The reader cannot see what the writer has written until the DB is reopened. See https://github.com/sanjosh/smallprogs/tree/master/rocksdb_test
Is the comment at https://github.com/facebook/rocksdb/issues/908#issuecomment-325695198 still accurate? That is, a process with a read-only handle will not see any writes made by another process until it re-opens the file, and that the writes will not corrupt the on-disk file from the point of view of the reader? The information in this bug report conflicts with the entry in the FAQ about multiple processes accessing a single rocksdb database.
@dgryski Yes, that still seems to be the case.
@cburgdorf @dgryski , we are currently working on the support for this, allowing multiple processes to read from the same database and tailing the logs of a primary process. :)
@riversand963 ha! Sounds awesome :+1: !
"we are currently working on the support for this, allowing multiple processes to read from the same database and tailing the logs of a primary process. :)"
@riversand963 Can you please elaborate on this? When will this be available?
@sayaji15, there is #4899 to achieve part of the goals. With this PR, a RocksDB instance can tail the MANIFEST of another active instance. I have not implemented the part of WAL-tailing-and-replaying yet, but plan to do so in the near future.
@riversand963 I'm trying to figure out if the feature I'm looking for is already available and if so how I would use it. I tried digging into #4899 and the changelog but I don't have much understanding of the internals to get the plain English answer that I'm looking for. Can you help me out?
Basically, what I need is:
If this is already available (from version 6.0 I'd suspect?). Are there any special options that I need to pass upon connection of the primary or secondary instances? Btw, I'm using python-rocksdb so chances are that it may not expose any new options but if I know what to look for I may be able to find a way to get there :)
Hey @cburgdorf, #4899 is available in 6.1, though we have not officially announced this feature yet.
If your code always disables WAL, you can already try it out with 6.1. There are two new functions rocksdb::DB::OpenAsSecondary that you can call to open a DB in secondary mode. You can check https://github.com/facebook/rocksdb/blob/master/include/rocksdb/db.h#L184 for more details.
The secondary (read) instance is able to see the state of the database up to the most recent MANIFEST write by the primary (read-write) instance. Current limitation is that you need to set max_open_files to -1 because this will make the secondary instance DBImplSecondary hold open file descriptors on all SST files, so that they are still accessible to the secondary even after the primary instance deletes them. This also implies that the underlying system should support this behavior (I believe POSIX does). Future plan is to relax this via hard-link or efficient copy.
If your system enables WAL, then we also have #5282 and #5161 to support WAL tailing (not in 6.1 yet). Current limitation is that we haven't implemented the support to trim memtable. If your system keeps running and writing to WAL, the secondary instance's memtable size will grow. I do plan to support this very soon.
Hey @riversand963 thank you very much for your detailed answer! That is very helpful :+1:
I'll try to see if I can get that working. I have created a tracking issue in python-rocksdb to expose the new OpenAsSecondary function.
I'm currently trying to find out if it's feasible to create a storage backend for Postgres based on RocksDB. Since postgres uses a multi process architecture (every connection opens a process) this is one of the problems I'm running into. My current idea is to use the RocksDB Allocator API to make rocksdb allocate in shared memory by giving it an allocator that does that. Do you see any problems with this approach.
Just to be clear on the goal, opening the DB as readonly is a no go. Since multiple connections need to be able to write to the database.
@JelteF I can not answer your question (and frankly priorities shifted so I haven't gotten around trying the OpenAsSecondaryapproach yet) but if your approach turns out viable I'd love if you report it back here :)
Somewhat related to multi-process read access to one database I wonder If one can backup a database from another process i.e. open a database as read-only and then use that for backup?
Most helpful comment
@cburgdorf @dgryski , we are currently working on the support for this, allowing multiple processes to read from the same database and tailing the logs of a primary process. :)