Sugerencias de SOA

Aborde cuellos de botella de escalabilidad con almacenamiento en caché distribuido

Iqbal Khan

Después de la expansión de las aplicaciones web para acomodar el uso de tráfico alto, la siguiente gran oleada se ha convertido en arquitectura orientada a servicios (SOA). SOA está destinada a convertirse en una manera estándar de desarrollar aplicaciones extremadamente escalables, y plataformas de computación nube como Windows Azure representa un enorme paso para hacer avanzar la SOA a fin de lograr este objetivo.

SOA permite que los usuarios distribuyan aplicaciones a varias ubicaciones, varios departamentos dentro de una organización y varios negocios a través de Internet. Además, permite reutilizar el código existente dentro de una organización y, lo que es más importante, la colaboración entre distintas unidades de negocios.

Una aplicación de SOA normalmente se implementa en una granja de servidores dentro de un entorno con equilibrio de carga. El objetivo es permitir que la aplicación controle toda la carga que le proporcione. La pregunta entonces pasa a ser: ¿cuáles son algunas de las consideraciones que debe tener en cuenta para mejorar tanto el rendimiento como la escalabilidad de su aplicación SOA?

A pesar de que, mediante el diseño, SOA tiene como objetivo proporcionar escalabilidad, hay varios problemas a los que debe enfrentarse antes de poder obtener realmente la escalabilidad. Algunos de estos problemas implican la manera en que codifica la aplicación SOA, pero los cuellos de botella más importantes a menudo se relacionan con la manera en que almacena los datos y cómo obtiene acceso a ellos. En este artículo, exploraré esos problemas y brindaré algunas soluciones.

Encontrar cuellos de botella de escalabilidad

Una aplicación SOA verdadera debe escalar fácilmente, al menos en lo que se refiere a la arquitectura de aplicaciones. Una aplicación SOA tiene dos componentes: componentes de servicio y aplicaciones cliente. La aplicación cliente puede ser una aplicación web, otro servicio o cualquier otra aplicación que depende de los componentes del servicio SOA para hacer su trabajo.

Una de las ideas clave detrás de SOA es dividir la aplicación en pequeños fragmentos a fin de que estos componentes puedan ejecutarse en varios servidores como servicios separados.

Idealmente, estos servicios deben carecer de estado en la medida de lo posible. Carecer de estado significa que no retienen datos a través de varias llamadas, lo que le permite ejecutar los servicios en varios equipos. No hay dependencia respecto de dónde estaban los datos la última vez, por lo que no hay datos que se mantengan en ningún servidor en particular a través de varias llamadas de servicio.

Como resultado, la arquitectura de aplicaciones SOA tiene una naturaleza inherentemente escalable. Puede llegar fácilmente a varios servidores y a todos los centros de datos. Sin embargo, tal como ocurre con cualquier otra aplicación, las aplicaciones SOA sí deben tratar con los datos, lo que puede ser un problema. Este acceso a datos se convierte en el cuello de botella de la escalabilidad. Los cuellos de botella normalmente implican los datos de aplicación, los que se almacenan en alguna base de datos, normalmente una base de datos relacional. Si la aplicación SOA usa datos de sesión, el almacenamiento de dichos datos también es un cuello de botella de la escalabilidad potencial.

Una aplicación SOA que se basa en otras aplicaciones SOA es otra área que probablemente presente un rendimiento y una escalabilidad insuficientes. Digamos que la aplicación llama a un servicio para hacer su trabajo, pero ese servicio llama a otros. Esos servicios pueden estar en la misma intranet o a través de la WAN en otras ubicaciones. Ese tipo de viaje de datos puede ser costoso. No puede escalar la aplicación de manera eficaz si hace esas llamadas una y otra vez, y estas son áreas en las que se producen cuellos de botella de escalabilidad, tal como se muestra en la figura 1.

Figure 1 SOA Architecture with Potential Scalability Bottlenecks
Figura 1 Arquitectura SOA con potenciales cuellos de botella de escalabilidad

Código para el rendimiento

Existen diversas técnicas de programación que pueden ayudar a mejorar el rendimiento de la aplicación SOA.

