Fault-Tolerance Techniques in Distributed Systems