[ 
https://issues.apache.org/jira/browse/SOLR-4589?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Hoss Man updated SOLR-4589:
---------------------------

    Attachment: SOLR-4589.patch

Digression...

{panel}
It really feals like the whole LazyDocument API and usage pattern -- 
particularly the semantics in which "LazyDocument.getField(FieldInfo)" can be 
used -- is really brittle and confusiong.

It assumes it will be called exactly once for each StorableField that exists 
for that field name, in order because the internal counter is assumed to 
correspond exactly wit the array index of the corresponding array of values. 
(In short: it's really only useful when called from StoredFieldVisitor)

If, for example, a client app tries to use the same LazyDocument instance to 
generate LazyField instances for the same field twice -- it will most likeley 
get an ArrayIndexOutOfBoundsError.  Likewise a user could read the jacadocs for 
LazyDocument.getField and assume that it works simlar to 
StorableDocument.getField expecting it to return a LazyField of the _first_ 
field value for the specified field.  They could wind up calling the method 
twice on the same field and getting lazy fields pointing at two differnet 
values (the first and second StorableField instances for that field name)

none of which directly relates to this particular bug, but since this public 
class seems to have been added solely for solr, it may be worth considering 
deprecating it, and moving the logic solr needs into protected/private classes.
{panel}

...as for the matter at hand...

I reworked the internals of hte class a bit so that:

* LazyField instances cache their underlying values similar to how lazy loading 
worked in 3.x
* Asking for the value of a LazyField instance causes all LazyField's (produced 
by the same LazyDocument) with the same field name to be "actualized" in a 
single pass over the underlying document

The changes eliminate the pathalogical case of iterating over many LazyFields, 
and shouldn't add much even in the edge case of only carrying about a single 
field value when there are many -- it's still a single loop in the underlying 
Document of the fields, there's just no more short circut for hte single value 
case.

In order for these changes to work, the LazDocument has to now keep a reference 
to every LazyField it generates so that they can all be repopulated when one of 
their filed name brothers is repopulated.  The memory footprint of this 
shouldn't be too bad in the common case (afterall: the LazyDocument was already 
fetching the entire underlying Document keeping the whole thing around as long 
as there was a single LazyField in the heap) but just to be safe i made it 
track the list of LazyFields using weak refrences -- so even if someone asks 
for a bunch of LazyField instance for a field named "foo", and then throws away 
all but a few of them, they can be garbage collected regardless of how many 
other "foo" LazyFields are still arround or when/if their real values are 
loaded.

Patch includes a few test updates in solr to sanity check that lazy loading 
value caching works, but i definitely want to add some true LazyDocument unit 
tests to the module (there don't seem to be any at all at the moment) to 
exercise the "all lazy fields with the same name get populated at the same 
time" and "what if a weakref LazyField goes away" logic before i'd consider 
committing.

----

Feedback would be greatly appreciated.
                
> 4.x + enableLazyFieldLoading + large nultivalued fields + varying fl = 
> pathalogical CPU load & response time
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: SOLR-4589
>                 URL: https://issues.apache.org/jira/browse/SOLR-4589
>             Project: Solr
>          Issue Type: Bug
>    Affects Versions: 4.0, 4.1, 4.2
>            Reporter: Hoss Man
>         Attachments: SOLR-4589.patch, 
> test-just-queries.out__4.0.0_mmap_lazy_using36index.txt, 
> test-just-queries.sh, test.out__3.6.1_mmap_lazy.txt, 
> test.out__3.6.1_mmap_nolazy.txt, test.out__3.6.1_nio_lazy.txt, 
> test.out__3.6.1_nio_nolazy.txt, test.out__4.0.0_mmap_lazy.txt, 
> test.out__4.0.0_mmap_nolazy.txt, test.out__4.0.0_nio_lazy.txt, 
> test.out__4.0.0_nio_nolazy.txt, test.out__4.2.0_mmap_lazy.txt, 
> test.out__4.2.0_mmap_nolazy.txt, test.out__4.2.0_nio_lazy.txt, 
> test.out__4.2.0_nio_nolazy.txt, test.sh
>
>
> Following up on a [user report of exterme CPU usage in 
> 4.1|http://mail-archives.apache.org/mod_mbox/lucene-solr-user/201302.mbox/%[email protected]%3E],
>  I've discovered that the following combination of factors can result in 
> extreme CPU usage and excessively HTTP response times...
> * Solr 4.x (tested 3.6.1, 4.0.0, and 4.2.0)
> * enableLazyFieldLoading == true (included in example solrconfig.xml)
> * documents with a large number of values in multivalued fields (eg: tested 
> ~10-15K values)
> * multiple requests returning the same doc with different "fl" lists
> I haven't dug into the route cause yet, but the essential observations is: if 
> lazyloading is used in 4.x, then once a document has been fetched with an 
> initial fl list X, subsequent requests for that document using a differnet fl 
> list Y can be many orders of magnitute slower (while pegging the CPU) -- even 
> if those same requests using fl Y uncached (or w/o lazy laoding) would be 
> extremely fast.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to