« 2007-03 | HomePage | 2007-06 »

Thursday, 31 May 2007

Hosting Sitecore

This article will briefly go through the diffent hosting options for your Sitecore solution (but in theory it applies to any web application where end customers may customize the physical application).

Single servers:

1. Single application, single tenant:

A common Sitecore setup, where a single customer (tenant) are hosted on a dedicated server with one web site (application) residing.

  1. Benefits:
    1. Easy backup/restore.
    2. Runtime independence (if one customer application crashes, or has bad performance, everything else is unaffected).
    3. Simplified operations environment (it is easier to configure performance monitors to uphold SLA).
  2. Disadvantages:
    1. Expensive hosting solution as you must purchase one server and one application per customer. However, this can naturally be solved by installing multiple virtual PC’s on each physical server (though you will still need to obtain all software for each instance).

2. Single application, multiple tenants:

In this configuration you will have a single Sitecore installation running on one server. The application runs multiple web sites for different tenants. This solution cannot be recommended with Sitecore if the tenants are different independent customers (e.g. Microsoft and SAP), but is acceptable if tenants are related (subsidiaries of a customer, such as www.sitecore.net and sdn.sitecore.net). The single site will have multiple host headers assigned pointing to the same web site, but the Sitecore application will return different content depending on host name.

  1. Benefits:
    1. Cheap hosting solution as limitations in reality are traditional server capabilities such as server load and database sizes. Largest solutions seen are 500 web sites on a single Sitecore application.
  2. Disadvantages:
    1. Complex backup and restore (you should use Sitecore packages or build your own function) as backup and restore will be for the entire application.
    2. Runtime dependence. If one web site crashes or consists of slow controls, the entire application is affected. This is usually not a problem with subsidiaries as they tend to re-use controls and design.
    3. Complex(not possible) operations if SLA guarantees detailed up-time and max time per page delivery.

3. Multiple applications, single tenant per. application

This is the preferred (but potentially dangerous) configuration for many hosters. One IIS runs several web sites (Sitecore applications), and each application contains a single tenant (customer). Some hosting vendors prefer separate application pools, some shared application pools and some mixes it (let’s go with shared application pools until one of the applications starts misbehaving). In reality there’s no right and no wrong, but using this approach does require a good understanding of .NET. Sitecore support manager, Jesper Jørgensen, has written a Blog post on the .NET memory (http://jesperen.wordpress.com/2007/05/23/understanding-as...):

A) Separate application pools

  1. Benefits:
    1. Mid-priced hosting solution. If you choose every site instance to have its own application pool, it’s a matter of installed physical RAM in the server that sets the maximum number of web sites running on a single server.
    2. Memory (and CPU) autonomy: In theory, if using separate application pools and setting maximum memory for each pool, it’s possible to run multiple web sites independent of each other. If web site A breaks, or leaks memory, web site B is not affected. However, this is not an exact science and applications sometimes does affect each other.
      Note! Setting the maximum RAM usage for a application pool, e.g. 1000 MB, it’s imperative that the web site honors the rules of the Max memory settings of the Sitecore configuration file (if max memory usage in your Sitecore application exceeds the max IIS site available, .NET recycles the entire application): http://sdn5.sitecore.net/SDN5/Articles/Administration/Sit....
    3. Easy back-up.
    4. Simplified operations environment (easy configuration of performance monitors).
  2. Disadvantages:
    1. Applications may affect each other potentially threaten SLA’s.
    2. Requires additional initial configuration.

B) Shared application pools

  1. Benefits:
    1. Cheaper hosting solution. As web sites and applications shares application pool, memory consumption can be held to a relative minimum.
    2. Easy back-up.
    3. Performance monitors can be configured for each application.
  2. Disadvantages:
    1. Applications will affect each other where misbehaving or high consumption web sites will decrease performance on other applications running on same application pool.
    2. Requires additional initial configuration.
    3. Operations on application level is not possible, making it hard to monitor strict SLA’s.

4. Multiple applications, multiple tenants per. application

This method is conceptually close option 3 with the difference that each customer can run multiple web sites in same Sitecore instance. Also, from a configuration perspective, it’s almost similar with the difference of configuring multiple host headers for each IIS web site.

Note! We cannot recommend this option to hosters who want to run multiple different customers in same Sitecore instance (if so, combine all disadvantages of option 2 and 3). 

  1. Benefits and Disadvantages: See option 3.

Multiple servers

Some customers may want to host their site(s) using a load-balanced setup due to either load or fail-over purposes.

The above configurations with benefits and disadvantages are also possible with multi-server setup under the same conditions that applies to traditional scaled Sitecore solutions. Documentation for such configurations can be obtained from the Sitecore developer network in white papers (scalability and performance) and information about the staging module.


Vocabulary in this article

  • Tenant: The customer or subsidiary of the customer that uses the application.
  • Hoster or hosting center: The entity that hosts the application (Sitecore) for the tenant (customer), e.g. 3 part external hosting center or a part of the customers organization.
  • The ISV: The provider of the software; Sitecore.
  • SLA (Service Level Agreement): The measurement points that must be uphold in order to honor the agreement the hoster signs with the tenant, e.g. up-time of 99,5%.

12:04 Posted in Sitecore | Permalink | Comments (0) | Email this

Thursday, 24 May 2007