Algo que puede hacer es diseñar la aplicación para que use llamadas de método web “pesadas”. No realice llamadas frecuentes entre la aplicación cliente SOA y el nivel de servicio de SOA. Normalmente existe una gran distancia entre ellos, porque no se ejecutan en el mismo equipo, a veces ni siquiera en el mismo centro de datos. Mientras menos llamadas hace desde la aplicación cliente a los niveles de servicio, mejor es el rendimiento. Las llamadas pesadas realizan más trabajo en una llamada que varias llamadas para realizar el mismo trabajo.

Otra técnica útil es emplear las llamadas de método web asincrónicas que son admitidas por Microsoft .NET Framework. Esto permite que la aplicación cliente SOA haga otras cosas mientras se llama al método web del nivel de servicio y se le ejecuta.

El costo de la serialización es otro aspecto a considerar para que así no serialice ningún dato innecesario. Sólo debe enviar datos que son requeridos de ida y vuelta, lo que le permite ser muy selectivo en lo que respecta al tipo de serialización que desea realizar.

Elección del protocolo de comunicación correcto

Para las aplicaciones SOA desarrolladas en Windows Communication Foundation (WCF), existen tres protocolos distintos que permiten que los clientes SOA se comuniquen con los servicios SOA. Estos protocolos son HTTP, TCP y canalizaciones con nombre.

Si tanto el cliente como el servicio están desarrollados en WCF y se ejecutan en la misma máquina, las canalizaciones con nombre ofrecen el mejor rendimiento. Una canalización con nombre usa memoria compartida entre los procesos de servidor y cliente.

TCP es bueno si tanto el cliente SOA como el servidor están desarrollados en WCF, pero se ejecutan en equipos distintos dentro de la misma intranet. TCP es más rápido que HTTP, pero una conexión TCP permanece abierta durante varias llamadas y, por lo tanto, no puede asignar cada llamada de WCF a un servidor distinto. Al emplear la opción NetTcpBinding que usa grupos de conexión, puede caducar las conexiones TCP con frecuencia para reiniciarlas a fin de que se asignen a un servidor distinto, lo que le brinda una forma de equilibrio de carga.

Observe que TCP no puede trabajar de manera confiable a través de la WAN, porque las conexiones de socket tienen con frecuencia a interrumpirse. Si el cliente SOA y el servicio no se basan en WCF o si están hospedados en distintas ubicaciones, su mejor opción es HTTP. A pesar de que HTTP no es tan rápido como TCP, ofrece una gran escalabilidad debido al equilibrio de carga.

Uso de almacenamiento en caché para mejorar el rendimiento del cliente

El uso meditado de almacenamiento en caché realmente puede mejorar el rendimiento del cliente SOA. Cuando un cliente SOA hace que un método web llame al nivel de servicio, puede almacenar en caché los resultados en el extremo de la aplicación cliente. Así, la próxima vez que este cliente SOA necesite realizar la misma llamada de método web, en lugar de eso obtiene esos datos desde la memoria caché.

Al almacenar datos en caché en el extremo cliente, la aplicación cliente SOA reduce el número de llamadas que hará al nivel de servicio. Este paso mejora el rendimiento, porque no tuvo que realizar una llamada de servicio SOA cara. También reduce la presión general sobre el nivel de servicio y mejora la escalabilidad. La figura 2 muestra un cliente WCF que usa almacenamiento en caché.

Figura 2 Almacenamiento en caché de cliente WCF

using System;
using Client.EmployeeServiceReference;

using Alachisoft.NCache.Web.Caching;

namespace Client {
  class Program {
    static string _sCacheName = "mySOAClientCache";
    static Cache _sCache = NCache.InitializeCache(_sCacheName);

    static void Main(string[] args) {
      EmployeeServiceClient client = 
        new EmployeeServiceClient("WSHttpBinding_IEmployeeService");

      string employeeId = "1000";
      string key = "Employee:EmployeeId:" + employeeId;
            
      // first check the cache for this employee
      Employee emp = _sCache.Get(key);

      // if cache doesn't have it then make WCF call
      if (emp == null) {
        emp = client.Load("1000");

        // Now add it to the cache for next time
       _sCache.Insert(key, emp);
      }
    }
  }
}

En muchas situaciones, el cliente se elimina físicamente del nivel de servicio y se ejecuta a través de la WAN. En ese caso, no hay manera de saber si se han actualizado los datos que almacenó en caché. Por lo tanto, debe identificar sólo los elementos de datos para almacenamiento en caché que sienta que no cambiarán por al menos unos minutos a quizás algunas horas, dependiendo de la aplicación. Entonces puede especificar la caducidad para estos elementos de datos en la memoria caché, para que así esta los elimine automáticamente en ese momento. Esto ayuda a garantizar que los datos en caché siempre estén actualizados y sean correctos.

Almacenamiento en caché distribuido para escalabilidad de servicio

Las verdaderas mejoras en la escalabilidad mediante el almacenamiento en caché se encuentran en el nivel de servicio de SOA. Los cuellos de botella de escalabilidad no siempre se eliminar, a pesar de las numerosas técnicas de programación ya mencionadas, porque los principales cuellos de botella de escalabilidad se producen con el acceso y el almacenamiento de datos. A menudo los servicios residen en una granja de servidores con equilibrio de carga, lo que permite que el mismo servicio escale muy bien, con la excepción del almacenamiento de datos que no puede escalar de la misma manera. De esta manera, el almacenamiento de datos se convierte en el cuello de botella de SOA.

Puede escalar el nivel de servicio si agrega más servidores a la granja de servidores, lo que aumenta la capacidad informática a través de estos servidores de aplicaciones adicionales. Pero todas esas transacciones de SOA siguen tratando con algunos datos. Esos datos deben almacenarse en algún lugar, y ese almacenamiento de datos puede convertirse fácilmente en el cuello de botella.

Esta barrera de almacenamiento de datos para la escalabilidad se puede mejorar en varios niveles. Los servicios SOA tratan con dos tipos de datos. Unos son los datos de estado de sesión y los otros son los datos de aplicaciones que residen en la base de datos (consulte la figure 3). Ambos provocan cuellos de botella de escalabilidad.

Figure 3 How Distributed Caching Reduces Pressure on a Database
Figura 3 Manera en que el almacenamiento en caché distribuido reduce la presión sobre una base de datos

Almacenamiento de estado de sesión en una caché distribuida

Una de las limitaciones del almacenamiento de estado de sesión predeterminado es que no admite granjas web debido a que es almacenamiento en memoria que reside dentro del proceso de servicio WCF. Una alternativa mucho mejor es usar el modo de compatibilidad ASP.NET y el estado de sesión ASP.NET en servicios WCF. Esto le permite especificar el almacenamiento OutProc, incluido StateServer, SqlServer o una caché distribuida como almacenamiento de estado de sesión.

La habilitación del modo de compatibilidad ASP.NET es un proceso de dos pasos. Primero, debe especificar la compatibilidad ASP.NET en la definición de clase, tal como aparece en la figura 4. Luego debe especificar esto en su archivo app.config, tal como se muestra en la figura 5. Observe que la figura 4 también demuestra cómo especificar una caché distribuida como el almacenamiento SessionState en el mismo archivo web.config.

Figura 4 Especificación de compatibilidad ASP.NET para servicios WCF en código

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;

namespace MyWcfServiceLibrary {
  [ServiceContract]
  public interface IHelloWorldService {
    [OperationContract]
    string HelloWorld(string greeting);
  }

  [ServiceBehavior (InstanceContextMode = 
    InstanceContextMode.PerCall)]
  [AspNetCompatibilityRequirements (RequirementsMode = 
    AspNetCompatibilityRequirementsMode.Allowed)]

  public class HelloWorldService : IHelloWorldService {
    public string HelloWorld(string greeting) {
      return string.Format("HelloWorld: {0}", greeting);
    }
  }
}

