I hope you’re all enjoying the 1.2.6 stable release of memcached. Don’t want to hear no whining about it crashing!
One of the most common questions in memcached land is the ever obnoxious “how do I put my sessions in memcached?”. The long standing answer is usually “you don’t”, or “carefully”, but people often walk the dark path instead. Many libraries do this as well, although I’ve seen at least one which gets it.
This isn’t as huge of a deal as people make it out to be. I’ve been asked about this over the mailing list, in IRC, in person, and even in job interviews. What people end up doing gives me the willies! Why! Why why why… Well, I know why.
So what is the deal with sessions? Why does everyone want to jettison them from mysql/postgres/disk/whatever? Well, a session is:
Ok well that sucks I guess. Every time a user loads a page we read a blob row from mysql, then write a blob row back. This is a lot slower than row without blobs. Alright, so I see it now. Memcached to the rescue!
Er, except maybe it’s a little complicated to actually memcached these things, since we need a write for every read… Why not just use memcached for sessions!? It lines up perfectly! Check it out:
Voila! ZERO reads or writes to the database, fantastic! Fast. Except I really don’t like the tradeoffs here. This is one example where I believe the experience of both your users and your operations team is cheapened. Users now get logged out when anything goes wrong with memcached! Operations has to dance on eggshells. Or needles. Painful.
So now what? Well we have zero accesses on our database, so it’s fast! But we can’t ever touch memcached again in fear of ticking off users. Progress be damned! Before you all think I’m completely off my rocker, I will admit there are some legitimate reasons to do this. If the way your site works doesn’t really impact users on loss of a session, or impacts few enough users, you can use this design pattern. How many people are actually affected if you get logged out of wikipedia.org? Well, the people writing revisions certainly mind, but the greater userbase is unaffected. They’re a non profit, they understand the tradeoff, etc. So that’s fine. It’s not fine for a lot of the people I see suggesting it or doing it. As developers get more comfy with memcached the session issue will become more of an obvious bottleneck.
The memcached/mysql hybrid really isn’t that bad at all. You can get rid of over 90% of the database reads, a lot of the writes, and leave your users logged in during rolling upgrades of memcached.
First, recap the components involved: The page session handler itself, and some batch job which reaps dead sessions. For small websites (like a vbulletin forum) these batch jobs are often run during page loads. For larger sites they will be crons and so forth. This batch job can also be used to save data about sessions for later analysis.
The pattern is simple. For reads fetch from memcached first, database second. For writes write to memcached, unless you haven’t synced the session to the database in the last N seconds. So if a user is clicking around they will only write to the database once every 120 seconds, and write to memcached every time.
Now modify the batch job. Crawl all expired sessions, and check memcached for the latest data. If session is not really expired don’t expire it then, if it is use the latest possible data from memcached. Write back to the database. Easy.
You take the tradeoff of sessions being mildly lossy for recent information, but you gain reliability back in your system. Reads against the database should be almost nonexistent, and write load should drop significantly, but not as much as reads.
So please, if you run some website I might eventually use, don’t put memcached in a place where restarting individual servers might piss me off. Thanks :)
I’d like to also challenge maintainers of session libraries for all languages to turn this design pattern into tunable (note all the places where I wrote N) libraries folks can plug in and use.
The more standard this stuff is the more likely the next fancy startup is going to get it right. Reuse is a great thing. I can’t say enough about how great efforts like krow‘s libmemcached go for standardizing how we use memcached, but it’s also a great help to ship libraries for common design patterns.
本文转载自网络,是在看memcached文档时看到的。文章发表的时间很早,是2008年的,但是内容很有意思,说的是要不要用memcahced来缓存用户会话信息。
文章罗列了一些使用memcached缓存用户会话信息将会遇到的一些问题,有些还可能会很严重,所以作者是不太推荐直接使用memcached来缓存用户会话信息。究其原因就是memcached仅仅是内存数据库,一旦发生故障停止工作了,缓存的所有信息就不存在了,重新起来后就是一个啥都没有的新实例。文章下面有评论说,这是单点故障问题,有其他避免措施可缓解故障,比如多点备份缓存,定时同步重要的信息到(mysql/postgres)数据库中等等。
Redis因为自带有同步缓存数据到disk的功能,只要配置好了,重新起来后会自动重建所有缓存信息,所以可以不用在意文章所述问题。还有就是,对于用户会话信息,对于轻量级别的认证信息,可以有很多其他机制在客户端/服务端传递,比如 JWT 就是其中之一,其本身可以包含额外信息,最重要的是对于验证该会话的有效性(是否本站签发、是否过期等等)提供了校验机制,而且不依赖缓存等存储机制。
本站为个人网站,集网络美文、技术文章与原创生活记录等,系孤芳自赏、个人用途,内容如有侵权请联系站长删除。