You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by John Vines <vi...@apache.org> on 2013/01/16 18:42:46 UTC

Performance/Object creation issues

In our application, we have an API call which takes in a thrift based
token, transforms it into the appropriate type of AuthenticationToken,
pulls the principal out of it and creates a SimplePrincipalCollection with
it, and uses that to build a Subject. I then do subject.login(token) with
that subject to authenticate. However, we noticed in testing that the
object creation from this process is killing performance. I changed it to
keep a Map of thrift token -> Subject, and then utilize isAuthenticated()
which seems to have alleviated the issue.

However, I'm a bit miffed at the original performance issues, since I had
set up Authentication caching. Is there a better way to just authenticate
given a token, or is my way the right way? Additionally, I feel that
caching a token->Subject is redundant with the authentication caching, so I
don't know if there are better practices in this case as well.

Thanks
John

Re: Performance/Object creation issues

Posted by Les Hazlewood <lh...@apache.org>.
>
> However, switching to the code Jared suggested seems to be just as
> effective.
>

Glad to hear it - Jared's suggestion is how we designed it to be used, so
I'm glad that it is working for you as expected.


> Also, thanks for the pointer to the DefaultSubjectDAO. I'm definitely
> working in a stateless space, so I'll look that over.
>

Yes, you'll want to do this for messaging, RPC or infrastructural
scenarios.  Based on your environment (as I understand it at least), a
successful authentication will create a Session, since that is the default
behavior for the 80/20 rule (i.e. webapps).  If you're doing this 800 times
a second, that's 800 sessions per second - no need for that for your use
case I think.

Please feel free to ask follow up questions - we have quite a few people
using Shiro in very high performance environments, and as is the case with
any of these, some tweaking will be necessary if your use case isn't a
traditional webapp.

Cheers,

Les

Re: Performance/Object creation issues

Posted by John Vines <vi...@apache.org>.
We were doing approximately 800 operations (1 authenticate per operation)
per second in a server type process functioning as a relay between a client
and distributed database. With the ConcurrentMarkSweep GC turned on and a
half gig of heap, after about 40 minutes of continuous hits, garbage
collection would start going crazy, bringing it down to about 20operations
per second and it wouldn['t recover. Taking out the authentication
prevented this from happening. However, switching to the code Jared
suggested seems to be just as effective. With all of those authentications
creating so many HashMaps, it seems like it was doing a fair amount of
object creation, hence the memory issues.

Also, thanks for the pointer to the DefaultSubjectDAO. I'm definitely
working in a stateless space, so I'll look that over.

John


On Wed, Jan 16, 2013 at 9:26 PM, Les Hazlewood <lh...@apache.org>wrote:

> Hi John,
>
> I'm curious - what performance overhead did you see?
>  SimplePrincipalCollection is a simple wrapper around a
> LinkedHashMap<String,Set> - was Map/Set construction slow? (I don't know
> your application's performance threshold requirements, and I'm always
> curious how to make things faster).
>
> Also, yes, I'll echo Jared's advice - you just need to call
> subject.login(authcToken) - no need to construct anything prior.  When you
> turn on authentication caching, AuthenticationInfo instances (and their
> internal PrincipalCollecition) are cached after creation and re-used while
> they exist in cache.
>
> Also know that Shiro defaults to storing authentication state
> (isAuthenticated, PrincipalCollection) in the Subject's Session.  This is
> however fully customizable and you can turn this off (for example, if
> you're building a stateless application and/or framework).  See the
> DefaultSubjectDAO JavaDoc for more information.
>
> On Wed, Jan 16, 2013 at 1:44 PM, John Vines <vi...@apache.org> wrote:
>
>> That seems a lot more performant. I guess all taht overhead of dealing
>> with PrincipalCollections the principalled Subjects did it in. Thanks for
>> your help.
>>
>> John
>>
>>
>> On Wed, Jan 16, 2013 at 3:21 PM, Jared Bunting <
>> jared.bunting@peachjean.com> wrote:
>>
>>> So, if I understand correctly, you are embedding the principal into the
>>> AuthenticationToken (in the API call), then getting it out, building up
>>> a Subject with it, then authenticating on that subject?
>>>
>>> My thought would be to do something like the following.
>>>
>>> AuthenticationToken authTok = api.convertToAuthToken(thriftToken); //
>>> this should be a very simple conversion...grabbing a field or two,
>>> parsing a string
>>>
>>> Subject subject = new Subject.Builder().buildSubject();
>>> subject.login(authTok); // if this is successful, the subject will be
>>> populated with the PrincipalCollection
>>>
>>> Then, in your realm, you do that actual conversion from your
>>> AuthenticationToken to your PrincipalCollection.  It is important to do
>>> it here, because this is where authentication caching happens.
>>>
>>> Does that make sense?  Does it address your issues at all?
>>>
>>> HTH,
>>> Jared
>>>
>>> On Wed 16 Jan 2013 11:42:46 AM CST, John Vines wrote:
>>> > In our application, we have an API call which takes in a thrift based
>>> > token, transforms it into the appropriate type of AuthenticationToken,
>>> > pulls the principal out of it and creates a SimplePrincipalCollection
>>> > with it, and uses that to build a Subject. I then do
>>> > subject.login(token) with that subject to authenticate. However, we
>>> > noticed in testing that the object creation from this process is
>>> > killing performance. I changed it to keep a Map of thrift token ->
>>> > Subject, and then utilize isAuthenticated() which seems to have
>>> > alleviated the issue.
>>> >
>>> > However, I'm a bit miffed at the original performance issues, since I
>>> > had set up Authentication caching. Is there a better way to just
>>> > authenticate given a token, or is my way the right way? Additionally,
>>> > I feel that caching a token->Subject is redundant with the
>>> > authentication caching, so I don't know if there are better practices
>>> > in this case as well.
>>> >
>>> > Thanks
>>> > John
>>>
>>>
>>>
>>
>

Re: Performance/Object creation issues

Posted by Les Hazlewood <lh...@apache.org>.
Hi John,

I'm curious - what performance overhead did you see?
 SimplePrincipalCollection is a simple wrapper around a
LinkedHashMap<String,Set> - was Map/Set construction slow? (I don't know
your application's performance threshold requirements, and I'm always
curious how to make things faster).

Also, yes, I'll echo Jared's advice - you just need to call
subject.login(authcToken) - no need to construct anything prior.  When you
turn on authentication caching, AuthenticationInfo instances (and their
internal PrincipalCollecition) are cached after creation and re-used while
they exist in cache.

Also know that Shiro defaults to storing authentication state
(isAuthenticated, PrincipalCollection) in the Subject's Session.  This is
however fully customizable and you can turn this off (for example, if
you're building a stateless application and/or framework).  See the
DefaultSubjectDAO JavaDoc for more information.

On Wed, Jan 16, 2013 at 1:44 PM, John Vines <vi...@apache.org> wrote:

> That seems a lot more performant. I guess all taht overhead of dealing
> with PrincipalCollections the principalled Subjects did it in. Thanks for
> your help.
>
> John
>
>
> On Wed, Jan 16, 2013 at 3:21 PM, Jared Bunting <
> jared.bunting@peachjean.com> wrote:
>
>> So, if I understand correctly, you are embedding the principal into the
>> AuthenticationToken (in the API call), then getting it out, building up
>> a Subject with it, then authenticating on that subject?
>>
>> My thought would be to do something like the following.
>>
>> AuthenticationToken authTok = api.convertToAuthToken(thriftToken); //
>> this should be a very simple conversion...grabbing a field or two,
>> parsing a string
>>
>> Subject subject = new Subject.Builder().buildSubject();
>> subject.login(authTok); // if this is successful, the subject will be
>> populated with the PrincipalCollection
>>
>> Then, in your realm, you do that actual conversion from your
>> AuthenticationToken to your PrincipalCollection.  It is important to do
>> it here, because this is where authentication caching happens.
>>
>> Does that make sense?  Does it address your issues at all?
>>
>> HTH,
>> Jared
>>
>> On Wed 16 Jan 2013 11:42:46 AM CST, John Vines wrote:
>> > In our application, we have an API call which takes in a thrift based
>> > token, transforms it into the appropriate type of AuthenticationToken,
>> > pulls the principal out of it and creates a SimplePrincipalCollection
>> > with it, and uses that to build a Subject. I then do
>> > subject.login(token) with that subject to authenticate. However, we
>> > noticed in testing that the object creation from this process is
>> > killing performance. I changed it to keep a Map of thrift token ->
>> > Subject, and then utilize isAuthenticated() which seems to have
>> > alleviated the issue.
>> >
>> > However, I'm a bit miffed at the original performance issues, since I
>> > had set up Authentication caching. Is there a better way to just
>> > authenticate given a token, or is my way the right way? Additionally,
>> > I feel that caching a token->Subject is redundant with the
>> > authentication caching, so I don't know if there are better practices
>> > in this case as well.
>> >
>> > Thanks
>> > John
>>
>>
>>
>

Re: Performance/Object creation issues

Posted by John Vines <vi...@apache.org>.
That seems a lot more performant. I guess all taht overhead of dealing with
PrincipalCollections the principalled Subjects did it in. Thanks for your
help.

John


On Wed, Jan 16, 2013 at 3:21 PM, Jared Bunting
<ja...@peachjean.com>wrote:

> So, if I understand correctly, you are embedding the principal into the
> AuthenticationToken (in the API call), then getting it out, building up
> a Subject with it, then authenticating on that subject?
>
> My thought would be to do something like the following.
>
> AuthenticationToken authTok = api.convertToAuthToken(thriftToken); //
> this should be a very simple conversion...grabbing a field or two,
> parsing a string
>
> Subject subject = new Subject.Builder().buildSubject();
> subject.login(authTok); // if this is successful, the subject will be
> populated with the PrincipalCollection
>
> Then, in your realm, you do that actual conversion from your
> AuthenticationToken to your PrincipalCollection.  It is important to do
> it here, because this is where authentication caching happens.
>
> Does that make sense?  Does it address your issues at all?
>
> HTH,
> Jared
>
> On Wed 16 Jan 2013 11:42:46 AM CST, John Vines wrote:
> > In our application, we have an API call which takes in a thrift based
> > token, transforms it into the appropriate type of AuthenticationToken,
> > pulls the principal out of it and creates a SimplePrincipalCollection
> > with it, and uses that to build a Subject. I then do
> > subject.login(token) with that subject to authenticate. However, we
> > noticed in testing that the object creation from this process is
> > killing performance. I changed it to keep a Map of thrift token ->
> > Subject, and then utilize isAuthenticated() which seems to have
> > alleviated the issue.
> >
> > However, I'm a bit miffed at the original performance issues, since I
> > had set up Authentication caching. Is there a better way to just
> > authenticate given a token, or is my way the right way? Additionally,
> > I feel that caching a token->Subject is redundant with the
> > authentication caching, so I don't know if there are better practices
> > in this case as well.
> >
> > Thanks
> > John
>
>
>

Re: Performance/Object creation issues

Posted by Jared Bunting <ja...@peachjean.com>.
So, if I understand correctly, you are embedding the principal into the 
AuthenticationToken (in the API call), then getting it out, building up 
a Subject with it, then authenticating on that subject?

My thought would be to do something like the following.

AuthenticationToken authTok = api.convertToAuthToken(thriftToken); // 
this should be a very simple conversion...grabbing a field or two, 
parsing a string

Subject subject = new Subject.Builder().buildSubject();
subject.login(authTok); // if this is successful, the subject will be 
populated with the PrincipalCollection

Then, in your realm, you do that actual conversion from your 
AuthenticationToken to your PrincipalCollection.  It is important to do 
it here, because this is where authentication caching happens.

Does that make sense?  Does it address your issues at all?

HTH,
Jared

On Wed 16 Jan 2013 11:42:46 AM CST, John Vines wrote:
> In our application, we have an API call which takes in a thrift based
> token, transforms it into the appropriate type of AuthenticationToken,
> pulls the principal out of it and creates a SimplePrincipalCollection
> with it, and uses that to build a Subject. I then do
> subject.login(token) with that subject to authenticate. However, we
> noticed in testing that the object creation from this process is
> killing performance. I changed it to keep a Map of thrift token ->
> Subject, and then utilize isAuthenticated() which seems to have
> alleviated the issue.
>
> However, I'm a bit miffed at the original performance issues, since I
> had set up Authentication caching. Is there a better way to just
> authenticate given a token, or is my way the right way? Additionally,
> I feel that caching a token->Subject is redundant with the
> authentication caching, so I don't know if there are better practices
> in this case as well.
>
> Thanks
> John