[ 
https://issues.apache.org/jira/browse/OAK-8185?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16807672#comment-16807672
 ] 

Tomek Rękawek edited comment on OAK-8185 at 4/2/19 12:02 PM:
-------------------------------------------------------------

Let me elaborate a bit on the way how the Composite Node Store works with 
regards to the mount support. We have a single writeable mount {{/}} and a 
number of read-only mounts. For the production purposes we usually have a 
single read-only mount, called {{libs}}. This mount is available under a few 
paths:

* /libs
* /apps
* /jcr:system/rep:permissionStore/oak:mount-libs-crx.default

Apart from that there's something called "path-fragments", which allows to have 
dynamically mounted paths. If, in the global mount, we have a node named 
{{oak:mount-libs-...}}, its subtree will be also taken from the {{libs}} mount.

Now, in order to make the composite node store performant, we need to minimize 
the number of places where we have the CompositeNodeState/Builder wrappers. For 
instance, we need to have such a wrapper for the {{/}}, because calling 
{{getChild("libs")}} should give us a node from one node store while calling 
{{getChild("content")}} should redirect us to another. The path fragments makes 
this task a bit difficult, because the {{oak:mount-...}} may appear anywhere. 
In order to mitigate this issue, the mount configuration has one more property: 
{{pathsSupportingFragments}}. This way we can define the subtrees supporting 
potential dynamic mounts. The {{pathsSupportingFragments}} supports pattern, so 
we can also define the depth of this tree. For instance, the for the production 
we use:

{noformat}
/oak:index/*$
{noformat}

This way, the pathSupportingFragments are only supported under the direct 
children of the /oak:index. See OAK-6585 for more info on the patterns.

With this setup, we were able to limit the instances of 
CompositeNodeState/Builder wrappers only to following paths:

* /
* /jcr:system
* /jcr:system/rep:permissionStore
* /oak:index
* /oak:index/[index-name]

Now, about the benchmarks. Since the Composite Node Store requires a few 
repositories that are joined together, it's quite hard to prepare a fixture 
that'll match the production env with all the benchmarks. The current 
Oak-Composite-Store fixture mounts a few read-only repositories under a few 
paths using the pattern {{mount-%d-path-%d}}. However, they are not used for 
reading. The {{pathsSupportingFragments}} is set to {{/}}, therefore the 
Composite Node Store doesn't use the skip-to-native-store optimization 
described above. After switching the {{pathSupportingFragments}} to something 
more restrictive, like {{/oak:index/*$}}, the only composite-wrapped node will 
be {{/}}. See  [^OAK-8185-update-fixture.patch]. The numbers looks as follows:

{noformat}
Apache Jackrabbit Oak 1.12-SNAPSHOT
# GetDeepNodeTest                  C     min     10%     50%     90%     max    
   N
Oak-Segment-Tar                    1      49      51      54      59      76    
1095
Oak-Composite-Store                1      57      59      63      69     105    
 936
{noformat}

I'm open to suggestions on how to reflect the Composite Node Store performance 
better in the oak-benchmarks. I feel that right now (before or after applying 
the patch) the numbers are not really relevant for the real-life usage.


was (Author: tomek.rekawek):
Let me elaborate a bit on the way how the Composite Node Store works with 
regards to the mount support. We have a single writeable mount {{/}} and a 
number of read-only mounts. For the production purposes we usually have a 
single read-only mount, called {{libs}}. This mount is available under a few 
paths:

* /libs
* /apps
* /jcr:system/rep:permissionStore/oak:mount-libs-crx.default

Apart from that there's something called "path-fragments", which allows to have 
dynamically mounted paths. If, in the global mount, we have a node named 
{{oak:mount-libs-...}}, its subtree will be also taken from the {{libs}} mount.

Now, in order to make the composite node store performant, we need to minimize 
the number of places where we have the CompositeNodeState/Builder wrappers. For 
instance, we need to have such a wrapper for the {{/}}, because calling 
{{getChild("libs")}} should give us a node from one node store while calling 
{{getChild("content")}} should redirect us to another. The path fragments makes 
this task a bit difficult, because the {{oak:mount-...}} may appear anywhere. 
In order to mitigate this issue, the mount configuration has one more property: 
{{pathsSupportingFragments}}. This way we can define the subtrees supporting 
potential dynamic mounts. The {{pathsSupportingFragments}} supports pattern, so 
we can also define the depth of this tree. For instance, the for the production 
we use:

{noformat}
/oak:index/*$
{noformat}

This way, the pathSupportingFragments are only supported under the direct 
children of the /oak:index. See OAK-6585 for more info on the patterns.

With this setup, we were able to limit the instances of 
CompositeNodeState/Builder wrappers only to following paths:

* (will complete this list in a few minutes)

Now, about the benchmarks. Since the Composite Node Store requires a few 
repositories that are joined together, it's quite hard to prepare a fixture 
that'll match the production env with all the benchmarks. The current 
Oak-Composite-Store fixture mounts a few read-only repositories under a few 
paths using the pattern {{mount-%d-path-%d}}. However, they are not used for 
reading. The {{pathsSupportingFragments}} is set to {{/}}, therefore the 
Composite Node Store doesn't use the skip-to-native-store optimization 
described above. After switching the {{pathSupportingFragments}} to something 
more restrictive, like {{/oak:index/*$}}, the only composite-wrapped node will 
be {{/}}. See  [^OAK-8185-update-fixture.patch]. The numbers looks as follows:

{noformat}
Apache Jackrabbit Oak 1.12-SNAPSHOT
# GetDeepNodeTest                  C     min     10%     50%     90%     max    
   N
Oak-Segment-Tar                    1      49      51      54      59      76    
1095
Oak-Composite-Store                1      57      59      63      69     105    
 936
{noformat}

I'm open to suggestions on how to reflect the Composite Node Store performance 
better in the oak-benchmarks. I feel that right now (before or after applying 
the patch) the numbers are not really relevant for the real-life usage.

> Improve CompositeNodeStore performance
> --------------------------------------
>
>                 Key: OAK-8185
>                 URL: https://issues.apache.org/jira/browse/OAK-8185
>             Project: Jackrabbit Oak
>          Issue Type: Improvement
>          Components: store-composite
>            Reporter: Marcel Reutegger
>            Assignee: Tomek Rękawek
>            Priority: Minor
>         Attachments: OAK-8185-update-fixture.patch, composite-node-builder.txt
>
>
> While working on OAK-8141 I noticed the benchmark numbers for GetDeepNodeTest 
> on Oak-Composite-Store are rather low compared to Oak-Segment-Tar.
> {noformat}
> Apache Jackrabbit Oak 1.12-SNAPSHOT
> # GetDeepNodeTest                  C     min     10%     50%     90%     max  
>      N 
> Oak-Segment-Tar                    1      35      37      39      41      64  
>   1524
> Oak-Composite-Store                1     203     204     208     214     236  
>    288
> {noformat}
> In an offline conversation [~tomek.rekawek] mentioned the overhead shouldn't 
> be that big because the implementation should switch to the non-composite 
> implementation as soon as the read operation traverses into the 
> global/writable node store. It seems however, this is not the case  when 
> running GetDeepNodeTest. So, this may well be a bug and not an improvement, 
> as filed at the moment.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to