在 ASP.net 中可以使用静态变量来缓存信息吗?
目前我正在 ASP.net 上使用 C# 3.5 开发项目管理应用程序。 为了减少对数据库的点击,我使用静态变量缓存大量信息。 例如,用户列表保存在内存中的静态类中。 该类在启动时从数据库中读取所有信息,并在发生更改时更新数据库,但它永远不需要从数据库中读取。
该类在写入数据库的同时使用更新的信息对其他 Web 服务器(如果存在)执行 ping 操作。 ping 机制是一种 Windows 服务,缓存对象使用随机可用端口注册到该服务。 它也用于其他事情。
数据量并不是那么大。 目前,我只是使用它来缓存用户(密码哈希、权限、姓名、电子邮件等),它只是保存对数据库进行的一堆调用。
我想知道这种方法是否有任何陷阱和/或是否有更好的方法来缓存数据?
At the moment I am working on a project admin application in C# 3.5 on ASP.net. In order to reduce hits to the database, I'm caching a lot of information using static variables. For example, a list of users is kept in memory in a static class. The class reads in all the information from the database on startup, and will update the database whenever changes are made, but it never needs to read from the datebase.
The class pings other webservers (if they exist) with updated information at the same time as a write to the database. The pinging mechanism is a Windows service to which the cache object registers using a random available port. It is used for other things as well.
The amount of data isn't all that great. At the moment I'm using it just to cache the users (password hashes, permissions, name, email etc.) It just saves a pile of calls being made to the database.
I was wondering if there are any pitfalls to this method and/or if there are better ways to cache the data?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
陷阱:静态字段的作用域是每个应用程序域,增加的负载将使服务器在池中生成更多应用程序域。 如果您只从静态中读取,这不一定是问题,但您会在内存中获得重复的数据,并且每次创建或回收应用程序域时都会受到打击。
最好使用 Cache 对象 - 它是用于类似这样的事情。
编辑:事实证明我对 AppDomains 的看法是错误的(正如评论中指出的那样) - 更多的应用程序实例将在负载下生成,但它们都将在同一个 AppDomain 中运行。 (但是您仍然应该使用 Cache 对象!)
A pitfall: A static field is scoped per app domain, and increased load will make the server generate more app domains in the pool. This is not necessarily a problem if you only read from the statics, but you will get duplicate data in memory, and you will get a hit every time an app domain is created or recycled.
Better to use the Cache object - it's intended for things like this.
Edit: Turns out I was wrong about AppDomains (as pointed out in comments) - more instances of the Application will be generated under load, but they will all run in the same AppDomain. (But you should still use the Cache object!)
只要您可以预期缓存永远不会增长到大于可用内存量的大小,就可以了。 另外,请确保每个数据库只有一个该应用程序的实例,否则应用程序不同实例中的缓存可能会“不同步”。
在我工作的地方,我们有一个自行开发的 O/RM,我们所做的事情类似于您对某些表所做的事情,这些表预计不会增长或改变太多。 所以,你所做的并不是史无前例的,而且事实上在我们的系统中,是经过尝试且真实的。
As long as you can expect that the cache will never grow to a size greater than the amount of available memory, it's fine. Also, be sure that there will only be one instance of this application per database, or the caches in the different instances of the app could "fall out of sync."
Where I work, we have a homegrown O/RM, and we do something similar to what you're doing with certain tables which are not expected to grow or change much. So, what you're doing is not unprecedented, and in fact in our system, is tried and true.
您必须考虑的另一个陷阱是线程安全。 您的所有应用程序请求都在同一个 AppDomain 中运行,但可能来自不同的线程。 访问静态变量必须考虑到它是从多个线程访问的。 可能比您期望的开销要多一些。 缓存对象更适合此目的。
Another Pitfall you must consider is thread safety. All of your application requests are running in the same AppDomain but may come on different threads. Accessing a static variable must account for it being accessed from multiple threads. Probably a bit more overhead than you are looking for. Cache object is better for this purpose.
嗯...“经典”方法是应用程序缓存,但如果您从不更新静态变量,或者如果您这样做的话,则了解锁定问题,并且您了解它们可以在应用程序域重新启动后随时消失,那么我不会我真的没有看到使用静电的危害。
Hmmm... The "classic" method would be the application cache, but provided you never update the static variables, or understand the locking issues if you do, and you understand that they can disappear at anytime with an appdomain restart then I don't really see the harm in using a static.
我建议您研究为您的应用程序提供分布式缓存的方法。 您可以查看NCache 或indeXus.Net
我建议这样做的原因是因为您采用了自己的临时方式来更新正在缓存的信息。 静态变量/引用很好,但它们不会更新/刷新(因此您必须自己处理老化)并且您似乎有一个分布式设置。
I suggest you look into ways of having a distributed cache for your app. You can take a look at NCache or indeXus.Net
The reason I suggested that is because you rolled your own ad-hoc way of updating information that you're caching. Static variables/references are fine but they don't update/refresh (so you'll have to handle aging on your own) and you seem to have a distributed setup.