Figura 5 Especificación de compatibilidad ASP.NET para servicios WCF en configuración

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <sessionState cookieless="UseCookies"
      mode="Custom" 
      customProvider="DistCacheSessionProvider" 
      timeout="20">
      <providers>
        <add name="DistCacheSessionProvider" 
          type="Vendor.DistCache.Web.SessionState.SessionStoreProvider"/>
      </providers>
    </sessionState>
    <identity impersonate="true"/>
  </system.web>

  <system.serviceModel>
    <!-- ... -->
    <serviceHostingEnvironment 
      aspNetCompatibilityEnabled="true"/>
  </system.serviceModel>
</configuration>

Las opciones de almacenamiento de sesión StateServer y SqlServer no escalan de manera correcta y, en el caso de StateServer, también es un punto único de error. Una caché distribuida es una alternativa mucho mejor, porque escala de buena manera y replica sesiones en varios servidores para la confiabilidad.

Almacenamiento en caché de datos de aplicación

Los datos de aplicación son, por lejos, el uso de datos más pesado en un servicio WCF y su almacenamiento y acceso son un importante cuello de botella de escalabilidad. Para abordar este problema del cuello de botella de escalabilidad, puede usar almacenamiento en caché distribuido en la implementación a nivel de servicio de SOA. Una caché distribuida se usa para almacenar en caché sólo un subconjunto de los datos que se encuentran en la base de datos en función de la necesidad del servicio WCF en una pequeña ventana de pocas horas.

De manera adicional, una caché distribuida brinda a una aplicación SOA un importante aumento de escalabilidad, porque esta caché puede escalar como resultado de la arquitectura que emplea. Mantiene distribuidos los elementos a través de varios servidores, y sigue brindándole a la aplicación SOA una vista lógica a fin de pensar que es sólo una caché. Pero la caché realmente reside en varios servidores y es eso lo que permite que la caché escale realmente. Si usa almacenamiento en caché distribuido entre el nivel de servicio y la base de datos, mejorará considerablemente el rendimiento y la escalabilidad del nivel de servicio.

La lógica básica que se debe implementar es, antes de ir a la base de datos, comprobar si la caché ya contiene los datos. Si es así, tómelos de la caché. De lo contrario, vaya a la base de datos, búsquelos y póngalos en la caché para la próxima vez. En la figura 6 se muestra un ejemplo.

Figura 6 Servicio WCF que usa almacenamiento en caché

using System.ServiceModel;
using Vendor.DistCache.Web.Caching;

namespace MyWcfServiceLibrary {
  [ServiceBehavior]
  public class EmployeeService : IEmployeeService {
    static string _sCacheName = "myServiceCache";
    static Cache _sCache = 
      DistCache.InitializeCache(_sCacheName);

    public Employee Load(string employeeId) {
      // Create a key to lookup in the cache.
      // The key for will be like "Employees:PK:1000".
      string key = "Employee:EmployeeId:" + employeeId;

      Employee employee = (Employee)_sCache[key];
      if (employee == null) {
        // item not found in the cache. 
        // Therefore, load from database.
        LoadEmployeeFromDb(employee);

        // Now, add to cache for future reference.
       _sCache.Insert(key, employee, null,
          Cache.NoAbsoluteExpiration,
          Cache.NoSlidingExpiration,
          CacheItemPriority.Default);
      }

      // Return a copy of the object since 
      // ASP.NET Cache is InProc.
      return employee;
    }
  }
}

Al almacenar en caché los datos de aplicación, el servicio WCF ahorra muchos viajes caros a la base de datos y, en lugar de eso, encuentra los datos de transacciones que se usan con frecuencia en una caché en memoria cercana.

Caducidad de los datos en caché

Las caducidades le permiten especificar durante cuánto tiempo los datos deben permanecer en caché antes de que esta los elimine de manera automática. Existen dos tipos de caducidades que puede especificar: caducidad de tiempo absoluto y caducidad de tiempo variable o tiempo de inactividad.

Si los datos en la caché también existen en la base de datos, sabe que otros usuarios o aplicaciones que probablemente no tienen acceso a su caché pueden cambiar estos datos en la base de datos. Cuando eso sucede, los datos de su caché se vuelven obsoletos, que es algo que no desea. Si puede adivinar durante cuánto tiempo cree que sea seguro mantener estos datos en la caché, puede especificar una caducidad de tiempo absoluto. Puede decir algo similar a “caducar este elemento en 10 minutos a partir de ahora” o “caducar este elemento a la medianoche de hoy". En ese momento la caché caducará este elemento:

