Übersetzung vorschlagen
 
Andere Vorschläge:

progress indicator
Keine anderen Vorschläge
MSDN Magazin > Home > Ausgaben > 2009 > MSDN Magazin Juli 2009 >  Skalieren Sie aus: Verteilte Zwischenspeicherun...
Inhalt anzeigen:  Englisch mit deutscher ÜbersetzungInhalt anzeigen: Englisch mit deutscher Übersetzung
Dies sind maschinell übersetzte Inhalte, die von den Mitgliedern der Community bearbeitet werden können. Sie können die Übersetzung verbessern, indem Sie auf den jeweils zum Satz gehörenden Link "Bearbeiten" klicken.Mithilfe des Dropdown-Steuerelements "Inhalt anzeigen" links oben auf der Seite können Sie zudem bestimmen, ob nur der englische Originaltext, nur die deutsche Übersetzung oder beides nebeneinander angezeigt werden.
Scale Out
Distributed Caching On The Path To Scalability
Iqbal Khan

This article discusses:
  • Distributed caching
  • Scalability
  • Database synchronization
This article uses the following technologies:
ASP.NET, Web services, HPC applications
If you're developing an ASP.NET application, Web services or a high-performance computing (HPC) application, you're likely to encounter major scalability issues as you try to scale and put more load on your application. With an ASP.NET application, bottlenecks occur in two data stores. The first is the application data that resides in the database, and the other is ASP.NET session state data that is typically stored in one of three modes (InProc, StateServer, or SqlServer) provided by Microsoft. All three have major scalability issues.
Web services typically do not use session state, but they do have scalability bottlenecks when it comes to application data. Just like ASP.NET applications, Web services can be hosted in IIS and deployed in a Web farm for scalability.
HPC applications that are designed to perform massive parallel processing also have scalability problems because the data store does not scale in the same manner. HPC (also called grid computing) has traditionally used Java, but as .NET gains market share, it is becoming more popular for HPC applications as well. HPC applications are deployed to hundreds and sometimes thousands of computers for parallel processing, and they often need to operate on large amounts of data and share intermediate results with other computers. HPC applications use a database or a shared file system as a data store, and both of these do not scale very well.

Distributed Caching
Caching is a well-known concept in both the hardware and software worlds. Traditionally, caching has been a stand-alone mechanism, but that is not workable anymore in most environments because applications now run on multiple servers and in multiple processes within each server.
In-memory distributed caching is a form of caching that allows the cache to span multiple servers so that it can grow in size and in transactional capacity. Distributed caching has become feasible now for a number of reasons. First, memory has become very cheap, and you can stuff computers with many gigabytes at throwaway prices. Second, network cards have become very fast, with 1Gbit now standard everywhere and 10Gbit gaining traction. Finally, unlike a database server, which usually requires a high-end machine, distributed caching works well on lower cost machines (like those used for Web servers), which allows you to add more machines easily.
Distributed caching is scalable because of the architecture it employs. It distributes its work across multiple servers but still gives you a logical view of a single cache. For application data, a distributed cache keeps a copy of a subset of the data in the database. This is meant to be a temporary store, which might mean hours, days or weeks. In a lot of situations, the data being used in an application does not need to be stored permanently. In ASP.NET, for example, session data is temporary and needed for maybe a few minutes to a few hours at most.
Similarly, in HPC, large portions of the processing requires storing intermediate data in a data store, and this is also temporary in nature. The final outcome of HPC might be stored in a database, however. Figure 1 shows a typical configuration of a distributed cache in an enterprise.
Figure 1 Distributed Cache Shared by Various Apps in an Enterprise (Click the image for a larger view)

Must-Have Features in Distributed Cache
Traditionally, developers have considered caching only static data, meaning data that never changes throughout the life of the application. But that data is usually a very small subset—maybe 10%—of the data that an application processes. Although you can keep static data in the cache, the real value comes if you can cache dynamic or transactional data—data that keeps changing every few minutes. You still cache it because within that time span, you might fetch it tens of times and save that many trips to the database. If you multiply that by thousands of users who are trying to perform operations simultaneously, you can imagine how many fewer reads you have on the database.
But if you cache dynamic data, the cache has to have certain features designed to avoid data integrity problems. A typical cache should have features for expiring and evicting items, as well as other capabilities. I'll explore these features in the following sections.

Expirations
Expirations are at the top of the list. They let you specify how long data should stay in the cache before the cache automatically removes it. You can specify two types of expirations: absolute-time expiration and sliding-time (or idle-time) expiration.
If the data in your cache also exists in a master data source, you know that this data can be changed in the database by users or applications that might not have access to the cache. When that happens, the data in the cache becomes stale. If you're able to estimate how long this data can be safely kept in the cache, you can specify absolute-time expiration—something like, "Expire this item 10 minutes from now" or "Expire this item at midnight tonight."
One interesting variation to absolute expiration is whether your cache can reload an updated copy of the cached item directly from your data source. This is possible only if your cache provides a read-through feature (see later sections) and allows you to register a read-through handler that reloads cached items when absolute expiration occurs. Except for a few commercial caches, most caches do not support this feature.
You can use idle-time (sliding-time) expiration to expire an item if it is not used for a given period of time. You can specify something like, "Expire this item if nobody reads or updates it for 10 minutes." This approach is useful when your application needs the data temporarily, but once the application is finished using it, you want the cache to automatically expire it. ASP.NET session state is a good candidate for idle-time expiration.
Absolute-time expiration helps you avoid situations in which the cache has a stale copy of the data or a copy that is older than the master copy in the database. Idle-time expiration is meant to clean up the cache after your application no longer needs certain data. Instead of having your application keep track of necessary cleanup, you let the cache take care of it.

Evictions
Most distributed caches are in-memory and do not persist the cache to disk. This means that in most situations, memory is limited and the cache size cannot grow beyond a certain limit, which could be the total memory available or much less than that if you have other applications running on the same machine.
Either way, a distributed cache should allow you to specify a maximum cache size (ideally, in terms of memory size). When the cache reaches this size, it should start removing cached items to make room for new ones, a process usually referred to as evictions.
Evictions are made based on various algorithms. The most popular is least recently used (LRU), where those cached items that have not been touched for the longest time are removed. Another algorithm is least frequently used (LFU). Here, those items that have been touched the least number of times are removed. There are a few other variations, but these two are the most popular.

Caching Relational Data
Most data comes from a relational database, but even if it does not, it is relational in nature, meaning that different pieces of data are related to one another—for example, a customer object and an order object.
When you have these relationships, you need to handle them in a cache. That means the cache should know about the relationship between a customer and an order. If you update or remove a customer from the cache, you might want the cache to also automatically update or remove related order objects from the cache. This helps maintain data integrity in many situations.
But again, if a cache cannot keep track of these relationships, you have to do it, and that makes your application much more cumbersome and complex. It's a lot easier if you just tell the cache at the time data is added that an order is associated with a customer, and the cache then knows that if that customer is updated or removed, related orders also have to be updated or removed from the cache.
ASP.NET Cache has a really cool feature called CacheDependency, which allows you to keep track of relationships between different cached items. Some commercial caches also have this feature. Figure 2 shows an example of how ASP.NET Cache works.
using System.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);

   Cache.Insert("key2", "Value 2", dep2);
}
This is a multilayer dependency, meaning that A can depend on B and B can depend on C. So, if your application removes C, A and B have to be removed from the cache as well.

