Rob Howard
Telligent Systems, Inc.
The title is colloquial, but it has aroused your interest, right? ASP. NET cache is one of my favorite ASP. NET features so far. Why? This is because some strange performance and scalability results can be obtained by using the cache, which can be easily measured and converted to the application.ProgramActually saved funds. This will make you the CTO's favoriteCodeMonkey, because you have an impact on the ROI of critical applications ). In other words, the cache actually saves money!
At a higher level, in ASP. NET 1.1, cache is used as the least recently used (LRU) support)AlgorithmThe concept hash table is implemented to ensure that items can be deleted from the cache if memory is needed (a group of programming interfaces used to insert and remove items in the cache ), finally, the concept of dependencies, supporting time, files, and key dependencies are implemented.
The dependency model is one of the more important functions of caching, because it allows the following statement:
• |
At this moment, the item in the cache is no longer valid (time-based dependency ). |
• |
If this cache entry is changed, another cache entry is invalid (key-based dependency ). |
• |
If the file is changed, the item in the cache is no longer valid (based on the file dependency ). |
When programming with cache, you should always check whether this item exists before using it. Therefore, it is a good method to follow the following pattern when using the cache:
'#1-get a reference to the objectdim mycachedarraylist as arraylist = cache ("myarraylist")' #2-check if the reference is nullif (mycachedarraylist) is nothing then 'Add items to array list mycachedarraylist = populatemyarraylist () 'cache. insert ("myarraylist", mycachedarraylist) end if '#3-return the datareturn mycachedarraylist
Looks good, isn't it? We have a flexible model for storing data in memory that is not efficient under certain conditions. This model has several shortcomings that ASP. NET developers often need to solve. One drawback is that the database cache is invalid, which means that this item is removed from the cache when some data in the database is changed. The second disadvantage is that you can create your own cache dependencies.
The good news is that in ASP. NET 2.0 (previously codenamed "Whidbey"), both defects are fixed. There are now two database cache dependency models-one for Microsoft SQL Server 7 and 2000, and the other for SQL Server 2005 (the previous Code was "Yukon "). The second major change is:CachedependencyClass is not sealed and is recondensed so that you can write your own dependency rules for the cache.
The bad message is that ASP. NET 2.0 cannot be used for production. However, at present, we can use ASP. NET 1.1 to generate a similar database cache invalidation system. In fact, when I was still in ASP. net Team, I used this technology to prototype the database cache invalidation mechanism for Microsoft SQL Server 7 and SQL Server 2000.
The two database cache invalidation options provided in ASP. NET 2.0 are extremely different. The options for SQL Server 2000 or SQL Server 7.0 are restricted to a function called "table-level notification. Only notifications of operations performed on SQL tables are triggered. For example, update, insert, and delete operations on a table. However, in SQL Server 2005, you can receive notifications of changes to results that are invalid at the dynamic SQL, stored procedures, views, and simple tables levels.
Unfortunately, Asp. NET 1.1 copies the database cache dependency model used by SQL Server 2005, because the database has built-in new features to support notifications that are unavailable in earlier versions of SQL Server.
Invalid database cache: What you need to know
Currently, there are a variety of technologies used to achieve database cache efficiency. The first technology I provided was about four years ago. It used the Extended Stored Procedure technology to notify ASP. NET of data changes in the database. This prototype is the first exploration by the ASP. NET team on how to implement invalid database cache. If you want to read more details about this technology, readArticle.
Another technology that many people have used is to allow SQL Server to access external files (File dependencies) when data changes in the database and the cache needs to be invalid ).
These technologies are doing very well, and they give birth to many excellent articles and are very suitable for small applications. However, if you want to generate complex large applications, we strongly recommend that you avoid using these technologies. For example, we will not use these technologies to develop our own applications, such as forums running at www.asp.net/forums, or the next version called Community Server (www.communityserver.org) We want to generate ).
Next we will briefly discuss why these existing technologies are flawed-starting with the extended stored procedure model.
Extended Stored Procedure http push model
The extended stored procedure PUSH model uses the following Architecture:
• |
A custom class used to add items to the cache and make the item dependent on a database notification. |
• |
An httphandler that can receive notifications and make the items in the cache invalid. |
• |
Triggers on tables in the database that are monitored for changes. |
• |
A table in the database is used to track tables monitored for changes and applications that require notification when data changes occur. |
• |
An extended stored procedure is used to call the httphandler of an application to notify it of changes. |
When a change is detected, a change notification stored procedure is called no matter which logic is required in the stored procedure or trigger. This change notification process retrieves the list of web applications to which you want to notify changes, and then calls an extended stored procedure for each application to make HTTP calls to the Web application, to instruct it to remove a specific cache entry and push the changes to the application. Web applications only receive an HTTP request containing the cache key to be removed. Internally, this application is called only with the sent cache keyCache. Remove ().
That sounds good, doesn't it? Yes, and it actually works well. But below are some disadvantages:
• |
The extended stored procedure performs HTTP callback on servers that require invalid caching. Stored procedures are executed as part of the "Atomic" operation to change data in the database. It is called from the trigger when the table is modified. Unlike other protocols, HTTP is notIgnore after sending; On the contrary, any given request is expected to respond. Therefore, the extended stored procedure cannot be completed before the HTTP call is completed. If the Web server is located in a slow network or takes a long time to respond, this delay will impede the completion of database operations. This obstruction further causes SQL Server to serialize other updates/delete/insert statements, or worse, it may impede thread completion. Now, multiply this factor by the number of servers in the server farm and the total number of database operations. |
• |
If the Web ServerNetwork garden Mode(Multiple processes will be created to simulate virtual web servers), there is no way to instruct how to allocate a given request to a specific process. In other words, when running in network garden mode, the server will run many virtual web servers for the application. When the Extended Stored Procedure calls back to the server to notify it that the change has occurred, it cannot ensure that all virtual web servers are notified. Finally, you may have updated only one application, but not the other applications. |
If you are running a small server environment, do not run the web server in network garden mode, and SQL server should not be a race resource in the system. The http push model of the extended storage process works well. However, if an application suddenly grows, the database may be blocked or the cache may not always synchronize.
File update Model
The second technique (which is undoubtedly simpler than the other technique) updates files during data changes rather than attempting to use HTTP callback to the application. ASP. NET application developers use standard cache files to change dependencies to monitor file changes. When files are changed, cached items are removed.
This technology does not have any network Park problems related to the extended storage process pushing model, but it has many same blocking problems related to the extended storage process technology. In addition, it introduces its own features:
• |
When using this technology, file contention becomes a problem, because when the "change" file is not locked by another operation, SQL Server can only update this file. Therefore, all changes in the database to be notified must be coordinated to lock the file, change some values, and then unlock the file. In other words, the database can serialize the work for this file. The problem is still the possible serialization and blocking problems on SQL Server. |
• |
When using this technology, file change notifications also become a problem, because to use the change file in the Web field, you must share it, and grant the correct security permissions to various web servers so that they can view the sharing and monitor file changes. |
The file update model is applicable to small server environments and network parks. It is also suitable for SQL Server instances that do not compete for resources. In fact, it may be a better option because it is much simpler than the Extended Stored Procedure solution. However, in a large server environment or database environment where the system selects resources, the model crashes.
As you can see, both technologies are applicable, but you need to make good decisions based on whether these technologies can be used based on the server size and load. Each time you introduce known blocking operations into an application, potential scalability and performance bottlenecks are added.
Invalid database cache: ASP. NET 2.0 Style
The original goal of the Extended Stored Procedure cache invalidation model is to start some early prototype chemical work on database cache invalidation issues. The ASP. NET team knows that this feature is a problem they want to solve in version 2.0, but they need to better understand how to generate this feature in a scalable manner.
In fact, as a company, Microsoft knows how important this is, and in ASP.. net, IIS, SQL Server, and ADO. net, ISA Server, and other teams have established a new team calledThe Caching Taskforce.
NoteMy blog post on the Bill Gates conference is designed to help him understand what we have done in the ASP. NET/Yukon implementation. You can read this article in http://weblogs.asp.net/rhoward/archive/2003/04/28/6128.aspx.
The result of this cache Working Group is two new database cache ineffective architectures. The first one is designed in the system, and is only part of ASP. NET, ADO. net, and SQL Server 2005. It generates a scalable model for pushing notifications at the ultra-granularity level. For example, please notify me when the specific results of a specific stored procedure are changed. Invalid cache SQL Server 2005 implementations cannot be mirrored or implemented in. NET Framework Version 1.1. We will discuss how the system works in future articles. The purpose of the second technology is to support invalid database cache for SQL Server 7.0 and SQL Server 2000. Obviously, nothing can be added to the database, so we must work within the limits of today's technology. The good news is that ASP. NET 1.1 supports the same technology as SQL Server 7.0 and SQL Server 2000.
Haven't we arrived yet?
We have seen it on TV. If you have children, I am afraid you have already experienced it. When the children are sitting in a car and traveling to a long time place, the system keeps asking if the destination has been reached. At this time, they are constantly polling until they receive the desired response.
Similarly, the database cache invalidation Technology for SQL Server 7.0 and SQL Server 2000 polls the database to check for any changes. Here, the unconscious response is usually negative-isn't polling a bad thing? However, once you learn more about what is happening, the simplicity and scalability of the design will be immediately presented to you.
For any database cache invalidation system, two major problems must be overcome:
• |
Prevent database congestion:It is critical that the database be as fast and efficient as possible, so blocking and serialization must be avoided during data changes. Fundamentally, the purpose of a database is to effectively manage access to data and allow such access. |
• |
Ensure cache consistency:If a solution can only ensure that the notification is sent to a single virtual server on the Web server running in network garden mode, this solution is useless. All applications must be notified of data changes. |
The premise for generating the round-robin model is that the cost of round-robin database is much lower than the cost of re-executing the original query. In addition, polling should not occur on the request thread, but be performed as a background operation.
Here, a good solution is the Community Server. The Community Server is a complex application that uses many standardized tables to combine relevant data to meet requests. A common task is to retrieve a paged dataset through a stored procedure to display the paging view of threads in a specific forum. The stored procedure meeting the paging thread view request executes a series of selection statements for joining from 3 to 5 tables, creates a temporary table, selects from the temporary table, and then executes another join. In other words, it is an operation to convert data that must meet a request.
Using the database cache invalidation model used in ASP. NET 2.0 (We will implement this model later), we created a change notification table in the database. Originally requested data is cached at the application level, where data can be quickly retrieved, and the application layer polls the database every several seconds to determine whether the data has changed. Different from the original request, polling will access a single table whose row depth is not greater than the number of tables in the database. The polling operation Retrieves all records from the change notification table. It is very likely that the table is so small that all results can be paged into the memory of the SQL statement and accessed quickly.
Then, the results of the Change Notification table will be analyzed within the application layer. The result set is a list of IDS changed for each table in the database. If the change id value is different from the change ID of the current cache, the related cache entries will be invalid, use the full search operation for the next request (because the data is not in the cache), and refill the cache, then the process is restarted. Figure 1 shows how the Architecture Works.
Figure1.Architecture Diagram
One of the most important aspects of this Round Robin mechanism is that round robin occurs in different background threads than the thread that executes the request. Therefore, if results can be provided from the cache, the database will never be accessed during the request. However, once the changes are detected, the entries are removed from the cache, And the next request is executed normally and the cache is refilled, and the system is restarted, as shown in figure 2.
Figure2.Modified architecture Diagram
To complete polling in the background thread, we will use a class that I like most but little-known in. NET Framework-Timer.TimerClass locatedSystem. threadingNamespace. PassTimerYou can do this by creating an event that is periodically triggered at a specified time interval programmatically. WhenTimerWhen it is awakened, it captures a thread from the thread pool of the current application domain and raises an event. Our code runs regularly within the event to verify changes in the database or missing changes.
Background Service
We use the same technology in the Community server to send an email or compile a posting index based on the preset interval (instead of for each request. This saves us a lot of time in adding a new POST request, because previously, we performed the above operations each time we added a new post.
In Community Server, we useTimerAs a static instance in httpmodule. When an ASP. NET application is initialized, the static timer is instantiated and the internal cycle of polling is determined. When a polling event is triggered, we perform the following operations:
• |
Execute necessary SQL statements to receive a series of change IDs from the database. |
• |
Compare the change ID in the database with the value stored in the ASP. NET cache. Unmatched values in the cache are updated, which forcibly removes the dependency from the cache. |
From the blackbelt slides and demos of my Microsoft tech ed 2004 Presentation (which is located in the http://www.rob-howard.net), you can download a full sample of database cache invalidation.
This sample code snippet is applicable to the northwind sample database that is included with SQL Server. Before using it, you also need to make some changes to the database.
First, you need to addChangenotificationTable:
Create Table [DBO]. [changenotification] ([Table] [nvarchar] (256) Collate SQL _latin1_general_cp1_ci_as not null, [changeid] [int] not null)
Second, you needProductsAdd a trigger to the table:
Create trigger [changenotificationtrigger] on [DBO]. [products] For insert, update, delete asupdate changenotificationset changeid = changeid + 1 where [Table] = 'products'
Every timeProductsWhen a table is modified, the trigger is applied to update the table.ChangenotificationThe rows in the table.
Although this is an extremely simple example, if you want to implement the above functions for your application, this example can provide a good starting point. Some unaddressed shortcomings in this example include:
• |
Table-level changes only:It is not very difficult to modify the view or even the row level. |
• |
Row lock:The update logic needs to be added to take into accountProductsLarge table modifications. For example, if you update 100 productsChangenotificationMake 100 changes to the table. Similar to the version included in ASP. NET 2.0, you may want to add some logic to better handle large updates. |
Summary
The ASP. NET cache system is a function that all ASP. NET developers should strive to use. Please plan to use the cache as soon as possible, and understand what aspects of the application can greatly help you use the cache best. Several ASP. NET 1.1 restrictions (for example, invalid database cache) can be overcome by using the same technology as ASP. NET 2.0. In this articleTimerThe usage of the class illustrates a possible way to achieve this goal, and despite multiple other options, we recommend that you use this round robin technology. I think you will also find that,TimerClass is also useful for solving other problems.