-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Locking removed in session::read #27
Comments
Hi Melvyn. I agree that the merit of locking is arguable given the performance/complexity downsides. However, if one wants a redis session store that does not use locking they could just use the handler built into phpredis which I know some people are already doing. So although I hadn't strongly considered supporting a non-locking version I am not opposed to it (as long as it isn't the default). The only two benefits I can see over the built-in handler would be support without the phpredis module (no idea how many people go this route) and compression of the session data. I think the data compression is very valuable since it will let you store more sessions or for longer in the same amount of memory which is a limited resource on a large site. Regarding the use-case for locking, the typical basic ecommerce site would work fine without it for the most part. But, if a user were to for example add two products to the cart in quick succession (or your site was really slow ;) then they might for example see two success messages on one page and none on the other, or see only one success message, or possibly worse (only one product gets added?). Another example might be the order success page.. If while an order was processing another page load occurred it could clobber the "last order id" and then the success page would throw an error and redirect and the user would never know if their order completed. I haven't tested all of the scenarios and instead have just opted to go the safe/proper route. It is also quite possible that some other feature or third-party module really depends on stable session data and you wouldn't know it until it started causing problems. For what it's worth, the "files" session handler does use locking (with no break/timeout mechanism) and the other handlers do not support any locking. In short: If I receive a well-formatted pull request that adds a 'use_locking' option that defaults to '1' (for all of the poeple out there expecting to get locking) then I will merge it. :) |
Hi Collin, The session data can become quite big, because of site-specific data being stored in there so compression is needed. Adding two products to the cart I can see how that's an issue with Ajax-based cartadd. As for page loads during order completion, since the write locking is still in place, I don't think a conflict would occur, but it's an interesting test. |
The checkout success scenario:
It is a very unlikely race condition, but a race condition with negative consequences nevertheless. The adminhtml probably has more scenarios with all of the "form_data" and grids and ajax features. Perhaps the configuration setting could be separate for each "area"? |
Added a config option and also a constant to allow disabling locking in 0a03d8c. |
Today at another site we replicated the issue. It was caused by a security scanner. It fires requests in parallel, causing the lock to occur. The issue to solve here is the lock wait timeout. When two requests are fired simultaneously, the lock wait timeout is the one causing the problem:
If this were a spinlock that bailed out to a time wait, we'd solve it, as can be observed:
These are all reads without locking. They are in milliseconds, yet we sleep for 1.5 seconds. That's enough time for additional requests to come in and so the waits pile up.
Or even both. What do you think? |
You have to be careful to not ignore other situations when trying to optimize another.. IIRC, the motivation behind a 1.5 second timeout is:
All of that said, this was addressed already (0.51 second sleep time) so you should be using the github version. :) |
I just found a bug where there should have been a "continue" after the sleep, so it was actually sleeping twice. Fixing this should further help your issue with high concurrency so give the latest version a go. |
That may explain why I always saw a minimum delay of 3 seconds. Good catch. |
Hi Colin,
we've removed the locking for a client of ours in session::read and are currently running a battery of tests.
The rationale is this:
By removing the locking in session::read we are no longer seeing slowdowns in session::read (which ran upwards of 40 seconds in the site in question).
So far we've not seen any drawbacks. A test is currently running which:
3)1 item is added to the cart
This site is load balanced with 2 webservers, a shared session redis store, shared and loadbalanced redis cache and shared single database. 50 users with different login id's are fired at the site. Software used for testing is Neoload 4.1.
At present we have not seen any errors and each virtual user has now completed 2 full iterations.
Browsing through the session store in phpRedisAdmin we're also seeing the sessions with a TTL of 3599 or 3600 seconds (session time is set to 1 hour).
There's also a lot of custom code in this Magento installation, but the sessions still identify cart ownership. I can also see things like last visited url in the session data correctly change over time.
I think our tests cover the possible breakage that could happen, but I'm open to other tests that should be done to verify session accuracy. Do you have any concerns about removing the locking code and how we should test for it?
The text was updated successfully, but these errors were encountered: