Skip to content

[BUG] ActionPrivileges initialization can take a long time in clusters with a large number of roles with repeated index patterns #5464

@cwperks

Description

@cwperks

What is the bug?

With Optimized Privilege Evaluation, much of the work of privilege evaluation is now done upfront by creating optimized data structures on node boostrap or if an index is created/deleted (change to cluster state)

An issue is observed, where the initialization of the ActionPrivileges takes a long time in clusters with a large number of roles that have the same repeated index patterns across role definitions.

Below is a snapshot of the hot threads output:

69.6% (348.1ms out of 500ms) cpu usage by thread 'opensearch[f97f9501b3e26a987f62a225d50caa46][generic][T#8]'
     5/10 snapshots sharing following 30 elements
       org.opensearch.security.support.WildcardMatcher$SimpleMatcher.test(WildcardMatcher.java:487)
       org.opensearch.security.support.WildcardMatcher$SimpleMatcher.test(WildcardMatcher.java:461)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner.lambda$test$0(WildcardMatcher.java:530)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner$$Lambda/0x000000020343a9c0.test(Unknown Source)
       [email protected]/java.util.stream.MatchOps$1MatchSink.accept(MatchOps.java:90)
       [email protected]/java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:1034)
       [email protected]/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
       [email protected]/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
       [email protected]/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
       [email protected]/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
       [email protected]/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230)
       [email protected]/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196)
       [email protected]/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
       [email protected]/java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:632)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner.test(WildcardMatcher.java:530)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner.test(WildcardMatcher.java:517)
       org.opensearch.security.support.WildcardMatcher$3$1.init(WildcardMatcher.java:324)
       org.opensearch.security.support.WildcardMatcher$3$1.hasNext(WildcardMatcher.java:303)
       org.opensearch.security.privileges.ActionPrivileges$StatefulIndexPrivileges.<init>(ActionPrivileges.java:1014)
       org.opensearch.security.privileges.ActionPrivileges.updateStatefulIndexPrivileges(ActionPrivileges.java:247)
       org.opensearch.security.privileges.ActionPrivileges.updateClusterStateMetadata(ActionPrivileges.java:265)
       org.opensearch.security.privileges.ClusterStateMetadataDependentPrivileges.lambda$updateClusterStateMetadataAsync$0(ClusterStateMetadataDependentPrivileges.java:68)
       org.opensearch.security.privileges.ClusterStateMetadataDependentPrivileges$$Lambda/0x00000002035066e0.run(Unknown Source)
       [email protected]/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
       [email protected]/java.util.concurrent.FutureTask.run(FutureTask.java:317)
       app//org.opensearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:964)
       [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
       [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
       [email protected]/java.lang.Thread.runWith(Thread.java:1596)
       [email protected]/java.lang.Thread.run(Thread.java:1583)
     3/10 snapshots sharing following 23 elements
       [email protected]/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:526)
       [email protected]/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
       [email protected]/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
       [email protected]/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230)
       [email protected]/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196)
       [email protected]/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
       [email protected]/java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:632)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner.test(WildcardMatcher.java:530)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner.test(WildcardMatcher.java:517)
       org.opensearch.security.support.WildcardMatcher$3$1.init(WildcardMatcher.java:324)
       org.opensearch.security.support.WildcardMatcher$3$1.hasNext(WildcardMatcher.java:303)
       org.opensearch.security.privileges.ActionPrivileges$StatefulIndexPrivileges.<init>(ActionPrivileges.java:1014)
       org.opensearch.security.privileges.ActionPrivileges.updateStatefulIndexPrivileges(ActionPrivileges.java:247)
       org.opensearch.security.privileges.ActionPrivileges.updateClusterStateMetadata(ActionPrivileges.java:265)
       org.opensearch.security.privileges.ClusterStateMetadataDependentPrivileges.lambda$updateClusterStateMetadataAsync$0(ClusterStateMetadataDependentPrivileges.java:68)
       org.opensearch.security.privileges.ClusterStateMetadataDependentPrivileges$$Lambda/0x00000002035066e0.run(Unknown Source)
       [email protected]/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
       [email protected]/java.util.concurrent.FutureTask.run(FutureTask.java:317)
       app//org.opensearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:964)
       [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
       [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
       [email protected]/java.lang.Thread.runWith(Thread.java:1596)
       [email protected]/java.lang.Thread.run(Thread.java:1583)
     2/10 snapshots sharing following 30 elements
       org.opensearch.security.support.WildcardMatcher$SimpleMatcher.test(WildcardMatcher.java:483)
       org.opensearch.security.support.WildcardMatcher$SimpleMatcher.test(WildcardMatcher.java:461)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner.lambda$test$0(WildcardMatcher.java:530)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner$$Lambda/0x000000020343a9c0.test(Unknown Source)
       [email protected]/java.util.stream.MatchOps$1MatchSink.accept(MatchOps.java:90)
       [email protected]/java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:1034)
       [email protected]/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
       [email protected]/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
       [email protected]/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
       [email protected]/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
       [email protected]/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230)
       [email protected]/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196)
       [email protected]/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
       [email protected]/java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:632)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner.test(WildcardMatcher.java:530)
       org.opensearch.security.support.WildcardMatcher$MatcherCombiner.test(WildcardMatcher.java:517)
       org.opensearch.security.support.WildcardMatcher$3$1.init(WildcardMatcher.java:324)
       org.opensearch.security.support.WildcardMatcher$3$1.hasNext(WildcardMatcher.java:303)
       org.opensearch.security.privileges.ActionPrivileges$StatefulIndexPrivileges.<init>(ActionPrivileges.java:1014)
       org.opensearch.security.privileges.ActionPrivileges.updateStatefulIndexPrivileges(ActionPrivileges.java:247)
       org.opensearch.security.privileges.ActionPrivileges.updateClusterStateMetadata(ActionPrivileges.java:265)
       org.opensearch.security.privileges.ClusterStateMetadataDependentPrivileges.lambda$updateClusterStateMetadataAsync$0(ClusterStateMetadataDependentPrivileges.java:68)
       org.opensearch.security.privileges.ClusterStateMetadataDependentPrivileges$$Lambda/0x00000002035066e0.run(Unknown Source)
       [email protected]/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
       [email protected]/java.util.concurrent.FutureTask.run(FutureTask.java:317)
       app//org.opensearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:964)
       [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
       [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
       [email protected]/java.lang.Thread.runWith(Thread.java:1596)
       [email protected]/java.lang.Thread.run(Thread.java:1583)

Another issue is that updates to ActionPrivileges are performed asynchronously(when cluster state changes) by creating a new thread from the generic threadpool. It may make sense to create a dedicated threadpool for these tasks to not take threads away from the generic pool for re-computing the ActionPrivileges.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingtriagedIssues labeled as 'Triaged' have been reviewed and are deemed actionable.v3.2.0

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions