Cache Tuner V2

Hello Everyone, Sorry for being away for a while. I got busy due to personal and professional commitments. But I’m back with lot of new learnings which I’ve planned to share with you.

Cache Tuner is one of my favorite modules [Widely accepted and appreciated by Sitecore community – Thanks for your appreciation, It motivates me to work on weekend to update this module instead of watching India-Australia match 😉], and thought to update it to handle few of the following use cases:

  1. Sitecore 9.1 Compatible : As you know, Sitecore made big architectural changes in Version 8.2 to make Sitecore caching much more better and extensible. But it broke few tools like CacheTuner and so others. In December, updated Cache Tuner to use new API : https://sitecorebasics.wordpress.com/2018/12/25/sitecore-9-compatible-cache-tuner/ While I was working on Cache Tuner V2, Thought to validate it on my Sitecore 9.1 Instance to make sure it works — And it indeed works! So, I have done all my validation on Sitecore 9.1. So, you can try with your new 9.1 instance with confidence. But please remember – If you find something new, Please report it on github or create PR with fix 🙂
  2. Drill down cache and clear specific cache : Since childhood, I’ve been always curious to know – How stuff works? (I’m sure for most of you as well, that’s why you are in this field). Same has been true for Sitecore Caching as well. As you know Sitecore caching uses same structure like HashTable. Where you have Key – Value pair. Along with that, Sitecore also has nested Hashtable. Which means one Key’s Value will also have another hashtable with Key – Value. At times when you are troubleshooting caching challenges, You must have thought of this. Is this caching issue or not? And to do that, Usually, what you do is, Use Sitecore Admin cache page to clear all cache and if it fixes the issue. Then it’s caching issue else it is something else. Sounds similar? You can do this on lower environment. But what if you must do same thing on production environment? During that you must be thinking. What If:
    1. I can see what’s inside each cache entry e.g. Click on YOURSITE[HTML] and see whether component which you are trying to troubleshoot exists or not in that list. I can clear specific Cache instead of FULL Cache e.g. You can just clear YOURSITE[HTML] cache and see whether it fixes your issues or not, Without affecting other caches. If you got excited and say — I know there’s module in marketplace which does exactly same thing – Then I would say cool down, as I also had same excitement, with this module : https://marketplace.sitecore.net/en/Modules/S/Sitecore_Cache_Admin.aspx Which I used a lot, And would like to Thanks this Module Admin. As this feature of Cache Tuner V2 is inspired from this module. But this module is not updated to support new Caching API Changes. Now, All above things are possible with CacheTunerV2 — I believe, This feature will be super helpful to community. And I’m excited to know your feedback on this.
  3. Clear all cache : Instead of relying on Cache Admin page, you can do it using CacheTuner page [Note : Please make sure you delete your cache tuner page, as soon as you are done with your Caching Tuning and troubleshooting. As CacheTuner page is not yet secure page]

Sounds exciting? And curios to know more about this. Let’s do it:

Screenshots:

Clear all Button
If Cache key has value, Then it will be clickable. If you would like to drill down and see what’s inside — please click desired cache key. Which will open Cache Detail page in new window with details of clicked cache key.
Cache detail page for website[html] cache key looks like this. #1 – Shows total number of cache entries stored in clicked cache, #2 – Cache details – In this example it is showing you how HTML Cache is getting stored for each component. #3 – Using “Clear Me!” button you can click particular cache. In this example website[html]

How to use it?

  1. Download from Cache Tuner V2 release : https://github.com/klpatil/CacheTuner/tree/CacheTunerV2 (Take a note of CacheTunerV2 branch and you can refer Release section : https://github.com/klpatil/CacheTuner/releases/tag/CTV2.0)
  2. Copy it under your desired folder. I recommend to have everything under CTV2 folder e.g. Webroot/MyTools/CTV2/* (All Cache Tuner v2 files in same folder)
  3. Access Cache Tuner V2 as per your copied folder e.g. https://<mysite>/mytools/ctv2/cachetuner.aspx
  4. That’s it – Fix you Caching issue and go home, your loved ones are waiting for you!

Hope you found this useful, There are few useful features in my roadmap. Thought to share with you. In case, you want to contribute to module.

Future release:

  1. Add Authorization
  2. Drill down cache details for all types, as of now it only supports few caching types only. And it should handle most of the use cases.
  3. Clear specific cache entry – As of now you can’t clear specific cache entry. You can clear specific cache container. e.g Instead of clearing website[html] would like to have a feature to clear cache entry which is inside website[html]
  4. Anything I missed? I’m all ears!

Old links:

https://sitecorebasics.wordpress.com/2011/04/27/cache-tuner-user-guide/

Thank you so much for reading!

Sitecore 9 Compatible Cache Tuner

Challenge:

In ~9 years of Sitecore experience have been happy to contribute 8 modules on Sitecore Marketplace (If you are new to Sitecore world and not aware of this, then let me explain you — It is Sitecore’s Play Store [Android]/App Store [iOs] where anyone (Including you) can contribute any Sitecore module ):

Contributed modules

Out of these modules, Which modules I really feel proud of and Cache Tuner is one of that. The reason behind it is — It is still widely used by community and lot of community members have already recommended it in community. Thank you folks!

This was my first shared module : https://sitecorebasics.wordpress.com/2011/04/28/cache-tuner-my-first-shared-source-module/ As you can see it was on old platform trac and If you tried tuning Sitecore cache then you must have come across Cache Tuning guide which has some rules based on which you tune Sitecore caches. CacheTuner helps you automate that, Sounds interesting? Read Cache Tuner guide : https://sitecorebasics.wordpress.com/2011/04/27/cache-tuner-user-guide/

Recently, I was trying to use it for my current project which is on Sitecore 9.0.2 and as soon as I ran it I got error due to Sitecore’s changes in Caching API (Sitecore 8.2).

Changes are mainly done to support DI and that’s why none of the methods are returning concrete classes.

Sitecore 9 Caching – Sitecore.Caching.CacheManager.GetAllCaches() changed from Sitecore 8

Solution:

I thought to spend time today to make it Sitecore 9 compatible, and you will be happy to know that now CacheTuner supports >=8.2 version. Needless to say, you have to rely on old CacheTuner for earlier versions. [You are still on older version? It’s time to upgrade :-)]

Have also created git repo for updated CacheTuner module : https://github.com/klpatil/CacheTuner

This is my Christmas gift for all of you, Have a Happy Holidays!

 

Unable to see components on Stats.aspx page for your Sitecore 8 MVC site?

Challenge:

We are near to launch one of our new site. Built on Sitecore 8.1 U1 and MVC, GlassMapper, TDS etc. As per our practice we applied HTML caching on all possible components. Which we were verifying whether it is working as per expectation or not. One of the way to do is using stats.aspx page. But when we opened it. It was displaying only one component — VisitorIdentification — Which is more of a Sitecore control. Then what happened to all our renderings? Same with you? Or you would like to be proactive? And eager to know what it was. Then this post is for you. Let’s delve in to it.

Solution:

As expected. We did a quick Google search and came across of this blog : https://blog.wesleylomax.co.uk/2015/11/20/sitecore-8-mvc-custom-site-not-showing-stats-aspx-page/

Two things came out from this blog post:

  1. This guy was unable to see his sites, where I was able to see site. But not renderings
  2. Required files were not attached.

Again, as expected. Raised Sitecore support ticket and they accepted it as BUG and provided Hot fix:

To fix the issue, please consider deploying the following patch:
1. Copy the attached Sitecore.Support.398176.dll assembly to the ‘\bin’ folder.
2. Copy the attached Sitecore.Support.Mvc.Statistics.config file to the ‘\App_Config\Include’ folder.

If there are any issues with this patch, please let us know. More information about Sitecore patches can be found here: https://kb.sitecore.net/articles/077333

To track the future status of this bug report, please use the reference number 94421. More information about public reference numbers can be found here:
https://kb.sitecore.net/articles/853187

Files can be downloaded from here :https://goo.gl/18BGgV

It worked? Awesome!

So, what was the issue? I am glad you are still reading. Lot of folks might have closed for the day. But I appreciate yo being curious to ask basic question “Why?”. Let me share what I understood:

  1. It looks recording stats information was not done for MVC pipeline or it might have been done at wrong place which was not working – Sitecore guys know it better. I am just assuming it here
  2. There are two IMP. pipeline in MVC <mvc.renderPlaceholder> and <mvc.renderRendering> where this guys have hooked code for recording that information e.g.    Statistics.AddRenderingData(…)

Special thanks to Pushpraj Ruhal (Sitecore support) guy who worked on this issue

Do you really need MediaRequestSessionModule? If no, then disable it for better performance!

Challenge:

Before few months back, We were working on performance challenges of our CM Server. And while investigating that we noticed that New Relic (If you are new to New Relic, then just for your information – it is an Application Performance Management Tool and it is your best friend while working on performance challenges) was showing spike in “MediaRequestSessionModule”

To be honest, We were not sure what this module does and is it really required or not?

Oh yes, we raised a support case and that discussion helped us to understand more about this module. Which we think is a worth share with you as well!

Here we go!

Solution:

First we tried to dig in to this issue. But after some point of time. We raised a Sitecore support case. And thanks to Paul Kravchenko for helping us to diagnose such issue.

Here’s a reply:

The  Sitecore.Resources.Media.MediaRequestSessionModule.ContextPostMapRequestHandler() method is just a handler for the standard ASP.NET HttpApplication.PostMapRequestHandler event, please read about it in the following article:
http://msdn.microsoft.com/en-us/library/system.web.httpapplication.postmaprequesthandler.aspx

The “Sitecore.Resources.Media.MediaRequestSessionModule” module was introduced in Sitecore CMS 6.3.0 rev. 100716, please refer to number 328238 in CMS release notes:
http://sdn.sitecore.net/Products/Sitecore%20V5/Sitecore%20CMS%206/ReleaseNotes/ChangeLog.aspx
To ensure that session state is still loaded for media requests when the media item has OMS tracking information, a new Sitecore.Resources.Media.MediaRequestSessionModule has been added to the web.config. (328238)

The matter is that the Sitecore.Resources.Media.MediaRequestSessionModule.ContextPostMapRequestHandler() method parses media request and gets corresponding item from database. This may be the reason of such high time consumption. Actually if you do not use SItecore Analytics you can safely comment out this module.

In summary, Sitecore.Resources.Media.MediaRequestSessionModule module parsed media request and gets corresponding item from database. Which has been introduced in Sitecore CMS 6.3.0 rev. 100716. To ensure that session state is still loaded for media requests when the media item has OMS tracking information. Now, If you do not use Sitecore Analytics you can safely comment out this module!

Just a note : We don’t have any stats which says with/without MediaRequestSessionModule how much % performance gain we get. But when you are working on highly scalable website, On which low response time is expected. You always try to save each drop. And as you know little drop makes a mighty ocean! As we don’t use OMS. So, it makes sense for us to disable it. As Steve jobs taught us let’s be free from clutter, as much as we can!

Happy Sitecoring! 🙂

Do you really need AccessResultCache on CD servers? If no, then disable it for better performance!

Challenge:

Before few months back. We were working on Performance issue of our CD Servers. It was really a nice challenge!  would like to share findings with you! So, it might be same challenge for your solution! If not, then also knowing that how we reached to it’s root cause is also a good to read!

We were facing following behavior:

1. Sometimes our CD Server’s response times were spiking and we were getting 502-Bad Gateway and 504-gateway timeout from our live servers!, after establishing pattern we found that it was linked with publishing.

Solution:

First we tried to dig in to this issue. But after some point of time. We raised a Sitecore support case. And thanks to Ekaterina for helping us to diagnose such issue.

To diagnose this issue we did following things:

  1. Configured performance counters — http://msdn.microsoft.com/en-us/library/ff647791.aspx [Especially section “Performance Counters Used to Measure ASP.NET Performance” along with contention counters, look for .Net CLR LocksAndThreads] and we found here that  during slowness time Contention rate/sec goes high. [Contention Rate / Sec. Displays the rate at which threads in the runtime attempt to acquire a managed lock unsuccessfully.]
  2. Sitecore log files and found “HttpModule is being initialized” entries. [Just a note : This entries indicates that your server is busy doing something and all current pool of Http Modules are not enough to serve the requests. So, ASP.NET will create new HttpModules to serve things. But if you see lot of this entries it may or may not be the problem. I think this is the whole new topic to blog — will do it sometime later on this. But in the meantime if you have any question on this, please do post a comment here. Will be happy to answer you!]
  3. Checked Diagnostics log — nothing helpful found
  4. We adjusted our EventQueue logging level to “high” on one of our CD Server and then plotted graph based on time taken by item:saved:remote.  And revealed to us that during spike item:saved:remote was taking lot of time.  [Just a note : Sitecore puts a lock during cache clearing and due to that contentions rate/sec may go high]
  5. Verify your GC mode — is it a workstation or server [http://ashishkhandelwal.arkutil.com/csharp/differences-between-server-and-workstation-gc/]  (Just a note: To verify it via code, you can use : System.Runtime.GCSettings.IsServerGC [Created simple aspx page and hosted it in our website])
  6. Generated memory dump using DebugDiag — Good to read Ekaterina’s blog here

out of all above activities, memory dump lead us towards the solution. Eager to know what was that? let’s discuss:

We submitted this memory dump to Sitecore support and from dump we found that our AccessResultCache size was 200 MB on CD server and which was causing this issue.

First, let’s discuss what’s the role of Sitecore cache. In Sitecore caching layers.  Every time when anybody accesses any item in Sitecore result of resolved security right is put to AccessResultCache. It is not related to content editing, but to content accessing at all. Resolving security usually takes much more time than accessing an item in a hashtable, therefore it is not so safe for performance to disable cache completely. So, for example If user A is accessing an item and to decide whether user A has access of that item or not, Sitecore resolves it’s security rights from DB and then puts it in AccessResultCache. So, when next time user A comes back to access the same item Sitecore can save time in resolving security rights again from DB and server it from cache.

But we found from dump is that AccessResultCache was occupying 10 GB. so it’s obvious now why it was so difficult to make cache clear operations on this large hashtable. And yes you must be thinking why it was occupying 10 GB when we restricted it to 200 MB. Exactly, we also had same question and got it answered from SC team that it is not easy to estimate object size accurately.

So, we were thinking why we need AccessResultCache on CD server? Because our content editing and authorization part is on CM server only. To, be more clear. Our server architecture is as follow [Courtesy — http://www.awareweb.com/AwareBlog/ArchConsideration.aspx]:

20110414Sitecore-Isolation-Architecture2

So, as per above diagram, we don’t have any authorization happening on CD Server. What, you also have the same architecture? You also have enabled AccessResultCache on CD server. [Just a note : to check how much space is occupied by each SC cache — CacheTuner module can be your friend — http://marketplace.sitecore.net/en/Modules/Cache_Tuner.aspx]

So, let’s see how to disable AccessResultCache from CD Server.

We were having following options availalbe to do it:

  1. Set AccessResultCache size to 0 MB — But If you disable the cache, then for each item the whole access will be checked up again each time when user accesses the site, and this may decrease performance. So, this is not a good option for you!
  2. Disable Security check completely on CD server — This is the best option. But to achieve this you have other options, out of which you need to decide the best one for you!
    1. Set SecurityEnabled property of corresponding database to false in web.config. [false for node]
    2. Another way is to place SecurityStateSwitcher switcher = new SecurityStateSwitcher(SecurityState.Disabled); in the beginning of httpRequestBegin pipeline.
    3. Rewrite SqlServerAuthorizationProvider

Okay. So, you must be thinking out of above 3 suggestions which you think is good idea to do? As we are striving for performance. Which one will perform high? We did a performance test for all of 3 options and we found that rewriting SqlServerAuthorizationProvider was the fastest option! And it also makes sense because on each item access we no need to do any security checks. So, eager to know how can you rewrite SqlServerAuthorizationProvider? Let’s see how can you do it:

  1. Create a class in your security project [for example — SCBasicsAuthorizationProvider], if not exist it would be great if you create new one. Make sure it’s type is Class Library. All you need to disable security check is to override
    public virtual AccessResult GetAccess(ISecurable entity, Account account, AccessRight accessRight)
    method, so it returns new AccessResult(AccessPermission.Allow,null).  See following sample code:
  2. On your CD server(s) take backup of everything.
  3. Open Web.Config and search for — SqlServerAuthorizationProvider, Sitecore.Kernel” connectionStringName=”web” embedAclInItems=”true” /> comment out this tag replace it with your class name created earlier e.g.     SCBasics.Security.SCBasicsAuthorizationProvider, SCBasics.Security” connectionStringName=”core” embedAclInItems=”true” />

SCBasicsAuthorizationProvider code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sitecore.Security.AccessControl;
using Sitecore.Security.Accounts;
using Sitecore.Diagnostics;
using Sitecore.Data.SqlServer;
using System.Collections.Specialized;
using Sitecore.Configuration;

namespace SCBasics.Security
{
public class SCBasicsAuthorizationProvider : SqlServerAuthorizationProvider
{
/// <summary>
/// Override for disabling AccessResultCache
/// on CD servers
/// </summary>
/// <param name="entity">Isecurable</param>
/// <param name="account">Account</param>
/// <param name="accessRight">AccessRight</param>
/// accessResult with Permission
public override AccessResult GetAccess(ISecurable entity, Account account, AccessRight accessRight)
{
AccessExplanation accessExplanation = new AccessExplanation("SCBasics : AccessResultCache disabled on CD Servers.");
AccessResult accessResult = new AccessResult(AccessPermission.Allow, accessExplanation);
return accessResult;
}
}
}

Deploy it and see your Sitecore CD server running faster than your thoughts!

Happy Sitecoring! 🙂

on each item access we no need to do security checks.