Synchronizing a Cache with Other Environments
Expirations and cache dependency features are intended to help you keep the cache fresh and correct. You also need to synchronize your cache with data sources that you and your cache don't have access to so that changes in those data sources are reflected in your cache to keep it fresh.
For example, let's say your cache is written using the Microsoft .NET Framework, but you have Java or C++ applications modifying data in your master data source. You want these applications to notify your cache when certain data changes in the master data sources so that your cache can invalidate a corresponding cached item.
Ideally, your cache should support this capability. If it doesn't, this burden falls on your application. ASP.NET Cache provides this feature through CacheDependency, as do some commercial caching solutions. It allows you to specify that a certain cached item depends on a file and that whenever this file is updated or removed, the cache discovers this and invalidates the cached item. Invalidating the item forces your application to fetch the latest copy of this object the next time your application needs it and does not find it in the cache.
If you had 100,000 items in the cache, 10,000 of them might have file dependencies, and for that you might have 10,000 files in a special folder. Each file has a special name associated with that cached item. When some other application—whether written in .NET or not—changes the data in the master data source, that application can communicate to the cache through an update of the file time stamp.

Database Synchronization
The need for database synchronization arises because the database is being shared across multiple applications, and not all those applications have access to your cache. If your application is the only application updating the database and it can also easily update the cache, you probably don't need the database synchronization capability. But in a real-life environment, that's not always the case. Whenever a third party or any other application changes the database data, you want the cache to reflect that change. The cache reflects changes by reloading the data, or at least by not having the older data in the cache.
If the cache has an old copy and the database a new copy, you now have a data integrity problem because you don't know which copy is right. Of course, the database is always right, but you don't always go to the database. You get data from the cache because your application trusts that the cache will always be correct or that the cache will be correct enough for its needs.
Synchronizing with the database can mean invalidating the related item in the cache so that the next time your application needs it, it will fetch it from the database. One interesting variant to this process is when the cache automatically reloads an updated copy of the object when the data changes in the database. However, this is possible only if your cache allows you to provide a read-through handler (see the next section) and then uses it to reload the cached item from the database. However, only some of the commercial caches support this feature, and none of the free ones do.
ASP.NET Cache has a SqlCacheDependency feature (see Figure 3) that allows you to synchronize the cache with a SQL Server 2005/2008 or Oracle 10g R2 or later version database—basically any database that has the .NET CLR built into it. Some of the commercial caches also provide this capability.
using System.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;

  Cache.Insert(key, cust, dep);
}
ASP.NET Cache SqlCacheDependency allows you to specify a SQL string to match one or more rows in a table in the database. If this row is ever updated, the DBMS fires a .NET event that your cache catches. It then knows which cached item is related to this row in the database and invalidates that cached item.
One capability that ASP.NET Cache does not provide but that some commercial solutions do is polling-based database synchronization. This capability is helpful in two situations. First, if your DBMS does not have the .NET CLR built into it, you cannot benefit from SqlCacheDependency. In that case, it would be nice if your cache could poll your database on configurable intervals and detect changes in certain rows in a table. If those rows have changed, your cache invalidates their corresponding cached items.
The second situation is when data in your database is frequently changing and .NET events are becoming too chatty. This occurs because a separate .NET event is fired for each SqlCacheDependency change, and if you have thousands of rows that are updated frequently, this could easily crowd your cache. In such cases, it is much more efficient to rely on polling, where with one database query you can fetch hundreds or thousands of rows that have changed and then invalidate corresponding cached items. Of course, polling creates a slight delay in synchronization (maybe 15–30 seconds), but this is acceptable in many cases.

Read-Through
In a nutshell, read-through is a feature that allows your cache to directly read data from your data source, whatever that may be. You write a read-through handler and register it with your cache, and then your cache calls this handler at appropriate times. Figure 4 shows an example.
using System.Web.Caching;
using System.Data.SqlClient;
using Company.MyDistributedCache;

...

public class SqlReadThruProvider : IReadhThruProvider
{
  private SqlConnection _connection;

  // Called upon startup to initialize connection
  public void Start(IDictionary parameters)
  {
    _connection = new SqlConnection(parameters["connstring"]);
    _connection.Open();
  }

  // Called at the end to close connection
  public void Stop() { _connection.Close(); }

  // Responsible for loading object from external data source
  public object Load(string key, ref CacheDependency dep)
  {
    string sql = "SELECT * FROM Customers WHERE ";
    sql += "CustomerID = @ID";
    SqlCommand cmd = new SqlCommand(sql, _connection);
    cmd.Parameters.Add("@ID", System.Data.SqlDbType.VarChar);

    // Let's extract actual customerID from "key"
    int keyFormatLen = "Customers:CustomerID:".Length;
    string custId = key.Substring(keyFormatLen,
    key.Length - keyFormatLen);
    cmd.Parameters["@ID"].Value = custId;

    // fetch the row in the table
    SqlDataReader reader = cmd.ExecuteReader();

    // copy data from "reader" to "cust" object
    Customers cust = new Customers();
    FillCustomers(reader, cust);

    // specify a SqlCacheDependency for this object
    dep = new SqlCacheDependency(cmd);
    return cust;
  }
}
Because a distributed cache usually lives outside your application, it is shared across multiple instances of your application or even multiple applications. One important capability of a read-through handler is that the data you cache is fetched by the cache directly from the database. Hence, your applications don't have to have database code. They can just fetch data from the cache, and if the cache doesn't have it, the cache goes and takes it from the database.
You gain even more important benefits if you combine read-through capabilities with expirations. Whenever an item in the cache expires, the cache automatically reloads it by calling your read-through handler. You save a lot of traffic to the database with this mechanism. The cache uses only one thread, one database trip, to reload that data from the database, whereas you might have thousands of users trying to access that same data. If you did not have read-through capability, all those users would be going directly to the database, inundating the database with thousands of parallel requests.
Read-through allows you to establish an enterprise-level data grid, meaning a data store that not only is highly scalable, but can also refresh itself from master data sources. This provides your applications with an alternate data source from which to read data and relieves a lot of pressure on your databases.
As mentioned earlier, databases are always the bottleneck in high-transaction environments, and they become bottlenecks due mostly to excessive read operations, which also slow down write operations. Having a cache that serves as an enterprise-level data grid above your database gives your applications a major performance and scalability boost.
However, keep in mind that read-through is not a substitute for performing some complex joined queries in the database. A typical cache does not let you do these types of queries. A read-through capability works well for individual object read operations but not in operations involving complex joined queries, which you always need to perform on the database.

Write Through, Write Behind
Write-through is just like read-through: you provide a handler, and the cache calls the handler, which writes the data to the database whenever you update the cache. One major benefit is that your application doesn't have to write directly to the database because the cache does it for you. This simplifies your application code because the cache, rather than your application, has the data access code.
Normally, your application issues an update to the cache (for example, Add, Insert, or Remove). The cache updates itself first and then issues an update call to the database through your write-through handler. Your application waits until both the cache and the database are updated.
What if you want to wait for the cache to be updated, but you don't want to wait for the database to be updated because that slows down your application's performance? That's where write-behind comes in, which uses the same write-through handler but updates the cache synchronously and the database asynchronously. This means that your application waits for the cache to be updated, but you don't wait for the database to be updated.
You know that the database update is queued up and that the database is updated fairly quickly by the cache. This is another way to improve your application performance. You have to write to the database anyway, but why wait? If the cache has the data, you don't even suffer the consequences of other instances of your application not finding the data in the database because you just updated the cache, and the other instances of your application will find the data in the cache and won't need to go to the database.