A Blog list update

I have just updated the Blog lists on Sitecore and added two new members of the Blogging community:

  • Kerry Bellerose
  • Jesper Jørgensen

08:50 Posted in Sitecore | Permalink | Comments (0) | Email this

Wednesday, 16 May 2007

Link database to replace XPath statements

Very often I notice developers who are trying to use XPath or Sitecore query statements to resolve referrals for an item, - for example to resolve which documents are using a certain Meta data field. This is absolutely feasible, and with small data structures even a reasonable approach, but with larger data structures, XPath queries that iterates large part of the structure, something that hurts performance.

 

Let’s assume the following scenario:

We have the following content structure:

medium_Link_database_to_replace_XPath_statements.png

Every single document in the content structure is being categorized by a Meta data field, e.g. a drop down field with data from the document category.

Let’s assume the solution has a web control in the right hand side display “other documents of this category”, using the meta data to look up these controls. In reality, what we want to do in this control is to take the current documents category, - then find the documents that refer the category, e.g. if “Find us” has a company information tag, we want to find other documents that have that too.

 

Using XSLT 

With small data structures, this can be done from XSLT by using the following code:

<xsl:variable name="docCategoryItem"
    select="sc:item(sc:fld('Category',.),.)" />
<xsl:variable name="ItemsLinkingToThisCategory"
   select="$home//item[sc:fld('Category',.)=$docCategoryItem/@id]" />
<h2>Other documents in the category '
  <xsl:value-of select="$docCategoryItem/@name"/>':</h2>
<xsl:for-each
  select="$ItemsLinkingToThisCategory[@id!=$sc_currentitem/@id]">
  <p><sc:link><sc:text field="title" /></sc:link></p>
</xsl:for-each>

 

This will result in full content structure iteration every time you load a document, which is fine with small data structures, but will hurt performance fatally with large data structures.

Using Sitecore query is faster, - but what happens if you are referring multiple categories? For every category, a full structure scan would be performed.

So, how can we easily resolve referrers?

Link database 

The answer lies in the name itself. To find all referrers, use the link database which maintains all ingoing and outgoing links from all standard lookup types and html types. If you want to do it from XSLT, build a XSL helper class that returns an XPathNodeIterator.

I have created a class testxslhelper, with the following code in a traditional Class Library project using Visual Studio:

 

using System.Xml.XPath;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Links;
using Sitecore.Xml;

namespace Sitecore
{
public class references
{

public Item getItem(XPathNodeIterator xpni) {
  xpni.MoveNext();
  return (Context.Database.GetItem(
    xpni.Current.GetAttribute("id", "")));
}

public XPathNodeIterator referrersfiltered(
  XPathNodeIterator xpni, string template) {
 
  template = template.ToLower();
  Item currentitem = getItem(xpni);
  ItemLink[] links =
    Globals.LinkDatabase.GetReferers(currentitem);

  Packet packet = new Packet("references");

  foreach (ItemLink link in links)
    if (link != null) {

      Item sourceitem = link.GetSourceItem();

      if (sourceitem != null)  {
        if ((sourceitem.TemplateName.ToLower() == template) &&
            (sourceitem.Parent.ID != ItemIDs.MastersRoot))
          packet.AddElement("item", link.SourceItemID.ToString());
      }

    }

  return packet.XmlDocument.CreateNavigator().Select("*");
}

}
}

 

To use this method, you should add it to your web.config XSLT extensions section:

 

<xslExtensions>
  <extension mode="on"
    type="Sitecore.Xml.Xsl.XslHelper, Sitecore.Kernel"
    namespace="http://www.sitecore.net/sc"
    singleInstance="true">
  </extension>
  :
  <extension mode="on"
    type="Sitecore.references, miscXSLHelper"
    namespace="http://www.sitecore.net/refs"
    singleInstance="true">
  </extension>
</xslExtensions>

 

Then apply it to your stylesheet definition:

 

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:sc="http://www.sitecore.net/sc"
  xmlns:dot=http://www.sitecore.net/dot
  xmlns:refs=http://www.sitecore.net/refs
  exclude-result-prefixes="dot sc refs">

 

Finally, use the new method from your XSLT:

 

<xsl:template match="*" mode="getLinkRefs">
  <xsl:variable name="docCategoryItem"
      select="sc:item(sc:fld('Category',.),.)" />
  <xsl:variable name="refs"
    select="test:referrersfiltered(
    $docCategoryItem,'sample item')/item" />

  <h2>Other documents in the category '
    <xsl:value-of select="$docCategoryItem/@name"/>':
  </h2>

  <xsl:for-each select="$refs">
    <xsl:variable name="refitem"
    select="sc:item(.,$sc_currentitem)" />

    <xsl:if test="$refitem/@id!=$sc_currentitem/@id">

      <p>
      <sc:link select="$refitem">
        <sc:text field="title" select="$refitem" />
      </sc:link>
      </p>

    </xsl:if>
  </xsl:for-each>

</xsl:template>

 

With small data structures, the difference between direct XSLT XPath lookup and the link database index lookup is minimal (e.g. a site with only 50 nodes), but even there I can measure a difference. If your content structure is more than 200 documents I would recommend that you consider using the second method.

 

Source: referncesource.zip

11:05 Posted in Sitecore | Permalink | Comments (0) | Email this