20 ms·
Groupcache: an alternative to memcached, written in Go
- happyhappy 13y agoI want to use this, but since the keys are immutable, how can I store data like sessions which can change and would sometimes have to be invalidated from the server side (i.e. you can't simply change the session ID in the cookie and use a new cache entry, because bad-guy could still be holding on to an old stolen session ID)? In general, how can one learn to think in an immutable fashion to effectively exploit this?
- lucian1900 13y agoThe simple solution is to always version everything. There's no such thing as an update, merely a new version of a thing.
- happyhappy 13y agoThat much is obvious.
- FooBarWidget 13y agoSo without any mutable storage, how do you verify that the version that the client requested is the latest version?
- justincormack 13y agoIf the client has an old link serve an old version. But have links to what will be future versions and make the client walk them. It is doable but different. Lots of stuff is static anyway, like CSS, so you can use for this and have a different process for stuff that varies.
- FooBarWidget 13y agoBut as the grandparent said, serving the old version may result in a security vulnerability. There are cases where you MUST serve the latest version, and the latest version only.
- samnardoni 13y agoThen don't use groupcache.
- perlgeek 13y agoThe general approach is to store initial values and then changesets to those objects. For example git has loads of immutable data (every commit, tree and blob is immutable), and only very little mutable data (the refs) that point to some of those immutable objects. You simply wouldn't use groupcache for session data; you'd use memcached.
- skybrian 13y agoThis isn't for sessions unless they're also backed up somewhere else. It's just for caching. You would need some other system where you look up which version of a session is current, then look up sessions in the cache by a unique version id.
- seunosewa 13y agoThat "other system" could and probably should be a database.
- twotwotwo 13y agoAs others said, groupcache isn't useful for session storage. memcache was used for a lot of things other than caching, because it was a very versatile hammer and a lot of things looked like nails. groupcache is for when your data's immutable and bandwidth used for the most popular keys might exhaust a single memcache server's pipe.
- borlak 13y agoI really wouldn't call this an alternative. If you are running memcached, it's very unlikely you can switch to Groupcache. Parts of your application may rely on the expiration feature. But the biggest change is the inability to overwrite a current cache key. Every application I've used does this constantly (object updates). Groupcache in its current form is useful for a very narrow set of applications.
- happyhappy 13y agoValues that must expire could perhaps use a truncated time value as part of the key? It's not as flexible as regular expiration, because the entries would only expire when you cross the point in time where the truncated time value changes, which could be a problem in a lot of applications (sudden surges of requests every x seconds)
- deleted 13y ago[deleted]
- happyhappy 13y agoRead the article for reasons for using groupcache.
- arscan 13y agoI would think that the real limiting factor right now is that it is only available for Go applications (its a Go library, not a standalone server). There are comparably very few Go applications in the wild that could use this... where a memcached server can interface with just about anything. Or am I missing something?
- drbawb 13y agoGroupcache being a library is what made me so excited about it in the first place. I'm writing a torrent tracker in Go that could make great use of a distributed cache. This would enable you to put an arbitrary number of "tracker nodes" behind a load-balancer. One of the goals of my project is that its easy to configure: everything except the RDBMS is hosted inside a single binary and configured with a single file. In the simplest case: that binary is responsible for two web-servers, a process-local cache, and a DB connection pool. (In more complex cases, each binary simply acts as another node behind a load-balancer; and they attempt to cooperate together.) It's useful to avoid hitting the disk by having the tracker cache torrents that are active. When you start adding more tracker nodes, this is where having a distributed cache would be nice. Without groupcache, that means I've just forced my users to install and configure memcached. With groupcache, the configuration and server are simply part of my application. (As an added bonus, since Go is statically linked, I haven't even added any external dependencies on shared libraries.) --- I agree that the use-cases for groupcache are far more limited in scope, but I was still glad to hear that this was a library, and not a standalone server. I think we need _more_ distributed caches implemented as libraries, not less. There are many use-cases where it may not be preferable to have a separate caching server. In my career: getting approval to install memcached on a customer's server could add _weeks_ to our deploy time simply because of red-tape; in my personal programming endeavors: setting up memcached is just an added layer of complexity that could easily be avoided by using libraries instead of servers. I'd argue that we should leave memcached [more specifically: standalone distributed caches] for the more complicated scenarios where a dedicated solution is called for. Bring on the distributed-cache libraries where a much simpler, ad-hoc solution would be more beneficial to end-users.
- joshfraser 13y agoFor those that didn't catch it, this is from Brad Fitzpatrick, the same guy who made memcache
- adamnemecek 13y agoASAIK, he wrote the original memcached in perl but what everyone is using now is a rewrite of memcached in C by Anatoly Vorobey [1]. Not that it diminishes his efforts or anything, just pointing it out. [1] http://en.wikipedia.org/wiki/Memcached#History http://en.wikipedia.org/wiki/Memcached#History
- remi 13y agoWell, at least he invented it :)
- alperakgun 13y agonext in line, memcached in js? or will anything which can be written in go will be written in go?
- blowski 13y agoAnd if stuff doesn't get written in Go, then people will criticise Go for not having anything in production. The internet is not going to run out of space through people writing too much software.
- pbreit 13y agoGo seems like a reasonable
- twotwotwo 13y agogroupcache has a couple of differences from memcached that are probably part of why it exists: - thundering herds suck, so it manages how the cache is filled when a key is missing - repeatedly retrieving super hot values will eventually exhaust the network pipe of whichever server held, so groupcache replicates hot values to more than one cache server Since this was built for dl.google.com, the 'value' might be big (say, a chunk of the Chrome binary) and the request rates for the top cache keys probably get pretty high. So, even if memcached is doing good work for lots of folks, the distinct features of groupcache probably address real needs in the app. And, yeah, groupcache and the dl.google.com rewrite are Go partly because Brad likes Go, but both projects had reasons to exist quite apart from deploying Go for Go's sake.
- willvarfar 13y agoI noticed this when he talked about speeding up the Google download servers. Very interesting :) Its an alternative to memcache but not a direct replacement. I hope he adds CAS etc. I hope they start using the kernel's buffer cache as the backing store, or explain why its not a good idea: http://williamedwardscoder.tumblr.com/post/13363076806/buffcacher http://williamedwardscoder.tumblr.com/post/13363076806/buffc...
- kin3tic 13y agoIf you want a CAS, you want Brad's other current project that is really just hitting some very interesting milestones: camlistore. It's his datastore to store "everything" and I'm convinced.
- fooyc 13y agoApparently there is no CAS by design, this allows groupcache to replicate hot keys on multiple hosts.
- willvarfar 13y agoYes, but if it was opt-in... Its nice if you can use groupcache as a memcache replacement even if some use-cases tie the hands of the implementation e.g. replication of hot items.
- happyhappy 13y agoI've been thinking about something similar. I don't see how timed expiration would conflict with the two most important features - the filling mechanism and the replication of hot items. Am I missing something that would make timed expiration impossible?
- willvarfar 13y agoYeah on the first pass of the problem you seem right. The CAS must have an authoritative node (my mind wanders thinking about replication and failover) but the key it protects - with the version baked in - can be replicated surely?
- reeses 13y agoAm I reading this as a distributed, immutable, weak hash table rather than what one would consider a 'cache'? Mind you, doing so avoids the hardest parts of caching (and especially distributed caching, which otherwise begins to underperform around ≥ 5-7 nodes), so I can see significant upside. No surprise stales, distribution update clogging, etc.
- otterley 13y agoHow do you set an item's TTL? How do you set the maximum size of the process's cache?
- lcampbell 13y ago> How do you set an item's TTL? Values stored are immutable, and expire when they are no longer used. There is no concept of a TTL. > How do you set the maximum size of the process's cache? The cache is broken into a set of named groups, each with their own separate cache and cache-filling method. The size of each group's cache is set when created via NewGroup[1]. -- [1] http://godoc.org/github.com/golang/groupcache#NewGroup http://godoc.org/github.com/golang/groupcache#NewGroup
- chetanahuja 13y agoI'd be curious to hear performance numbers (assuming a reasonable front-end server to this library). I get it that the replicated in-memory caching part is valuable. But (from painful experiences with Java) I also fear that a GC based memory management system is anti-optimal for an in-memory cache of small objects, especially as the size of heap grows to beyond a couple of GB( * ). (* ) http://cdn.parleys.com/p/5148922a0364bc17fc56c60f/GarbageCollection.pdf http://cdn.parleys.com/p/5148922a0364bc17fc56c60f/GarbageCol...
- thrownaway2424 13y agoGo's garbage collector sucks pretty hard for large heaps. A 16GB heap that's mostly live objects will take tens of seconds per round, during which no goroutines will run (it's a stop-the-world collector). Basically it's 15 years behind Java in this regard. If you're worried about this, stick with C++.
- nine_k 13y agoIs this figure for Go 1.0 or 1.1? The latter is said to have a much-improved parallel GC. http://golang.org/doc/go1.1#performance http://golang.org/doc/go1.1#performance
- lazyjones 13y agoA 16GB heap that's mostly live objects will take tens of seconds per round The situation you describe, as you describe it, is (no longer - was it ever?) a pathological case. I run stuff with 12-20GB active objects and a few dozen http hits a second and the only times I get a latency over 100ms is when I reload/refresh some data from disk (1.5GB of gob), then it goes to 150-250ms typically.
- justinmares 13y agoIt'd be interesting to compare this alternative to other solutions like Redis. Has anyone used both/either?
- joeblau 13y agoIf I were to speculate, I would say that Redis is probably faster.
- throwit1979 13y agoTIL that waiting for a network roundtrip is faster than accessing an in-process hash map directly.
- willvarfar 13y agoRedis is a data store and is limited by RAM. Groupcache is a distributed cache. They are not comparable?
- buro9 13y agohttp://talks.golang.org/2013/oscon-dl.slide#46 http://talks.golang.org/2013/oscon-dl.slide#46 > 64 MB max per-node memory usage So this is best used as a LRU cache of hot items. It doesn't compete/replace memcache comprehensively, but it does attack the use of memcache as a relief for hot items. I can see me mixing my Go programs with both groupcache and memcache. Edit: I have glanced through the code and cannot see where the 64 MB per-node limit comes in. Anyone see that?
- reidrac 13y agoThe fact it doesn't have cache expiration times or inc/dec discards it as memcache replacement, at least for me. Well, and the fact that only go is supported at the moment.
- nknighthb 13y agoIt's a configurable limit. 64MB is just what he set the limit to for that particular group, that's what the "64<<20" in the NewGroup call is for. You could configure it to use many gigabytes.
- buro9 13y agoAh, that's what I was not seeing when I was glancing through the source. In that case... for me it fully replaces memcache for how I'm using memcache today.
- RyanZAG 13y agoHow does this compare to Hazelcast[1]? Seems like the same idea, but far less features? [1] http://www.hazelcast.com/ http://www.hazelcast.com/
- arohner 13y agoHazelcast is incredibly buggy. Avoid at all costs.
- tacticus 13y agoGot any links\talks\papers on this as a dev group at my work just started using it.
- arohner 13y agoJust personal experience, sorry. * it deadlocks. Often. * it often doesn't recover from network partitions. Symptoms include both sides of the partition never merging, and deadlocks. Recovering requires rebooting the entire cluster at once. Due to their locking strategy, a rolling reboot of the cluster isn't enough. *some of the developers didn't seem to demonstrate understanding of races, or distributed systems. When I reported racing bugs, they asked if I could attach reliable unit tests.
- justinhj 13y agoI'm a bit confused about how you use this system with immutable keys. At face value it's a great idea, but I need a simple example of how's it is used to say retrieve a piece of data, then later update that to a new value. Is this anything like how vector clocks are used, where the client uses the clocks to figure out which is the right state in a distributed system?
- pjscott 13y agoThe use-case for which this was originally designed was a download server: the values were chunks of files, each of which gets its own unique identifier. If you want to update a file, you simply create a new file for your new version, and point clients at it instead of the old version.
- casperc 13y agoHow does its sharding by key algorithm work and how does it handle adding new peers? I was looking for at in the source, but couldn't find anything related to it.
- somethingnew 13y agohttp://en.wikipedia.org/wiki/Consistent_hashing http://en.wikipedia.org/wiki/Consistent_hashing
- dsymonds 13y agoYou need to implement that part yourself. Look in peers.go. It'll be dependent on how you discover peers in general.
- azth 13y agohttps://github.com/golang/groupcache/blob/master/sinks.go#L59 https://github.com/golang/groupcache/blob/master/sinks.go#L5... Uh oh. The dreaded cast we see here http://how-bazaar.blogspot.co.nz/2013/07/stunned-by-go.html http://how-bazaar.blogspot.co.nz/2013/07/stunned-by-go.html
- j_baker 13y agoI like the idea, but it seems like it would make deployment a pain. How do I spin up a new server without rebalancing and/or restarting the world? Not to mention that now when I do need to restart the world, I can't do so without also clearing my cache.
- somethingnew 13y agohttp://en.wikipedia.org/wiki/Consistent_hashing http://en.wikipedia.org/wiki/Consistent_hashing