Cache Query
Normally, your application finds objects in the cache based on a key, just like a hash table, as you've seen in the source code examples above. You have the key, and the value is your object. But sometimes you need to search for objects based on attributes other than the key. Therefore, your cache needs to provide the capability for you to search or query the cache.
There are a couple of ways you can do this. One is to search on the attributes of the object. The other involves situations in which you've assigned arbitrary tags to cached objects and want to search based on the tags. Attribute-based searching is currently available only in some commercial solutions through object query languages, but tag-based searching is available in commercial caches and in Microsoft Velocity.
Let's say you've saved a customer object. You could say, "Give me all the customers where the city is San Francisco," when you want only customer objects, even though your cache has employees, customers, orders, order items, and more. When you issue a SQL-like query such as the one shown in Figure 5, it finds the objects that match your criteria.
using Company.MyDistributedCache;

...

public List<Customers> FindCustomersByCity(Cache cache, string city)
{
  // Search cache with a LINQ query
  List<Customers> custs = from cust in cache.Customers
                          where cust.City == city
                          select cust;
  return custs;
}
Tagging lets you attach multiple arbitrary tags to a specific object, and the same tag can be associated with multiple objects. Tags are usually string-based, and tagging also allows you to categorize objects into groups and then find the objects later through these tags or groups.

Event Propagation
You might not always need event propagation in your cache, but it is an important feature that you should know about. It's a good feature to have if you have distributed applications, HPC applications, or multiple applications sharing data through a cache. What event propagation does is ask the cache to fire events when certain things happen in the cache. Your applications can capture these events and take appropriate actions in response.
Say your application has fetched some object from the cache and is displaying it to the user. You might be interested to know if anybody updates or removes this object from the cache while it is displayed. In this case, your application will be notified, and you can update the user interface.
This is, of course, is a very simple example. In other cases, you might have a distributed application where some instances of your application are producing data and other instances need to consume it. The producers can inform the consumers when data is ready by firing an event through the cache that the consumers receive. There are many examples of this type, where collaboration or data sharing through the cache can be achieved through event propagation.

