Working with the Chaos Monkey
codinghorror.com
codinghorror.com
CM is a form of active TDD at the system architecture level. This might evolve into setting up partition tests as a prerequisite to instantiating the deployment model (Translation: before you start putting something on a cloud instance, write code that turns the instance off and on from time to time) This assures that the requirements for survival are baked into the app and not something tacked on later after some public failure like the Amazonocolapse.
I was reading on HN the other day a guy talking about Google. He said he saw engineers pull the wires from dozens of routers handling GBs of data -- all without a hitch. The architecture was baked enough that failure was expected.
Many times failure modes like this are burned into hardware, but that kind of design is a long, long, long way from most people's systems.
As we're allowed to comment on anything public, I'll focus on a paper about disaster recovery at Google which focuses on the Perforce version control system[2]. As Perforce is centralized and proprietary it even raises a few novel issues. As they can't modify the code themselves it's in fact one of the few vertically scaled pieces of software at Google (Perforce instances run on machines with 256GB of RAM[3]).
Of particular interest to me is the Annual Disaster Recovery Test that Google runs. They assume that the admins/engineers at Mountain View are entirely unavailable and that the fail-overs happen with no advance notice. The idea is that during an actual disaster your staff won't have time to answer queries as to which folder that documentation was in or the order that commands need to be run.
[1] - This is in one of the official Google MapReduce papers, I'll try and hunt it down
[2] - http://www.perforce.com/perforce/conferences/us/2009/Present...
[3] - http://www.perforce.com/perforce/conferences/us/2009/Present...
The other problem is that Google just has a whole lot of code. They've got engineers cranking out code all day all over the world. Working at that sort of scale rules out other alternatives (note that Google hired the Subversion guys, and Google isn't using Subversion... this should tell you something).
http://www.armandofox.com/geek/past-projects/recovery-orient...
The idea of having a constantly persisted state is something I think would be massively innovative if applied right.
potential_victim(Minions) ->
fun (Pid) ->
not(pman_process:is_system_process(Pid))
and not lists:member(Pid, Minions)
end.
death_from_above(Minions) ->
Pids = lists:filter(potential_victim(Minions), erlang:processes()),
case Pids of
[] -> none;
_ ->
Victim = lists:nth(random:uniform(length(Pids)), Pids),
Name = pman_process:pinfo(Pid, registered_name),
exit(Victim, kill),
{ok, Victim, Name}
end.
The idea is to run it during load tests. Afterwards run your normal unit tests to check that nothing got permanently broken. It's good for finding broken supervisor trees.There is a similarity with mutation testing, but mutation testing is trying to throw things too far up the chain; it wants your program to crash and die so the test fails. Really, we want it the other way: proof that the test would have failed, but the program is still running effectively.
I've worked with runtime repair in the past, which is also sort of similar, but, IMHO, less effective than Erlang-style Let It Crash. [1]
To design a spacecraft right takes an infinite amount of effort. This is why it's a good idea to design them to operate when some things are wrong.
[1] http://spacecraft.ssl.umd.edu/old_site/academics/akins_laws....
Broadcom networking card and Windows Server 2008
The rest of it is making sure your app or site fails gracefully; that is that failure of one part doesn't bring down the whole. That can be expensive to retrofit, but actually should have been designed in from the beginning, as it is a generally accepted part of good design for anything running over a network.
That is a qualitative statement. It implies a value proposition in your head between engineering effort involved in doing CM style disaster prep vs product benefit.
Operationally, not doing some level of CM is like paying for operations with "Lottery Checks". A Lottery check has a payee and a nominal amount but where the amount is actually printed, there is a scratch off box. Sometimes when you scratch it off its for a lot more money than you intended to spend :-).
But it is very hard to talk rationally about "we're spending two engineers here to do nothing but try to randomly break the system and get bugs fixed that would cover for that problem." Because the problem is self inflicted it seems like a waste of money, and there is no guarantee that they will have found and fixed the problem which is going to kill you in the future. However, if you run an experiment enough times, you eventually achieve the solution. Think of it as the Monte Carlo method of systems test. Its a good thing and it helps people sleep at night.
And when the world does go pear shaped like it did with AWS here you may find yourself yawning rather than panicking, and that feels very good indeed.
This is my biggest concern with things like large nation-states, large banks, large reinsurance companies, large RAIDs, and large nuclear plants: we centralize resources into a larger resource pool in order to reduce the chances of failure, but in doing so we make the eventual failure more severe, and we reduce our experience in coping with it and our ability to estimate its probability. In fact, we may not even be reducing the chances of failure; we may just be fooling ourselves.
Consider the problem of replicating files around a network of servers. Perhaps you have a billion files and 200 single-disk servers with an MTBF of 10 years, and it takes you three days to replace a failed server.
One approach you can use is to pair up the servers into 100 mirrored pairs and put 10 million files on each pair. Now, about 20 servers will fail every year, leaving ten million files un-backed-up for three days. But the chance that the remaining server of that pair will fail during that time is 3/3650 = 0.08%. That will happen about once every 60 years, and so the expected lifetime of the average file on your system is about 6000 years.
So it's likely that your system will hum along for decades without any problems, giving you an enormous sense of confidence in its reliability. But if you divide the files that will be lost once every 60 years (ten million) by the 60 years, you get about 170 thousand files lost per year. The system is fooling you into thinking it's reliable.
Suppose, instead, that you replicate each file onto two servers, but those servers are chosen at random. (Without replacement.) When a server fails (remember, 20 times a year), there's about a one in six chance that another server will fail in the three days before it's replaced. When that happens, every three or four months, a random number of files will be lost --- about 10 million / 200, or about fifty thousand files, for a total data loss of about 170 thousand files a year. You will likely see this as a major problem, and you will undertake efforts to fix it, perhaps by storing each file on three or four servers instead of two.
This is despite the fact that this system loses data at the same average rate as the other one. In effect, instead of having 100 server pairs to store files on, you have 19,900 partition pairs, each partition consisting of 0.5% of a server. By making the independently failing unit much smaller, you've dramatically increased your visibility into its failure rate, and given yourself a lot of experience with coping with its failures.
In this case, more or less by hypothesis, the failure rate is independent of the scale of the thing. That isn't generally the case. If we had a lot of half-megawatt nuclear reactors scattered around the landscape instead of a handful of ten-gigawatt reactors, it's likely that each reactor would receive a lot less human attention to keep it in good repair. When it threatened to melt down, there wouldn't be a team of 200 experienced guys onsite to fight the problem. There would be a lot more shipments of fuel, and therefore a lot more opportunities for shipments of fuel rods to crash or be hijacked. And so on.
But we might still be better off that way, because instead of having to extrapolate nuclear-reactor safety from a total of three meltdowns of production reactors --- TMI, Tchernobyl, and Fukushima --- we'd have dozens, if not hundreds, of smaller accidents. And so we'd know which design elements were most likely to fail in practice, and how to do evacuation and decontamination most effectively. Instead of Tchernobyl having produced a huge cloud of radioactive smoke that killed thousands or tens of thousands of people, perhaps it would have killed 27, like the reactor failure in K-19.
With respect to nation-states, the issue is that strong nation-states are very effective at reducing the peacetime homicide rate, which gives them the appearance of substantially improving safety. Many citizens of strong nation-states in Europe have never lived through a war in their country, leading them to think of deaths by violence as a highly unusual phenomenon. But strong nation-states also create much bigger and more destructive wars. It is not clear that the citizens of, say, Germany are at less risk of death by violence than the citizens of much weaker states such as Micronesia or Brazil, where murder rates are higher.
"Oh no, CM is down, everything's working!"
Would have been interesting if the post had ended with "so from now on, we're going to use the Chaos Monkey."
But even you don't embrace the concept, the Chaos Monkey is likely going to become a uninvited house guest at some point in time. In StackOverflow's case, they bought a mainstream server with a mainstream OS, and discovered that that server came with a monkey.
Think of it another way. My brother and sister in law never worried about the failure characteristics of dinner plates, so they had lots of nice stuff. Then they had a baby. All of the sudden, falling plates and glasses became something that they had to think about.
Jeff had something happen on accident that Netflix was smart enough to engineer on purpose. Once again, Jeff learns an important lesson and shares with everyone. No need to give grief over that.