using Vendor.DistCache.Web.Caching;
...
// Add an item to ASP.NET Cache with absolute expiration
_sCache.Insert(key, employee, null, 
  DateTime.Now.AddMinutes(2),
  Cache.NoSlidingExpiration, 
  CacheItemPriority.Default, null);

También puede usar la caducidad de tiempo de inactividad o de tiempo variable para caducar un elemento si nadie lo usa durante un período determinado. Puede especificar algo como “caducar este elemento si nadie lo lee o actualiza durante 10 minutos”. Esto es útil cuando la aplicación necesita los datos temporalmente y cuando la aplicación deja de usarlos y se desea que la caché los caduque de manera automática. El estado de sesión en modo de compatibilidad ASP.NET es un buen ejemplo de la caducidad de tiempo de inactividad.

Observe que la caducidad de tiempo absoluto le ayuda a evitar situaciones en que la caché tiene una copia obsoleta o anterior de los datos que los que tiene la copia maestra en la base de datos. Por otro lado, la caducidad de tiempo de inactividad sirve para un propósito completamente distinto. En realidad está creada para simplemente limpiar la caché una vez que la aplicación deja de necesitar los datos. En lugar de hacer que la aplicación realice un seguimiento de esta limpieza, deja que la caché se preocupe de eso.

Administración de relaciones de datos en la caché

La mayor parte de los datos proviene de una base de datos relacional, e incluso si no fuese así, es relacional por naturaleza. Por ejemplo, intenta almacenar en caché un objeto de cliente y un objeto de pedido y ambos objetos están relacionados. Un cliente puede tener varios pedidos.

Cuando tiene este tipo de relaciones, necesita poder manejarlas en una caché. Esto significa que la caché debiera conocer la relación entre un cliente y un pedido. Si actualiza o elimina el cliente de la caché, puede desear que la caché elimine el objeto de pedido automáticamente de la caché. Esto ayuda a mantener la integridad de los datos en varias situaciones.

Si una caché no puede hacer seguimiento de estas relaciones, tendrá que hacerlo usted mismo, lo que hace que su aplicación sea más complicada y compleja. Es mucho más fácil si sólo le indica a la caché cuando agrega los datos acerca de esta relación. La caché sabe que si se llega a actualizar o a eliminar el cliente, también se debe eliminar el pedido.

ASP.NET tiene una característica útil que se llama CacheDependency, la que le permite hacer seguimiento de las relaciones entre distintos elementos en caché. Algunas cachés comerciales también cuentan con esta característica. A continuación presentamos un ejemplo de cómo ASP.NET le permite hacer seguimiento de las relaciones entre elementos en caché:

using Vendor.DistCache.Web.Caching;
...
public void CreateKeyDependency() {
  Cache["key1"] = "Value 1";

  // Make key2 dependent on key1.
  String[] dependencyKey = new String[1];
  dependencyKey[0] = "key1";
  CacheDependency dep1 = 
    new CacheDependency(null, dependencyKey);

  _sCache.Insert("key2", "Value 2", dep2);
}

Esta es una dependencia en varios niveles, lo que significa que A puede depender de B y B puede depender de C. Por lo tanto, si la aplicación actualiza C, es necesario eliminar tanto A como B de la caché.

Sincronización de la caché con una base de datos

La necesidad de realizar sincronización de la base de datos surge porque la base de datos realmente se comparte entre varias aplicaciones, y no todas esas aplicaciones cuentan con acceso a la caché. Si la aplicación de servicio WCF es la única que actualiza la base de datos y también puede actualizar fácilmente la caché, es posible que no necesite la capacidad de sincronización de la base de datos.

Pero, en un entorno real, no siempre se da ese caso. Las aplicaciones de terceros actualizan los datos en la base de datos y la caché se vuelve inconsistente con la base de datos. La sincronización de la caché con la base de datos garantiza que la caché siempre esté al tanto de estos cambios en la base de datos y pueda actualizarse en función de eso.