Cache Performance and Scalability
When considering the caching features discussed in the previous sections, you must not forget that the main reasons you're thinking of using a distributed cache, which are to improve performance and, more important, to improve the scalability of your application. Also, because your cache runs in a production environment as a server, it must also provide high availability.
Scalability is the fundamental problem a distributed cache addresses. A scalable cache is one that can maintain performance even when you increase the transaction load on it. So, if you have an ASP.NET application in a Web farm and you grow your Web farm from five Web servers to 15 or even 50 Web servers, you should be able to grow the number of cache servers proportionately and keep the same response time. This is something you cannot do with a database.
A distributed cache avoids the scalability problems that a database usually faces because it is much simpler in nature than a DBMS and also because it uses different storage mechanisms (also known as caching topologies) than a DBMS. These include replicated, partitioned, and client cache topologies.
In most distributed cache situations, you have two or more cache servers hosting the cache. I'll use the term "cache cluster" to indicate two or more cache servers joined together to form one logical cache. A replicated cache copies the entire cache on each cache server in the cache cluster. This means that a replicated cache provides high availability. If any one cache server goes down, you don't lose any data in the cache because another copy is immediately available to the application. It's also an extremely efficient topology and provides great scalability if your application needs to do a lot of read-intensive operations. As you add more cache servers, you add that much more read-transaction capacity to your cache cluster. But a replicated cache is not the ideal topology for write-intensive operations. If you are updating the cache as frequently as you are reading it, don't use the replicated topology.
A partitioned cache breaks up the cache into partitions and then stores one partition on each cache server in the cluster. This topology is the most scalable for transactional data caching (when writes to the cache are as frequent as reads). As you add more cache servers to the cluster, you increase not only the transaction capacity but also the storage capacity of the cache, since all those partitions together form the entire cache.
Many distributed caches provide a variant of a partitioned cache for high availability, where each partition is also replicated so that one cache server contains a partition and a copy or a backup of another server's partition. This way, you don't lose any data if any one server goes down. Some caching solutions allow you to create more than one copy of each partition for added reliability.
Another very powerful caching topology is client cache (also called near cache), which is very useful if your cache resides in a remote dedicated caching tier. The idea behind a client cache is that each client keeps a working set of the cache close by (even within the application's process) on the client machine. However, just as a distributed cache has to be synchronized with the database through different means (as discussed earlier), a client cache needs to be synchronized with the distributed cache. Some commercial caching solutions provide this synchronization mechanism, but most provide only a stand-alone client cache without any synchronization.
In the same way that a distributed cache reduces traffic to the database, a client cache reduces traffic to the distributed cache. It is not only faster than the distributed cache because it is closer to the application (and can also be InProc), it also improves the scalability of the distributed cache by reducing trips to the distributed cache. Of course, a client cache is a good approach only when you are performing many more reads than writes. If the number of reads and writes are equal, don't use a client cache. Writes will become slower because you now have to update both the client cache and the distributed cache.

High Availability
Because a distributed cache runs as a server in your production environment, and in many cases serves as the only data store for your application (for example, ASP.NET session state), the cache must provide high availability. This means that your cache must be very stable so that it never crashes and provides the ability to make configuration changes without stopping the cache.
Most users of a distributed cache require the cache to run without any interruptions for months at a time. Whenever they have to stop the cache, it is usually during a scheduled down time. That is why high availability is so critical for a distributed cache. Here are a few questions to keep in mind when evaluating whether a caching solution provides high availability.
  • Can you bring one of the cache servers down without stopping the entire cache?
  • Can you add a new cache server without stopping the cache?
  • Can you add new clients without stopping the cache?
In most caches, you use a specified maximum cache size so that the cache doesn't exceed the amount of data. The cache size is based on how much memory you have available on that system. Can you change that capacity? Let's say you initially set the cache size to be 1GB but now want to make it 2GB. Can you do that without stopping the cache?
Those are the types of questions you want to consider. How many of these configuration changes really require the cache to be restarted? The fewer, the better. Other than the caching features, the first criteria for having a cache that can run in a production environment is how much uptime the cache is going to give you.

Performance
Simply put, if accessing the cache is not faster than accessing your database, there is no need to have it. Having said that, what should you expect in terms of performance from a good distributed cache?
The first thing to remember is that a distributed cache is usually OutProc or remote, so access time will never be as fast as that of a stand-alone InProc cache (for example, ASP.NET Cache). In an InProc stand-alone cache, you can probably read 150,000 to 200,000 items per second (1KB object size). With an OutProc or a remote cache, this number drops significantly. In terms of performance, you should expect about 20,000 to 30,000 reads per second (1KB object size) as the throughput of an individual cache server (from all clients hitting on it). You can achieve some of this InProc performance by using a client cache (in InProc mode), but that is only for read operations and not for write operations. You sacrifice some performance in order to gain scalability, but the slower performance is still much faster than database access.

Gaining Popularity
A distributed cache as a concept and as a best practice is gaining more popularity. Only a few years ago, very few people in the .NET space knew about it, although the Java community has been ahead of .NET in this area. With the explosive growth in application transactions, databases are stressed beyond their limits, and distributed caching is now accepted as a vital part of any scalable application architecture.

Iqbal Khan is president and technology evangelist at Alachisoft. Alachisoft provides NCache, an industry-leading .NET distributed cache for boosting performance and scalability in enterprise applications. Iqbal has an MS in computer science from Indiana University, Bloomington. You can reach him at iqbal@alachisoft.com.

Scale-Out-Lösung
Verteilte Zwischenspeicherung auf dem Weg zur Skalierbarkeit
Iqbal Khan

Themen in diesem Artikel:
  • Verteiltes Zwischenspeichern
  • Skalierbarkeit
  • Die Datenbanksynchronisierung
In diesem Artikel werden die folgenden Technologien verwendet:
ASP.NET XML-Webdienste, HPC-Anwendungen
Wenn Sie ein ASP.NET entwickeln sind Anwendung, Webdienste oder eine High-Performance computing (HPC) Anwendung, wahrscheinlich Sie großen Skalierbarkeit Probleme auftreten, wie Sie versuchen, Skalieren und weitere Last auf Ihre Anwendung. Mit einer XML-Webdienste Anwendung Engpässe treten in beiden Datenspeichern. Die erste ist der Anwendungsdaten, die in der Datenbank befindet, und die andere ist XML-Webdienste Sitzung Status Daten, die normalerweise in einem von drei Modi (InProc, SqlServer oder StateServer) von Microsoft bereitgestellten gespeichert sind. Alle drei müssen wichtige Skalierbarkeitsprobleme.
Webdienste verwenden normalerweise keine Sitzungszustand, Sie verfügen jedoch über Skalierbarkeit Engpässe bei Anwendungsdaten. Wie ASP.NET-Anwendungen können XML-Webdienste in IIS gehostet und in einer Webfarm für Skalierbarkeit bereitgestellt werden.
HPC-Anwendungen, die Verarbeitungsschritte umfangreichen parallelen auch entwickelt werden, haben Skalierbarkeitsproblemen, da im Datenspeicher nicht auf dieselbe Weise skaliert wird. HPC (auch als Raster computing bezeichnet) wurde traditionell Java verwendet, aber als .NET Gewinne Marktanteil, gewinnt er beliebter für HPC-Anwendungen sowie. HPC-Anwendungen Hunderte und manchmal Tausende von Computern für die parallele Verarbeitung bereitgestellt werden, und werden häufig auf große Mengen von Daten und Freigabe Zwischenergebnisse mit anderen Computern ausgeführt werden müssen. HPC-Anwendungen verwenden eine Datenbank oder ein freigegebenes Dateisystem als Datenspeicher, und beide nicht sehr gut skalieren.

Verteilte Zwischenspeicherung
Zwischenspeicherung ist ein bekannter Konzept in Hardware und Software Welten. Traditionell Zwischenspeichern eines eigenständigen Mechanismus wurde, jedoch ist nicht mehr in den meisten Umgebungen brauchbare da Anwendungen jetzt auf mehreren Servern und in mehreren Prozessen innerhalb der einzelnen Server ausgeführt.
Im Arbeitsspeicher verteilte Zwischenspeicherung ist ein Formular der Zwischenspeicherung, das ermöglicht es den Cache mehrere Server erstrecken, sodass in Größe und transaktionale Kapazität vergrößert werden können. Verteilte Zwischenspeicherung ist jetzt möglich, eine Reihe von Gründen geworden. Zunächst Speicher sehr kostengünstig geworden und Sie können Computer mit viele Gigabyte zu throwaway Preisen Dinge. Zweitens sehr schnell verschafft Traction 10Gbit mit 1Gbit jetzt überall Standard geworden Netzwerkkarten. Verteiltes im Gegensatz zu einem Datenbankserver in der Regel einen High-End-Computer erfordert schließlich Zwischenspeichern funktioniert gut auf niedrigeren Kosten Computern (wie zum Webserver), dem Sie mehrere Computer problemlos hinzufügen können.
Verteilte Zwischenspeicherung ist wegen der Architektur, die es nutzt skalierbar. Er verteilt die Arbeit auf mehrere Server jedoch weiterhin erhalten Sie eine logische Ansicht eines einzelnen Caches. Für Anwendungsdaten bewahrt ein verteilter Cache eine Kopie einer Teilmenge der Daten in der Datenbank. Dies soll einem temporären Speicher, der Stunden, Tage oder Wochen bedeuten kann. In vielen Fällen muss die in einer Anwendung verwendeten Daten nicht dauerhaft gespeichert werden. In XML-Webdienste, ist z. B. Sitzungsdaten temporäre und erforderlichen vielleicht ein paar Minuten zu ein paar Stunden höchstens.
Ebenso in HPC, große Teile der Verarbeitung erfordert intermediate Daten in einem Datenspeicher gespeichert, und dies ist auch temporäre Natur. Das endgültige Ergebnis der HPC könnte jedoch in einer Datenbank gespeichert werden. Abbildung 1 zeigt eine typische Konfiguration eines verteilten Caches in einem Unternehmen.
Abbildung 1 verteilt Cache Shared von verschiedenen Anwendungen in einer Enterprise- (auf das Bild für eine größere Ansicht klicken.)

Muss haben Features in verteilten Cache
Bisher haben Entwickler berücksichtigt, die Zwischenspeicherung nur statischer Daten, Daten von Bedeutung, die während der gesamten Lebensdauer der Anwendung niemals ändert. Aber, dass Daten in der Regel eine sehr kleine Teilmenge ist – vielleicht 10 % – Daten, die eine Anwendung verarbeitet. Obwohl Sie statische Daten im Cache beibehalten können, der echte Wert stammt, wenn Sie dynamische oder Transaktionsnachrichten Daten zwischenspeichern können, Daten, die alle paar Minuten ändern, behält. Sie Zwischenspeichern weiterhin es da innerhalb dieser Zeitspanne kann es zehntausenden von Zeiten abrufen und viele Schleifen in der Datenbank speichern. Wenn Sie, die mit Tausenden von Benutzern, die versuchen multiplizieren, Operationen gleichzeitig ausführen, können Sie wie viele weniger Lesevorgänge angenommen, Sie in der Datenbank haben.
Aber wenn Sie dynamische Daten zwischenspeichern, hat der Cache, bestimmte Features entwickelt, um Datenintegritätsprobleme zu verhindern. Ein typischer Cache sollten Funktionen für ablaufen und Entfernen von Elementen sowie andere Funktionen verfügen. Ich werde diese Features in den folgenden Abschnitten untersuchen.

Ablaufzeiten
Ablaufzeiten sind am Anfang der Liste. Sie können angeben, wie lange Daten sollten im Cache bleiben, bevor der Cache automatisch entfernt. Sie können zwei Arten von Ablaufzeiten angeben: Absolute Zeit Ablaufdatum und Variable Zeit (oder im Leerlauf Zeit) ablaufen.
Wenn die Daten in den Cache auch in einer master-Datenquelle vorhanden ist, wissen Sie, dass diese Daten geändert werden können in der Datenbank von Benutzern oder Anwendungen, die nicht in den Cache zugreifen können. Wenn dies geschieht, werden die Daten im Cache veraltet. Wenn Sie können zu schätzen, wie lange diese Daten problemlos im Cache gespeichert werden können, können Sie Absolute Zeit Ablaufdatum angeben – etwas wie, "dieses Element jetzt in 10 Minuten ablaufen"oder "Läuft ab heute um Mitternacht dieses Element."
Eine interessante Variante um absolute Ablaufzeit ist, ob eine aktualisierte Kopie das zwischengespeicherte Element direkt aus der Datenquelle der Cache geladen werden kann. Dies ist möglich, nur, wenn der Cache eine Read-through stellt Features (siehe nachfolgenden Abschnitten) und ermöglicht Ihnen einen Read-through-Handler registrieren, die zwischengespeicherte Elemente, lädt tritt absolute Ablaufzeit. Abgesehen von ein paar kommerzielle Caches unterstützen die meisten Caches dieses Feature nicht.
Leerlauf-Time (gleitende-Time) Ablaufdatum können Sie ein Element ablaufen, wenn es für einen bestimmten Zeitraum nicht verwendet wird. Sie können wie "Ablaufen dieses Element" angeben, wenn niemand liest oder für 10 Minuten aktualisiert Dies ist sinnvoll Wenn Ihre Anwendung vorübergehend Daten benötigt, aber nach die Anwendung verwendet wird, soll den Cache automatisch es abläuft. ASP.NET-Sitzungszustand ist ein guter Kandidat für Leerlauf Zeit ablaufen.
Absolute Zeit Ablaufdatum hilft Ihnen, Situationen zu vermeiden, in denen der Cache hat eine veraltete Kopie der Daten oder eine Kopie, die älter als die Masterkopie in der Datenbank ist. Leerlauf Zeit ablaufen soll den Cache bereinigen, nachdem die Anwendung bestimmte Daten nicht mehr benötigt. Anstatt die notwendige Bereinigung der Anwendung können Sie den Cache kümmern sich.

Räumungen
Die meisten verteilten Caches im Arbeitsspeicher sind und den Cache Datenträger nicht beibehalten. Dies bedeutet, dass in den meisten Fällen Speicher beschränkt und die Cachegröße kann nicht vergrößert werden, über einen bestimmten Grenzwert, der verfügbare Gesamtarbeitsspeicher werden konnte oder viel kleiner als, wenn Sie andere Anwendungen auf demselben Computer ausgeführt haben.
In beiden Fällen ein verteilter Cache sollten Sie an eine maximale Cachegröße (im Idealfall hinsichtlich der Größe des Speichers) zulassen. Wenn der Cache diese Größe erreicht, sollten Sie beginnen, Entfernen zwischengespeicherter Elemente um Platz für neue, einen Prozess in der Regel als Räumungen bezeichnet zu schaffen.
Räumungen werden basierend auf verschiedenen Algorithmen durchgeführt. Die beliebtesten ist mindestens recently used (LRU), in denen die zwischengespeicherten Elemente, die für die längste Zeit nicht berührt wurden haben entfernt werden. Einen anderen Algorithmus ist mindestens häufig verwendete (LFU). Hier berührt die Elemente, die am wenigsten Anzahl werden entfernt. Es sind ein paar andere Variationen, aber diese beiden sind die beliebtesten.

Zwischenspeichern von relationale Daten
Die meisten Daten stammen aus einer relationalen Datenbank, auch wenn nicht, ist relationalen Natur, d. h., dass verschiedene zu anderen zusammengehörige Daten sind jedoch – z. B. ein Customer-Objekt und ein Auftrag-Objekt.
Wenn Sie diese Beziehungen haben, müssen Sie diese in einem Cache zu verarbeiten. Dies bedeutet im Cache die Beziehung zwischen einem Kunden und eine Bestellung kennen sollten. Wenn Sie aktualisieren oder ein Kunden aus dem Cache entfernen, sollten Sie den Cache auch automatisch aktualisieren oder zugehörige Order-Objekte aus dem Cache entfernen. Dadurch wird die Datenintegrität in vielen Situationen zu erhalten.
Aber erneut, wenn ein Cache nachverfolgen diese Beziehungen nicht möglich, müssen Sie ihn, und dadurch Ihre Anwendung noch viel mehr mühsam und komplexe. Es ist viel einfacher, wenn Sie einfach der Cache auf die Daten immer hinzugefügt wird, ein Auftrag einem Debitor zugeordnet ist, und der Cache dann weiß, dass dieses Kunden aktualisiert oder entfernt, Orders auch haben aktualisiert oder aus dem Cache entfernt werden.
XML-Webdienste Cache verfügt über eine wirklich tolle Funktion, die CacheDependency, dem Sie Beziehungen zwischen anderen zwischengespeicherten Elementen der bezeichnet. Einige kommerzielle Caches verfügen außerdem über dieses Feature. Abbildung 2 zeigt ein Beispiel der Funktionsweise von XML-Webdienste Cache.
using System.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);

   Cache.Insert("key2", "Value 2", dep2);
}
Dies ist eine mehrschichtige Abhängigkeit, Bedeutung, dass A B und B abhängen kann kann auf c: abhängen Damit, wenn Ihre Anwendung C entfernt, A und B aus dem Cache sowie entfernt werden.

