My question is about the fast storage into RAM. Actually my project is a big symfony2 app, and I use a lot session storage (Symfony\Component\HttpFoundation\Session\Session). I'd like to try something else because I'm not totally happy with symfony2 session since it stores only simple types in it, objects are not allowed. I did a search and redis seems to be the perfect choice BUT someone suggested memcache.
Could memcached be better than redis? Is redis worth a try (despite the learning time we've to spend on it)?
Related
We have MVC 4 application which communicates with backend D365 entities.
The application makes a lot of CRM calls to get the data hence it was really slow and the user experience was very poor
To improve its performance, cache layer has been added and whenever application gets a data from CRM, it puts it into Session variable.
Surely, that helped with the performance as within the user's session , it prevents the trip to server and everything is served from session data. However now the application is having a lot of data syncing issues. (data saved by one user is not reflected to others until they logout and re-login)
My questions : was it really a good way of handling the performance issue the application was having? In my opinion, rather then fixing the performance issue , a workaround was added which becomes the cause of other issue.
secondly question: is there a better architecture/design that can be put in place which will improve the performance as well as resolve the data syncing issues the application is having? I am thinking to add a distributed cache layer (Azure Redis likely) to replace in-place Session layer, and optionally (if that makes sense) to implement write-through strategy in Redis so that the front-end application only talks to Cache and let cache keep the data store up to date.
Any guidance or pointer is very much appreciated!
I think you're on the right path. As you've already experienced adding a cache to your application introduces new challenges: handling stale data. In your case it data is cached at the user-level, which means each user has its own cache. This works well if each user works on their own piece of the data. For instance: a banking app where each user sees only their own bank statements (and never those of others). However, this is not the case in your application. Multiple users operate on the same data and now you're running into synchronization issues. A quick fix could be to replace the Session cache with the Application cache which is shared with all users.
Externalizing your cache (e.g. Redis or Memcached) is another solution and offers many advantages (e.g. distribution; scaling; synchronization; etc.), but also increases the complexity of your application. Now your application is dependent on another piece of infrastructure with its own behavior.
If I have an object which works as a repository with Save(), GetProduct(prod id) etc, is it a good idea for this to be a singleton in an asp.net applications.
My thought is that because I have many accesses to the database, this would improve performance because it doesn't waist time recreating the repository object each time.
I haven't seen anything like this in any samples, so why is this wrong?
Thanks
Just be carreful that a singleton in ASP .net means that all users of your web site will use it to access data. That means that you will probably have to lock you methods and that could results in bottlenecks.
I remember that one time I had a real strange bug with singleton data manager in an ASP app.
If you don't want to recreate your repo each time a user request a page, you can also put you data repository object in the user session.
Unfortunately it really depends on how you access your Database, and how your repository class is really abstracting database connections, and transactions.
If you're just talking about the expenses of creating an in memory object for every http request then it's not a big deal. It's really not worth consideration.
If you're talking about low level database stuff, then again, it depends.
Particularly with ORMs like Linq to SQL or NHibernate, how you manage their sessions is quite important. Usually though you wouldn't want a "session's" or "datacontext's" scope to go beyond the http request, so no, a singleton wouldn't be a good idea IF the singleton is holding the DB Session as a singleton itself.
Consider using an IoC Container also, like Castle Windsor. Then to change a particular classe's "lifestyle" (singleton, transient, per web request, etc.) is a simple configuration change, and makes your application a bit more flexible.
Also, talking to the DB itself is more expensive that creating new objects in memory, so if you're really after performance consider clever caching.
Lastly, when considering Singletons, think about it from a conceptual point of view instead of performance. Does it make sense that this object be Singleton?
A little background: I currently make use of Memcached Providers for managing session state in my ASP.NET application. It provides facilities for using SQL Server as a fallback storage mechanism (when sessions need to be purged from the memcached cache). I'd like to look at creating a provider for RavenDB as it would be much more performant for this sort of task.
My question is, has anyone implemented such a thing? (or something similar?) - I'd hate to re-invent the wheel. Google does not yield any helpful results (other than my question about this in the RavenDB group itself), so I thought I'd take this question directly to the Stack Overflow community.
I was also seeking a RavenDB session-state store, and my search also failed.
So I created one:
github.com/mjrichardson/RavenDbSessionStateStoreProvider
Also available via a NuGet package.
Not as far as I know. RavenDB is pretty active project and Memcached has been practically dead for 2 yr and remained 32-bit. You might be better off just running RavenDB under IIS
OK, so code-wise it doesn't get smaller than this - single file: http://sourceforge.net/projects/aspnetsessmysql/files/MySqlSessionStateStore.cs/download
RavenDb provides a Session expiration bundle which means that documents are deleted after a specified lifetime. This is ideal for use as a session and means that your entire aggregate root will be retrieved from RavenDb, meaning much cleaner code:
RavenDb Expiration Bundle
We are developing an ASP.NET HR Application that will make thousands of calls per user session to relatively static database tables (e.g. tax rates). The user cannot change this information, and changes made at the corporate office will happen ~once per day at most (and do not need to be immediately refreshed in the application).
About 2/3 of all database calls are to these static tables, so I am considering just moving them into a set of static objects that are loaded during application initialization and then refreshed every 24 hours (if the app has not restarted during that time). Total in-memory size would be about 5MB.
Am I making a mistake? What are the pitfalls to this approach?
From the info you present, it looks like you definitely should cache this data -- rarely changing and so often accessed. "Static" objects may be inappropriate, though: why not just access the DB whenever the cached data is, say, more than N hours old?
You can vary N at will, even if you don't need special freshness -- even hitting the DB 4 times or so per day will be much better than "thousands [of times] per user session"!
Best may be to keep with the DB info a timestamp or datetime remembering when it was last updated. This way, the check for "is my cache still fresh" is typically very light weight, just get that "latest update" info and check it with the latest update on which you rebuilt the local cache. Kind of like an HTTP "if modified since" caching strategy, except you'd be implementing most of it DB-client-side;-).
If you decide to cache the data (vs. make a database call each time), use the ASP.NET Cache instead of statics. The ASP.NET Cache provides functionality for expiry, handles multiple concurrent requests, it can even invalidate the cache automatically using the query notification features of SQL 2005+.
If you use statics, you'll probably end up implementing those things anyway.
There are no drawbacks to using the ASP.NET Cache for this. In fact, it's designed for caching data too (see the SqlCacheDependency class http://msdn.microsoft.com/en-us/library/system.web.caching.sqlcachedependency.aspx).
With caching, a dbms is plenty efficient with static data anyway, especially only 5M of it.
True, but the point here is to avoid the database roundtrip at all.
ASP.NET Cache is the right tool for this job.
You didnt state how you will be able to find the matching data for a user. If it is as simple as finding a foreign key in the cached set then you dont have to worry.
If you implement some kind of filtering/sorting/paging or worst searching then you might at some point miss the quereing capabilities of SQL.
ORM often have their own quereing and linq makes things easy to, but it is still not SQL.
(try to group by 2 columns)
Sometimes it is a good way to have the db return the keys of a resultset only and use the Cache to fill the complete set.
Think: Premature Optimization. You'll still need to deal with the data as tables eventually anyway, and you'd be leaving an "unusual design pattern".
With event default caching, a dbms is plenty efficient with static data anyway, especially only 5M of it. And the dbms partitioning you're describing is often described as an antipattern. One example: multiple identical databases for multiple clients. There are other questions here on SO about this pattern. I understand there are security issues, but doing it this way creates other security issues. I've recently seen this same concept in a medical billing database (even more highly sensitive) that ultimately had to be refactored into a single database.
If you do this, then I suggest you at least wait until you know it's solving a real problem, and then test to measure how much difference it makes. There are lots of opportunities here for Unintended Consequences.
My first time really getting into caching with .NET so wanted to run a couple of scenarios by you.
Question 1: Many expensive objects
I've got some small objects (simple int/string properties) which are pretty expensive to instantiate. These are user statistic objects which each user may have 1 - 10 of. Is it good or bad practice to fill up the cache with these fellas?
Question 2: Few cheap regularly used objects
Also got a few objects (again small) which are used many times on every page load. Is the cache designed to be accessed so regularly?
Fanks!
stackoverflow: Cracking question suggestion tool btw.
1) I would cache them. You can always set CacheItemPriority.Low if you are worrying about the cache 'filling up'
2) Yes the cache is designed to be accessed regularly. It can lead to huge performance improvements.
The answer to both of your questions is to cache them aggressively if you can.
Objects that are expensive to instantiate yet relatively static (that is unchanging) throughout the application's life ought to be cached. Even relatively inexpensive objects should be cached if you can improve performance by doing so.
You may find yourself running into problems when you need to invalidate the cache when any of these objects become stale or obsolete. Cache invalidation can be a difficult problem especially in a multi-server environment.
I don't think there is any problem with hitting the cache too frequently...
Overall asp.net Caching is fairly intelligent int terms of deciding what to keep and generally managing space. As a rule though I wouldn't depend on the cache to store information, only use it as an alternative to hitting disk or DB. User objects may be better served by session state.
https://web.archive.org/web/20211020111559/https://aspnet.4guysfromrolla.com/articles/100902-1.aspx
is a great article explaining the built in capabilities of .net caching.
Let's address the question in your title - when caching is too much.
It's too much if you are putting so much in the cache that it is pushing other things away. If the web sites on the server in total is using more memory than there is physical memory, they will push each other out into the virtual memory that is stored on disk. That will practically mean that you are caching some of the objects on disk instead of in memory, which is a lot slower.
It's too much if you are putting so many objects in the cache that they push each other out, so that you rarely get to use any of the objects in the cache before they go away.
So, generally you can cache a lot before you reach the limit where there is no point in putting anything more in the cache.
When determine what's most benificial to cache, consider where the bottle necks are. If you for example have a database server with a lot more capacity than the web server, caching the database results doesn't save so much resources. Getting data from the database takes time, but it doesn't use much resources on the web server while waiting for it, so it will not affect the throughput much.