La sincronización con la base de datos normalmente significa invalidar el elemento en caché relacionado desde la caché, para que la próxima vez que la aplicación lo necesite, tendrá que buscarlo en la base de datos puesto que la caché no lo tiene.

ASP.NET tiene una característica SqlCacheDependency que le permite sincronizar la caché con SQL Server 2005, SQL Server 2008 o Oracle 10g R2 y posterior, es decir, prácticamente cualquier base de datos compatible con CLR. Algunas de las cachés comerciales también brindan esta capacidad. La figura 7 muestra un ejemplo del uso de dependencia de SQL para sincronizar con una base de datos relacional.

Figura 7 Sincronización de datos mediante dependencia de SQL

using Vendor.DistCache.Web.Caching;
using System.Data.SqlClient;
...

public void CreateSqlDependency(
  Customers cust, SqlConnection conn) {

  // Make cust dependent on a corresponding row in the
  // Customers table in Northwind database

  string sql = "SELECT CustomerID FROM Customers WHERE ";
  sql += "CustomerID = @ID";
  SqlCommand cmd = new SqlCommand(sql, conn);
  cmd.Parameters.Add("@ID", System.Data.SqlDbType.VarChar);
  cmd.Parameters["@ID"].Value = cust.CustomerID;

  SqlCacheDependency dep = new SqlCacheDependency(cmd);
  string key = "Customers:CustomerID:" + cust.CustomerID;
_  sCache.Insert(key, cust, dep);
}

Una capacidad que no brinda ASP.NET, pero sí algunas soluciones comerciales, es la sincronización de base de datos basada en sondeos. Esto es útil si el sistema de administración de bases de datos (DBMS) no es compatible con CLR y no es posible beneficiarse de SqlCacheDependency. En ese caso, sería bueno si la caché pudiera sondear la base de datos a intervalos configurables y detectar cambios en ciertas filas de una tabla. Si esas filas han cambiado, la caché invalida sus elementos en caché correspondientes.

Bus de servicio empresarial para escalabilidad de SOA

Bus de servicio empresarial (ESB) es un concepto de la industria en que se usan varias tecnologías para construirlo. Un ESB es una infraestructura para servicios web que media en la comunicación entre componentes. En términos simples, un ESB es una manera simple y poderosa para que varias aplicaciones compartan datos de manera asincrónica. Sin embargo, no es su propósito ser usado en todas las organizaciones, ni siquiera a través de una WAN. Normalmente las aplicaciones SOA, por diseño, se dividen en varias partes, por lo que cuando necesitan compartir datos entre sí, ESB es una herramienta poderosa.

Existen muchas formas de crear un ESB. En la figura 8 se muestra un ejemplo de un ESB creado con una caché distribuida. Varios componentes de servicio o aplicaciones de acoplamiento flexible pueden usarlo para compartir datos entre sí en tiempo real y a través de la red.


Figura 8 Un ESB creado con una caché distribuida

Debido a su naturaleza, una caché distribuida abarca varios equipos. Esto la hace altamente escalable, con lo que cumple el primer criterio de un ESB. Además, una buena caché distribuida replica todos sus datos de manera inteligente para garantizar que no se produzca una pérdida de datos si algún servidor de la caché deja de funcionar. (Explicaré esto más adelante). Finalmente, una buena caché distribuida ofrece mecanismos inteligentes para la propagación de eventos.

Existen dos tipos de eventos que debe proporciona una caché distribuida para ser apta para un ESB. Primero, cualquier aplicación cliente del ESB debe poder registrar el interés en un elemento de datos del ESB, a fin de que, si alguien lo modifica o elimina, se notifique de inmediato a la aplicación cliente. Segundo, la caché debiera permitir que las aplicaciones cliente activen eventos personalizados en el ESB para que se notifique de inmediato a todas las demás aplicaciones conectadas al ESB a las que les interese este evento personalizado, sin importar si están en la red (por supuesto, dentro de la intranet).

