On 10/13/13 8:09 PM, Michael Sokolov wrote:
On 10/13/2013 1:52 PM, Adrien Grand wrote:
Hi Michael,

I'm not aware enough of operating system internals to know what
exactly happens when a file is open but it sounds to be like having
separate files per document or field adds levels of indirection when
loading stored fields, so I would be surprised it it actually proved
to be more efficient than storing everything in a single file.

That's true, Adrien, there's definitely a cost to using files. There are some gnarly challenges in here (mostly to do with the large number of files, as you say, and with cleaning up after deletes - deletion is always hard). I'm not sure it's going to be possible to both clean up and maintain files for stale commits; this will become problematic in the way that having index files on NFS mounts are problematic.

I think the hope is that there will be countervailing savings during writes and merges (mostly) because we may be able to cleverly avoid copying the contents of stored fields being merged. There may also be savings when querying due to reduced RAM requirements since the large stored fields won't be paged in while performing queries. As I said, some simple tests do show improvements under at least some circumstances, so I'm pursuing this a bit further. I have a preliminary implementation as a codec now, and I'm learning a bit about Lucene's index internals. BTW SimpleTextCodec is a great tool for learning and debugging.

The background for this is a document store with large files (think PDFs, but lots of formats) that have to be tracked, and have associated metadata. We've been storing these externally, but it would be beneficial to have a single data management layer: i.e. to push this down into Lucene, for a variety of reasons. For one, we could rely on Solr to do our replication for us.

I'll post back when I have some measurements.

-Mike
This idea actually does seem to be working out pretty nicely. I compared time to write and then to read documents that included a couple of small indexed fields and a binary stored field that varied in size. Writing to external files, via the FSFieldCodec, was 3-20 times faster than writing to the index in the normal way (using MMapDirectory). Reading was sometimes faster and sometimes slower. I also measured time for a forceMerge(1) at the end of each test: this was almost always nearly zero when binaries were external, and grew larger with more data in the normal case. I believe the improvements we're seeing here result largely from removing the bulk of the data from the merge I/O path.

As with any performance measurements, a lot of factors can affect the measurements, but this effect seems pretty robust across the conditions I measured (different file sizes, numbers of files, and frequency of commits, with lots of repetition). One oddity is a large difference between Mac SSD filesystem (15-20x writing, reading 0.6x) via FSFieldCodec) and Linux ext4 HD filesystem (3-4x writing, 1.5x reading).

The codec works as a wrapper around another codec (like the compressing codecs), intercepting binary and string stored fields larger than a configurable threshold, and storing a file number as a reference in the main index which then functions kind of like a symlink. The codec intercepts merges in order to clean up files that are no longer referenced, taking special care to preserve the ability of the other codecs to perform bulk merges. The codec passes all the Lucene unit tests in the o.a.l.index package.

The implementation is still very experimental: there are lots of details to be worked out: for example, I haven't yet measured the performance impact of deletions, which could be pretty significant. It would be really great if someone with intimate knowledge of Lucene's indexing internals were able to review it: I'd be happy to share the code and my list of TODO's and questions if there's any interest, but at least I thought it would be interesting to know that the approach does seem to be worth pursuing.

-Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: java-user-unsubscr...@lucene.apache.org
For additional commands, e-mail: java-user-h...@lucene.apache.org

Reply via email to