Synchronisieren ein im mit anderen Umgebungen
Ablaufzeiten und Cacheabhängigkeit Features soll Ihnen den Cache aktuell und korrekt helfen. Außerdem müssen Sie den Cache mit Datenquellen zu synchronisieren, auf die Sie und Ihren Cache zugreifen können nicht, so dass Änderungen in diesen Datenquellen im Cache neue beibehalten reflektiert werden.
Z. B. angenommen der Cache wird mit Microsoft .NET Framework geschrieben, jedoch Java oder C++-Anwendungen ändern von Daten in der master Datenquelle haben. Möchten Sie diese Anwendungen, um den Cache benachrichtigen, wenn bestimmte Daten in den master-Datenquellen ändert, sodass Ihren Cache ein entsprechendes zwischengespeichertes Element für ungültig erklären kann.
Im Idealfall sollte der Cache diese Funktion unterstützen. Wenn es nicht ist, fällt diese Last auf Ihre Anwendung. XML-Webdienste Cache bietet dieses Feature durch CacheDependency, wie einige kommerziellen Lösungen zwischenspeichernden. Sie können angeben, dass bestimmte zwischengespeicherte Element einer Datei abhängig und, bei jedem dieser Datei aktualisiert oder entfernt wird, der Cache dies erkennt und das zwischengespeicherte Element für ungültig erklärt. Die Element erzwingt die Anwendung der aktuellsten Kopie dieses Objekts die nächste Abrufen Ihrer Anwendung Zeit ungültig benötigt er und nicht im Cache gefunden.
Wenn Sie 100.000 Elemente im Cache hatten, 10.000 davon möglicherweise Dateiabhängigkeiten und, Sie müssen möglicherweise 10.000 Dateien in einem speziellen Ordner. Jede Datei verfügt über einen speziellen Namen, die das zwischengespeicherte Element zugeordnet. Wenn eine andere Anwendung – ob oder nicht in .NET geschrieben – ändert die Daten in der master Datenquelle, die Anwendung in den Cache über eine Aktualisierung des Zeitstempels Datei kommunizieren können.

