This document provides an overview of distributed systems and some of the key challenges in building reliable distributed systems. It defines what a distributed system is and discusses some of the core challenges, including dealing with component failures. It describes different types of failures that can occur and emphasizes that distributed systems must be designed with an assumption of failure. It also summarizes some of the main protocols used in distributed systems like TCP/IP and discusses how client-server architectures help address some reliability issues.