Con la ayuda de un ESB, es posible realizar con mucha facilidad una gran cantidad de intercambios de datos a través del ESB que, de lo contrario, requerirían llamadas de SOA de una aplicación a otra. Además, un servicio WCF simple no está diseñado para realizar fácilmente el uso compartido de datos asincrónicos. Pero el ESB hace este trabajo sin problemas. Puede crear fácilmente situaciones en las que los datos incluso se empujen a los clientes del ESB si han demostrado interés en ellos.

Alta disponibilidad y escalabilidad de caché

La topología de almacenamiento en caché es un término que se usa para indicar cómo se almacenan realmente los datos en una caché distribuida. Existen diversas topologías de almacenamiento en caché que están diseñadas para adaptarse a distintos entornos. Aquí explicaré tres: caché con particiones, caché con particiones y replicada y caché replicada.

Con particiones y con particiones y replicada son dos topologías de almacenamiento en caché que desempeñan roles importantes en el escenario de escalabilidad. En ambas topologías, la caché se divide en particiones, y cada partición se almacena en distintos servidores de caché en el clúster. La caché con particiones y replicada tiene una réplica de cada partición almacenada en un servidor de caché distinto.

Las cachés con particiones y las cachés con particiones y replicadas son la topología más escalable para el almacenamiento en caché de datos de transacciones (donde escribe en la caché con la misma frecuencia que lee) por, cuando agrega más servidores de caché al clúster, no sólo aumenta la capacidad de transacción, sino que también aumenta la capacidad de almacenamiento de la caché, debido a que todas esas particiones en conjunto forman la caché completa.

Una tercera topología de almacenamiento en caché, la caché replicada, copia toda la caché a cada servidor de caché en el clúster. Esto significa que la caché replicada brinda alta disponibilidad y sirve para un uso con muchas lecturas. Sin embargo, no es recomendable para realizar actualizaciones frecuentes, porque las actualizaciones se realizan en todas las copias de manera sincrónica y no son tan rápidas como con otras topologías de almacenamiento en caché.

Tal como aparece en la figura 9, la topología de caché con particiones y replicada es ideal para una combinación de escalabilidad y alta disponibilidad. No pierde datos debido a las réplicas de cada partición.


Figura 9 Topología de almacenamiento en caché con particiones y replicado para escalabilidad

Es posible aumentar más aún la alta disponibilidad mediante la agrupación en clústeres de caché dinámica, que es la capacidad de agregar o eliminar servidores de caché del clúster de caché en tiempo de ejecución sin detener la caché o las aplicaciones cliente. Como una caché distribuida se ejecuta en un entorno de producción, la alta disponibilidad es un requisito de característica importante.

Pasos siguientes

Como ya ha visto, una aplicación SOA no puede escalar de manera eficaz cuando los datos que usa se mantienen en un almacenamiento que no es escalable para transacciones frecuentes. Es aquí donde el almacenamiento en caché distribuido realmente ayuda.

El almacenamiento en caché distribuido es un nuevo concepto, pero que rápidamente está obteniendo aceptación entre los desarrolladores de .NET como un procedimiento recomendado para cualquier aplicación de alta transacción. Los servidores de bases de datos tradicionales también mejoran, pero sin el almacenamiento en caché distribuido no pueden cumplir con la demanda cada vez más grande de escalabilidad en las aplicaciones de hoy en día.

Las técnicas que he descrito debieran ayudarle a llevar sus aplicaciones SOA a nuevos niveles de escalabilidad. Pruébelas hoy. Para leer más análisis sobre el almacenamiento en caché distribuido, consulte el artículo de MSDN Library escrito por J.D. Meier, Srinath Vasireddy, Ashish Babbar y Alex Mackman en el sitio web msdn.microsoft.com/library/ms998562.          

Iqbal Khan  es presidente y experto en tecnología de Alachisoft. Alachisoft proporciona NCache, una caché distribuida de NET líder en la industria para aumentar el rendimiento y la escalabilidad en aplicaciones empresariales. Khan posee un máster en informática de la Universidad de Indiana, Bloomington. Puede ponerse en contacto con él en iqbal@alachisoft.com.

Gracias a los siguientes expertos técnicos por su ayuda en la revisión de este artículo:  Kirill Gavrylyuk y Stefan Schackow