Hi all, For years, Solr has been only as fast as Lucene allows. Every gain in storage formats, query execution or faceting has had to come from upstream, on Lucene's timeline and within the limits of the JVM. At SearchScale, we wanted to see how far Solr could go without waiting on that, so we've started exploring what it would take to swap Lucene's internals for something faster: Luxir <https://github.com/luxir-search/luxir/>, a C++ search engine, by Yonik Seeley!
SoLux runs Luxir at the codec level, and the split works like this: - *Solr and Lucene still handle:* documents, analysis, segments, commits, NRT and SolrCloud. - *Luxir takes over:* storing the postings, doc values, points and stored fields, and running queries, filters, facets and joins natively in one call per request, through the FFM API, with no JNI. - *Packaging:* it ships as a Solr module (luxir-codec), enabled through the configset. *Headline numbers.* We indexed 100M e-commerce events into 3 nodes × 3 shards, then ran four query types from 16 concurrent clients, on a Ryzen 9 7950X and a Ryzen 9 5950X: SoLux vs stock Solr Indexing 1.8–2.1× faster Terms facet throughput 2.0–2.1× Range facet throughput 2.7–2.8× Join throughput 5.9–6.0× All query tasks, total time 2.1× less product_id terms facet + avg(price) 0.55–0.57×, slower: our next target The benchmark, full results, exact versions and step-by-step instructions to reproduce it are in luxir.md. It also lists the changes behind these numbers and what each one contributed: https://github.com/SearchScale/solr-bench/blob/master/luxir.md *Changes to Luxir.* SoLux runs Luxir with four patches on top of upstream Luxir project, kept in luxir-lucene. These are needed to improve on query and indexing performance. - 0001 <https://github.com/SearchScale/luxir-lucene/blob/main/luxir-patches/0001-query-materialize-large-point-ranges-as-bitsets.patch>: build large point ranges as bitsets instead of sorting doc arrays. - 0002 <https://github.com/SearchScale/luxir-lucene/blob/main/luxir-patches/0002-query-skip-term-windows-without-docs-when-counting.patch>: when counting, jump to the window holding a term's next doc instead of stepping through every window. - 0003 <https://github.com/SearchScale/luxir-lucene/blob/main/luxir-patches/0003-reader-seek-explicit-term-sets-block-by-block.patch>: look up explicit term sets block by block, decoding only the requested terms' metadata. - 0004 <https://github.com/SearchScale/luxir-lucene/blob/main/luxir-patches/0004-query-answer-sparse-range-verification-from-block-re.patch>: answer a range check behind a selective filter from each column block's min and max, reading values only in blocks that cross the range. Together with a faster range-facet bucket lookup, this took filtered range facets from 14.2 to 5.3 ms per shard. *Caveats:* - This is experimental. Each configuration ran once. - The Luxir nodes run with the security manager off, so the native library can load. - SoLux still sits on Lucene's segments and needs four small Solr core changes. I'd love your feedback, and results from your own hardware. Thanks, Ishan