Datenbank-Synchronisierung
Die Notwendigkeit der Datenbanksynchronisierung entsteht, weil die Datenbank in mehreren Anwendungen gemeinsam genutzt wird wird, und nicht alle diese Anwendungen Zugriff auf den Cache haben. Wenn Ihre Anwendung ist die einzige Anwendung Aktualisieren der Datenbank, und es kann auch einfach den Cache aktualisieren, müssen Sie nicht wahrscheinlich die Datenbank-Synchronisierung-Funktion. In einer realen Umgebung, ist jedoch nicht immer der Fall. Wenn die Daten der Datenbank eines Drittanbieters oder einer anderen Anwendung geändert wird, soll den Cache die Änderung widerzuspiegeln. Der Cache spiegelt Änderungen wider, durch das Neuladen der Daten oder auf mindestens, dass keine älteren Daten im Cache.
Wenn der Cache eine alte Kopie und der Datenbank eine neue Kopie verfügt, haben Sie jetzt ein Datenproblem Integrität, da Sie nicht wissen, welche Kopie geeignet ist. Natürlich, die Datenbank ist immer rechts, aber nicht immer rufen Sie die Datenbank. Sie erhalten Daten aus dem Cache, da Ihre Anwendung vertraut, dass der Cache immer richtig sein oder, dass der Cache für seine Anforderungen korrekt genug wird.
Synchronisieren mit der Datenbank kann bedeuten verknüpfte Element im Cache ungültig, so, dass das nächste Mal, das die Anwendung, benötigt, es es aus der Datenbank abgerufen wird. Eine interessante Variante zu diesem Prozess ist, wenn der Cache wird automatisch eine aktualisierte Kopie des Objekts, geladen wenn die Daten in der Datenbank geändert. Dies ist jedoch möglich, wenn Sie der Cache einen Read-through-Handler bereitstellen kann (Siehe nächsten Abschnitt) und dann zum Laden des zwischengespeicherten Element aus der Datenbank verwendet. Jedoch nur einige der professionellen Caches dieses Feature unterstützt, und führen Sie keine der frei.
XML-Webdienste Cache verfügt über ein SqlCacheDependency-Feature (siehe Abbildung 3), können Sie den Cache mit einer SQL Server 2005/2008, Oracle 10 g R2 oder höher Datenbankversion synchronisieren – im Grunde jede Datenbank, die die .NET CLR integriert verfügt. Einige der professionellen Caches bieten auch diese Funktion.
using System.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;

  Cache.Insert(key, cust, dep);
}
XML-Webdienste Cache SqlCacheDependency können Sie eine SQL-Zeichenfolge entsprechend eine oder mehrere Zeilen in einer Tabelle in der Datenbank angeben. Wenn diese Zeile ständig aktualisiert wird, löst das DBMS eine .NET-Ereignis, die der Cache abfängt. Anschließend wird das zwischengespeichertes Element bezieht sich auf diese Zeile in der Datenbank und das zwischengespeicherte Element für ungültig erklärt kennt.
Eine Funktion, die ASP.NET Cache nicht bietet, aber dass einigen kommerziellen Lösungen ist Polling-basierten Datenbank-Synchronisierung. Diese Funktion ist in zwei Situationen hilfreich. Zuerst, wenn DBMS keinen .NET CLR integriert, können nicht von SqlCacheDependency profitieren Sie. In diesem Fall wäre es schön Wenn der Cache konnte Ihrer Datenbank in konfigurierbaren Abständen Abfragen und Erkennen von Änderungen in bestimmten Zeilen einer Tabelle. Wenn diese Zeilen geändert haben, macht Ihren Cache Ihre entsprechende zwischengespeicherte Elemente ungültig.
Die zweite Situation ist, wenn Daten in Ihrer Datenbank häufig ändern ist und .NET Ereignisse zu interaktionsintensive immer werden. Dies geschieht, weil ein separates .NET-Ereignis ausgelöst wird für jede Änderung SqlCacheDependency und wenn Sie Tausende von Zeilen, die häufig aktualisiert werden haben, konnte dies problemlos Ihren Cache crowd. In solchen Fällen ist es wesentlich effizienter beruhen auf Abruf, wobei können mit einer Datenbankabfrage Sie abrufen Hunderte oder Tausende von Zeilen, die geändert wurden und anschließend entsprechende zwischengespeicherte Elemente ungültig. Natürlich Polling erstellt eine leichte Verzögerung bei der Synchronisierung (vielleicht 15–30 Sekunden), aber dies ist in vielen Fällen akzeptabel.

Read-Through
Kurz gesagt, Read-through ist eine Funktion, die den Cache Daten direkt aus der Datenquelle lesen ermöglicht unabhängig sein können. Sie schreiben einen Read-through-Handler und registrieren Sie es mit Ihren Cache und der Cache ruft dann diesen Handler entsprechenden Zeiten. Abbildung 4 zeigt ein Beispiel.
using System.Web.Caching;
using System.Data.SqlClient;
using Company.MyDistributedCache;

...

public class SqlReadThruProvider : IReadhThruProvider
{
  private SqlConnection _connection;

  // Called upon startup to initialize connection
  public void Start(IDictionary parameters)
  {
    _connection = new SqlConnection(parameters["connstring"]);
    _connection.Open();
  }

  // Called at the end to close connection
  public void Stop() { _connection.Close(); }

  // Responsible for loading object from external data source
  public object Load(string key, ref CacheDependency dep)
  {
    string sql = "SELECT * FROM Customers WHERE ";
    sql += "CustomerID = @ID";
    SqlCommand cmd = new SqlCommand(sql, _connection);
    cmd.Parameters.Add("@ID", System.Data.SqlDbType.VarChar);

    // Let's extract actual customerID from "key"
    int keyFormatLen = "Customers:CustomerID:".Length;
    string custId = key.Substring(keyFormatLen,
    key.Length - keyFormatLen);
    cmd.Parameters["@ID"].Value = custId;

    // fetch the row in the table
    SqlDataReader reader = cmd.ExecuteReader();

    // copy data from "reader" to "cust" object
    Customers cust = new Customers();
    FillCustomers(reader, cust);

    // specify a SqlCacheDependency for this object
    dep = new SqlCacheDependency(cmd);
    return cust;
  }
}
Da verteilter Cache normalerweise außerhalb der Anwendung befindet, über mehrere Instanzen der Anwendung oder sogar mehrere Anwendungen freigegeben. Eine wichtige Funktion eines Handlers Read-through ist, die Sie Zwischenspeichern, Daten vom Cache direkt aus der Datenbank abgerufen werden Daher müssen Ihre Anwendungen Datenbankcode verfügen. Sie können nur Daten aus dem Cache abrufen, und wenn es im Cache vorhanden ist, der Cache wechselt und dauert aus der Datenbank.
Sie erhalten sogar noch wichtiger Vorteile, wenn Sie mit Ablaufzeiten Read-through Funktionen kombinieren. Wenn ein Element im Cache abläuft, geladen Cache automatisch durch Aufrufen des Read-through-Handlers. Mit diesem Mechanismus, speichern Sie einen starken Datenverkehr in der Datenbank. Der Cache verwendet nur ein Thread, eine Datenbank Reise, Daten aus der Datenbank neu laden, während Sie Tausende von Benutzern dieselben Daten zugreifen möchte möglicherweise. Wenn Sie nicht Read-through-Funktion, würden diese Benutzer direkt an die Datenbank wird inundating der Datenbank mit Tausenden von parallelen Anforderungen werden.
Read-Through können Sie eine auf Unternehmensebene Datenraster, d. h. einen Datenspeicher, der nicht nur hoch skalierbar, sondern selbst auch von master-Datenquellen aktualisieren kann herstellen. Dies ermöglicht Ihrer Anwendungen mit einer alternativen Datenquelle aus dem Daten gelesen und nimmt sehr viel Druck auf Ihre Datenbanken.
Wie bereits erwähnt, Datenbanken sind immer den Engpass in High-Transaktion-Umgebungen, und Sie Engpässe aufgrund hauptsächlich zu übermäßigen lesen Operationen, deren Schreibvorgänge auch verlangsamt werden. Auftreten eines Caches, die fungiert als ein Datenblatt auf Enterprise-Ebene über Ihre Datenbank Ihre Anwendungen eine größere Leistung und Skalierbarkeit Boost bietet.
Allerdings beachten, dass Read-through ist kein Ersatz für die Durchführung einige komplexen verknüpften Abfragen in der Datenbank. Ein typischer Cache lässt keine Sie diese Arten von Abfragen. Eine Funktion Read-through funktioniert gut für einzelne-Objekt Lesevorgänge jedoch nicht in Operationen mit komplexe verknüpfte Abfragen, die Sie immer in der Datenbank ausführen müssen.

