Game day exercises at Stripe
stripe.com
stripe.com
Rule #1 of programming is that if you didn't test it, it doesn't work. (It may still not work for real after you test it, but at least it's got something.)
You can't claim to anyone, or even yourself, that you have some kind of fault-tolerant system if you don't do this kind of test after every change.
I agree with you that it should be common, but I'd suspect an honest survey of the field would show that it's far from standard practice. I'd guess fewer than 25% of companies do this in any meaningful way.
They shut down servers and components of the system to make sure they are resilent to failures.
> The Simian Army is a suite of tools for keeping your cloud operating in top form. Chaos Monkey, the first member, is a resiliency tool that helps ensure that your applications can tolerate random instance failures
More interestingly is that it is opensource. [2]
[1] http://techblog.netflix.com/2012/07/chaos-monkey-released-in...
The first one I like to do is to restore the entire infrastructure from the off-site backup. When I know this is good I can sleep soundly.
On the plus side, Antirez has said that this configuration will soon be supported: https://news.ycombinator.com/item?id=8522630 (thanks Antirez!), so future users will be able to run in this configuration safely.
I'm happy to see there will be features added to support the use cases that Stripe and others have in mind.
In a distributed system, some nodes can act like a cache and others like a persistent store.
Their setup would have been fine _if_ the master never came back up. If the master didn't restart, then something in their infrastructure would have probably started using the replicas for data (and/or they would have promoted one of the replicas to be the new master, then the other replica would replicate from the new master).
But—having persistence on the replicas did allow them to copy the dataset off to backup storage. Then they were able to restore the old data when it was needed. So, we can prove their setup was persistent since they lost all their data and recovered it. :)
The replicas will try to reconnect to their original master forever unless something else (like Sentinel) redirects them in an actual failover/promotion setup.
So, the master had data, it died, it restart with no data, then the replicas immediately reconnect. If the master had persistence enabled, it would have reloaded the old dataset on startup and the replicas would have re-downloaded everything—since they are replicas of the master, they will always prefer the master data over their own, even if the master is empty.
If you were in a strange case where the disk failed and you replaced it with an empty disk (is that what you mean by "fresh disk?") then it's the same as starting an empty dataset. Not entirely relevant since the server would be intentionally started empty after a maintenance action instead of just restarting the already-populated process that restarts as empty because there's no saved dataset to load on startup.
The "all replicas resync an empty dataset" is a logical consequence of the configuration they enabled, but one without obvious repercussions without either directly experiencing it or a longer multi-chain thought experiment. (but, fixes for such things are already on the way—soon!)
Funny enough what triggers this problem when you have master persistence turned down is, the lack of failover, if the reboot happens fast enough, in case you are using Sentinel, for it to failover to a replica. So no failure was sensed at all, just the master magically wiped its data set.
So from the point of view of distributed systems, if you want to analyze the sum of Redis replicated nodes + Sentinel, the problem is that the system is not designed to cope with nodes losing state on restarts.
However it is possible to improve it, and I'm doing it, but before diskless replication it was IMHO pretty useless to have support for persistence-less operations in conjunction with replication, since the slaves to synchronize required anyway the master to save an RDB file on disk.
https://blog.pagerduty.com/2013/11/failure-friday-at-pagerdu...
The learnings from forcing actual failure in production parts of your stack are incredible.
What they have found, in a worst case scenario Redis is worse than Postgres.
So for example, their Redis response times might look like ,{1ms, 1ms, 1ms, 9ms}, while their Postgres response times might look like {3ms, 4ms, 3ms, 4ms}. Looking at it this way you can expect redis to perform better, however that outlier is worrying. For stripe they value having consistent and predictable performance over varying performance.
In other anecdotal evidence, I've been using Redis as a persistent store since 2011 and haven't lost any data.
There's always the giant caveat: just because software says it does X doesn't mean it does X until you have seen it actually happen. In this case, restarting a zero-persistence master was bad because it goes run->die->restart[empty]. Then, the replicas immediately reconnect, resync[empty], and now they are completely up to date with the master (which is the only Redis contract asked for here: always be an exact copy of your master; since persistence was not requested, the replicas re-sync an empty dataset).
In better news: there are already fixes for each of these issues showing up in Redis very quite Real Soon Now.
Anyway. Redis is considerably mature but still have edge cases that will literally void all you data. And that's definitely not okay when it's being used as your source of truth.