Durch Schreiben, hinter schreiben
Write-through ist wie Read-through: Sie einen Ereignishandler bereitstellen und der Cache Ruft den Handler die Daten in der Datenbank, schreibt Wenn Sie den Cache aktualisieren. Ein großer Vorteil ist, dass Ihre Anwendung nicht direkt in der Datenbank zu schreiben, da der Cache für Sie durchführt. Dies vereinfacht den Anwendungscode, weil der Cache anstelle der Anwendung der Datenzugriffscode aufweist.
Normalerweise stellt Ihre Anwendung ein Update für den Cache (z. B. hinzufügen, einfügen oder entfernen). Der Cache aktualisiert sich selbst zuerst und gibt dann einen Update-Aufruf an die Datenbank über den Write-through-Handler. Die Anwendung wartet, bis der Cache und der Datenbank aktualisiert werden.
Möchten was geschieht, wenn Sie warten, bis der Cache aktualisiert werden, aber Sie nicht warten für die Datenbank aktualisiert werden, da, die Leistung Ihrer Anwendung verlangsamt? Das ist Write-Behind in Stelle kommt, die den gleichen Write-through-Handler verwendet jedoch synchron den Cache aktualisiert und der Datenbank asynchron. Dies bedeutet, dass die Anwendung wartet, bis des Caches aktualisiert werden, aber Sie nicht warten, bis die Datenbank aktualisiert werden.
Sie wissen, dass der Datenbankaktualisierung einrichten Warteschlange und, dass die Datenbank ziemlich schnell vom Cache aktualisiert wird. Dies ist eine andere Möglichkeit zur Leistungssteigerung Ihrer Anwendung. Müssen Sie trotzdem auf die Datenbank schreiben, aber warum warten? Der Cache die Daten enthält, beeinträchtigt nicht Sie selbst, wenn die Folgen von anderen Instanzen der Anwendung die Daten nicht an die Datenbank zu finden, weil Sie nur den Cache aktualisiert und die anderen Instanzen der Anwendung die Daten im Cache findet und müssen nicht zu der Datenbank zu wechseln.

Cache-Abfragen
Normalerweise sucht die Anwendung Objekte im Caches basierend auf einen Schlüssel, wie eine Hashtabelle, wie Sie in den Codebeispielen Quelle oben gesehen haben. Sie haben den Schlüssel und der Wert ist das Objekt. Jedoch manchmal müssen Sie nach Objekten basierend auf Attributen außer den Schlüssel zu suchen. Daher muss der Cache der Möglichkeit für Sie zur Suche oder Abfrage im Cache bereitstellen.
Es gibt einige Möglichkeiten, die Sie dies tun können. Eine ist auf die Attribute des Objekts suchen. Der andere umfasst die Situationen, in der zwischengespeicherten Objekte beliebige Tags zugewiesen haben und durchsuchen möchten basierend auf der Tags. Attribut basierende Suche steht derzeit nur in einigen kommerziellen Lösungen über Objekt Abfragesprachen, Tags basierte Suche steht jedoch in kommerziellen Caches und Microsoft-Geschwindigkeit.
Angenommen, Sie ein Customer-Objekt gespeichert haben. Konnte sagen Sie "mir alle Debitoren geben, wobei Berlin, ist der Ort"Wenn Sie nur Kundenobjekte möchten, obwohl Ihr Cache Mitarbeiter, Kunden, Bestellungen, Bestellartikel und mehr verfügt. Wenn Sie eine SQL-ähnliche Abfrage wie in Abbildung 5, ermittelt der Objekte, die Ihren Kriterien entsprechen.
using Company.MyDistributedCache;

...

public List<Customers> FindCustomersByCity(Cache cache, string city)
{
  // Search cache with a LINQ query
  List<Customers> custs = from cust in cache.Customers
                          where cust.City == city
                          select cust;
  return custs;
}
Tags können Sie mehrere beliebige Tags eines bestimmten Objekts anfügen und das gleiche Tag kann mehrere Objekte zugeordnet werden. Tags sind in der Regel zeichenfolgenbasierte und tagging auch können Sie Objekte in Gruppen kategorisieren und suchen Sie dann die Objekte später über diese Tags oder Gruppen.

Ereignis-Verteilung
Möglicherweise nicht immer müssen Ereignis Weitergabe im Cache, aber es ist ein wichtiges Feature, dem Sie kennen sollten. Es ist ein gutes Feature verfügen, wenn Sie Anwendungen, HPC-Anwendungen oder mehrere Anwendungen, die Freigabe von Daten über einen Cache verteilt haben. Welche Ereignis Verteilung wird Fragen Cache zum Auslösen von Ereignissen, wenn bestimmte Vorgänge in den Cache auftreten. Anwendungen können diese Ereignisse erfasst und entsprechenden Aktionen als Reaktion.
Genommen Sie an, Ihre Anwendung hat ein Objekt aus dem Cache abgerufen und ist es dem Benutzer anzeigt. Möglicherweise möchten wissen, wenn jemand aktualisiert oder dieses Objekt aus dem Cache entfernt, während er angezeigt wird. In diesem Fall die Anwendung benachrichtigt, und Sie können die Benutzeroberfläche aktualisieren.
Dies natürlich ist ein sehr einfaches Beispiel ist. In anderen Fällen müssen Sie möglicherweise eine verteilte Anwendung, wobei einige Instanzen der Anwendung werden Daten erzeugt und anderen Instanzen verwenden müssen. Die Producer können die Consumer darüber informieren, wenn Daten können durch Auslösen eines Ereignisses durch den Cache, den die Consumer empfangen. Es gibt viele Beispiele für dieses Typs, wobei Zusammenarbeit oder Daten, die Freigabe durch den Cache über Ereignis Verteilung erreicht werden kann.

Cacheleistung und Skalierbarkeit
Bei der Überlegung der Zwischenspeicherung in den vorherigen Abschnitten beschriebenen Features müssen Sie nicht vergessen, dass die Hauptassembly Du Thinking Gründe verwenden einen verteilten Cache, die Leistung zu verbessern und, wichtiger die Skalierbarkeit der Anwendung zu verbessern. Auch, da der Cache in einer Produktionsumgebung als Server ausgeführt wird, muss Sie auch hohen Verfügbarkeit bereitstellen.
Skalierbarkeit ist das grundlegende Problem, das verteilter Cache Adressen. Ein skalierbarer Cache ist eine Leistung verwalten können, selbst wenn Sie die Transaktion-Auslastung erhöhen. Wenn Sie also eine XML-Webdienste Anwendung in einer Webfarm und Sie Ihre Webfarm von fünf Webservern zu 15 oder sogar 50 Webservern vergrößert, sollten können Sie proportional vergrößern die Anzahl der Cache-Server und die gleichen Antwortzeit beibehalten. Dies wird mit einer Datenbank nicht möglich.
Ein verteilter Cache vermeidet die Skalierbarkeitsprobleme, die eine Datenbank in der Regel, ausgesetzt da es viel einfacher Natur als ein DBMS und da verschiedenen Speichermechanismen (auch bekannt als Zwischenspeicherung Topologien) als ein DBMS verwendet. Dazu gehören repliziert, partitioniert, und Client-Cache-Topologien.
In den meisten verteilten Cache Situationen haben Sie zwei oder mehr Cache-Server als Host für den Cache. Den Begriff "Cache-Cluster" wird verwendet werden.Formular ein logischer Cache angehören zusammen, um zwei oder mehr Cache Server anzugeben. Ein replizierter Cache kopiert den gesamten Cache auf jedem Cacheserver im Cache-Cluster. Dies bedeutet, dass replizierter Cache hohen Verfügbarkeit bietet. Alle einem Cacheserver ausfällt, unterbrochen nicht Sie alle Daten im Cache, weil eine Kopie der Anwendung sofort zur Verfügung steht. Es ist auch eine Topologie sehr effizient und bietet gute Skalierbarkeit, wenn Ihre Anwendung dazu viel lesen-Intensive Vorgänge. Wenn Sie weitere Cache-Server hinzufügen, fügen Sie die Cache-Cluster, viel lesen Transaktion Kapazität hinzu. Ein replizierter Cache ist jedoch nicht die ideale Topologie für Schreibintensive Operationen. Wenn Sie den Cache so häufig aktualisieren wie Sie es lesen, verwenden Sie die replizierte Topologie an.
Ein partitionierter Cache Cache in Partitionen unterteilt und speichert eine Partition auf jedem Server Cache in den Cluster. Diese Topologie ist die skalierbare zum Zwischenspeichern von Transaktionsdaten (Wenn Schreibvorgänge im Cache als häufig als Lesevorgänge werden). Wenn Sie weitere Cache-Server zum Cluster hinzufügen, erhöhen Sie nicht nur die Kapazität der Transaktion, sondern auch die Speicherkapazität der Cache, da diese Partitionen zusammen den gesamten Cache bilden.
Viele verteilte Caches bieten eine Variante des ein partitionierter Cache für hohe Verfügbarkeit, wobei jede Partition auch repliziert wird, so dass der Server einen Cache eine Partition und eine Kopie oder eine Sicherung von einem anderen Server-Partition enthält. Auf diese Weise nicht Sie alle Daten verlieren, wenn alle ein Server ausfällt. Einige zwischenspeichernden Lösungen können Sie mehr als eine Kopie jeder Partition hinzugefügten Zuverlässigkeit zu erstellen.
Ein weiteres sehr leistungsfähige Zwischenspeichern Topologie ist Clientcache (auch aufgerufen, in der Nähe Cache), das ist sehr nützlich, wenn der Cache in einer remote dedizierten Zwischenspeichern Ebene befindet. Die Idee hinter einem Clientcache ist, dass jeder Client ein Workingset des Caches Schließen durch (auch innerhalb der Anwendungsprozess) auf dem Clientcomputer hält. Jedoch nur da verteilter Cache mit der Datenbank mit anderen Mitteln (wie erwähnt früher) synchronisiert werden, muss ein Clientcache mit verteilten Cache synchronisiert werden. Einigen kommerziellen zwischenspeichernden Lösungen bieten diese Synchronisierungsmechanismus, aber die meisten bieten nur einen eigenständigen Clientcache ohne Synchronisierung.
Auf dieselbe Weise, dass ein verteilter Cache Datenverkehr in der Datenbank verringert wird verringert ein Clientcache Netzwerkverkehr zum verteilten Cache. Es ist nicht nur schneller als der verteilte Cache da er an die Anwendung näher (und InProc kann auch sein), verbessert die Skalierbarkeit des verteilten Cache auch durch Verringern der Schleifen zum verteilten Cache. Natürlich ist einem Clientcache ein guter Ansatz nur, wenn Sie viele mehr Lese-als Schreibvorgängen durchführen. Wenn die Anzahl der Lese- und Schreibvorgänge gleich sind, verwenden Sie keinen Clientcache. Schreibvorgänge werden langsamer, da Sie jetzt dem Clientcache und dem verteilte Cache aktualisieren.

Hohe Verfügbarkeit
Da verteilter Cache ausgeführt, wird wie ein Server in Ihrer Produktionsumgebung und in vielen Fällen als Datenspeicher für Ihre Anwendung nur dient (z. B. XML-Webdienste Sitzungszustand), der Cache muss hohen Verfügbarkeit bereitstellen. Dies bedeutet, dass der Cache sehr stabil sein muss, so dass es nie stürzt ab und die Möglichkeit Konfigurationsänderungen bietet ohne Beenden des Caches.
Die meisten Benutzer eines verteilten Caches benötigen den Cache ohne alle Unterbrechungen für Monate gleichzeitig ausgeführt werden. Wenn Sie den Cache zu beenden haben, ist es normalerweise während einer geplanten unten Zeit. Deshalb hoher Verfügbarkeit für eine verteilte Cache so wichtig ist. Hier finden Sie einige Fragen im Auge behalten beim Auswerten, ob eine Zwischenspeicherung Lösung hohen Verfügbarkeit bietet.
  • Können Sie einen der Server Cache Ausfall ohne Beenden des gesamten Caches?
  • Können Sie einen neuen Cacheserver ohne Anhalten des Caches hinzufügen?
  • Können Sie neue Clients ohne Unterbrechung des Caches hinzufügen?
In den meisten Caches verwenden Sie angegebene maximale Cachegröße, so dass der Cache die Menge der Daten nicht überschritten wird. Basiert die Größe des Caches für wie viel Speicher Sie verfügbaren auf dem System verfügen. Können Sie die Kapazität ändern? Angenommen, Sie anfänglich die Cachegröße auf 1 GB festgelegt aber jetzt machen von 2 GB. Können Sie das? ohne Beenden des Caches
Diese sind die Typen von Fragen zu berücksichtigen. Wie viele diese Konfigurationsänderungen erfordern wirklich Cache neu gestartet werden? Weniger, desto besser. Andere als die Zwischenspeicherung Features ist die ersten Kriterien für einen Cache, der in einer Produktionsumgebung ausgeführt werden müssen wie viel der Cache soll Ihnen Betriebszeit.

Leistung
Wenn nicht den Zugriff auf den Cache schneller Zugriff auf Ihre Datenbank ist, besteht keine Notwendigkeit, damit einfach put. Müssen andererseits, sollten hinsichtlich der Leistung von eine gute verteilte Cache Erwartungen?
Als Erstes zu merken ist ein verteilter Cache normalerweise OutProc oder Remote, damit Zugriffszeit noch nie so schnell wie von einer eigenständigen InProc-Cache (z. B. ASP.NET Cache). In einem eigenständigen InProc-Cache können Sie wahrscheinlich 150.000 zu 200.000 Elemente pro Sekunde (1 KB Objektgröße) lesen. Mit einer OutProc oder einen remote-Cache löscht dieser Zahl erheblich. Hinsichtlich der Leistung sollten Sie über 20.000 zu 30.000 Lesevorgänge pro Sekunde (1 KB Objektgröße) als den Durchsatz eines einzelnen Cache-Servers (von allen Clients auf davon) erwarten. Sie können einige dieser InProc-Leistung erzielen, indem mit einem Clientcache (im InProc-Modus), aber das ist nur für Lesevorgänge und nicht für Schreiboperationen. Sie einige Leistung opfern, um Skalierbarkeit zu erhalten, aber langsamere Leistung ist immer noch viel schneller als Datenbankzugriff.

Verschafft Häufigkeit
Ein verteilter Cache als ein Konzept und als bewährte Methode ist Weitere beliebter. Vor, nur ein paar Jahren wusste sehr wenige Personen in der .NET Speicherplatz darüber, obwohl die Java-Gemeinde vor von .NET in diesem Bereich wurde. Mit dem Zündkapsel Wachstum Transaktionen der Anwendung Datenbanken sind Ihre Grenzen Produktionsbelastung und verteilte Zwischenspeicherung wird jetzt ein notwendiger Bestandteil jeder skalierbare Anwendungsarchitektur akzeptiert.

Iqbal Khan ist Präsident und Technologie Evangelist Alachisoft. Alachisoft bietet NCache, eine branchenführende .NET Cache für die Steigerung von Leistung und Skalierbarkeit in Unternehmensanwendungen verteilt. Iqbal hat eine MS in Informatik von Indiana University Bloomington. Sie erreichen ihn unter iqbal@alachisoft.com.

Page view tracker