├── LICENSE ├── README.md └── notes ├── 01_api_design ├── 01_overview.md ├── 02_rest.md ├── 03_graphql.md ├── 04_grpc.md ├── 05_state_management.md └── 06_data_transmission.md ├── 02_network_communications ├── 01_overview.md ├── 02_tcp_and_udp.md ├── 03_http_protocol.md ├── 04_web_sockets.md └── 05_metrics_and_analysis.md ├── 03_server_technologies ├── 01_web_server_overview.md ├── 02_static_dynamic_content.md ├── 03_tomcat.md ├── 04_apache.md ├── 05_nginx.md ├── 06_forward_proxies.md ├── 07_reverse_proxies.md └── 08_load_balancing.md ├── 04_databases ├── 01_types_of_databases.md ├── 02_transactions.md ├── 03_indexes.md ├── 04_isolation_levels.md ├── 05_data_warehousing.md ├── 06_replication.md └── 07_ halloween_problem.md ├── 05_caching ├── 01_caching_strategies.md ├── 02_redis.md ├── 03_content_delivery_networks.md └── 04_database_caching.md ├── 06_data_processing ├── 01_pub_sub_vs_queue.md ├── 02_messaging_system_integration.md ├── 03_batch_processing.md └── 04_stream_processing.md ├── 07_data_formats ├── 01_protocol_buffers.md ├── 02_xml.md ├── 03_json.md └── 04_yaml.md ├── 08_security ├── 01_auth.md ├── 02_tls.md ├── 03_security_vulnerabilities.md ├── 04_security_best_practices_and_measures.md └── 05_third_party_cookies_vulnerabilities.md ├── 09_deployment ├── 01_centos_digital_ocean.md └── 02_static_python_website_netlify.md └── 10_distributed_systems ├── 01_coordination_services.md ├── 02_gossip_protocol.md ├── 03_linearizability.md ├── 04_concurrent_writes.md ├── 05_operational_transform.md └── 06_algorithms_summary.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Adam Djellouli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /notes/01_api_design/01_overview.md: -------------------------------------------------------------------------------- 1 | ## API communication protocols 2 | 3 | API communication protocols describe how different software components exchange data and invoke functionality across networks. They define the transport mechanisms, data formats, interaction styles, and often how developers should structure their requests and responses. These protocols are often chosen based on specific project needs, such as required data formats, real-time communication, or existing infrastructure. Below is a comprehensive overview of several common protocols and approaches, complete with diagrams and bullet-point notes for easier reference. 4 | 5 | ``` 6 | +-------------+ Request +-------------+ 7 | | | ------------------> | | 8 | | Client | | Server | 9 | | | <------------------ | | 10 | +-------------+ Response +-------------+ 11 | ``` 12 | 13 | This basic diagram shows a client making a request to a server and the server sending a response. Different protocols can change how data is structured, the method of transport, and the overall interaction pattern (e.g., streaming vs. single request). 14 | 15 | ### gRPC 16 | 17 | ``` 18 | +---------+ Proto +---------+ 19 | | | <---- Buffer -| | 20 | | Client | | Server | 21 | | | -----> defs ->| | 22 | +---------+ +---------+ 23 | ``` 24 | 25 | - It is widely **useful** in microservices architectures due to its efficient binary serialization with Protocol Buffers. 26 | - It often leverages **HTTP/2** features such as multiplexing and flow control to optimize network usage. 27 | - It supports **streaming** communication in multiple directions, including client-to-server, server-to-client, or both simultaneously. 28 | - It can generate **boilerplate** code automatically from .proto files, reducing manual work in client and server implementations. 29 | - It requires some **learning** for teams that are new to Protocol Buffers and RPC-based communication. 30 | - It can offer strong **performance** benefits when handling high-throughput or low-latency operations. 31 | 32 | ### REST 33 | 34 | ``` 35 | +-----------+ GET/POST/PUT/DELETE +-----------+ 36 | | | -------------------------------> | | 37 | | Client | | Server | 38 | | | <------------------------------- | | 39 | +-----------+ JSON/XML/etc. +-----------+ 40 | ``` 41 | 42 | - It is often **simple** to adopt because it builds on standard HTTP methods like GET, POST, PUT, and DELETE. 43 | - It relies on **resources** identified by URLs, making it straightforward to map endpoints to data entities. 44 | - It is frequently **common** for web-facing APIs, due to wide tool support and developer familiarity. 45 | - It typically uses **JSON** as the data format, although XML, YAML, or other formats can also be used. 46 | - It can experience **over-fetching** or under-fetching issues if clients need more flexible queries. 47 | - It is normally **stateless**, meaning requests contain all necessary information without storing sessions on the server. 48 | 49 | ### GraphQL 50 | 51 | ``` 52 | +------------+ query { ... } / mutation { ... } +------------+ 53 | | | -----------------------------------------> | | 54 | | Client | | GraphQL | 55 | | | <----------------------------------------- | Server | 56 | +------------+ JSON response +------------+ 57 | ``` 58 | 59 | - It is especially **helpful** when clients need precise data fetching, as it allows specifying exactly which fields to retrieve. 60 | - It uses a **single** endpoint that handles queries, mutations, and subscriptions, simplifying API routing. 61 | - It requires a **schema** that defines types, which is used to validate and guide incoming requests. 62 | - It helps reduce **network** overhead in scenarios where multiple resources are needed in a single request. 63 | - It can introduce **complexity** in server-side resolvers and schema design, especially for large applications. 64 | - It often employs **JSON** for responses, though the actual request body is a text-based query string. 65 | 66 | ### SOAP 67 | 68 | ``` 69 | +-----------+ +-----------+ 70 | | | <--------------------------------> | | 71 | | Client | XML-based messages | Server | 72 | | | <--------------------------------> | | 73 | +-----------+ +-----------+ 74 | ``` 75 | 76 | - It is often **useful** in enterprise environments where strict standards and formal contracts are required. 77 | - It relies on **XML** for message structure, using envelopes, headers, and bodies to encapsulate data. 78 | - It commonly uses **WSDL** documents for describing service interfaces, data types, and operations. 79 | - It can integrate **WS-Security** for message-level encryption, signing, and authentication. 80 | - It can feel more **verbose** than other protocols due to extensive XML and additional layers of abstraction. 81 | - It often proves **reliable** for legacy or heavily regulated industries that value formal web service contracts. 82 | 83 | ### WebSockets 84 | 85 | ``` 86 | +-----------+ <-----------------> +-----------+ 87 | | | persistent | | 88 | | Client | <-------------------> | Server | 89 | | | bidirectional | | 90 | +-----------+ <-----------------> +-----------+ 91 | ``` 92 | 93 | - It can be **helpful** for real-time communication, enabling client and server to send messages at any time. 94 | - It uses an **upgrade** mechanism that starts over HTTP, switching the connection to a persistent WebSocket protocol. 95 | - It supports **text** or binary frames for data, allowing flexible message formats such as JSON or custom binaries. 96 | - It can reduce **latency** compared to repeatedly opening and closing connections for frequent updates. 97 | - It is often combined with **client-side** JavaScript libraries to manage open connections for chat, notifications, or live feeds. 98 | - It can require specialized **infrastructure** or load-balancing solutions for scaling high-traffic real-time applications. 99 | 100 | ### Server-Sent Events (SSE) 101 | 102 | ``` 103 | +-----------+ text/event-stream +-----------+ 104 | | | <------------------- | | 105 | | Client | continuous feed | Server | 106 | | | <------------------- | | 107 | +-----------+ +-----------+ 108 | ``` 109 | 110 | - It is **useful** when a unidirectional, server-to-client streaming pattern is needed, such as live updates. 111 | - It sends **text/event-stream** formatted data over a single HTTP connection, staying open for continuous events. 112 | - It can handle **reconnection** automatically by specifying retry intervals, making it straightforward for many browser-based clients. 113 | - It typically works best for **lightweight** push scenarios like notifications or real-time dashboards. 114 | - It lacks **bidirectional** communication, so any client-to-server updates must use separate endpoints. 115 | - It is often simpler than WebSockets if client feedback to the server is minimal or infrequent. 116 | 117 | ### Comparison Table 118 | 119 | | Protocol/Style | Transport | Data Format | Interaction Style | Benefits | Drawbacks | Ideal Use Cases | 120 | |----------------|-------------------|------------------|------------------------------|-------------------------------------------------------|-----------------------------------------------------------|----------------------------------------------------------------------------------------| 121 | | **gRPC** | HTTP/2 | Protocol Buffers | Unary & streaming | High **performance**, code generation | Requires learning curve with Protocol Buffers | Low-latency microservices and multi-language ecosystems | 122 | | **REST** | HTTP | JSON, XML, etc. | Stateless request-response | Widely **common**, simple tooling | Over-fetching/under-fetching issues | Web APIs with broad client support | 123 | | **GraphQL** | HTTP | JSON (response) | Query language & runtime | **Flexible** field selection, single endpoint | Resolver complexity in large schemas | Complex client data requirements with multiple linked resources | 124 | | **SOAP** | HTTP, SMTP, etc. | XML | RPC-style or document style | **Useful** for enterprise standards (WS-Security) | Verbose payloads, more complex to implement | Strictly regulated or legacy systems needing formal service definitions | 125 | | **WebSockets** | TCP (Upgraded) | Text or Binary | Bidirectional, real-time | **Helpful** for interactive applications | Requires persistent connections, specialized scaling | Chat, live dashboards, gaming, collaborative editing | 126 | | **SSE** | HTTP (One-way) | text/event-stream| Server-to-client streaming | **Straightforward** setup for continuous updates | Only supports unidirectional communication | Live feeds, notifications, real-time event distribution where client rarely sends data | 127 | -------------------------------------------------------------------------------- /notes/01_api_design/04_grpc.md: -------------------------------------------------------------------------------- 1 | ## gRPC 2 | gRPC is a high-performance open-source framework that was developed at Google for remote procedure calls. It uses the Protocol Buffers (protobuf) serialization format by default and runs over HTTP/2 to support features like full-duplex streaming and efficient compression. Many microservices architectures choose gRPC for its speed and type safety, enabling strong contracts between service providers and consumers. 3 | 4 | ### Architecture Overview 5 | gRPC builds on the concept that a client can directly call methods on a server application as if it were a local object, with the communication details handled under the hood. It relies on protocol buffers to define data schemas (messages) and service endpoints (RPC methods). When a client calls a method, gRPC handles the transport details over HTTP/2, manages efficient binary serialization, and returns a strongly typed response. 6 | 7 | ``` 8 | +---------------------------+ +---------------------------+ 9 | | | | | 10 | | gRPC Client | | gRPC Server | 11 | | (Desktop, Mobile, etc.) | | (Implements gRPC methods) | 12 | +---------------------------+ +------------+--------------+ 13 | | ^ | 14 | | 1. Client calls gRPC method | | 15 | | (Unary, Streaming, etc.) | | 16 | v | | 17 | +---------------------------+ | | 18 | | HTTP/2 request with |---------------> | 19 | | protobuf-encoded data | | 20 | +---------------------------+ | 21 | | 22 | (Server processes request, prepares response) | 23 | | 24 | +---------------------------+ | 25 | | HTTP/2 response with |<---------------------------| 26 | | protobuf-encoded data | 27 | +---------------------------+ 28 | | 29 | | 2. Client decodes 30 | | protobuf message 31 | v 32 | +---------------------------+ 33 | | Uses strong-typed data | 34 | | in the application logic | 35 | +---------------------------+ 36 | ``` 37 | 38 | This diagram shows how the client calls a remote procedure, sends serialized data over HTTP/2, and receives a response in the same serialized format. The strong typing provided by protobuf ensures that both client and server agree on data structures before runtime. 39 | 40 | ### Core Concepts 41 | 42 | ### Protocol Buffers (Protobuf) 43 | Protocol Buffers is a language-neutral, platform-neutral, extensible mechanism for serializing structured data. In a `.proto` file, developers define message types (data structures) and services (RPC methods). Code generation tools then produce client and server stubs in multiple languages based on these definitions. 44 | 45 | #### Service Definition 46 | A service definition describes the RPC methods that can be invoked. Each method specifies the request and response message types, along with the direction of data flow (unary or streaming). Here is a sample `.proto` file: 47 | 48 | ```proto 49 | syntax = "proto3"; 50 | 51 | package bookstore; 52 | 53 | // Message definitions 54 | message Book { 55 | string id = 1; 56 | string title = 2; 57 | string author = 3; 58 | } 59 | 60 | message GetBookRequest { 61 | string id = 1; 62 | } 63 | 64 | message BookList { 65 | repeated Book books = 1; 66 | } 67 | 68 | // Service definition 69 | service Bookstore { 70 | // Unary request/response 71 | rpc GetBook(GetBookRequest) returns (Book); 72 | 73 | // Server streaming 74 | rpc ListBooks(google.protobuf.Empty) returns (stream Book); 75 | 76 | // Client streaming 77 | rpc AddBooks(stream Book) returns (BookList); 78 | 79 | // Bidirectional streaming 80 | rpc Chat(stream Book) returns (stream Book); 81 | } 82 | ``` 83 | 84 | This definition includes a Bookstore service with four RPC methods, demonstrating unary, server streaming, client streaming, and bidirectional streaming calls. 85 | 86 | #### Communication Modes 87 | gRPC supports four primary communication patterns: 88 | 89 | - Unary RPC. The client sends a single request and receives a single response. 90 | - Server streaming RPC. The client sends a single request; the server sends back a stream of responses. 91 | - Client streaming RPC. The client sends a stream of requests; the server responds once the entire client stream is complete. 92 | - Bidirectional streaming RPC. Both client and server simultaneously read and write in a stream until they have finished. 93 | 94 | #### Code Generation 95 | After defining your `.proto` file, use `protoc` with gRPC plugins to generate language-specific stubs. The following table summarizes some common protoc flags: 96 | 97 | | Flag | Description | 98 | |-------------------------|------------------------------------------------------------------------| 99 | | `--proto_path` | Specifies directories in which to search for imports. | 100 | | `--go_out`, `--java_out` | Generates language-specific source files (for instance, Go, Java). | 101 | | `--go-grpc_out` | Generates gRPC service interfaces in Go. | 102 | | `--grpc-java_out` | Generates gRPC service stubs for Java. | 103 | | `--plugin` | Allows specifying the path to the gRPC plugin for protoc. | 104 | 105 | As an example, running protoc in Go might look like this: 106 | 107 | ```bash 108 | protoc --proto_path=. --go_out=. --go-grpc_out=. bookstore.proto 109 | ``` 110 | 111 | This command generates Go files containing message types and service interfaces you can implement on your server, and client stubs you can use to invoke RPC methods. 112 | 113 | ### Example Implementation in Go 114 | Here is a simplified snippet showing how you might implement a Bookstore service in Go. 115 | 116 | ```go 117 | package main 118 | 119 | import ( 120 | "context" 121 | "fmt" 122 | "net" 123 | 124 | "google.golang.org/grpc" 125 | pb "path/to/generated/bookstore" 126 | ) 127 | 128 | type bookstoreServer struct { 129 | pb.UnimplementedBookstoreServer 130 | } 131 | 132 | func (s *bookstoreServer) GetBook(ctx context.Context, req *pb.GetBookRequest) (*pb.Book, error) { 133 | // For demonstration, returns a static book. 134 | return &pb.Book{ 135 | Id: req.GetId(), 136 | Title: "A Sample Book", 137 | Author: "An Author", 138 | }, nil 139 | } 140 | 141 | func main() { 142 | listener, err := net.Listen("tcp", ":50051") 143 | if err != nil { 144 | fmt.Println("Failed to listen:", err) 145 | return 146 | } 147 | 148 | grpcServer := grpc.NewServer() 149 | pb.RegisterBookstoreServer(grpcServer, &bookstoreServer{}) 150 | 151 | fmt.Println("gRPC server listening on port 50051...") 152 | if err := grpcServer.Serve(listener); err != nil { 153 | fmt.Println("Failed to serve:", err) 154 | } 155 | } 156 | ``` 157 | 158 | In this example, `bookstoreServer` provides a method `GetBook` that satisfies the interface generated from the `.proto` file. After creating a TCP listener on port 50051, you create a gRPC server and register the Bookstore service implementation. 159 | 160 | ### Working with gRPC on the Command Line 161 | Clients typically connect using generated stubs in the same language as the server, but `grpcurl` is a popular CLI tool for testing gRPC services without needing to write code. Below is a demonstration of how to use grpcurl to call the Bookstore service. 162 | 163 | ``` 164 | grpcurl -plaintext -d '{"id":"123"}' localhost:50051 bookstore.Bookstore/GetBook 165 | ``` 166 | 167 | - Example output: 168 | ```json 169 | { 170 | "id": "123", 171 | "title": "A Sample Book", 172 | "author": "An Author" 173 | } 174 | ``` 175 | - Interpretation of the output: 176 | The response shows the book data retrieved from the server. The JSON matches the message defined in the `.proto` file. The `-plaintext` option is used for an unencrypted connection (often acceptable for local testing). The `-d` flag sends the request body, which is converted internally to protobuf. 177 | 178 | ### Performance Characteristics 179 | A big reason many teams pick gRPC is speed. gRPC uses HTTP/2 for multiplexing multiple messages over a single connection, supporting flow control and efficient streaming. A simple concurrency formula for server capacity might be written as 180 | ``` 181 | Server capacity = total_threads / average_call_duration 182 | ``` 183 | When calls are short and concurrency is managed well, gRPC servers can handle many simultaneous requests. Streaming helps when large datasets must be transferred in chunks without blocking the entire pipeline. 184 | 185 | ### Best Practices 186 | Consider a few approaches when designing and operating gRPC services: 187 | 188 | - Keep `.proto` definitions organized, preferably with smaller files that each handle a logical domain. 189 | - Employ secure connections by using TLS in production environments to encrypt traffic on HTTP/2. 190 | - Use deadlines or timeouts to prevent client calls from hanging indefinitely. 191 | - Rely on load balancing strategies that are compatible with HTTP/2 and maintain persistent connections. 192 | - Monitor service performance by collecting metrics on request latencies, error rates, and resource usage. 193 | 194 | -------------------------------------------------------------------------------- /notes/01_api_design/05_state_management.md: -------------------------------------------------------------------------------- 1 | ## State Managment 2 | Stateful and stateless designs are common terms in software architecture. They describe how an application handles data over multiple interactions. This set of notes explains the differences between applications that remember information between requests and those that treat every request as a fresh transaction. Various diagrams and code snippets illustrate how each approach operates in practice. Brief formulas appear to show how state management can affect concurrency and scaling. 3 | 4 | ### The Concept of State 5 | Software can store information about user interactions, sessions, preferences, or transactions. That information, known as state, may influence future application behavior. In a stateful design, the application keeps that data in memory or persistent storage, while in a stateless design, it processes requests without retaining previous context. 6 | 7 | A quick concurrency formula for a system that stores user sessions in memory could look like this: 8 | 9 | ``` 10 | M_total = N_sessions * S_session 11 | ``` 12 | 13 | M_total indicates total memory required, N_sessions is the number of simultaneous sessions, and S_session is the memory required per session. A large number of sessions might strain the system if each session state is stored server-side. 14 | 15 | ### Stateful Applications 16 | A stateful application tracks user or session data across requests. This means the server knows who you are and what you were doing even if you pause and resume your activity. That knowledge can make complex features easier to implement, though it complicates scaling, since each server instance must share or replicate the session data. 17 | 18 | Here is a high-level ASCII diagram illustrating how a stateful server might maintain and update the state as multiple clients interact: 19 | 20 | ``` 21 | +-----------+ +-----------+ 22 | | Client A | | Client B | 23 | +-----+-----+ +-----+-----+ 24 | | | 25 | | Request with | Request with 26 | | Session Info | Session Info 27 | v v 28 | +-----------------------------------------+ 29 | | API Server | 30 | |-----------------------------------------| 31 | | State Management (Session Tracking) | 32 | | - User Data | 33 | | - Preferences | 34 | | - Interaction History | 35 | +-----------------------------------------+ 36 | ^ ^ 37 | | Response with | Response with 38 | | Updated State | Updated State 39 | +-----+-----+ +-----+-----+ 40 | | Client C | | Client D | 41 | +-----------+ +-----------+ 42 | ``` 43 | 44 | The server updates this shared state and returns new information to each client, enabling more cohesive workflows. 45 | 46 | #### Advantages of Stateful Applications 47 | 1) They can maintain logical continuity, which often leads to more intuitive code when designing multi-step processes. 48 | 2) Users enjoy smoother experiences since the server remembers data like login sessions or shopping cart contents. 49 | 3) Complex, multi-stage workflows can be handled more easily because the server has all necessary context. 50 | 51 | #### Disadvantages of Stateful Applications 52 | 1) Scaling can be difficult because each instance of the application needs consistent access to session data. 53 | 2) A single server crash may cause data loss if session state is stored in memory without proper failover mechanisms. 54 | 3) Load balancing may require session affinity or other strategies to ensure that consecutive requests from the same user go to the correct server instance. 55 | 56 | #### Example: Stateful Counter 57 | In a stateful counter, the server remembers the current count. Each button click updates the server’s stored value, and the new total is returned to the client: 58 | 59 | ```javascript 60 | // Client-side 61 | button.addEventListener("click", function() { 62 | // Just notify the server that the button was clicked 63 | fetch('/increment', { method: 'POST' }) 64 | .then(response => response.json()) 65 | .then(data => { 66 | console.log(data.counter); // e.g., 5 67 | }); 68 | }); 69 | 70 | // Server-side 71 | let counter = 0; 72 | 73 | app.post("/increment", (req, res) => { 74 | counter++; 75 | res.json({ counter: counter }); 76 | }); 77 | ``` 78 | 79 | This approach keeps the counter variable in the server’s memory. If more than one server handles requests, they must share or synchronize this count. 80 | 81 | ### Stateless Applications 82 | Stateless applications process each request independently, with no knowledge of what happened before. This design can ease scaling, because any instance can handle any request without needing special session information. The downside is that each request or client must provide all data needed to complete a transaction, which sometimes makes the application logic more complex. 83 | 84 | #### Advantages of Stateless Applications 85 | 1) They can easily scale horizontally by simply adding more server instances. 86 | 2) Failure handling is simplified because the server does not need to recover prior user sessions. 87 | 3) Requests are idempotent more often, since each request includes everything required for processing. 88 | 89 | #### Disadvantages of Stateless Applications 90 | 1) Complex multi-step flows can be harder to implement because no session context is stored on the server. 91 | 2) Code may become verbose when the client must repeatedly send data to re-establish context. 92 | 3) Client overhead increases, as the client must remember and provide relevant information each time. 93 | 94 | #### Example: Stateless Counter 95 | In a stateless version of a counter, the server expects the current count from the client. It increments that number and sends it back, without storing the updated value in its own memory: 96 | 97 | ```javascript 98 | // Client-side 99 | let counter = 0; 100 | 101 | button.addEventListener("click", function() { 102 | fetch('/increment', { 103 | method: 'POST', 104 | headers: { 'Content-Type': 'application/json' }, 105 | body: JSON.stringify({ currentCount: counter }) 106 | }) 107 | .then(response => response.json()) 108 | .then(data => { 109 | counter = data.counter; 110 | console.log(counter); // e.g., 5 111 | }); 112 | }); 113 | 114 | // Server-side 115 | app.post("/increment", (req, res) => { 116 | let newCount = req.body.currentCount + 1; 117 | // No server storage of newCount 118 | res.json({ counter: newCount }); 119 | }); 120 | ``` 121 | 122 | This design does not keep track of the count internally on the server, so scaling out to multiple server instances is simple. Each request contains the necessary input from the client. 123 | 124 | ### Common Considerations 125 | There are several universal factors that affect both stateful and stateless applications. Networking plays a huge role, because any distributed application must handle potential timeouts or disconnections. Storage and filesystem modifications need consistent practices to avoid data corruption. Database interactions must be robust, whether or not the server itself is holding session data. 126 | 127 | A short formula might illustrate overhead differences. Let T_stateful be the average time per request in a stateful application and T_stateless in a stateless application. If requests require loading and saving session data from a shared store, T_stateful could exceed T_stateless by the session overhead: 128 | 129 | ``` 130 | T_stateful = T_processing + T_sessionOverhead 131 | T_stateless = T_processing 132 | ``` 133 | 134 | In simpler workflows, the session overhead might not be large, but in high-traffic scenarios, it can become significant. 135 | 136 | ### Identifying Stateful vs Stateless Designs 137 | A good way to identify whether a system is stateful or stateless is to see if the server stores user-specific data over time. A stateful server might keep a session object or memory of user interactions, while a stateless server often expects clients to include necessary data in every request. 138 | 139 | Below is an illustration of a web application that implements a simple counter, with the server either remembering or forgetting the current count between requests: 140 | 141 | ``` 142 | +-----------------------------+ 143 | | | 144 | | Web Application | 145 | | (Counter App) | 146 | | | 147 | +-----------------------------+ 148 | || 149 | || User Interface 150 | \/ 151 | +-----------------------------+ 152 | | | 153 | | +------------+ | 154 | | | Button | | 155 | | +------------+ | 156 | | | 157 | | Count Display | 158 | | [ 0 ] | 159 | | | 160 | +-----------------------------+ 161 | || 162 | || Button Click 163 | \/ 164 | +-----------------------------+ 165 | | | 166 | | Server Handling | 167 | | | 168 | | Increment & Store Count | 169 | | (Stateful) or Respond | 170 | | with Increment (Stateless)| 171 | | | 172 | +-----------------------------+ 173 | || 174 | || Update & Display 175 | || New Count 176 | \/ 177 | +-----------------------------+ 178 | | | 179 | | Count Display | 180 | | [ 1 ] | 181 | | | 182 | +-----------------------------+ 183 | ``` 184 | 185 | A stateful approach has the server track the count internally. A stateless approach relies on the client to send the current count with every interaction. Each style has unique trade-offs, so the best choice depends on factors like scalability requirements, complexity of the workflow, and overall system design. 186 | -------------------------------------------------------------------------------- /notes/01_api_design/06_data_transmission.md: -------------------------------------------------------------------------------- 1 | ## Data transmission 2 | 3 | Data transmission in API design covers how information is sent and received between a client and a server. This involves choosing data formats, transport protocols, security measures, and techniques to ensure both correctness and efficiency. Whether an application is stateful or stateless affects the data payloads and what metadata is carried on each request. 4 | 5 | ### Factors in Data Transmission 6 | API design typically revolves around sending requests and receiving responses. Data travels back and forth in a structured format, often accompanied by headers and security tokens. A few critical considerations come into play when deciding how to transmit data: 7 | 8 | - **Transport Protocol**: HTTP, HTTP/2, and HTTP/3 are common for web-based APIs. 9 | - **Serialization Format**: JSON, XML, Protocol Buffers, or other structured encodings. 10 | - **Security and Encryption**: TLS/SSL for data in transit. 11 | - **Compression**: Gzip or Brotli can reduce payload sizes. 12 | - **Caching**: Storing responses temporarily to reduce redundant requests. 13 | 14 | In a stateless world, each request must contain everything needed to process it. In a stateful system, requests can be smaller because the server stores user context, but more overhead might appear at the infrastructure level, such as session replication across multiple nodes. 15 | 16 | ### Transmission Protocols 17 | Different protocols come with their own rules for data framing, security, and performance: 18 | 19 | #### HTTP/1.1 20 | It is still widely used but supports only a single request-response at a time per TCP connection. To achieve concurrency, multiple connections are opened. This can cause overhead when requests are numerous. 21 | 22 | #### HTTP/2 23 | It adds multiplexing, allowing multiple requests and responses to be interleaved over a single TCP connection. This reduces round trips and can speed up API calls. The binary framing layer also permits efficient flow control. 24 | 25 | #### HTTP/3 26 | It operates over QUIC (built on UDP) rather than TCP and aims to offer improved performance, especially when packet loss occurs, because QUIC can handle data streams without resetting the entire connection. 27 | 28 | #### WebSockets 29 | WebSockets provide a persistent, two-way channel over a single TCP connection. They are particularly useful in real-time applications where server and client frequently communicate. However, WebSockets can introduce complexity around state maintenance if the server must track each open connection. 30 | 31 | ``` 32 | Client Server 33 | | | 34 | | 1. Connect over WebSocket | 35 | | --------------------------------->| 36 | | | 37 | | 2. Server keeps an open | 38 | | channel for messages | 39 | |<----------------------------------| 40 | | | 41 | | 3. Messages flow freely | 42 | |<---------------> | 43 | | | 44 | ``` 45 | 46 | In a stateful setting, the server might maintain a list of active connections and user contexts. In a stateless scenario, each message can carry necessary context (like an authentication token) so the server knows how to handle it without remembering session details. 47 | 48 | ### Serialization Formats 49 | APIs must transmit data in a way that client and server both understand. Common formats include: 50 | 51 | #### JSON 52 | JavaScript Object Notation is human-readable and widely used in RESTful APIs. A typical JSON response might look like this: 53 | 54 | ```json 55 | { 56 | "id": 123, 57 | "name": "Example", 58 | "attributes": ["fast", "secure"] 59 | } 60 | ``` 61 | 62 | #### XML 63 | Extensible Markup Language was more common in older SOAP-based services. It is verbose compared to JSON, but some systems still rely on it: 64 | 65 | ```xml 66 | 67 | 123 68 | Example 69 | 70 | fast 71 | secure 72 | 73 | 74 | ``` 75 | 76 | #### Protocol Buffers 77 | Often used with gRPC, Protocol Buffers (protobuf) is a binary format defined by `.proto` files. It is compact and efficient but less human-readable. Protobuf works well in high-performance environments or internal microservices. 78 | 79 | #### MessagePack, Avro, and Others 80 | These formats are also used to reduce size or improve parsing speed. They are less widespread than JSON and XML for public APIs but remain popular internally where performance matters. 81 | 82 | ### Stateless vs Stateful Transmission Patterns 83 | A stateless application requires each request to carry necessary context. A typical formula for additional payload size in a stateless design might be: 84 | 85 | ``` 86 | Extra_payload = N_contextFields * S_perField 87 | ``` 88 | 89 | N_contextFields is how many user/session fields must be included, and S_perField is the size (in bytes) of each field. Over many requests, stateless designs can lead to higher network usage if there is significant context. However, scaling is simpler because each request can be handled by any server instance. 90 | 91 | By contrast, a stateful design might keep user/session data on the server, reducing request payload: 92 | 93 | ``` 94 | Request_payload_stateful < Request_payload_stateless 95 | ``` 96 | 97 | But the server has to replicate or synchronize sessions, which can introduce infrastructure complexity. 98 | 99 | ### Security in Transit 100 | Encryption is crucial to protect sensitive data. HTTPS (HTTP over TLS) ensures confidentiality and integrity. API keys, OAuth tokens, or other credentials typically go in headers. If the app is stateful, the server might store session IDs in cookies, while stateless designs often pass tokens (like JWT) with each request. 101 | 102 | #### Example: Passing a Bearer Token 103 | ```bash 104 | curl -X GET \ 105 | -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \ 106 | https://api.example.com/data 107 | ``` 108 | 109 | - The client includes a JWT in the `Authorization` header for each request. 110 | - The server verifies the token without storing session info (stateless) or might keep session claims in memory or a database (stateful). 111 | 112 | ### Compression and Chunking 113 | Compressing large responses can save bandwidth and speed up response times. The server can automatically compress data if the client’s `Accept-Encoding` header indicates support: 114 | 115 | ```text 116 | Accept-Encoding: gzip, deflate, br 117 | ``` 118 | 119 | Chunked transfer encoding can break large responses into smaller pieces, so the client begins processing data before the entire payload arrives. This approach benefits streaming data but can complicate stateful logic if partial updates must be tracked. 120 | 121 | ### Caching Layers 122 | Caching can dramatically reduce data transmission by serving responses directly from a cache instead of re-fetching. HTTP headers (e.g., `Cache-Control`, `ETag`) can guide caching decisions. Even in a stateful setup, certain resources may not depend on session state and can be cached easily. 123 | 124 | ``` 125 | Client 126 | | 127 | v 128 | +-------------+ 129 | | Cache | 130 | | (Proxy) | 131 | +-------------+ 132 | | 133 | v 134 | +-----------------------+ 135 | | API Server | 136 | | (Stateless or not) | 137 | +-----------------------+ 138 | ``` 139 | 140 | If the requested data hasn’t changed, the proxy returns the cached copy without reaching the server. This design often helps with static resources or read-heavy endpoints. 141 | 142 | ### Example Requests in Different Formats 143 | 144 | #### JSON-based REST 145 | ```bash 146 | curl -X POST -H "Content-Type: application/json" \ 147 | -d '{"userId":123,"action":"login"}' \ 148 | https://example.com/api/login 149 | ``` 150 | - The server returns a JSON response with login status. 151 | - Session tokens might be included in a cookie or an authorization header. 152 | 153 | #### GraphQL 154 | ```bash 155 | curl -X POST -H "Content-Type: application/json" \ 156 | -d '{ 157 | "query": "query { user(id: 123) { name, status } }" 158 | }' \ 159 | https://example.com/graphql 160 | ``` 161 | - The request includes the query in JSON form. 162 | - GraphQL can reduce data transfer by returning only the requested fields. 163 | 164 | #### gRPC with Protobuf 165 | ```bash 166 | grpcurl \ 167 | -d '{"id":"123"}' \ 168 | -plaintext \ 169 | localhost:50051 bookstore.Bookstore/GetBook 170 | ``` 171 | - The client transmits a protobuf message. 172 | - The server responds in a compact binary format. 173 | -------------------------------------------------------------------------------- /notes/02_network_communications/01_overview.md: -------------------------------------------------------------------------------- 1 | ## Network communications 2 | Network communications in a backend context involve the flow of data between clients (browsers, mobile apps, or other services) and server-side applications or services. This process spans multiple layers, from physical transmission over cables or wireless signals, through protocols such as TCP or UDP, and up to application-level constructs like HTTP requests or WebSockets. Understanding these layers helps backend developers build scalable, secure, and efficient systems. 3 | 4 | ### The Layered Perspective 5 | Networking concepts are often explained via layered models. The OSI (Open Systems Interconnection) model has seven layers, while the simplified TCP/IP model typically references four layers. From a backend developer’s point of view, these details become most critical in the Transport and Application layers, where data is packaged, routed, delivered, and processed by the server application. 6 | 7 | ``` 8 | +-------------------------------------------------+ 9 | | Application Layer (HTTP, gRPC, etc.) | 10 | +-------------------------------------------------+ 11 | | Transport Layer (TCP, UDP) | 12 | +-------------------------------------------------+ 13 | | Internet Layer (IP) | 14 | +-------------------------------------------------+ 15 | | Network Access Layer (Ethernet, Wi-Fi) | 16 | +-------------------------------------------------+ 17 | ``` 18 | 19 | The diagram above illustrates the four-layer TCP/IP approach, showing how data moves from higher-level protocols like HTTP down to the physical medium. 20 | 21 | ### Transport Layer Choices 22 | ### TCP vs UDP 23 | Backend applications frequently rely on TCP for most requests that require reliability, such as web pages, JSON APIs, and database connections. UDP is preferred in scenarios where speed and reduced overhead are more important than guaranteed delivery, such as real-time streaming or specific internal network communications. 24 | 25 | **TCP** 26 | - Connection-oriented. 27 | - Guarantees ordered delivery and data integrity. 28 | - Uses flow control and congestion control to optimize throughput. 29 | 30 | **UDP** 31 | - Connectionless. 32 | - No overhead for acknowledgments or retransmissions. 33 | - Well-suited for scenarios where low-latency is more important than reliability. 34 | 35 | ### Application Layer Protocols 36 | #### HTTP-Based (REST, GraphQL) 37 | When developing a REST or GraphQL API, each incoming request is typically transmitted over TCP using HTTP. The server (often listening on ports 80 for HTTP or 443 for HTTPS) parses the request, processes it, and returns a response with headers, status codes, and a response body (JSON, XML, etc.). 38 | 39 | An example flow for a REST request looks like this: 40 | 41 | 1. **DNS Lookup**: The client resolves `api.example.com` to an IP address. 42 | 2. **TCP Handshake**: The client and server perform a TCP handshake on port 443 if HTTPS is used. 43 | 3. **TLS Handshake** (if applicable): The client and server negotiate encryption parameters. 44 | 4. **HTTP Request**: The client sends a request header and optional body. 45 | 5. **Application Logic**: The server processes the request, possibly interacting with databases or external services. 46 | 6. **HTTP Response**: The server sends a status code, headers, and body back to the client. 47 | 48 | ``` 49 | Client (Browser / Mobile) Server (HTTP/HTTPS Listener) 50 | | | 51 | 1. DNS |---------------------------------> (DNS resolves hostname) 52 | | | 53 | 2. TCP |------------------ SYN ----------> (Connection attempt) 54 | 3. Hand- |<----------- SYN-ACK ------------ (Server acknowledges) 55 | shake |------------------ ACK ----------> (Connection established) 56 | | | 57 | 4. TLS |<==== Key Exchange, if HTTPS ===>| 58 | | | 59 | 5. HTTP |------ GET /api/posts HTTP/1.1 -->| 60 | Request | | 61 | | 6. Internal Logic | 62 | | (Database calls, etc.) | 63 | 7. HTTP |<-- 200 OK + JSON in body --------| 64 | Response | | 65 | ``` 66 | 67 | #### WebSockets 68 | WebSockets enable two-way, persistent connections over a single TCP channel. The client initiates a WebSocket handshake via an HTTP request, upgrading the protocol. Once established, messages can flow in both directions without repeated handshakes. 69 | 70 | ``` 71 | +--------------------------+ +--------------------------+ 72 | | WebSocket Client | | WebSocket Server | 73 | | (Browser, etc.) | | (Backend Service) | 74 | +--------------------------+ +-----------+--------------+ 75 | | ^ 76 | | 1. HTTP handshake with upgrade | 77 | |------------------------------------->| 78 | | | 79 | | 2. Connection upgraded to WS | 80 | |<-------------------------------------| 81 | | | 82 | | 3. Bi-directional communication | 83 | |<---------------> | 84 | | | 85 | ``` 86 | 87 | Real-time applications, such as chat systems or collaboration tools, often use WebSockets to push updates instantly from server to client. 88 | 89 | #### gRPC 90 | gRPC (Google Remote Procedure Call) rides on top of HTTP/2 and uses Protocol Buffers (protobuf) by default. It provides efficient, type-safe request/response interactions, plus streaming features. The sequence includes establishing an HTTP/2 connection, then sending RPC calls within the multiplexed channel. 91 | 92 | ### Middleware, Load Balancing, and Reverse Proxies 93 | Backend systems often employ load balancers or reverse proxies to distribute incoming requests across multiple servers. Middleware can intercept requests to handle cross-cutting concerns like authentication, rate-limiting, or logging. 94 | 95 | ``` 96 | Internet 97 | | 98 | | Inbound Traffic (User Requests) 99 | v 100 | +---------------------+ 101 | | Load Balancer / | 102 | | Reverse Proxy | 103 | +---------+-----------+ 104 | | 105 | | Requests distributed 106 | | 107 | +---------v---------------------+ 108 | | Pool of Server Instances | 109 | | e.g., multiple Docker nodes | 110 | +------------------------------+ 111 | ``` 112 | 113 | Reverse proxies like Nginx or HAProxy terminate the incoming TCP connection, possibly handle HTTPS, and then forward packets to the appropriate backend service. 114 | 115 | ### Concurrency and Scaling 116 | Scalability depends on how effectively the backend handles multiple concurrent requests. A high-level concurrency formula might show that maximum concurrency is limited by the product of each request’s duration and the available resources: 117 | 118 | ``` 119 | Max_Concurrent = (Threads or Connections) / (Average_Req_Duration) 120 | ``` 121 | 122 | When load becomes too high, new instances may be started or network traffic can be routed differently (horizontal scaling). Some services implement asynchronous I/O (e.g., Node.js, Go, or async frameworks in Python/Java) to handle many connections efficiently. 123 | 124 | ### Security Layers 125 | #### TLS/SSL 126 | Most production APIs use HTTPS (HTTP over TLS) to encrypt traffic between client and server. This protects data from eavesdropping or tampering. Certificates are issued by Certificate Authorities, and the server’s certificate is validated by the client. 127 | 128 | #### Firewalls and Security Groups 129 | Backend infrastructure often sits behind firewalls, which block unwanted traffic. Cloud environments (AWS, Azure, GCP) provide Security Groups or Network Access Control Lists (ACLs) to limit inbound traffic to specific ports or IP addresses. 130 | 131 | #### Authentication and Authorization 132 | Tokens (JWT, OAuth2), API keys, or session cookies are typically included in request headers to authenticate callers. Authorization logic checks what the caller is allowed to do. 133 | 134 | ### Data Formats and Transmission Efficiency 135 | #### JSON, XML, Protocol Buffers 136 | APIs usually serve data in JSON because it is widely supported and human-readable. XML is common in certain enterprise contexts, while Protocol Buffers and other binary formats offer high performance in microservice architectures. 137 | 138 | #### Compression and Caching 139 | HTTP compression (gzip, Brotli) reduces payload size. Caching can take place at client, proxy, or server levels, using headers like `Cache-Control` and `ETag` to control validity. This can drastically lower bandwidth usage and reduce server load. 140 | 141 | ### Common Network Communication Patterns in Backends 142 | - **Request-Response**: The most common model, where the client sends a request and waits for a server response. 143 | - **Pub/Sub**: A server publishes updates, and subscribers receive messages (e.g., via WebSockets, messaging queues, or streaming). 144 | - **Streaming**: Long-lived connections (HTTP/2, WebSockets, or gRPC streams) enable continuous flows of data. 145 | -------------------------------------------------------------------------------- /notes/02_network_communications/02_tcp_and_udp.md: -------------------------------------------------------------------------------- 1 | ## TCP vs UDP 2 | Transmission Control Protocol (TCP) and User Datagram Protocol (UDP) are foundational Internet protocols that operate on top of IP (Internet Protocol). They determine how data is packaged, addressed, transmitted, and received between devices. TCP prioritizes reliability and ordered delivery. UDP focuses on speed and efficiency with less overhead. Both protocols have unique benefits, and choosing one often depends on the requirements for data integrity, latency, and network conditions. 3 | 4 | ### TCP (Transmission Control Protocol) 5 | TCP is a connection-oriented protocol that ensures packets arrive in sequence. It provides reliability mechanisms like acknowledgments, retransmissions, and congestion control. This makes it ideal for scenarios where missing or out-of-order data is unacceptable, such as file transfers or loading web pages. 6 | 7 | #### How TCP Works 8 | The TCP process begins with a three-way handshake to establish a connection before sending payload data. The ASCII diagram below gives a high-level view of that handshake between a client and a server: 9 | 10 | ``` 11 | Client Server 12 | | | 13 | | 1. SYN (Synchronize) | 14 | |------------------------------->| 15 | | | 16 | | 2. SYN + ACK (Acknowledge) | 17 | |<-------------------------------| 18 | | | 19 | | 3. ACK | 20 | |------------------------------->| 21 | | | 22 | | Connection Established | 23 | |<==============================>| 24 | ``` 25 | 26 | After the connection is established, data is sent in segments. TCP ensures data integrity by requiring the receiver to acknowledge each segment. If an acknowledgment is not received, the segment is retransmitted. 27 | 28 | #### Features of TCP 29 | 1) Connection-Oriented Communication: A handshake is required to initialize and tear down the connection. 30 | 2) Ordered Delivery: Packets arrive in the correct sequence or get reassembled in the proper order. 31 | 3) Reliability: Acknowledgments, timeouts, and retransmissions ensure packets are not lost. 32 | 4) Flow and Congestion Control: Mechanisms adjust the sending rate based on network conditions. 33 | 34 | #### Code Example: Simple TCP Server in Python 35 | ```python 36 | import socket 37 | 38 | HOST = '127.0.0.1' 39 | PORT = 5000 40 | 41 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 42 | s.bind((HOST, PORT)) 43 | s.listen() 44 | print("TCP server listening on port", PORT) 45 | 46 | conn, addr = s.accept() 47 | with conn: 48 | print("Connected by", addr) 49 | data = conn.recv(1024) 50 | print("Received:", data.decode()) 51 | conn.sendall(b"Hello from TCP server!") 52 | ``` 53 | 54 | - After running this code, the server binds to localhost on port 5000 and waits for a connection. 55 | - A client can connect using telnet or netcat, send data, and receive a response. 56 | 57 | #### Typical TCP Use Cases 58 | 1) Web browsing (HTTP/HTTPS). 59 | 2) File transfers (FTP or SCP). 60 | 3) Email protocols (SMTP, IMAP, POP3). 61 | 4) Database connections that require guaranteed delivery of queries and results. 62 | 63 | ### UDP (User Datagram Protocol) 64 | UDP is a connectionless protocol that sends packets called datagrams without establishing a formal channel. It avoids the overhead of handshakes, acknowledgments, and ordered delivery. This makes it well-suited for real-time applications where speed matters more than absolute reliability. 65 | 66 | #### How UDP Works 67 | Communication takes place by sending datagrams to a specified IP and port without any pre-negotiated connection. The following ASCII diagram illustrates how a client and server might exchange data over UDP: 68 | 69 | ``` 70 | Client Server 71 | | | 72 | | 1. UDP Datagram (Data) | 73 | |----------------------------------->| 74 | | | 75 | | 2. UDP Datagram (Response) | 76 | |<-----------------------------------| 77 | | | 78 | | (No handshake or guaranteed | 79 | | arrival order) | 80 | ``` 81 | 82 | Packets may arrive out of sequence, or they might be lost. There is no built-in retry mechanism. UDP relies on the application layer to handle or ignore such issues. 83 | 84 | #### Features of UDP 85 | 1) Connectionless Communication: No handshake or session establishment. 86 | 2) No Guaranteed Delivery: Datagrams can be lost or arrive out of order. 87 | 3) Low Overhead: Faster than TCP due to minimal extra fields in headers and no retransmissions by default. 88 | 4) Suitable for Broadcast or Multicast: Commonly used in local network discoveries or streaming. 89 | 90 | #### Code Example: Simple UDP Server in Python 91 | ```python 92 | import socket 93 | 94 | HOST = '127.0.0.1' 95 | PORT = 5001 96 | 97 | with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: 98 | s.bind((HOST, PORT)) 99 | print("UDP server listening on port", PORT) 100 | 101 | while True: 102 | data, addr = s.recvfrom(1024) 103 | print("Received from", addr, ":", data.decode()) 104 | s.sendto(b"Hello from UDP server!", addr) 105 | ``` 106 | 107 | - This UDP server awaits datagrams on port 5001. 108 | - A client can send datagrams using netcat (nc -u 127.0.0.1 5001) and read responses. 109 | 110 | #### Typical UDP Use Cases 111 | 1) Live video or audio streaming where some packet loss is tolerable. 112 | 2) Online gaming with real-time position updates. 113 | 3) Domain Name System (DNS) lookups for speed. 114 | 4) Internal network broadcast or multicast services. 115 | 116 | ### Comparing TCP and UDP 117 | 118 | | Aspect | TCP | UDP | 119 | |---------------------|---------------------------------------------------|------------------------------------| 120 | | Connection Model | Connection-oriented (3-way handshake) | Connectionless | 121 | | Reliability | Guaranteed delivery with retransmissions | No guarantees, best-effort | 122 | | Ordering | Packets arrive in sequence or are reordered | Packets can arrive in any order | 123 | | Overhead | Higher overhead for handshakes and acknowledgments| Lower overhead, lightweight headers| 124 | | Speed | Slower than UDP due to control mechanisms | Usually faster but less reliable | 125 | | Typical Use Cases | Web requests, file transfers, database access | Streaming media, online games, DNS | 126 | 127 | ### Performance and Throughput 128 | A simplified throughput equation can be used for TCP to illustrate the effects of congestion control: 129 | 130 | ``` 131 | Throughput_tcp ≈ (Window_size / RTT) 132 | ``` 133 | 134 | Window_size is how many bytes can be sent before waiting for an acknowledgment, and RTT is the round-trip time for a segment to reach the receiver and for an acknowledgment to come back. If packet loss is high, the window shrinks and throughput drops. UDP does not have a built-in window mechanism, so throughput depends on application-layer strategies and network capacity. 135 | 136 | ### Security Considerations 137 | Both TCP and UDP can run over secure channels like TLS or DTLS. 138 | 1) TCP over TLS: Often known as HTTPS (for web traffic). 139 | 2) UDP over DTLS: Provides security for datagram-based traffic, such as secure VoIP. 140 | -------------------------------------------------------------------------------- /notes/03_server_technologies/01_web_server_overview.md: -------------------------------------------------------------------------------- 1 | ## Web Server Overview 2 | 3 | Backend engineers are responsible for setting up and maintaining servers that host web applications, APIs, and databases. A solid understanding of server management principles is crucial for delivering robust, high-performing, and secure systems. 4 | 5 | ### Client-Server Architecture 6 | 7 | Client-server architecture underpins most modern networked systems and the internet. It describes how clients (which request services) interact with servers (which provide these services). 8 | 9 | ``` 10 | +-----------+ +-----------+ 11 | | Client 1 | | Client 2 | 12 | +-----+-----+ +-----+-----+ 13 | ^ ^ 14 | | | 15 | | Request/Response | Request/Response 16 | | | 17 | v ^ 18 | +-----+-----+ +-----+-----+ 19 | | | | | 20 | | +------------> | 21 | | Server <------------+ Server | 22 | | | | | 23 | | | | | 24 | +-----+-----+ +-----+-----+ 25 | ^ ^ 26 | | | 27 | v ^ 28 | +-----+-----+ +-----+-----+ 29 | | Client 3 | | Client 4 | 30 | +-----------+ +-----------+ 31 | ``` 32 | 33 | 1. **Client** 34 | - Sends requests for data or services, typically through protocols like HTTP, FTP, or SMTP. 35 | - Can be anything from a web browser to a mobile app or IoT device. 36 | 37 | 2. **Server** 38 | - Receives and processes client requests, then returns appropriate responses. 39 | - Could be a web server, database server, mail server, etc. 40 | 41 | 3. **Communication** 42 | - Relies on a network (often the internet). 43 | - Common protocols include HTTP for web traffic, FTP for file transfer, and SMTP for email. 44 | 45 | #### Architecture Patterns 46 | 47 | - **Two-Tier Architecture** 48 | - Direct communication between client and server. 49 | - Suitable for simple setups or smaller user bases. 50 | 51 | ``` 52 | +--------+ +------------------+ 53 | | Client | <--> | Server (DB) | 54 | +--------+ +------------------+ 55 | ``` 56 | 57 | - **Three-Tier Architecture** 58 | - Separates presentation (client), application (middle layer), and data (database) layers. 59 | - Helps in organizing complex applications, enhancing security, and scaling individual layers independently. 60 | 61 | ``` 62 | +--------+ +------------------+ +------------------+ 63 | | Client | <--> | App Server | <--> | Database | 64 | +--------+ +------------------+ +------------------+ 65 | ``` 66 | 67 | - **N-Tier (Multi-Tier) Architecture** 68 | - Adds more layers, such as separate microservices, caching servers, or specialized business logic layers. 69 | - Offers enhanced scalability, flexibility, and maintainability. 70 | 71 | ``` 72 | +--------+ 73 | | Client | 74 | +---+----+ 75 | | 76 | v 77 | +-------------------+ +-------------------+ 78 | | Web Tier (API) | <--> | Business Logic | 79 | +--------+----------+ +---------+---------+ 80 | | | 81 | v v 82 | +-------------------+ +--------------------+ 83 | | Caching / Queue | | Database / Storage| 84 | +-------------------+ +--------------------+ 85 | ``` 86 | 87 | #### Advantages 88 | 89 | - **Scalability**: Servers can handle many clients concurrently. 90 | - **Maintenance**: Upgrading back-end services does not disrupt client applications. 91 | - **Security**: Central control over data and authentication. 92 | - **Resource Sharing**: Efficient usage of server hardware and software resources. 93 | 94 | #### Disadvantages 95 | 96 | - **Dependency**: Clients rely on server uptime. 97 | - **Network Dependency**: Requires stable network connections. 98 | - **Congestion**: High load can overwhelm the server if not scaled properly. 99 | 100 | ### Server Types 101 | 102 | Servers can be provisioned in different ways depending on performance requirements, budget, and desired control: 103 | 104 | 1. **Dedicated Servers** 105 | - A single physical machine dedicated to one application or client. 106 | - High performance, maximum control, but often costlier. 107 | 108 | 2. **Virtual Private Servers (VPS)** 109 | - A virtualized portion of a physical server. 110 | - More affordable than dedicated servers, offering reasonable performance and control. 111 | 112 | 3. **Cloud Servers** 113 | - Managed by cloud providers like AWS, Azure, or Google Cloud. 114 | - Highly scalable and flexible, pay-as-you-go model. 115 | - Cost can vary based on usage and resource consumption. 116 | 117 | ``` 118 | +-----------+ 119 | | Client 1 | 120 | +-----+-----+ 121 | | 122 | | HTTP Request 123 | v 124 | +-----------------------+ 125 | | Web Server | 126 | |-----------------------| 127 | | - Hosts Web Pages | 128 | | - Processes Requests | 129 | | - Sends Responses | 130 | +-----------------------+ 131 | ^ 132 | | HTTP Response 133 | | 134 | +-----+-----+ 135 | | Client 2 | 136 | +-----------+ 137 | ``` 138 | 139 | ### Operating Systems 140 | 141 | - **Linux (Ubuntu, CentOS, Debian, etc.)** 142 | - Popular in server environments for stability, security, and open-source ecosystem. 143 | - Powerful command-line tools, extensive community support. 144 | 145 | - **Windows Server** 146 | - Chosen for .NET environments or for integrating with other Microsoft services. 147 | - Graphical interfaces and Windows-centric tools. 148 | 149 | ### Server Configuration 150 | 151 | To run services effectively, servers require careful setup: 152 | 153 | - **Web Server Software**: Apache, Nginx, IIS, or others. 154 | - **Database Servers**: MySQL, PostgreSQL, MongoDB, etc. 155 | - **Caching Systems**: Redis or Memcached for faster data retrieval. 156 | - **Language Runtimes/Frameworks**: Node.js, Python, Ruby, Java, PHP. 157 | 158 | #### Example Setup (Ubuntu + Nginx + Node.js + MongoDB) 159 | 160 | 1. **Install OS**: Start with Ubuntu as the server operating system. 161 | 2. **Install Nginx**: Configure it to serve static files and proxy requests to Node.js. 162 | 3. **Install Node.js**: Run the application logic or API. 163 | 4. **Install MongoDB**: Store and manage application data. 164 | 5. **Configure Firewalls**: Secure traffic, allowing only HTTP/HTTPS and SSH as needed. 165 | 166 | ### Security 167 | 168 | Securing a server is crucial to prevent unauthorized access and data breaches: 169 | 170 | - **Firewalls**: Configure iptables or ufw to control network traffic. 171 | - **SSL/TLS Certificates**: Use HTTPS for secure client-server communication. 172 | - **User Access Control**: Implement key-based SSH authentication, minimal open ports. 173 | - **Regular Updates**: Keep system packages and software patched. 174 | - **Intrusion Detection**: Tools like fail2ban or tripwire to monitor malicious activity. 175 | 176 | ### Performance Tuning 177 | 178 | Optimizing server performance involves balancing resource usage and application demands: 179 | 180 | - **Load Balancing**: Use reverse proxies (e.g., HAProxy, Nginx) or load balancers to distribute requests. 181 | - **Caching**: Implement in-memory caches or content caching to reduce repeated computation. 182 | - **Resource Monitoring**: Tools like `top`, `htop`, or `nmon` help identify CPU, RAM, or I/O bottlenecks. 183 | - **Database Indexing**: Proper indexes and query optimization for better query performance. 184 | 185 | ### Backup and Disaster Recovery 186 | 187 | A robust strategy ensures minimal downtime and data loss: 188 | 189 | - **Regular Backups**: Automate database snapshots and file backups (daily, weekly). 190 | - **Redundancy**: Set up replicas or high-availability clusters (e.g., MySQL replication). 191 | - **Recovery Testing**: Regularly test restoring backups to validate the process. 192 | 193 | ### Automation and CI/CD 194 | 195 | Streamlined development and deployment pipelines keep the server environment consistent and reliable: 196 | 197 | - **Scripting**: Use Bash, Python, or Ansible for repetitive admin tasks. 198 | - **Continuous Integration**: Tools like Jenkins, GitLab CI automate building and testing code changes. 199 | - **Continuous Deployment**: Deploy updates quickly and safely to staging or production. 200 | 201 | ### Monitoring and Alerts 202 | 203 | Detecting and responding to issues quickly is essential: 204 | 205 | - **Monitoring Tools**: Nagios, Prometheus, Grafana for real-time metrics and alerting. 206 | - **Log Management**: ELK Stack (Elasticsearch, Logstash, Kibana) for centralizing and analyzing logs. 207 | - **Alerts**: Configure email/SMS/Slack alerts for system anomalies, such as high CPU usage or downtime. 208 | -------------------------------------------------------------------------------- /notes/03_server_technologies/02_static_dynamic_content.md: -------------------------------------------------------------------------------- 1 | ## Static and Dynamic Content 2 | Web servers deliver two main types of content: static and dynamic. Static content usually consists of files (HTML, CSS, images, JavaScript) that rarely change and can be served directly from the file system or a cache. Dynamic content is generated on the fly by server-side logic (such as PHP, Node.js, or Python) or by client-side scripts interacting with APIs. Understanding these distinctions helps optimize performance, caching strategies, and user experience. 3 | 4 | ### Static Content 5 | Static content is pre-generated and served “as is” from the server without needing to run additional processing or database queries. Since the files do not change often, the server can simply read them from disk (or memory cache) and send them to clients. 6 | 7 | #### Examples of Static Content 8 | 1) **HTML Files**: Basic web pages with fixed layout and text. 9 | 2) **Images and Videos**: Media assets such as JPEG, PNG, MP4. 10 | 3) **CSS Stylesheets**: Styling instructions for webpages. 11 | 4) **JavaScript Files**: Client-side scripts that do not change (though they might produce dynamic behavior in the browser). 12 | 13 | #### How Static Serving Works 14 | A simplified ASCII diagram illustrates the process of delivering static resources: 15 | 16 | ``` 17 | Client (Browser) Web Server (Static) 18 | | | 19 | | 1. HTTP GET /image.png | 20 | |------------------------->| 21 | | | 22 | | 2. Lookup file on disk 23 | | or in memory cache 24 | | | 25 | | 3. Serve file as response 26 | |<-------------------------| 27 | | | 28 | | (Browser displays image) 29 | ``` 30 | 31 | #### Pros of Static Content 32 | 1) **High Performance**: No server-side processing beyond file I/O, so requests are usually fast. 33 | 2) **Cache Friendly**: Files can be cached by CDNs, browsers, and proxies, reducing repeated fetches. 34 | 3) **Scalable**: Serving static files can handle massive traffic with minimal overhead when combined with caching or CDNs. 35 | 4) **Security**: Static files do not directly expose server-side code or database connections. 36 | 37 | #### Cons of Static Content 38 | 1) **Lacks Real-Time Updates**: Requires manual or automated build steps to modify content. 39 | 2) **Limited Personalization**: Cannot easily tailor content based on user inputs or database queries. 40 | 41 | #### Simple Example with Nginx 42 | Here is a minimal Nginx configuration snippet to serve static files from `/var/www/html`: 43 | 44 | ```nginx 45 | server { 46 | listen 80; 47 | server_name example.com; 48 | 49 | root /var/www/html; 50 | index index.html; 51 | 52 | location / { 53 | try_files $uri $uri/ =404; 54 | } 55 | } 56 | ``` 57 | 58 | Explanation: 59 | - The server listens on port 80 for HTTP requests. 60 | - Files in `/var/www/html` are served directly. 61 | - If a file isn’t found, a 404 error is returned. 62 | 63 | ### Dynamic Content 64 | Dynamic content is generated at request time. Server-side scripts or programs build responses by interacting with databases, performing logic, and customizing output per user or context. Alternatively, content can also be dynamically rendered on the client side using JavaScript that calls backend APIs. 65 | 66 | #### Server-Side Dynamic Content 67 | This approach involves frameworks like Express (Node.js), Django (Python), Ruby on Rails, PHP, or Java-based applications. A typical request flow might look like: 68 | 69 | ``` 70 | Client (Browser) Application Server 71 | | | 72 | | 1. HTTP GET /profile | 73 | |------------------------->| 74 | | | 75 | | 2. Run server-side code: 76 | | - Validate session 77 | | - Query database for user data 78 | | - Render template with user info 79 | | | 80 | | 3. Return generated HTML 81 | |<-------------------------| 82 | | | 83 | | (Browser displays personalized page) 84 | ``` 85 | 86 | The server might fetch user data from a database, apply business rules, then generate an HTML page on the fly. 87 | 88 | #### Client-Side Dynamic Content 89 | In this scenario, the server often delivers a mostly static HTML/JavaScript app. Once loaded, client-side JavaScript calls an API (e.g., a REST or GraphQL endpoint) to retrieve or submit data. The browser updates the DOM dynamically without reloading the entire page. 90 | 91 | 1) **Initial load**: Serve an HTML/JS bundle. 92 | 2) **API calls**: The JavaScript code fetches data from endpoints. 93 | 3) **DOM updates**: The application dynamically changes the page content in response to user input or new data. 94 | 95 | #### Pros of Dynamic Content 96 | 1) **Personalization**: Content can adapt to user sessions, preferences, or real-time data. 97 | 2) **Database-Driven**: Frameworks easily fetch from databases and create fresh views. 98 | 3) **Rich Interactivity**: Client-side applications can present dynamic UIs without full page reloads. 99 | 100 | #### Cons of Dynamic Content 101 | 1) **Higher Server Load**: Generating pages or serving data from DB queries adds overhead. 102 | 2) **Caching Complexity**: Output can vary per request, making it harder to cache effectively. 103 | 3) **Security Concerns**: Server-side code can have vulnerabilities (SQL injection, cross-site scripting) if not written properly. 104 | 105 | #### Simple Server-Side Example (Node.js/Express) 106 | 107 | ```js 108 | const express = require('express'); 109 | const app = express(); 110 | const PORT = 3000; 111 | 112 | app.get('/hello/:name', (req, res) => { 113 | const userName = req.params.name; 114 | // Dynamic response 115 | res.send(`

Hello, ${userName}!

`); 116 | }); 117 | 118 | app.listen(PORT, () => { 119 | console.log(`Server running on http://localhost:${PORT}`); 120 | }); 121 | ``` 122 | 123 | Explanation: 124 | - The route `/hello/:name` captures a parameter in the URL. 125 | - The server renders a custom greeting with the user-supplied name. 126 | - Each request is processed at runtime. 127 | 128 | ### Hybrid Approaches and Caching 129 | Real-world applications often serve a mix of static and dynamic content. For instance, static files (images, CSS) might be on a CDN, while dynamic requests go to application servers. 130 | 131 | #### Edge-Side Includes and Partial Templating 132 | - Some sites generate partial dynamic components while the rest of the page remains static. 133 | - CDNs can handle static portions while dynamically fetching content fragments from an origin server. 134 | 135 | #### Server-Side Caching Layers 136 | For dynamic pages that don’t change frequently, caching can be applied at various layers: 137 | 138 | ``` 139 | Client CDN/Reverse Proxy Application Server 140 | | | | 141 | | 1. Request /blog | | 142 | |------------------------->| 2. Cache check | 143 | | |-> if found, serve from cache | 144 | | |-> else forward to origin | 145 | |<-------------------------| | 146 | | (cached or newly fetched content) | 147 | ``` 148 | 149 | When the server knows a page rarely changes, it can store the generated output. The next request might be served directly from cache, accelerating performance. 150 | 151 | ### Performance Considerations 152 | 153 | #### Response Times and Throughput 154 | A formula for concurrency can illustrate the difference in server load for static vs dynamic: 155 | 156 | ``` 157 | Max_Connections = (Available_Threads or Workers) / Average_Request_Time 158 | ``` 159 | 160 | - For static files, `Average_Request_Time` is minimal (reading from file system or memory). 161 | - For dynamic requests, generating content can increase `Average_Request_Time`, thus lowering `Max_Connections`. 162 | 163 | #### Scalability 164 | Static servers are easily scaled horizontally with CDNs or multiple mirrored instances. Dynamic servers often require logic replication, database scaling, or load-balancing across multiple application nodes. 165 | 166 | #### Bandwidth Usage 167 | Large static files can be served via CDN to reduce load on the origin server. Dynamic requests frequently have smaller payloads (JSON, HTML fragments), but the server’s CPU and database resources handle the heavier processing. 168 | 169 | ### Example Deployment Scenarios 170 | 171 | #### Fully Static Site with CDN 172 | 1) HTML/CSS/JS are built (e.g., via a static site generator). 173 | 2) Content is uploaded to a CDN like Cloudflare or AWS CloudFront. 174 | 3) Users fetch content from geographically distributed edge servers. 175 | 176 | ``` 177 | Client 178 | | 179 | | (HTTP GET) 180 | v 181 | [CDN Edge Server] -- retrieves from origin if needed --> [Origin Bucket or Host] 182 | ``` 183 | 184 | This design excels for blogs, documentation, or landing pages without user-specific data. 185 | 186 | #### Dynamic Web App with API 187 | 1) A Node.js or Python server handles user sessions. 188 | 2) Requests that need personalization or database queries go through the backend. 189 | 3) Static assets (images, scripts) can still be offloaded to a CDN. 190 | 191 | ``` 192 | Client 193 | | 194 | | GET /app 195 | v 196 | [Web/App Server] -- queries DB --> [Database] 197 | | 198 | | Serves HTML or JSON 199 | v 200 | Client updates the UI 201 | ``` 202 | 203 | In this pattern, the server merges data with templates or returns JSON for a client-side app to render. 204 | 205 | ### When to Choose Static vs Dynamic 206 | 1) **Static**: Content that seldom changes, marketing pages, product brochures, or high-traffic sites that can benefit from CDN caching. 207 | 2) **Dynamic**: Personalized dashboards, e-commerce with custom user carts, real-time feeds, or any scenario that relies on active data processing. 208 | 209 | Real-world applications commonly blend both. Static resources like images and CSS are straightforward to cache, while dynamic endpoints handle user interactions or frequent data updates. 210 | -------------------------------------------------------------------------------- /notes/03_server_technologies/06_forward_proxies.md: -------------------------------------------------------------------------------- 1 | ## Proxies in Network Architecture 2 | 3 | Proxies function as intermediaries in the communication flow between clients and servers, performing tasks such as **request routing**, **caching**, **encryption offloading**, and **IP masking**. By inserting themselves between the client and the destination server, proxies can manage connections in ways that provide **anonymity**, **load balancing**, and **performance improvements**. Below is an expanded discussion with ASCII diagrams and practical explanations of how proxies are organized and used. 4 | 5 | ### A Layer of Indirection 6 | 7 | ``` 8 | # General Proxy Setup 9 | 10 | +-----------+ +---------+ +------------+ 11 | | Client | -----> | Proxy | -----> | Server(s) | 12 | +-----------+ +---------+ +------------+ 13 | ^ | ^ 14 | | (Network) | 15 | +---------------------------------------+ 16 | ``` 17 | 18 | 1. **Client** 19 | - Initiates the request (e.g., a user’s web browser, a mobile app, or an API consumer). 20 | - Sees the proxy as the destination server in many configurations. 21 | 22 | 2. **Proxy** 23 | - Receives requests, optionally modifies them, then forwards them to the actual server. 24 | - Returns the server’s response to the client as if it were the origin itself. 25 | 26 | 3. **Server** 27 | - Hosts the actual resources or services the client is trying to access. 28 | - May see all traffic as originating from the proxy rather than from the real client IP. 29 | 30 | ### Varieties of Proxy Servers 31 | 32 | #### Open Proxies 33 | 34 | - **Definition**: Freely accessible by any user on the internet. 35 | - **Primary Use**: Anonymizing online traffic by masking user IPs. 36 | - **Risks**: 37 | - Often unverified or maintained by unknown third parties. 38 | - Potential for malicious activity, e.g., monitoring user data or distributing malware. 39 | 40 | ``` 41 | # Simple Open Proxy 42 | 43 | Client -> Public/Open Proxy -> Destination Server 44 | ``` 45 | 46 | #### Anonymous Proxies 47 | 48 | - **Definition**: Reveals its proxy status to the server but does **not** disclose the client’s IP address. 49 | - **Benefits**: 50 | - Balance between **concealing** the client IP and performing request-forwarding tasks. 51 | - Often used for safer browsing or bypassing content filters while announcing “This is a proxy.” 52 | 53 | #### Transparent Proxies 54 | 55 | - **Definition**: Neither hides the proxy server’s identity nor the client’s IP address. 56 | - **Main Role**: Caching and content filtering without providing anonymity. 57 | - **Typical Usage**: 58 | - Organizational networks or ISPs to **improve performance** by caching frequently accessed data. 59 | - **Example**: A hotel Wi-Fi service that intercepts HTTP requests to apply usage policies. 60 | 61 | #### Reverse Proxies 62 | 63 | - **Definition**: Deployed in front of **servers** to handle inbound requests. 64 | - **Roles**: 65 | - **Load balancing**: Distributing requests among multiple back-end servers. 66 | - **SSL Offloading**: Terminates SSL/TLS so back-end servers handle only plain HTTP. 67 | - **Security**: Filters incoming traffic, blocks suspicious or malicious payloads. 68 | 69 | ``` 70 | ASCII DIAGRAM: Reverse Proxy in Front of Web Servers 71 | 72 | Internet 73 | | 74 | (Requests/Responses) 75 | v 76 | +--------------------+ 77 | | Reverse Proxy | 78 | | (Load Balancer) | 79 | +---------+----------+ 80 | | 81 | (Distributes traffic) 82 | +-------+-------+ 83 | | | 84 | v v 85 | +-----------+ +-----------+ 86 | | Server1 | | Server2 | 87 | +-----------+ +-----------+ 88 | ``` 89 | 90 | ### Forward Proxy Architecture 91 | 92 | A **forward proxy** is typically set up on the client side of a connection. It receives outbound requests from clients and relays them to the internet. This can provide **privacy** (the server sees only the proxy’s IP), caching, or traffic filtering. 93 | 94 | ``` 95 | ASCII DIAGRAM: Forward Proxy Setup 96 | 97 | Clients Forward Proxy Internet 98 | -------------------------------------------------------- 99 | | | | | | | 100 | | C1 |---Request--| |---Request-->| W1 | 101 | | |<--Response-| FP |<--Response--| | 102 | |------| | | |------| 103 | | C2 |---Request--| |---Request-->| W2 | 104 | | |<--Response-| |<--Response--| | 105 | |------| | | |------| 106 | | C3 |---Request--| |---Request-->| W3 | 107 | | |<--Response-| |<--Response--| | 108 | -------------------------------------------------------- 109 | ``` 110 | 111 | - **Clients (C1, C2, C3)**: Send outbound web requests. 112 | - **Forward Proxy (FP)**: Intercepts and relays requests to external websites (W1, W2, W3). 113 | - **Use Cases**: 114 | - Corporate networks restricting external access. 115 | - Individuals bypassing geographical restrictions or content filters. 116 | - Caching frequently accessed resources (e.g., OS updates) to save bandwidth. 117 | 118 | ### Reverse Proxy Architecture 119 | 120 | A **reverse proxy** stands before your internal servers to receive incoming traffic from the internet. Users make requests to the proxy’s IP or domain name, and the proxy decides which server in the back-end should handle each request. 121 | 122 | ``` 123 | ASCII DIAGRAM: Reverse Proxy Setup 124 | 125 | Internet Reverse Proxy Internal Network 126 | ------------------------------------------------------------------------- 127 | | | | | | WS1 | WS2 | ... | WSn | 128 | | | | | |-----|-----| |-----| 129 | | WWW |---Request--| RP |---Request--| | | | | 130 | | |<--Response-| |<--Response-|-----|-----|-----|-----| 131 | | | | | | | | | | 132 | ------------------------------------------------------------------------- 133 | ``` 134 | 135 | - **Reverse Proxy (RP)**: Terminates incoming requests from external clients, selects an internal server (WS1, WS2, etc.) for processing, and then sends the server’s response back to the client. 136 | - **Common Tasks**: 137 | - **Load Balancing**: Distributes requests based on server health or capacity. 138 | - **Security**: May filter suspicious requests, hide back-end servers behind private IPs, or handle DDoS mitigation. 139 | - **SSL/TLS Offloading**: Terminates SSL/TLS connections, passing unencrypted traffic to internal servers. 140 | 141 | 142 | ### Easy Way to Remember: Forward vs. Reverse 143 | 144 | 1. **Forward Proxy** 145 | - **Acts on behalf of the client**. 146 | - Clients connect to resources through it. 147 | - Provides client anonymity, caching, or content filtering. 148 | 149 | **Analogy**: A personal assistant (forward proxy) obtains data from the outside world, so external services see the assistant rather than the real person making the request. 150 | 151 | 2. **Reverse Proxy** 152 | - **Acts on behalf of the server**. 153 | - Internet clients see the proxy as the “server.” 154 | - Balances load, hides internal infrastructure, adds security layers. 155 | 156 | **Analogy**: A receptionist or front desk (reverse proxy) routes incoming callers or visitors to the correct department, ensuring they never directly see or contact internal offices without going through the receptionist. 157 | 158 | 159 | ### Additional Advantages of Proxies 160 | 161 | - **Anonymity & Privacy** 162 | - Masks the client’s IP, ensuring the **destination server** sees only the proxy IP. 163 | - Can also encrypt traffic, preventing eavesdropping on intermediate hops. 164 | 165 | - **Geo-Restriction Bypass** 166 | - A client can connect through a proxy in a different **geographic** region, accessing content that might otherwise be blocked. 167 | 168 | - **Traffic Filtering and Security** 169 | - Proxies can enforce **organizational policies**, like blocking malicious or time-wasting sites. 170 | - Reverse proxies can filter harmful requests, scanning for suspicious patterns to protect back-end servers. 171 | 172 | - **Load Balancing** 173 | - Reverse proxies distribute **incoming** requests across multiple servers, improving uptime and response times. 174 | 175 | - **Caching** 176 | - Both forward and reverse proxies can cache content. Forward proxies typically cache external content for local users; reverse proxies cache content for external users, reducing load on servers. 177 | 178 | ``` 179 | ASCII DIAGRAM: Combined Reverse Proxy / Cache 180 | 181 | +--------------+ +---------------+ +---------------+ 182 | | Internet | ---> | Reverse Proxy | ---> | Web Server | 183 | +--------------+ | + Cache | +---------------+ 184 | +---------------+ 185 | ``` 186 | 187 | - When clients request popular resources, the proxy can **serve** them from its cache instead of hitting the origin server, leading to faster responses and reduced server load. 188 | 189 | ### Considerations 190 | 191 | - **Performance Impact** 192 | - Proxies add an extra network hop, so choose or configure them carefully to avoid becoming a bottleneck. 193 | - Memory and CPU overhead for caching or SSL termination can be substantial in high-traffic scenarios. 194 | 195 | - **Security Risks** 196 | - Improperly configured proxies can leak private data or become open entry points for attacks. 197 | - Open proxies, in particular, can be associated with illegal activities if not monitored. 198 | 199 | - **Logging and Analytics** 200 | - Proxies see all traffic, making them prime points for monitoring, usage control, and access logs. 201 | - Must handle **privacy** concerns and comply with data protection regulations. 202 | 203 | - **Scalability** 204 | - Large-scale architectures may deploy multiple **proxy nodes** in a cluster, sometimes behind a load balancer, to handle increased throughput. 205 | 206 | - **Compatibility** 207 | - Some protocols (e.g., WebSockets, HTTPS) require additional considerations to function properly through proxies. 208 | - Reverse proxies dealing with TLS might need special configurations (SNI, ALPN). 209 | -------------------------------------------------------------------------------- /notes/03_server_technologies/07_reverse_proxies.md: -------------------------------------------------------------------------------- 1 | ## Reverse Proxy 2 | 3 | A reverse proxy is a special server that receives incoming requests from external clients and forwards them to one or more internal web servers. By acting as an intermediary, it hides the details of the internal network, providing a single entry point that can improve load balancing, security, caching, and overall performance of the back-end servers. 4 | 5 | ``` 6 | ASCII DIAGRAM: Reverse Proxy in Action 7 | 8 | +----------------------+ 9 | | Internet | 10 | +---------+-----------+ 11 | | 12 | (Incoming Requests) 13 | v 14 | +------+------+ 15 | | Reverse | 16 | | Proxy | 17 | +------+------+ 18 | | 19 | (Traffic routed to appropriate server) 20 | +------+--------+--------+------+ 21 | | | | | | 22 | v v v v v 23 | +---------+--+ +----------+--+ +----------+--+ 24 | | Web Server 1 | | Web Server 2 | | Web Server 3 | 25 | +--------------+ +--------------+ +--------------+ 26 | ``` 27 | 28 | 1. **Client**: Makes an HTTP/HTTPS request to a domain or IP, not knowing there are multiple servers behind a reverse proxy. 29 | 2. **Reverse Proxy**: Decides which internal server handles the request, often based on load-balancing rules or caching policies. 30 | 3. **Internal Servers**: Process the request and send a response back through the proxy, which then returns it to the client. 31 | 32 | ### Comparing Forward and Reverse Proxies 33 | 34 | | **Forward Proxy** | **Reverse Proxy** | 35 | |-----------------------------------------------------------|----------------------------------------------------------------| 36 | | Sits between **clients** and the **internet**. | Positioned between **external users** and **internal servers**.| 37 | | **Primarily** used for client anonymity, caching, or content filtering on outbound connections. | **Primarily** used for load balancing, security, caching, and controlling inbound connections. | 38 | | Often used to bypass **geographic restrictions** or apply organizational policies for outbound traffic. | Often used to protect internal servers from direct exposure, enhance performance, and handle SSL offloading. | 39 | 40 | 41 | ### How a Reverse Proxy Works 42 | 43 | 1. **Request to Proxy**: A client sends a request (e.g., `GET /index.html`) to the reverse proxy’s IP or domain. 44 | 2. **Server Selection**: The proxy checks its rules (like load balancing or caching). 45 | 3. **Forwarding**: The request is routed to a suitable **backend** server (e.g., one with the smallest load). 46 | 4. **Response Return**: The chosen server responds back to the proxy. 47 | 5. **Final Delivery**: The proxy sends the server’s response to the client as if it was from the proxy itself. 48 | 49 | ``` 50 | Client -> Reverse Proxy -> Web Server -> Reverse Proxy -> Client 51 | ``` 52 | 53 | ### Common Use Cases 54 | 55 | I. Load Balancing 56 | 57 | - **Distributes** incoming requests across multiple servers to avoid overloading any one host. 58 | - Improves **availability** by detecting offline servers and redirecting traffic to healthy ones. 59 | 60 | II. Web Acceleration 61 | 62 | - **Caching**: Frequently accessed pages or resources can be saved at the proxy for faster delivery. 63 | - **Compression**: Compresses responses to reduce bandwidth and speed up transmissions. 64 | - **SSL/TLS Termination**: Proxy handles encryption/decryption, easing the CPU load on web servers. 65 | 66 | III. Security and Anonymity 67 | 68 | - **Shielding**: Hides the internal structure and IPs of your server farm. 69 | - **Attack Mitigation**: Can filter suspicious traffic or block malicious payloads before they reach back-end servers. 70 | - **Logging and Monitoring**: Consolidates logging and tracking of requests at the proxy level. 71 | 72 | IV. SSL Encryption 73 | 74 | - **SSL Offloading**: The proxy handles certificate details and SSL encryption, letting back-end servers communicate via plain HTTP. 75 | - **Easier Certificate Management**: Central place to manage SSL certificates for multiple services. 76 | 77 | ### Types of Reverse Proxies 78 | 79 | I. Software-Based 80 | 81 | - **Examples**: Nginx, Apache HTTP Server, HAProxy, Envoy. 82 | - **Characteristics**: 83 | - **Flexible**: Highly configurable via modules or directives. 84 | - **Open Source**: Large community support and extensive documentation. 85 | - **Scalable**: Can handle small to medium sites as well as high-traffic applications. 86 | 87 | II. Hardware-Based 88 | 89 | - **Appliances** from F5, Citrix, or Cisco. 90 | - **Specialized**: Dedicated hardware with optimized chips for SSL acceleration or content switching. 91 | - **High Performance**: Suited to enterprise data centers needing ultra-low latency and high throughput. 92 | - **Costly**: More expensive than software solutions but provides advanced feature sets and reliability. 93 | 94 | III. Cloud-Based Reverse Proxies 95 | 96 | - **Managed Solutions**: Services like AWS Elastic Load Balancing (ALB/ELB), Cloudflare, or Akamai. 97 | - **Advantages**: 98 | - **Scalable**: Instantly add more capacity. 99 | - **Global**: Edge locations reduce latency for users worldwide. 100 | - **Low Maintenance**: Offload management of hardware and updates to the provider. 101 | 102 | ### Security Implications 103 | 104 | I. Security Benefits 105 | 106 | - **Hides Backend Servers**: Attackers only see the reverse proxy’s address, reducing attack surface on internal servers. 107 | - **Traffic Filtering**: Built-in Web Application Firewalls (WAFs) can block SQL injection, XSS, or suspicious patterns. 108 | - **DDoS Mitigation**: Can throttle or blacklist offending IPs, and help absorb volumetric attacks. 109 | 110 | II. Potential Risks 111 | 112 | - **Single Point of Failure**: If the proxy itself goes down without redundancy, the entire site may be inaccessible. 113 | - **Misconfiguration**: Complex rules or incomplete SSL setups can create vulnerabilities. 114 | - **Trust Issues**: The proxy has access to unencrypted data if SSL is terminated at the proxy. Proper security measures are essential. 115 | 116 | III. Integrating with Other Security Tools 117 | 118 | - **Firewalls**: Combine with perimeter firewalls or intrusion prevention systems (IPS). 119 | - **WAF (Web Application Firewall)**: Deploy on or alongside the proxy to inspect HTTP traffic in detail. 120 | - **Regular Updates**: Keep proxy software current with security patches, ensuring known exploits are mitigated. 121 | -------------------------------------------------------------------------------- /notes/03_server_technologies/08_load_balancing.md: -------------------------------------------------------------------------------- 1 | ## Load Balancing in Distributed Systems 2 | 3 | Load balancing is central to designing robust distributed systems. It ensures that incoming requests or workloads are equitably distributed across multiple servers or nodes, thereby preventing any single server from becoming a bottleneck. This technique also boosts system resilience, providing higher availability and scalability. 4 | 5 | ``` 6 | ASCII DIAGRAM: High-Level Load Balancing 7 | 8 | +---------+ 9 | | Client | 10 | +----+----+ 11 | | 12 | (HTTP/TCP Requests) 13 | v 14 | +-----+------+ 15 | | Load | 16 | | Balancer | 17 | +-----+------+ 18 | | 19 | (Distributes requests) 20 | v 21 | +-----------+-----------+ 22 | | Server 1 (S1) | 23 | +-----------+-----------+ 24 | | Server 2 (S2) | 25 | +-----------+-----------+ 26 | | Server 3 (S3) | 27 | +-----------+-----------+ 28 | ``` 29 | 30 | - A client sends requests to the **Load Balancer (LB)** instead of a single server. 31 | - The load balancer **distributes** requests among multiple servers based on a chosen algorithm. 32 | - **Responses** are returned to the load balancer, which then passes them back to the client. 33 | 34 | ### Significance of Load Balancing 35 | 36 | Implementing a load balancer in a distributed system offers **multiple** advantages: 37 | 38 | - **Resource Utilization** 39 | - Each server handles a fair portion of the traffic, avoiding under-utilization or overburdening. 40 | - **Reduced Latency** 41 | - Requests can be processed **concurrently**, leading to faster response times. 42 | - **High Availability** 43 | - If a server fails, the load balancer redirects traffic to other active servers. 44 | - Ensures minimal disruption during hardware or software failures. 45 | - **Scalability** 46 | - Additional servers can be **added** seamlessly behind the load balancer to handle increased loads. 47 | 48 | ### How Load Balancers Work 49 | 50 | Load balancers apply algorithms to decide where each incoming request goes. They typically include: 51 | 52 | #### Health Checks 53 | 54 | - The load balancer **pings** or **sends heartbeats** to servers to verify if they are up and responding correctly. 55 | - Unresponsive servers are **taken** out of rotation until they recover. 56 | 57 | #### Traffic Distribution Techniques 58 | 59 | Below are common methods for distributing requests: 60 | 61 | 1. **Least Connection** 62 | - Routes new requests to the server with the fewest active connections. 63 | - Helpful if requests have varying durations, preventing busy servers from becoming overloaded. 64 | 65 | 2. **Least Response Time** 66 | - Considers both the **current number** of active connections and the **average latency**. 67 | - Aims to pick the server that can respond **fastest**. 68 | 69 | 3. **Least Bandwidth** 70 | - Monitors ongoing traffic in Mbps or Gbps and sends new requests to the server with the **lowest** bandwidth utilization. 71 | 72 | 4. **Round Robin** 73 | - Sequentially distributes requests across servers in a **cyclical** order (S1 → S2 → S3 → S1 …). 74 | - **Weighted Round Robin** accounts for each server’s capacity, giving a powerful server more requests. 75 | 76 | 5. **IP Hash** 77 | - Uses a **hash** of the client’s IP address to pick a server. 78 | - Ensures the same client IP typically routes to the same server (session persistence), common in Layer 4 load balancing. 79 | 80 | 6. **Consistent Hashing** 81 | - The hash of the request (e.g., session ID, cache key) maps to a server “ring.” 82 | - When a server is **added** or **removed**, only a small subset of the keys or requests are remapped, aiding caching consistency. 83 | 84 | 7. **Layer 7 Load Balancing** 85 | - **Application-level** load balancing that inspects HTTP headers, URLs, cookies, etc. 86 | - Allows content-aware routing (e.g., static file requests go to a specialized cluster, API requests go elsewhere). 87 | - More resource-intensive but offers **fine-grained** control. 88 | 89 | ``` 90 | ASCII DIAGRAM: Multiple Load Balancing Methods 91 | 92 | +------------------+ 93 | | Load Balancer | 94 | +--------+---------+ 95 | | 96 | +---------------+---------------+ 97 | | | 98 | v v 99 | +----------------+ +----------------+ 100 | | Server Pool | | Routing via | 101 | | (LeastConn, RR)| | IP/Consistent| 102 | | etc. | | Hash, etc. | 103 | +----------------+ +----------------+ 104 | ``` 105 | 106 | 107 | ### Load Balancer Resilience 108 | 109 | Ironically, load balancers can become a **single point of failure** if not designed carefully. Various techniques mitigate this risk: 110 | 111 | 1. **Load Balancer Clustering** 112 | - Multiple load balancers run in **active-active** or **active-passive** configurations. 113 | - A *heartbeat* mechanism monitors whether a load balancer node has failed. 114 | 115 | 2. **Active-Passive Pair** 116 | - If the **active** LB node fails, the **passive** node takes over, preventing downtime. 117 | - Usually involves sharing a **virtual IP** or using DNS-based failover. 118 | 119 | 3. **DNS-based Load Balancing** 120 | - DNS records (like `round-robin DNS`) distribute traffic among multiple LB IPs. 121 | - Can be combined with **health checks** at the DNS level. 122 | 123 | ### Best Practices for Load Balancing 124 | 125 | - **Use Health Checks**: Regularly verify server availability to avoid sending requests to unhealthy nodes. 126 | - **Monitor Performance**: Track metrics like **requests per second**, **latency**, **error rates**, and **connection counts** to optimize distribution. 127 | - **Enable TLS Offloading**: Terminate SSL/TLS at the load balancer to reduce CPU overhead on backend servers. 128 | - **Implement Caching**: If feasible, use **edge caching** or LB caching to minimize requests hitting servers. 129 | - **Session Persistence**: For applications needing sticky sessions, configure IP hash, cookies, or other *persistence* methods carefully. 130 | - **Automate Scaling**: Integrate load balancer configuration with **auto-scaling** groups so that adding/removing servers updates load balancing pools dynamically. 131 | -------------------------------------------------------------------------------- /notes/04_databases/02_transactions.md: -------------------------------------------------------------------------------- 1 | ## Database Transactions 2 | 3 | Database transactions are a fundamental concept in data management, providing a reliable means to group one or more operations into a logical unit of work. This approach ensures that the database transitions from one valid state to another, even amidst concurrent user activity or potential system interruptions. Below is an expanded overview in notes form, presented with diagrams and lists for clarity. 4 | 5 | ``` 6 | +---------------------------------------------------+ 7 | | Application (Transaction Context) | 8 | | | 9 | | Begin Transaction ---> Perform Operations | 10 | | | 11 | | Commit or Rollback <--- Confirmation | 12 | +---------------------------------------------------+ 13 | ``` 14 | 15 | Transactions often start with a **begin** statement, then involve multiple data operations, and finally end with either **commit** (to make changes permanent) or **rollback** (to undo partial or failed changes). 16 | 17 | ### ACID: The Core Properties 18 | 19 | - Each transaction enforces **Atomicity** by treating all operations as a single, indivisible unit that either fully applies or fully reverts. 20 | - The database maintains **Consistency** by ensuring that constraints or rules are not violated after a transaction completes. 21 | - Concurrent transactions aim for **Isolation**, which means they behave as though they are running one after the other. 22 | - Data achieves **Durability** by persisting commits on reliable storage, so completed transactions remain in effect even after a crash. 23 | 24 | ### Dealing with Single Object Writes 25 | 26 | ``` 27 | Single Object Write Flow 28 | +-------------------------+ 29 | | Begin | 30 | +-----------+------------+ 31 | | 32 | v 33 | +-------------------------+ 34 | | Lock or version check | 35 | +-----------+------------+ 36 | | 37 | v 38 | +-------------------------+ 39 | | Write data | 40 | +-----------+------------+ 41 | | 42 | v 43 | +-------------------------+ 44 | | Commit / Rollback | 45 | +-------------------------+ 46 | ``` 47 | 48 | - A log-based system can be **helpful** for ensuring atomicity by using a Write-Ahead Log (WAL) to record pending changes before they are applied. 49 | - A lock-based system can be **useful** for isolation by preventing other transactions from modifying the same object concurrently. 50 | - An MVCC approach can be **advantageous** because it allows multiple readers to access different object versions without waiting for locks. 51 | - A single object write often involves **minimal** overhead, but can still benefit from standardized transaction methods for consistency and durability. 52 | 53 | ### Advanced Transaction Management 54 | 55 | Transactions involving multiple objects or distributed environments call for more sophisticated techniques. They help coordinate complex tasks while preserving consistency across diverse systems or tables. 56 | 57 | #### Two-Phase Commit (2PC) 58 | 59 | ``` 60 | Coordinator Participant(s) 61 | +-----------------------+ +------------------------------+ 62 | | Prepare Transaction | --> | Pre-commit / Validate | 63 | | (Request Vote) | | -------------------------> | 64 | | | | (Vote) | 65 | | -------------------> | +------------------------------+ 66 | | (Votes) | 67 | | <-------------------- | 68 | +-----------------------+ 69 | | 70 | v 71 | +-----------------------+ 72 | | Commit / | 73 | | Rollback | 74 | +-----------------------+ 75 | ``` 76 | 77 | - The coordinator sends a **prepare** request to each participant, asking if it can commit. 78 | - Each participant responds with a **vote** (commit or abort) based on local checks. 79 | - If all participants vote commit, the coordinator issues a final **commit**; otherwise, it issues a **rollback**. 80 | - This protocol can be **helpful** in distributed databases to keep atomicity when multiple nodes are involved. 81 | - There can be **blocking** scenarios if the coordinator or participants fail at certain stages, so careful design is needed. 82 | 83 | #### Deadlock Detection and Prevention 84 | 85 | ``` 86 | Deadlock Example 87 | 88 | Transaction A Transaction B 89 | | | 90 | lock Resource X lock Resource Y 91 | | | 92 | waits for Y waits for X 93 | | | 94 | (circular wait -> deadlock) 95 | ``` 96 | 97 | - Deadlock arises when transactions hold locks in a cycle, each waiting for a resource the other holds. 98 | - Detection algorithms can be **useful** for periodically scanning transactions to see if cycles have formed. 99 | - Prevention strategies can be **helpful** by forcing transactions to acquire locks in a predefined order or by rolling back one transaction when a cycle is probable. 100 | - Timeouts can be **practical** in resolving stuck transactions if the system cannot conclusively detect a deadlock. 101 | 102 | ### Concurrency Control Methods Comparison 103 | 104 | Below is a summary of different methods employed to handle concurrent transactions: 105 | 106 | | Method | Mechanism | Pros | Cons | Common Use Cases | 107 | |----------------|-------------------------|-----------------------------------------------------------------|---------------------------------------------------------------------|---------------------------------------| 108 | | Locks | Lock data objects | It can be **effective** for strict consistency. | It can lead to contention and potential deadlocks. | Traditional RDBMS with high integrity | 109 | | MVCC | Maintain multiple versions of data | It often allows **high** read concurrency. | It can require additional storage for versions. | Databases that serve many read queries| 110 | | Timestamp | Use timestamps to order transactions | It can be **straightforward** to reason about order. | It can roll back transactions that conflict with newer timestamps. | Systems needing simpler concurrency | 111 | | Optimistic | Validate changes at commit | It can be **appropriate** for low-conflict workloads. | It can cause commits to fail if conflicts are detected at end. | Highly distributed or mostly-read apps| 112 | 113 | -------------------------------------------------------------------------------- /notes/04_databases/06_replication.md: -------------------------------------------------------------------------------- 1 | ## Replication 2 | 3 | Replication is a method of maintaining copies of data across multiple nodes in distributed systems, making it useful for improving availability, reducing latency, and distributing load. Below are detailed notes, organized in bullet points, each containing one highlighted word in the middle to emphasize a key concept. Simple ASCII diagrams are included to illustrate how replication can be structured. 4 | 5 | ``` 6 | +---------+ 7 | | Client | 8 | +----+----+ 9 | | 10 | Read/Write Requests 11 | | 12 | v 13 | +-----------+-----------+ 14 | | Leader | (Single Leader Replication) 15 | +-----------+-----------+ 16 | | Replication Log 17 | +-----------+-----------+ 18 | | Follower(s) | 19 | +-----------------------+ 20 | ``` 21 | 22 | - Replication is **helpful** for ensuring access to data even if one node fails or becomes unreachable. 23 | - Multiple replicas can be **useful** for distributing read queries, reducing latency for users in different locations. 24 | - Redundancy is **important** when a critical system must remain operational during hardware or software failures. 25 | - Different replication strategies can be **valuable** for balancing performance, consistency, and fault tolerance. 26 | - Monitoring replication lag is **essential** for applications that require up-to-date reads and strong consistency guarantees. 27 | 28 | ### Single Leader Replication 29 | 30 | Single leader replication designates one node as the leader, which receives all write operations. The followers continuously replicate changes from the leader, ensuring that each follower eventually converges to the same state. 31 | 32 | ``` 33 | +-----------+ +------------+ 34 | | Leader | Log ---> | Follower | 35 | +-----+-----+ +------------+ 36 | | 37 | | Log 38 | v 39 | +-----------+ 40 | | Follower | 41 | +-----------+ 42 | ``` 43 | 44 | - An **asynchronous** approach can increase throughput because the leader sends updates without waiting for followers to acknowledge them. 45 | - A **synchronous** method helps safeguard data by waiting for at least one follower to confirm updates before considering the write complete. 46 | - Initializing a follower is **efficient** if you use a full data snapshot, then replay subsequent log records to become up-to-date. 47 | - A replication log is **central** to both statement-based and log-based methods, capturing all changes to propagate them to followers. 48 | - Single leader replication is **beneficial** for applications that require a strict ordering of writes and simpler conflict resolution. 49 | 50 | ### Managing Leader Failure 51 | 52 | When the current leader fails or becomes unreachable, the system needs to conduct a failover procedure to select a new leader. This process should be carefully handled to avoid data loss and minimize downtime. 53 | 54 | - A failover can be **triggered** manually by an operator or automatically by a system health check. 55 | - A **consensus** algorithm like Raft or Paxos is often used to allow followers to agree on the new leader. 56 | - Data loss is **possible** with asynchronous replication if the leader crashes before all writes are replicated. 57 | - Minimizing failover time is **advantageous** for maintaining higher availability and reducing service disruption. 58 | - Keeping track of each follower’s replication progress is **helpful** for promoting the most up-to-date follower to leader. 59 | 60 | ### Implementing the Replication Log 61 | 62 | Replication logs form the backbone of data propagation from the leader to followers. Two common strategies are statement-based replication (replicating SQL commands) and log-based replication (using a write-ahead log). 63 | 64 | ``` 65 | +-------------+ 66 | | Leader DB | 67 | +------+------+ 68 | | (Log Records) 69 | v 70 | +-------------+ 71 | | Follower DB | 72 | +-------------+ 73 | ``` 74 | 75 | - Statement-based replication is **straightforward** but can lead to nondeterministic behavior if stored procedures behave differently on each node. 76 | - Log-based replication captures **low-level** changes, ensuring that every byte-level modification is propagated accurately. 77 | - Write-ahead logs can be **useful** for both durability and replication, allowing a single place to track database modifications. 78 | - The choice between statement-based or log-based replication is **driven** by factors like performance, deterministic behavior, and schema complexity. 79 | - Implementations need to be **careful** with triggers, user-defined functions, and any nondeterministic operations. 80 | 81 | ### Replication Lag and Eventual Consistency 82 | 83 | In distributed systems, the delay between a write operation on the leader and its visibility on the followers is known as replication lag. This delay can affect how quickly data converges across nodes, leading to an eventually consistent state if delays are long. 84 | 85 | - Applications may be **affected** by reading stale data if the system design does not address read-after-write consistency. 86 | - Monotonic reads are **desired** by some applications, where each subsequent read by a user sees the same or newer data. 87 | - A consistent prefix read is **important** when you want to ensure that reads reflect the chronological order of writes. 88 | - Eventual consistency is **common** in high-availability systems that accept temporary data divergence for better performance and uptime. 89 | - Monitoring replication lag is **critical** for diagnosing performance bottlenecks and adjusting system parameters. 90 | 91 | ### Multi Leader Replication 92 | 93 | In a multi-leader setup, each node can accept writes and replicate them to others, making it useful for geographically distributed deployments or cases where local write performance is prioritized. However, handling conflicting writes becomes more challenging. 94 | 95 | ``` 96 | +-------+ 97 | |Node A | 98 | +---+---+ 99 | | ^ 100 | (Writes) | | (Writes) 101 | v | 102 | +---+---+ 103 | |Node B | 104 | +---+---+ 105 | | ^ 106 | (Writes) | | (Writes) 107 | v | 108 | +---+---+ 109 | |Node C | 110 | +-------+ 111 | ``` 112 | 113 | - Write conflicts are **likely** when multiple leaders accept writes concurrently, requiring conflict resolution strategies. 114 | - Conflict resolution can be **handled** by methods like last-write-wins, custom merge logic, or prompting user intervention. 115 | - Latency can be **reduced** for local operations since each region can write to its closest leader. 116 | - A multi-leader design is **beneficial** for collaboration software that allows multiple active editors in different regions. 117 | - Dealing with circular or cyclical replication is **crucial** for avoiding infinite update loops among nodes. 118 | 119 | ### Leaderless Replication 120 | 121 | Leaderless systems eliminate the concept of a single leader node, allowing any replica to accept writes. Such systems typically rely on a quorum approach to ensure most nodes agree on a given update or read, aiming to maintain consistency without centralized coordination. 122 | 123 | ``` 124 | Leaderless Model 125 | +-----+ 126 | Write -> |Node1| <----- 127 | +-----+ | 128 | | 129 | +-----+ +-----+ 130 | Read <- |Node2| <--|Node3| 131 | +-----+ +-----+ 132 | ``` 133 | 134 | - A **quorum** read or write operation ensures that a majority of replicas confirm the operation, making data consistent if enough nodes respond. 135 | - Anti-entropy processes are **essential** for reconciling divergent replicas in the background. 136 | - Read-repair is **helpful** for fixing stale replicas whenever a read detects inconsistent data versions. 137 | - Leaderless designs are **common** in distributed key-value stores like Cassandra or Riak, which prioritize availability. 138 | - Eventual convergence is **achieved** when all nodes have consistent data after replicated writes. 139 | -------------------------------------------------------------------------------- /notes/04_databases/07_ halloween_problem.md: -------------------------------------------------------------------------------- 1 | ## Halloween Problem 2 | 3 | The Halloween Problem is a well-known issue in database systems where an update operation might unintentionally modify the same rows multiple times. The name originates from its initial discovery on October 31 (Halloween), but the problem itself has no thematic connection to that holiday. This document explains how the Halloween Problem occurs and covers strategies for avoiding repeated, unintended updates in relational databases. 4 | 5 | ### Nature of the Halloween Problem 6 | 7 | The core issue arises when an `UPDATE` operation modifies a row such that the row continues to meet the criteria for further updates. In certain databases, particularly those that scan rows in an order influenced by the columns being updated, the same row may be re-selected and updated again. This leads to repeated increments or changes, skewing final results and undermining data integrity. 8 | 9 | A classic example involves increasing salaries of employees who earn below a given threshold. If an employee’s salary goes from \$45,000 to \$49,500 after one update, that row might still qualify for another 10% raise if the database re-checks it, repeatedly boosting that salary. 10 | 11 | ### Intermediate Table Method 12 | 13 | This solution separates the rows to be updated into a temporary holding area, ensuring they only receive changes once. 14 | 15 | 1) Rows that satisfy the update condition are copied from the original table into a temporary or intermediate table. They are effectively isolated so they do not reappear in the primary scan. 16 | 2) Updates are applied in the temporary table. Because these rows no longer interact with the ongoing scan in the main table, they are not re-selected for the same update. 17 | 3) After the updates, the rows are moved back into the original table in a controlled manner, preventing them from qualifying for additional changes. 18 | 19 | ``` 20 | Original Table Intermediate Table Original Table 21 | +-------------+ +-------------+ +-------------+ 22 | | Row 1 | | Row 1* | | Row 1* | 23 | | Row 2 | Select | Row 3* | Update & | Row 2 | 24 | | Row 3 | --------> | Row 5* | --------> | Row 3* | 25 | | Row 4 | | | | Row 4 | 26 | | Row 5 | +-------------+ | Row 5* | 27 | +-------------+ +-------------+ 28 | ^ | 29 | |_______________________ Move Back _____________________| 30 | ``` 31 | 32 | This approach can be encapsulated within a single transaction to preserve data consistency. It does entail copying data twice, so performance trade-offs should be considered. 33 | 34 | ### Indexing Strategies 35 | 36 | Indexes that do not change when the underlying rows are updated help prevent rows from re-qualifying for the same update. 37 | 38 | 1) A non-clustered index, which stores row pointers in a separate structure, is often chosen. Its physical order is not tied to the data’s actual row layout. 39 | 2) When the database uses this non-clustered index to find rows to update, the changes do not affect the ordering mechanism that the index provides. 40 | 3) For clustered indexes that reorder data based on the updated column, re-qualifying rows can occur if the updated value shifts their position in the scan order. 41 | 42 | ``` 43 | Original Table (with Data) Index (Non-Clustered) 44 | +----------------------+ +---------------+ 45 | | Row 1: Data A | | Index Row 1 | 46 | | Row 2: Data B | Update | Index Row 2 | 47 | | Row 3: Data C | -------->| Index Row 3 | 48 | | Row 4: Data D | | Index Row 4 | 49 | | Row 5: Data E | | Index Row 5 | 50 | +----------------------+ +---------------+ 51 | ^ ^ ^ 52 | | |___________________________| 53 | | Referenced by 54 | | 55 | | (Rows updated based on index order, 56 | | preventing re-scanning of same row) 57 | ``` 58 | 59 | Non-clustered indexes can add overhead to database maintenance, so indexing decisions must balance mitigation of the Halloween Problem with overall query performance. 60 | 61 | ### Isolation Levels 62 | 63 | Transaction isolation levels determine how data changes become visible to other operations and can help avoid repeated updates. 64 | 65 | 1) Higher isolation levels, such as Serializable, restrict how transactions read and modify rows, preventing a row from matching the update condition multiple times within the same transaction. 66 | 2) Repeatable Read limits re-reading of changed data but can still miss certain edge cases. Serializable guarantees that no phantom rows slip in, yet it can reduce concurrency. 67 | 3) Locks or row versions might be applied to ensure data remains stable throughout the transaction. 68 | 69 | ``` 70 | Transaction 1 Transaction 2 71 | +-----------------+ +-----------------+ 72 | | Read Row 1 | | Read Row 1 | 73 | | Update Row 1 | | Wait to Update | 74 | | Commit | | Update Row 1 | 75 | | | | Commit | 76 | +-----------------+ +-----------------+ 77 | ^ ^ 78 | |__________Isolation_________| 79 | ``` 80 | 81 | While higher levels limit repeated updates, they can also impose performance costs by increasing lock contention. 82 | 83 | ### Database Engine Optimization 84 | 85 | Modern database engines often have built-in techniques to minimize or eliminate the Halloween Problem: 86 | 87 | 1) Row versioning creates new row copies instead of in-place modifications, preventing rows from meeting the criteria repeatedly during the same scan. 88 | 2) Snapshot isolation gives each transaction a stable snapshot of data as of its start time, so updated rows do not reappear for that transaction. 89 | 3) Query optimizers may detect potential Halloween scenarios and automatically adjust the query execution plan to avoid re-qualifying rows. 90 | 4) Advanced locking and concurrency controls also ensure consistency without requiring explicit manual intervention. 91 | 92 | These optimizations vary across database systems, so a thorough understanding of your specific DBMS features is helpful. 93 | 94 | ### Order by Primary Key 95 | 96 | When you update rows in stable key order (often the primary key), the database processes rows in a consistent sequence that is not affected by the columns being modified. 97 | 98 | 1) An `ORDER BY ` clause in the `UPDATE` statement ensures the engine respects a stable ordering. Rows are processed in ascending (or descending) order of the key. 99 | 2) Since the primary key does not change, rows already updated will not be revisited in a way that triggers repeated updates. 100 | 101 | ``` 102 | +---------------------+ 103 | | Original Table | 104 | | with Data | 105 | +---------------------+ 106 | | Row 1: Key 1, Data A| 107 | | Row 2: Key 2, Data B|---+ 108 | | Row 3: Key 3, Data C| | Update in order 109 | | Row 4: Key 4, Data D| | of Primary Key 110 | | Row 5: Key 5, Data E| | 111 | +---------------------+ | 112 | | | 113 | | v 114 | +---------------------+ +-----------------------+ 115 | | Update Operation | | Updated Table | 116 | | ORDER BY Primary Key| | with Data | 117 | +---------------------+ +-----------------------+ 118 | | Process Row 1 | | Row 1: Key 1, Data A* | 119 | | Process Row 2 | | Row 2: Key 2, Data B* | 120 | | Process Row 3 | | Row 3: Key 3, Data C* | 121 | | Process Row 4 | | Row 4: Key 4, Data D* | 122 | | Process Row 5 | | Row 5: Key 5, Data E* | 123 | +---------------------+ +-----------------------+ 124 | ``` 125 | 126 | This approach relies on an indexed or quickly searchable primary key to avoid performance bottlenecks. It also works best if the key is guaranteed to remain stable through the updates. 127 | 128 | ### Locking Mechanisms 129 | 130 | Locking rows during updates is another approach to prevent repeated modification of the same data. 131 | 132 | 1) Row-level locking or exclusive locks ensure that once a row is updated in a transaction, no other transaction (including the same one) can alter or re-read it in a way that triggers repeated criteria matching. 133 | 2) These locks are typically released only upon transaction commit, so a row is not revisited during the same operation. 134 | 3) Although effective, locking can reduce concurrency and heighten the risk of deadlocks if transactions hold locks on different resources while waiting for each other. 135 | 136 | ``` 137 | +----------------------+ +----------------------+ 138 | | Transaction 1 | | Transaction 2 | 139 | | Updating Table | | Waiting to Update | 140 | +----------------------+ +----------------------+ 141 | | 1. Read Row 1 | | 1. Wait for Row 1 | 142 | | 2. Lock Row 1 |------>| 2. Wait... | 143 | | 3. Update Row 1 | | | 144 | | 4. Release Lock | | 3. Read Row 1 | 145 | +----------------------+ | 4. Lock Row 1 | 146 | | 5. Update Row 1 | 147 | | 6. Release Lock | 148 | +----------------------+ 149 | ``` 150 | 151 | Managing these locks is important especially in busy systems, to prevent long wait times or widespread contention. 152 | -------------------------------------------------------------------------------- /notes/05_caching/01_caching_strategies.md: -------------------------------------------------------------------------------- 1 | ## Caching 2 | 3 | Caching is a technique used to speed up data retrieval by placing frequently accessed or computationally heavy information closer to the application or the end user. Below is an expanded set of notes on caching, presented with a simple ASCII diagram and bullet points that emphasize key considerations. Each bullet point is a complete sentence containing a single **bold** word in the middle. 4 | 5 | ``` 6 | +-------------+ +-------------+ 7 | | Client | | Server | 8 | | | | | 9 | | | Request | | 10 | | +---------->+ | 11 | | | | | 12 | | |<----------+ | 13 | +------+------| +------+------+ 14 | |Cache | | Data | 15 | |Miss | | Storage| 16 | | | | | 17 | | | | | 18 | +------v------+ +--------v-----+ 19 | | Cache | | | 20 | |(Fast Access)|<----------+ | 21 | +-------------+ Cached | | 22 | | | 23 | +--------------+ 24 | ``` 25 | 26 | - A caching strategy can be **beneficial** for reducing round-trip times between clients and the primary data store. 27 | - Caching can be **vulnerable** to data staleness when updates in the main data store are not immediately reflected in the cache. 28 | - Cache hits can be **tracked** to measure how often requested items are served from the cache versus the underlying system. 29 | - Cache misses can be **costly** because they require fetching data from slower storage and populating the cache. 30 | - The overall memory footprint can be **optimized** by selecting cache eviction policies that remove unneeded or rarely used data. 31 | 32 | ### Types of Cache 33 | 34 | Modern computing stacks use multiple caches at different layers, each addressing a specific scope and performance requirement. 35 | 36 | - Hardware caches are **essential** at the CPU level (L1, L2, L3) or between main memory and disk, reducing memory access times. 37 | - An application server cache is **helpful** when frequently accessed items are kept in memory, decreasing database load. 38 | - A distributed cache can be **useful** for sharing cached data across multiple server instances in a cluster. 39 | - A Content Delivery Network (CDN) can be **advantageous** for caching static assets close to users, minimizing latency. 40 | - Edge caching can be **adopted** at the network boundary to deliver region-specific or frequently used data faster. 41 | 42 | ### Cache Write Policies 43 | 44 | Different write policies determine how the cache interacts with the underlying data store during write operations. 45 | 46 | - A write-through approach can be **reliable** because all writes are immediately persisted to both cache and storage, albeit with higher latency. 47 | - A write-around method is **practical** for workloads that do not require recently written items to appear in the cache right away. 48 | - A write-back (write-behind) policy is **faster** for writes because the cache is updated immediately and the main storage is updated asynchronously. 49 | - The choice of write policy can be **influential** in balancing consistency, throughput, and risk of data loss. 50 | - Monitoring asynchronous queues is **needed** in write-back systems to ensure updates eventually reach the primary storage. 51 | 52 | ### Cache Eviction Policies 53 | 54 | When the cache is full, an eviction policy determines which items to discard so that new items can be stored. 55 | 56 | - FIFO removes the oldest entries first and can be **straightforward** when items have similar usage patterns. 57 | - LIFO removes the newest entries first, which can be **uncommon** in modern caching but may be used in specialized scenarios. 58 | - LRU discards items that have not been accessed for the longest period and is **popular** due to its effectiveness in many real-world usage patterns. 59 | - LFU targets items with the fewest accesses and is **suitable** when certain objects exhibit much higher popularity than others. 60 | - Random replacement can be **unpredictable**, but it avoids overhead from tracking usage frequency or order. 61 | 62 | ### Cache Invalidation and Consistency 63 | 64 | Ensuring that the cache reflects changes in the underlying data store can be one of the most **difficult** aspects of caching. 65 | 66 | - Time-to-live (TTL) can be **assigned** to each cache entry so it expires automatically after a set duration. 67 | - Explicit invalidation calls can be **triggered** whenever an update is made to the primary data, removing or refreshing outdated cache entries. 68 | - Versioning or checksums are **helpful** for identifying outdated data in distributed caches. 69 | - Stale reads might be **tolerable** in some applications (eventually consistent scenarios) but unacceptable in strictly consistent systems. 70 | - Consistency requirements can be **varied**, ranging from strong consistency to eventual or read-your-own-write guarantees. 71 | 72 | ### Multi-Layer Caching 73 | 74 | Some architectures employ multiple cache layers, each targeting different bottlenecks or data usage patterns. 75 | 76 | ``` 77 | Client 78 | | 79 | | (Browser Cache) 80 | | 81 | v 82 | Reverse Proxy / CDN 83 | | 84 | | (Edge Cache) 85 | | 86 | v 87 | Application Server 88 | | 89 | | (In-Memory Cache) 90 | | 91 | v 92 | Database or Persistent Store 93 | ``` 94 | 95 | - A multi-layer approach can be **helpful** for capturing opportunities to cache at every step in the data retrieval process. 96 | - Browser caches can be **encouraged** by sending appropriate HTTP headers (e.g., Cache-Control, ETag). 97 | - In-memory caches on the server side can be **valuable** for storing session data, configurations, or frequently accessed queries. 98 | - CDNs and reverse proxies can be **effective** for reducing load on the origin server by delivering cached static and semi-static content. 99 | - Each layer introduces **complexity** in invalidation and monitoring, requiring careful coordination. 100 | 101 | ### Monitoring and Metrics 102 | 103 | Effective caching strategies rely on continuous monitoring and tuning based on real-world usage patterns. 104 | 105 | - A cache hit rate is **crucial** for estimating how effectively the cache serves incoming requests. 106 | - A cache miss penalty is **significant** for quantifying the extra time spent fetching data from slower storage. 107 | - Request latency distributions are **observed** to determine if caching is addressing performance hotspots. 108 | - Memory usage trends are **reviewed** to prevent over-allocation or under-utilization of the cache. 109 | - Profiling tools can be **utilized** to detect which data is most frequently accessed or frequently invalidated. 110 | -------------------------------------------------------------------------------- /notes/05_caching/02_redis.md: -------------------------------------------------------------------------------- 1 | # Redis 2 | Redis is an open-source, in-memory data store that can be used as a high-performance cache system. It's often referred to as a "data structure server" because it can store and manipulate various data structures like strings, lists, sets, and more. As a backend developer, understanding how to use Redis as a cache can significantly improve the performance and scalability of your applications. 3 | 4 | ``` 5 | +-----------+ 6 | | Client 1 | 7 | +-----------+ 8 | | 9 | | SET/GET 10 | | 11 | +---------------------+ 12 | | Redis Server | 13 | |---------------------| 14 | | - Key-Value Store | 15 | | - Pub/Sub | 16 | | - Data Structures | 17 | +---------------------+ 18 | | 19 | | SET/GET 20 | | 21 | +-----------+ 22 | | Client 2 | 23 | +-----------+ 24 | ``` 25 | 26 | ## Key Concepts 27 | 28 | ### In-Memory Data Store 29 | 30 | Redis stores data in memory, which allows for incredibly fast read and write operations. This makes it suitable for use as a cache, where quick access to frequently used data is essential. 31 | 32 | ### Key-Value Store 33 | 34 | Redis uses a key-value data model. Data is stored and retrieved using keys, which makes it easy to organize and access cached data. 35 | 36 | ### Data Expiration 37 | 38 | Redis allows you to set an expiration time for keys. This feature is especially useful in cache scenarios, as it helps automatically remove stale data from the cache. 39 | 40 | ## Using Redis as a Cache 41 | 42 | To use Redis effectively as a cache, consider the following: 43 | 44 | ### Cache Invalidation 45 | 46 | Implement a strategy for cache invalidation. Decide when and how cache entries should be invalidated to ensure that your application always serves up-to-date data. 47 | 48 | ### Cache Loading 49 | 50 | When a cache miss occurs (i.e., the requested data is not found in Redis), have a mechanism in place to load the data from the primary data source (e.g., a database), cache it in Redis, and return it to the client. 51 | 52 | ### Cache Keys 53 | 54 | Choose meaningful and consistent naming conventions for your cache keys. This helps with organization and makes it easier to manage cached data. 55 | 56 | ### Expiration Time 57 | 58 | Set appropriate expiration times for cache keys based on your application's requirements. Short-lived data may have a shorter expiration time, while long-lived data can have a longer one. 59 | 60 | ## Redis Clients 61 | 62 | To interact with Redis from your backend code, you'll need to use a Redis client library. Some popular options include: 63 | 64 | - **ioredis**: A robust, high-performance Redis client for Node.js. 65 | - **StackExchange.Redis**: A .NET library for Redis. 66 | - **Jedis**: A Java client for Redis. 67 | 68 | Choose a client library that best fits your programming language and requirements. 69 | 70 | ## Monitoring and Maintenance 71 | 72 | Regularly monitor your Redis cache to ensure it's performing as expected. Tools like Redis Sentinel or Redis Cluster can help with high availability and fault tolerance. 73 | 74 | ## Security Considerations 75 | 76 | - Secure your Redis instance by setting strong passwords. 77 | - Limit access to your Redis server to trusted IP addresses. 78 | - Be cautious when exposing Redis to the internet, and consider using VPNs or other security measures. 79 | -------------------------------------------------------------------------------- /notes/05_caching/03_content_delivery_networks.md: -------------------------------------------------------------------------------- 1 | ## Content Delivery Network 2 | 3 | A Content Delivery Network (CDN) is a geographically distributed system of servers that deliver web assets such as images, videos, and other media to users based on their proximity to the servers. This design is *helpful* for reducing latency and improving the performance of websites or applications that serve a global audience. CDNs typically operate through specialized data centers known as Points of Presence (PoPs), where content is cached and quickly served to end-users. 4 | 5 | ``` 6 | +--------------+ 7 | | End User | 8 | +------+-------+ 9 | | 10 | (Request Content) 11 | | 12 | +---------v---------+ 13 | | CDN Edge Server | 14 | +---------+---------+ 15 | | (If cache miss) 16 | | 17 | +---------v---------+ 18 | | Origin Server | 19 | +-------------------+ 20 | ``` 21 | 22 | 23 | ### How CDNs Work 24 | 25 | - A distributed infrastructure is **helpful** for placing servers in multiple geographic locations. 26 | - A caching mechanism can be **useful** for storing frequently requested content close to end-users. 27 | - A load-balancing strategy is **beneficial** for preventing any single server from becoming overloaded. 28 | - A request-routing system is **effective** for directing users to the nearest or fastest edge server. 29 | - An anycast network can be **advantageous** for simplifying traffic routing across multiple CDN nodes. 30 | 31 | 32 | ### Components 33 | 34 | - Edge servers are **important** for caching and delivering content from PoPs to nearby users. 35 | - Origin servers serve as **primary** content sources when edge servers do not have the requested assets. 36 | - PoPs (Points of Presence) are **essential** for housing edge servers and processing local traffic. 37 | - Monitoring and analytics tools are **helpful** for tracking CDN performance, cache hit ratios, and latency metrics. 38 | - Control planes are **useful** for managing CDN configurations, purging caches, and provisioning new edge locations. 39 | 40 | 41 | ### Types of Content Delivered 42 | 43 | - Static content is **common** for items like images, CSS, JavaScript, and downloadable files. 44 | - Dynamic content can be **served** through CDNs for personalized web pages and real-time updates. 45 | - Streaming media is **practical** for delivering live or on-demand video, audio, and other large media files. 46 | - Software updates and patches are **distributed** efficiently to reduce bottlenecks during high-demand periods. 47 | - API responses can be **cached** for short durations to reduce repeated requests to the origin servers. 48 | 49 | 50 | ### Benefits of CDNs 51 | 52 | - Reduced latency is **helpful** because content is served from a location geographically close to the user. 53 | - Improved load times can be **beneficial** for enhancing user experience and reducing bounce rates. 54 | - Scalability allows **efficient** handling of sudden spikes in traffic without overwhelming origin servers. 55 | - Reliability improves **uptime** by distributing requests across multiple servers, lessening single-point failures. 56 | - Security features are **valuable** for mitigating DDoS attacks and supporting encrypted connections. 57 | 58 | 59 | ### CDN Features 60 | 61 | - Caching ensures **faster** delivery by storing files on edge servers located near end-users. 62 | - Content purging is **crucial** for updating or removing cached items when new versions are available. 63 | - Geo-targeting is **helpful** for serving localized content or complying with regional regulations. 64 | - Compression techniques are **effective** for reducing file sizes and transmission times. 65 | - SSL/TLS encryption is **important** for securing data in transit and protecting user privacy. 66 | 67 | 68 | ### Common CDN Providers 69 | 70 | - Akamai is **well-known** for having one of the largest and oldest CDN networks worldwide. 71 | - Cloudflare provides **robust** security capabilities along with standard CDN services. 72 | - Amazon CloudFront is **integrated** tightly with AWS, offering seamless deployment for cloud-based apps. 73 | - Google Cloud CDN is **useful** for projects hosted on Google Cloud Platform, simplifying setup. 74 | - Fastly offers **real-time** CDN configurations and edge computing capabilities. 75 | 76 | 77 | ### Use Cases 78 | 79 | - E-commerce sites are **enhanced** by faster page loads, boosting customer satisfaction and conversions. 80 | - Media streaming can be **optimized** with CDNs delivering high-quality audio and video at scale. 81 | - Software distribution is **streamlined** when updates and downloads are hosted on edge servers. 82 | - Websites and blogs see **improvements** in user engagement and SEO rankings due to reduced load times. 83 | - Mobile applications can be **benefited** by minimizing latency for users on various networks and devices. 84 | 85 | 86 | ### CDN Challenges 87 | 88 | - Cost considerations are **important** when serving large traffic volumes or hosting heavy content. 89 | - Complexity arises **often** in configuring and maintaining multi-layer caching rules. 90 | - Cache invalidation can be **tricky** if content changes frequently, requiring precise updates. 91 | - Geographic coverage might be **limited** in certain regions, affecting performance for users there. 92 | - Vendor lock-in could be **possible** if proprietary features prevent easy migration to another CDN. 93 | 94 | 95 | ### Best Practices 96 | 97 | - Content optimization is **helpful** for ensuring the CDN can effectively cache files, including compressing images and minifying scripts. 98 | - Performance monitoring is **useful** for tracking metrics such as latency, throughput, and cache hit rates. 99 | - Access control with SSL/TLS is **beneficial** for protecting data and verifying authenticity during delivery. 100 | - Cache purging strategies need **thought** to guarantee users see up-to-date information when content changes. 101 | - Testing configurations is **advisable** for simulating real-world traffic patterns before going live. 102 | -------------------------------------------------------------------------------- /notes/05_caching/04_database_caching.md: -------------------------------------------------------------------------------- 1 | ## Database Caching 2 | 3 | Database caching stores frequently used query results or objects in a cache, bringing them closer to the application for *faster* data retrieval. This reduces load on the primary database and shortens response times, ultimately improving user experience. 4 | 5 | ``` 6 | +--------------+ 7 | | Application | 8 | +-------+------+ 9 | | 10 | | (Query/Write) 11 | v 12 | +-------+------+ 13 | | Cache | 14 | +-------+------+ 15 | | (Cache Miss) 16 | v 17 | +-------+------+ 18 | | Database | 19 | +--------------+ 20 | ``` 21 | 22 | - Using a database cache is **beneficial** for minimizing round trips to the main database system. 23 | - It can be **vulnerable** to stale data if invalidation or refresh mechanisms are not managed carefully. 24 | - A high cache hit ratio is **indicative** of effective caching strategies and configurations. 25 | - Miss penalties can be **costly** if frequent queries bypass the cache due to short time-to-live settings or poor usage patterns. 26 | - The right caching approach can be **advantageous** for supporting more concurrent requests and reducing infrastructure costs. 27 | 28 | ### How Database Caching Works 29 | 30 | - Query results caching can be **helpful** by storing entire result sets for fast retrieval on subsequent identical queries. 31 | - Object caching is **useful** when individual rows or entities need to be reused frequently by the application. 32 | - Page caching is **common** in systems that render HTML or certain content fragments from database-driven processes. 33 | - Application logic is **essential** in deciding what gets cached and under which conditions to keep the cache effective. 34 | 35 | ### Types of Database Caches 36 | 37 | - In-memory caches like Redis or Memcached store **fast** access data directly in RAM. 38 | - Distributed caches can be **scalable** because they handle large datasets and high traffic across multiple nodes. 39 | - Local caches reside **within** an application server’s memory space, offering quick lookups without network overhead. 40 | - Hybrid approaches are **possible** if you combine local caches for quick hits and distributed caches for system-wide consistency. 41 | 42 | ### Benefits of Database Caching 43 | 44 | - Reduced latency is **crucial** for delivering a responsive user experience with minimal delays. 45 | - Improved performance is **key** to handling more transactions or concurrent users without database bottlenecks. 46 | - Scalability is **enhanced** since the application can scale horizontally without proportionally increasing database load. 47 | - Cost efficiency is **sought** by offloading repetitive queries from the main database to a cheaper caching layer. 48 | 49 | ### Cache Strategies 50 | 51 | ``` 52 | Read-Through: 53 | App -> Cache -> DB 54 | ^ 55 | Log updates from DB 56 | 57 | Write-Through: 58 | App -> (Cache & DB simultaneously) 59 | 60 | Write-Behind: 61 | App -> Cache -> DB (asynchronously) 62 | 63 | Cache-Aside: 64 | App -> (Cache first, then DB if not found) 65 | ``` 66 | 67 | - A read-through policy is **common** because the cache automatically retrieves from the database on a miss. 68 | - A write-through approach can be **valuable** for ensuring the cache always reflects the latest writes. 69 | - A write-behind strategy is **efficient** if asynchronous database updates are acceptable and short delays are tolerable. 70 | - A cache-aside (lazy loading) pattern is **flexible** since the application explicitly manages when to load or update cache entries. 71 | 72 | ### Cache Eviction Policies 73 | 74 | - LRU evicts items **unused** for the longest period, matching many typical read access patterns. 75 | - MRU eliminates the **most** recently used items, which can be helpful for specific workloads. 76 | - FIFO discards items **inserted** earliest, regardless of recent usage frequency. 77 | - LFU targets items **accessed** the least often, which is ideal for data with skewed popularity distributions. 78 | 79 | ### Cache Consistency 80 | 81 | - Strong consistency is **guaranteed** when the cache always reflects the current database state, often at the cost of performance. 82 | - Eventual consistency is **acceptable** in systems tolerant of brief delays or slight data staleness after updates. 83 | - Conflict resolution can be **tricky** in distributed caches, requiring well-defined update and invalidation rules. 84 | - Monitoring your application’s correctness needs is **important** in determining which consistency model to adopt. 85 | 86 | ### Tools and Technologies 87 | 88 | - Redis is **popular** for storing key-value pairs and more complex data structures in memory. 89 | - Memcached is **lightweight** and widely used for simple, high-performance caching of strings or objects. 90 | - Amazon ElastiCache is **managed** within AWS, offering easy setup for Redis or Memcached clusters. 91 | - Ehcache is **versatile**, integrating smoothly with Java-based applications and various storage backends. 92 | 93 | ### Implementation Best Practices 94 | 95 | - Identifying cacheable data is **critical** for avoiding overhead from caching unneeded or rarely accessed items. 96 | - Setting TTLs appropriately is **vital** to balance performance with the risk of serving stale data. 97 | - Monitoring cache performance is **essential** for adjusting configurations and eviction policies over time. 98 | - Handling cache invalidation is **important** if frequent updates to underlying data can lead to inconsistency. 99 | - Optimizing cache size is **necessary** to ensure that caches are neither overfilled nor underutilized. 100 | 101 | ### Common Use Cases 102 | 103 | - Web applications are **accelerated** by caching query-intensive pages or session data. 104 | - E-commerce platforms gain **efficiency** by caching product details, price checks, and user profiles. 105 | - CMS-based websites see **improvements** in response times when articles and media are readily accessible. 106 | - Analytics workloads can be **streamlined** by caching results of complex queries or transformations. 107 | 108 | ### Challenges 109 | 110 | - Cache invalidation is **difficult** because stale or outdated data can lead to inconsistencies. 111 | - Consistency management becomes **complex** in distributed setups requiring synchronization among multiple caches. 112 | - Cache miss penalties are **heightened** if the system frequently retrieves data from the database due to short TTLs or improper caching logic. 113 | - Strike a balance between **performance** benefits and potential complexities introduced by caching layers. 114 | -------------------------------------------------------------------------------- /notes/06_data_processing/01_pub_sub_vs_queue.md: -------------------------------------------------------------------------------- 1 | ## Message Queues and Publish-Subscribe Patterns 2 | 3 | Message queues enable asynchronous, decoupled communication in distributed systems by allowing publishers to send messages to a queue that consumers process independently, typically in first-in, first-out order. This approach reduces direct dependencies between services, enhances reliability and scalability, and supports multiple publishers and consumers. Additionally, the publish-subscribe pattern uses message brokers to distribute messages to interested subscribers without requiring publishers to manage subscriptions. The following notes include diagrams and best practices for effectively implementing message queues and pub-sub systems. 4 | 5 | ### Message Queue 6 | 7 | A message queue is a fundamental building block for asynchronous, decoupled communication in distributed systems. Publishers send messages to a queue, and one or more consumers retrieve those messages in a controlled fashion—often in first-in, first-out (FIFO) order—to process them independently. Below are expanded notes and diagrams illustrating message queues, along with the publish-subscribe pattern. 8 | 9 | ``` 10 | Basic Message Queue 11 | 12 | +----------+ +-----------+ 13 | | Publisher| | Consumer | 14 | +----+-----+ +-----+-----+ 15 | | ^ 16 | | (Send Message) | 17 | v | 18 | +------+-------------------------+------+ 19 | | Message Queue | 20 | +---------------------------------------+ 21 | (FIFO Retrieval) 22 | ``` 23 | 24 | - A message queue can be **essential** for removing direct dependencies between services that produce data and those that process it. 25 | - It is often **used** in scenarios requiring reliable messaging, fault tolerance, and scaling across multiple consumers. 26 | - Each message is **dequeued** once by a consumer to avoid duplication in simple queue configurations. 27 | - The queue can be **configured** to hold messages temporarily when downstream systems are busy or offline. 28 | 29 | ``` 30 | Multiple Publishers and Consumers 31 | 32 | +-----------+ +------------+ 33 | |Publisher A| |Publisher B | 34 | +-----+-----+ +-----+------+ 35 | | | 36 | | (Push Msg) | (Push Msg) 37 | v v 38 | +-----+-----------------+------+ 39 | | Message Queue | 40 | +------------------------------+ 41 | ^ ^ ^ 42 | | | | 43 | +-----+----+ +--+-----+ +--+-----+ 44 | |Consumer1 | |Consumer2| |Consumer3| 45 | +----------+ +---------+ +---------+ 46 | ``` 47 | 48 | - Having multiple publishers is common when events or data originate from various system components. 49 | - Supporting multiple consumers is helpful for parallel processing, workload sharing, or specialized job handling. 50 | - FIFO ordering can be maintained in a simple queue but might need special configurations for concurrency. 51 | - Advanced queue systems often include visibility timeouts, retry policies, and dead-letter queues for unprocessable messages. 52 | 53 | ### Publish-Subscribe Pattern (Pub-Sub) 54 | 55 | In the pub-sub paradigm, publishers send messages on a topic (or channel) without needing to know who subscribes. Subscribers register interest in one or more topics, receiving all relevant messages without interfering with other subscribers. 56 | 57 | ``` 58 | ASCII DIAGRAM: Basic Pub-Sub 59 | 60 | +--------------+ 61 | | Publisher | 62 | +------+-------+ 63 | | 64 | (Publish to Topic) 65 | v 66 | +-----+------+ 67 | | Message | 68 | | Broker | 69 | +-----+------+ 70 | | 71 | +----------+----------+ 72 | | | 73 | v v 74 | +-----+-----+ +----+------+ 75 | |Subscriber1| |Subscriber2| 76 | +-----------+ +-----------+ 77 | ``` 78 | 79 | - A publish-subscribe broker is important for decoupling producers from consumers, letting them evolve independently. 80 | - Each subscriber is registered for certain topics and automatically receives all messages on those topics. 81 | - Multiple subscribers can be helped by receiving identical messages, which is beneficial for logging or analytics. 82 | - The publisher does not need to be aware of the subscription logic, simplifying scaling and modifications. 83 | 84 | ``` 85 | Multiple Topics & Subscribers 86 | 87 | +-----------+ 88 | | Publisher | 89 | +-----+-----+ 90 | | 91 | (Publish: TopicA, TopicB) 92 | v 93 | +------+---------+ 94 | | Pub-Sub | 95 | | Broker | 96 | +-----+----------+ 97 | / \ 98 | / \ 99 | v v 100 | +-------------+ +-------------+ 101 | | Topic A | | Topic B | 102 | | Subscribers | | Subscribers | 103 | +-----+-------+ +-----+-------+ 104 | ``` 105 | 106 | - Different topics can be targeted for different categories of events or messages. 107 | - Subscribers might be selective, subscribing to only the topics relevant to their processing logic. 108 | - Pub-sub is favored in event-driven architectures where multiple services must react to the same event. 109 | 110 | ### Concepts in Message Queues and Pub-Sub 111 | 112 | - Asynchronous processing allows tasks to run independently, reducing wait times and improving responsiveness. 113 | - Distributed processing helps handle scalability by assigning tasks to multiple machines or containers. 114 | - FIFO (First-In, First-Out) ensures predictable ordering where necessary, which is particularly important in certain business workflows. 115 | - Message integrity guarantees reliable delivery and accurate content, which is crucial for financial or critical systems. 116 | - Error handling provides strategies such as retries, dead-letter queues, and alternative routing to manage failures effectively. 117 | 118 | ### Best Practices 119 | 120 | - Ensuring message reliability involves setting up acknowledgments or receipts to confirm proper message delivery. 121 | - Monitoring system performance requires tracking metrics like queue length, throughput, and message delays for efficient scaling. 122 | - Implementing robust error handling includes deploying dead-letter queues for messages that fail repeatedly. 123 | - Scalability is maintained by partitioning queues or adding more broker nodes when load increases. 124 | - Securing the pipeline includes using authentication and encryption to protect messages, especially in multi-tenant or external environments. 125 | -------------------------------------------------------------------------------- /notes/06_data_processing/04_stream_processing.md: -------------------------------------------------------------------------------- 1 | ## Stream Processing 2 | 3 | Stream processing involves ingesting, analyzing, and taking action on data *as it is produced*. This near-real-time or real-time methodology is *helpful* for applications that need to respond quickly to continuously updating information, such as IoT sensor readings, financial transactions, or social media data. By processing events or records as they arrive, systems can *quickly* generate insights, trigger alerts, or update dashboards without waiting for a complete batch. 4 | 5 | ``` 6 | ASCII DIAGRAM: Stream Processing Overview 7 | 8 | +---------------+ +---------------------------------+ +--------------+ 9 | | | | Stream Processing | | | 10 | | Data Sources +----->+ (Real-time/Near-real-time) +----->+ Final Output | 11 | | (Sensors, etc.) | +-----+ +-----+ +-----+ | | (Dashboard, | 12 | +---------------+ | | P1 | | P2 | | P3 | | | Alerts, etc.) 13 | +----+-----+---+-----+---+-----+---+ +--------------+ 14 | ``` 15 | 16 | - A data stream is **continuously** produced by various sources, like logs, sensors, or user activities. 17 | - A stream processing system **consumes** these events as they arrive, applying transformations, aggregations, or filtering. 18 | - Final results, such as alerts, dashboards, or enriched data records, are **emitted** with minimal delay. 19 | 20 | ### Message Brokers 21 | 22 | Message brokers provide asynchronous communication between producing and consuming services, often serving as a backbone for stream processing pipelines. 23 | 24 | - **Load Balancing**: Distributes incoming messages across *multiple* consumers. 25 | - **Fan-out**: Broadcasts messages so every subscribed consumer can *receive* a copy. 26 | - **Queue vs. Pub-Sub**: A queue model is *often* used for point-to-point communication (one consumer), while pub-sub broadcasts messages to multiple subscribers. 27 | 28 | ``` 29 | ASCII DIAGRAM: Message Broker in the Pipeline 30 | 31 | Publisher(s) Message Broker Consumer(s) 32 | +------------+ (Push) +-----------+ (Pull) +------------+ 33 | | Service A | ----------> | Topic | <----------| Service B | 34 | +------------+ +-----+-----+ +------------+ 35 | \ 36 | +------------+ 37 | | Service C | 38 | +------------+ 39 | ``` 40 | 41 | - This log-based structure can be **critical** in ensuring message ordering and replay capabilities for consumers. 42 | - Topic partitioning is **often** used to scale throughput and handle fault tolerance. 43 | 44 | ### Log-Based Message Brokers 45 | 46 | Log-based brokers (like Apache Kafka) store messages in an immutable, append-only log. Consumers read from an **offset** that tracks their position, allowing for replaying messages or consuming them at different rates. 47 | 48 | - **Sequential** processing lets consumers receive messages in the order produced, crucial for maintaining consistency. 49 | - **Partitioning** topics across multiple logs provides **scalability**; each partition can be processed by a separate consumer or consumer group. 50 | 51 | ``` 52 | ASCII DIAGRAM: Log-Based Broker (Conceptual) 53 | 54 | +---------+ 55 | Producer ---> | Partition 0 | ---> Consumer Group 1 56 | +---------+ 57 | Producer ---> | Partition 1 | ---> Consumer Group 2 58 | +---------+ 59 | Producer ---> | Partition 2 | ---> Consumer Group 2 60 | +---------+ 61 | ``` 62 | 63 | - Each partition is **independent**, so reading from one partition does not affect the offsets in another. 64 | - If a consumer fails, another consumer in the group can **take over** reading from the partition where it left off. 65 | 66 | ### Change Data Capture (CDC) 67 | 68 | CDC captures and streams **row-level** database changes in real time. By converting inserts, updates, and deletes into event streams, CDC simplifies synchronizing data across systems. 69 | 70 | - **Event Generation**: Whenever a record in the database changes, an event is appended to the stream. 71 | - **Data Synchronization**: Downstream services or microservices can **subscribe** to these change events, ensuring they have up-to-date data without heavy polling. 72 | 73 | ``` 74 | ASCII DIAGRAM: CDC Flow 75 | 76 | Database CDC Engine Message Broker Consumers 77 | +------------+ +---------------+ +---------------+ +-----------------+ 78 | | Table(s) |-->| Binlog Reader | --------> | Topic(s) | -----> | Microservices | 79 | +------------+ +---------------+ +-------+-------+ +-----------------+ 80 | | 81 | v 82 | +---------------+ 83 | | Analytics | 84 | +---------------+ 85 | ``` 86 | 87 | This approach is **especially** popular for maintaining read replicas, caches, or downstream analytics systems in near real time. 88 | 89 | ### Event Sourcing 90 | 91 | Event Sourcing maintains an append-only log of all **state changes** in an application, rather than storing only the latest state. By replaying these events, the application’s state can be reconstructed at any point in time, providing excellent **auditability** and historical insight. 92 | 93 | - **Event Log**: All changes are appended as discrete events, forming a chronological record. 94 | - **State Reconstruction**: The current or past state is obtained by replaying every event from the start, or from a known checkpoint. 95 | - **Debugging & Auditing**: Full history of changes can be **helpful** for diagnosing issues or analyzing user actions. 96 | 97 | ### Streams and Time 98 | 99 | Time management in distributed stream systems can be **complex** due to network delays and clock drift. Common windowing strategies address how events are grouped over time: 100 | 101 | 1. **Hopping Windows** 102 | - Fixed-size windows, with a “hop” period that is **larger** than the window size, leaving gaps in coverage. 103 | - Example: Window of size 6 minutes, but a new window starts every 10 minutes, leading to partial coverage. 104 | 105 | 2. **Sliding Windows** 106 | - Overlapping windows, each capturing a fixed duration but **starting** at smaller intervals. 107 | - Example: A 6-minute window slides every 2 minutes, allowing continuous coverage of data. 108 | 109 | 3. **Tumbling Windows** 110 | - Consecutive, non-overlapping windows of a fixed **size**. 111 | - Example: Every 6 minutes forms a new batch of events with no overlap or gap. 112 | 113 | ``` 114 | ASCII DIAGRAM: Time Window Examples (Conceptual) 115 | 116 | Hopping (Size=6, Hop=10) 117 | [0---6] [10--16] [20--26] 118 | 119 | Sliding (Size=6, Slide=2) 120 | [0---6] 121 | [2---8] 122 | [4---10] 123 | [6---12] 124 | 125 | Tumbling (Size=6) 126 | [0---6][6---12][12--18][18--24] 127 | ``` 128 | 129 | ### Stream Joins 130 | 131 | Joining data in a streaming environment allows correlation of events from multiple sources or combining real-time events with reference data. 132 | 133 | - **Stream-Stream Join**: Correlates events arriving on two (or more) streams, requiring stateful tracking of unjoined events until a corresponding match arrives. 134 | - **Stream-Table Join**: Combines a stream of incoming events with a static or slowly changing table (often a cached copy). 135 | - **Table-Table Join**: Involves joining two changing datasets, typically kept in sync via CDC or event sourcing. 136 | 137 | ``` 138 | ASCII DIAGRAM: Stream-Stream Join (Conceptual) 139 | 140 | Stream A (Orders) Join on OrderID Stream B (Payments) 141 | (A1) ------------------> +--------------+ <---------------- (B1) 142 | (A2) ------------------> | Join State | <---------------- (B2) 143 | (A3) ------------------> +--------------+ <---------------- (B3) 144 | ``` 145 | 146 | Intermediate state must be **maintained** to match events from each stream within a specified time window. 147 | 148 | ### Fault Tolerance 149 | 150 | Ensuring a streaming system remains reliable in the face of failures is **critical**: 151 | 152 | - **Micro-batching** can simplify fault-tolerance, treating short spans of data as a batch. 153 | - **Checkpointing** periodically saves the progress (offsets, partial aggregations) to stable storage. 154 | - **Idempotent** operations allow reprocessing events without duplicating side effects. 155 | 156 | ``` 157 | ASCII DIAGRAM: Checkpointing Example 158 | 159 | Stream 160 | | 161 | v 162 | +---------+---------+ 163 | | Stream Processing | 164 | +---------+---------+ 165 | | 166 | | (Periodic Save State) 167 | v 168 | +------------------+ 169 | | Checkpoint Store| 170 | +------------------+ 171 | ``` 172 | 173 | When a node fails, it can **recover** from the latest checkpoint, replaying only the events since that point. 174 | 175 | ## Key Stream Processing Technologies 176 | 177 | - **Apache Kafka**: A widely used log-based message broker with support for streams via Kafka Streams or ksqlDB. 178 | - **Apache Flink**: Offers low-latency, high-throughput stream processing with advanced state management. 179 | - **Apache Spark Streaming**: Built on Spark’s micro-batch model, helpful for near-real-time processing of large datasets. 180 | - **Apache Pulsar**: Combines a scalable message queue with stream processing capabilities, including geo-replication. 181 | 182 | ### When to Use Stream Processing 183 | 184 | - **Real-time Analytics**: Dashboards showing up-to-the-second metrics (e.g., IoT sensor readings, site traffic). 185 | - **Fraud Detection**: Financial transactions monitored as they occur, triggering **immediate** alerts on anomalies. 186 | - **Monitoring & Alerting**: Infrastructure logs and events analyzed on the fly, **responding** to performance issues quickly. 187 | - **Personalization**: Recommending items or content to users in near real time based on new interactions. 188 | -------------------------------------------------------------------------------- /notes/07_data_formats/01_protocol_buffers.md: -------------------------------------------------------------------------------- 1 | ## Protocol Buffers Overview 2 | 3 | Protocol Buffers (often referred to as *protobuf*) is a language-neutral, platform-independent method for serializing structured data. Originally created at Google, it excels at enabling efficient data interchange between services, storing information in a compact binary format, and sustaining backward and forward compatibility across different versions of the data schema. 4 | 5 | ``` 6 | ASCII DIAGRAM: Flow of Working with Protobuf 7 | 8 | +-----------+ +---------+ +---------------------+ 9 | | .proto | Use | Protoc | Gen | Language Classes | 10 | | (Schema) +-------->+ Compiler+-------->+ (Java, Python, etc.) 11 | +-----------+ +----+----+ +----------+----------+ 12 | | | 13 | | (Serialize/ | (Deserialize/ 14 | | Deserialize) | Manipulate) 15 | v v 16 | +---------------------+ +---------------------+ 17 | | In-memory Objects | | In-memory Objects | 18 | +---------------------+ +---------------------+ 19 | ^ ^ 20 | | (Binary Data) | 21 | +------------<--------------->+ 22 | ``` 23 | 24 | - You **define** your data schema once in a .proto file, which is language-agnostic. 25 | - The **Protobuf compiler** (`protoc`) generates data model classes for your target programming language. 26 | - Your code **creates**, **serializes**, or **deserializes** Protobuf messages using these generated classes. 27 | - The **resulting** binary format is smaller and faster to process compared to verbose text formats like JSON or XML. 28 | 29 | ### Basic Concepts 30 | 31 | 1. **.proto Files** 32 | - Written in a syntax resembling IDLs (Interface Definition Languages). 33 | - Contain **message** declarations representing data structures and **fields** with typed, numbered entries. 34 | - Each field’s number identifies it in the binary encoding, so it should not be changed once deployed. 35 | 36 | 2. **Generated Code** 37 | - `protoc` converts .proto definitions into classes in various languages (Java, Python, C++, Go, etc.). 38 | - These classes provide **getters**, **setters**, and **builder** patterns to manipulate field values. 39 | 40 | 3. **Serialization** 41 | - Protobuf messages are encoded as a **compact, binary** format. 42 | - Serialization is **efficient** in terms of both space and time. 43 | - Deserialization uses the same schema-based approach to reconstruct the original objects. 44 | 45 | ### Example: Person and AddressBook 46 | 47 | A simple .proto file might define a `Person` message with nested fields and an `AddressBook` that holds multiple `Person` messages: 48 | 49 | ```protobuf 50 | syntax = "proto3"; 51 | 52 | message Person { 53 | string name = 1; 54 | int32 id = 2; 55 | string email = 3; 56 | 57 | enum PhoneType { 58 | MOBILE = 0; 59 | HOME = 1; 60 | WORK = 2; 61 | } 62 | 63 | message PhoneNumber { 64 | string number = 1; 65 | PhoneType type = 2; 66 | } 67 | 68 | repeated PhoneNumber phones = 4; 69 | } 70 | 71 | message AddressBook { 72 | repeated Person people = 1; 73 | } 74 | ``` 75 | 76 | - **syntax = "proto3"** designates Protobuf v3 features. 77 | - **message Person** acts like a class, with a `name`, `id`, `email`, and repeated `phones`. 78 | - **enum PhoneType** lists valid phone types. 79 | - **nested message** `PhoneNumber` is defined inside `Person`. 80 | - **AddressBook** holds multiple `Person` objects via a repeated field. 81 | 82 | ### Compilation and Generated Classes 83 | 84 | 1. **Compile** the .proto file: 85 | 86 | ```shell 87 | protoc --java_out=. addressbook.proto 88 | ``` 89 | 90 | 2. **Output** classes (for example, in Java) will include `Person`, `Person.PhoneNumber`, `Person.PhoneType`, and `AddressBook`. 91 | 92 | 3. **Usage** in Java (example): 93 | 94 | ```java 95 | Person person = Person.newBuilder() 96 | .setName("Alice") 97 | .setId(123) 98 | .setEmail("alice@example.com") 99 | .addPhones( 100 | Person.PhoneNumber.newBuilder() 101 | .setNumber("555-1234") 102 | .setType(Person.PhoneType.HOME) 103 | ) 104 | .build(); 105 | 106 | // Serialization 107 | byte[] data = person.toByteArray(); 108 | 109 | // Deserialization 110 | Person parsedPerson = Person.parseFrom(data); 111 | System.out.println(parsedPerson.getName()); // "Alice" 112 | ``` 113 | 114 | ### Advantages of Protocol Buffers 115 | 116 | 1. **Efficiency** 117 | - **Compact** binary representation saves bandwidth and reduces latency. 118 | - **Fast** to parse compared to JSON or XML due to the binary encoding approach. 119 | 120 | 2. **Language-Neutral** 121 | - Protobuf supports **many** languages and platforms, making it *flexible* for cross-language communication. 122 | 123 | 3. **Backward/Forward Compatibility** 124 | - Fields can be *added* or *removed* from message types over time without breaking existing code. 125 | - Each field’s unique numeric **tag** enables easy evolution of the schema. 126 | 127 | 4. **Schema-Driven** 128 | - The **.proto** file defines a clear contract for data exchange, promoting strong typing and consistent usage across services. 129 | 130 | ### Common Use Cases 131 | 132 | - **Inter-Service Communication** 133 | - Microservices exchanging messages across a network in a *compact*, *schema-enforced* format. 134 | - Often used with gRPC, which builds on HTTP/2 and Protobuf for *efficient* remote procedure calls. 135 | 136 | - **Persistent Storage** 137 | - Writing structured data to disk in a binary format that is easily read back or migrated to new formats. 138 | - Helps with *metadata storage*, saving configurations, or logging events with minimal space overhead. 139 | 140 | - **Mobile and IoT** 141 | - Minimizes data transfer overhead for resource-constrained devices. 142 | - Minimizes *message size* for real-time updates or device telemetry. 143 | 144 | ### Protocol Buffers vs JSON 145 | 146 | | **Aspect** | **Protobuf** | **JSON** | 147 | |--------------------------|--------------------------------------------------|------------------------------------------------------| 148 | | **Encoding** | Binary | Text (UTF-8, etc.) | 149 | | **Readability** | Not human-readable | Human-readable (plain text) | 150 | | **Size & Performance** | Smaller, faster to parse | Larger, slower to parse | 151 | | **Schema Definition** | Required (`.proto` files) | Not required (schemaless) | 152 | | **Evolution** | Facilitated by numeric tags (forward/backward) | Relies on optional fields or versioning manually | 153 | | **Tooling** | Protobuf compiler needed, specialized libraries | Widespread support, easy debugging with text format | 154 | 155 | **Choose JSON** if easy debugging, simplicity, or direct human editing is a priority. 156 | **Choose Protobuf** if efficiency, strict schema, or large-scale message passing is crucial. 157 | 158 | ### Best Practices 159 | 160 | - **Consistent Naming**: Use descriptive field names in `.proto` files that match your project’s conventions (e.g., `snake_case` for field names if in Python or `camelCase` in Java). 161 | - **Versioning**: *Add fields* with new tags rather than re-using or changing existing field numbers to maintain backward compatibility. 162 | - **Avoid Floats if Possible**: Floating-point imprecision can cause issues. Prefer integers, fixed, or decimal-encoded strings for currency. 163 | - **Enums for Controlled Values**: If fields have a fixed set of valid options, define them in an enum for stronger validation. 164 | - **Document Your .proto**: Include comments describing each message and field to aid developers who consume your schema. 165 | -------------------------------------------------------------------------------- /notes/07_data_formats/02_xml.md: -------------------------------------------------------------------------------- 1 | # XML Format 2 | 3 | XML, or Extensible Markup Language, is a markup language used to encode documents in a format that is both human-readable and machine-readable. It is widely used for the representation of arbitrary data structures, such as those used in web services. 4 | 5 | ## Basics of XML 6 | 7 | 1. **Elements**: The building blocks of an XML document, they can contain other elements, text, or attributes. 8 | 2. **Attributes**: Contain additional information about elements but are not considered part of the data contained in the elements. 9 | 3. **Syntax**: XML syntax refers to the rules that govern the way an XML document is coded. 10 | 11 | ## XML Syntax Rules 12 | 13 | 1. **XML Declaration**: An XML document starts with an XML declaration which specifies the XML version. 14 | 2. **Root Element**: Each XML document should have a root element that contains all other elements. 15 | 3. **Tag Names**: XML tags are case sensitive and must start with a letter or underscore. 16 | 4. **Closing Tags**: Every start tag in XML should have a matching end tag. 17 | 5. **Attribute Values**: Attribute values must be surrounded by quotation marks. 18 | 19 | ## Example 20 | 21 | Here's an example of an XML (eXtensible Markup Language) file: 22 | 23 | ```xml 24 | 25 | 26 | John Doe 27 | 30 28 | Engineering 29 |
30 | 1234 Main St 31 | Anytown 32 | CA 33 | 12345 34 |
35 | 36 | Java 37 | C# 38 | Python 39 | 40 |
41 | ``` 42 | 43 | ## Benefits of XML 44 | 45 | 1. **Self-descriptive**: XML uses text strings rather than binary code, which makes it easy for humans to read and write. 46 | 2. **Platform Independent**: XML data can be processed by any machine or operating system, making it a versatile choice for data storage and transmission. 47 | 3. **Supports Unicode**: This allows almost any information in any human language to be communicated. 48 | 49 | ## Common Uses of XML 50 | 51 | - **Data Storage**: XML is often used for storing data in a structured manner. 52 | - **Data Transport**: XML provides a hardware- and software-independent way of sharing data. 53 | - **Configuration Files**: Many software use XML files for configuration. 54 | - **RSS Feeds**: RSS feeds, which are used to syndicate content on the web, are typically written in XML. 55 | 56 | ## Best Practices for XML 57 | 58 | 1. **Use Meaningful Element Names**: Element names should describe the data and be easy to understand. 59 | 2. **Keep it Simple**: Try to minimize the depth of your XML structure and the number of attributes. 60 | 3. **Error Handling**: Use a parser that supports error handling to ensure that your XML documents are well-formed. 61 | 4. **Validate Your XML**: Use an XML Schema or DTD (Document Type Definition) to validate the structure and content of your XML. 62 | 5. **Security**: Be aware of potential security issues, such as XML External Entity (XXE) attacks, when parsing XML documents. 63 | -------------------------------------------------------------------------------- /notes/07_data_formats/03_json.md: -------------------------------------------------------------------------------- 1 | # JSON 2 | 3 | JSON, or JavaScript Object Notation, is a lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate. It is a text format that is completely language independent but uses conventions familiar to programmers of the C family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. 4 | 5 | ## Basics of JSON 6 | 7 | 1. **Data Types**: JSON supports a variety of data types including strings, numbers, booleans, arrays, and objects (key-value pairs). 8 | 9 | 2. **Syntax**: JSON syntax is derived from JavaScript object notation syntax, but the JSON format is text only. Code for reading and generating JSON data can be written in any programming language. 10 | 11 | ## JSON Syntax Rules 12 | 13 | 1. **Data is in name/value pairs**: Data is represented in name/value pairs (e.g., "name":"John"). 14 | 2. **Data is separated by commas**: The name/value pairs are separated by commas. 15 | 3. **Objects are encapsulated within opening and closing curly braces `{}`**: An object can be thought of as an unordered set of name/value pairs. An object begins with `{` (left brace) and ends with `}` (right brace). Each name is followed by `:` (colon) and the name/value pairs are separated by `,` (comma). 16 | 4. **Arrays are encapsulated within opening and closing square brackets `[]`**: An array is an ordered collection of values. An array begins with `[` (left bracket) and ends with `]` (right bracket). Values are separated by `,` (comma). 17 | 18 | ## Example 19 | 20 | Here's a simple example of a JSON file: 21 | 22 | ```json 23 | { 24 | "employee": { 25 | "name": "John Doe", 26 | "age": 30, 27 | "department": "Engineering", 28 | "address": { 29 | "street": "1234 Main St", 30 | "city": "Anytown", 31 | "state": "CA", 32 | "zipCode": "12345" 33 | }, 34 | "skills": ["Java", "C#", "Python"] 35 | } 36 | } 37 | ``` 38 | 39 | ## Benefits of JSON 40 | 41 | 1. **Human-Readable**: JSON is a text-based format that is easy to read and write. 42 | 2. **Language Independent**: JSON uses JavaScript syntax, but the JSON format is text only, allowing it to be used across different programming languages. 43 | 3. **Lightweight**: JSON has a much smaller grammar and maps more directly onto the data structures used in modern programming languages. 44 | 45 | ## Common Uses of JSON 46 | 47 | - **Data Storage**: JSON is often used for storing data in a structured manner. 48 | - **Data Transport**: JSON provides a hardware- and software-independent way of sharing data. 49 | - **Configuration Files**: Many software use JSON files for configuration. 50 | 51 | ## JSON vs XML 52 | 53 | While both JSON and XML can be used to store and exchange data, JSON is often preferred due to its simplicity and speed. JSON is easier to read and write, and faster to parse and generate than XML. 54 | 55 | | **Feature** | **JSON (JavaScript Object Notation)** | **XML (eXtensible Markup Language)** | 56 | |-----------------------|-------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------| 57 | | **Format** | Lightweight and text-based. | Verbose and document-based format. | 58 | | **Readability** | Generally easier to read due to its concise format. | Less human-readable due to more verbose nature. | 59 | | **Data Types** | Supports basic data types like string, number, array, boolean, and null. | Does not have built-in support for data types; everything is a string. | 60 | | **Parsing** | Easy to parse with standard JavaScript functions. | Requires a parser to read and manipulate. | 61 | | **Size** | Typically smaller, making it faster to transmit. | Larger file sizes due to additional markup elements. | 62 | | **Extensibility** | Not as extensible due to its fixed structure. | Highly extensible and allows for custom-defined tags and structures. | 63 | | **Metadata** | Limited support for metadata. | Excellent support for metadata. | 64 | | **Comments** | Does not support comments. | Supports comments. | 65 | | **Security** | Considered more secure as it is less prone to entity and DTD attacks. | Prone to certain types of attacks like entity and DTD attacks. | 66 | | **Array Representation** | Uses square brackets for arrays. | Uses custom tag names for arrays; no built-in array representation. | 67 | | **Use Cases** | Often used in web services and APIs due to its compatibility with JavaScript and lightweight nature. | Preferred for complex document structures and when metadata is crucial.| 68 | 69 | ## Best Practices for JSON 70 | 71 | 1. **Use Meaningful Key Names**: Key names should describe the data and be easy to understand. 72 | 2. **Keep it Simple**: Try to minimize the depth of your JSON structure. 73 | 3. **Validate Your JSON**: Use a JSON validator to ensure that your JSON syntax is correct. 74 | 4. **Use JSON Linting Tools**: JSON linting tools can help to format your JSON correctly and catch any syntax errors. 75 | 5. **Security**: When parsing JSON, be aware of potential security risks such as injection attacks. 76 | -------------------------------------------------------------------------------- /notes/07_data_formats/04_yaml.md: -------------------------------------------------------------------------------- 1 | # YAML 2 | 3 | YAML, or "YAML Ain't Markup Language," is a human-readable data serialization format. It is commonly used for configuration files and data exchange between languages with different data structures. YAML is designed to be readable and concise, with a focus on data readability over markup verbosity. 4 | 5 | ## Basics of YAML 6 | 7 | 1. **Data Types**: YAML supports scalar types (such as strings, integers, and floats), complex mappings (associative arrays or objects), and sequences (lists or arrays). 8 | 9 | 2. **Syntax**: YAML syntax is designed to be easily readable and writable by humans. It uses indentation to denote structure, allowing for a more natural representation of nested data structures. 10 | 11 | ## YAML Syntax Rules 12 | 13 | 1. **Indentation-based Hierarchy**: Indentation is used to represent the hierarchy and structure of data. The amount of indentation affects the interpretation of the data. 14 | 2. **Scalars**: Scalars are simple, single-value data types, including integers, floats, and strings. 15 | 3. **Mappings**: Mappings (similar to dictionaries or objects in other languages) are represented using a colon and space `: ` to denote key-value pairs. 16 | 4. **Lists**: Lists (or sequences) are denoted by a hyphen `-` at the start of the item in the list. 17 | 5. **Support for Comments**: YAML supports comments using the `#` symbol. 18 | 19 | ## Example 20 | 21 | Here's a simple example: 22 | 23 | ```yaml 24 | employee: 25 | name: John Doe 26 | age: 30 27 | department: Engineering 28 | address: 29 | street: 1234 Main St 30 | city: Anytown 31 | state: CA 32 | zipCode: 12345 33 | skills: 34 | - Java 35 | - C# 36 | - Python 37 | ``` 38 | 39 | ## Benefits of YAML 40 | 41 | 1. **Human-Friendly**: YAML is designed with human readability in mind, making it easy to write and understand. 42 | 2. **Flexible**: Capable of representing complex data structures in a clear manner. 43 | 3. **Widespread Usage**: Commonly used in configuration files and development tools. 44 | 45 | ## Common Uses of YAML 46 | 47 | - **Configuration Management**: Widely used in software configuration, particularly in DevOps tools. 48 | - **Data Serialization**: Used for storing and transmitting data in a readable format. 49 | - **Development Tools**: Often used for writing configuration files for development and deployment environments. 50 | 51 | ## YAML vs JSON 52 | 53 | While both YAML and JSON are used for data serialization, YAML is more human-readable, which makes it preferred for configuration files. JSON, being more compact and parsed natively by JavaScript, is often used for web APIs and data interchange. 54 | 55 | | **Feature** | **YAML (YAML Ain't Markup Language)** | **JSON (JavaScript Object Notation)** | 56 | |---------------------------|--------------------------------------------------------------------------|-----------------------------------------------------------------------| 57 | | **Format** | Human-readable, text-based format. | Lightweight, text-based format. | 58 | | **Readability** | Highly readable due to its minimalistic design and use of indentation. | Readable, though less human-friendly than YAML due to bracket usage. | 59 | | **Data Types** | Supports complex data types and structures. | Supports basic data types like string, number, array, boolean, and null. | 60 | | **Comments** | Allows comments. | Does not support comments. | 61 | | **Hierarchical Structure**| Uses indentation to denote structure, which can be more intuitive. | Uses braces `{ }` and brackets `[ ]` to denote objects and arrays. | 62 | | **Parsing** | Requires a YAML parser. | Easily parsed with standard JavaScript functions. | 63 | | **File Extension** | `.yaml` or `.yml` | `.json` | 64 | | **Verbose** | Less verbose than JSON in many cases due to the lack of brackets. | More verbose due to use of brackets and commas. | 65 | | **Security** | Requires careful parsing due to potential security issues. | Generally secure, but also requires secure parsing practices. | 66 | | **Use Cases** | Often used for configuration files, data serialization, and in applications where human readability is a priority. | Commonly used in web services, APIs, and settings where a lightweight and easily parsable format is desired. | 67 | 68 | ## Best Practices for YAML 69 | 70 | 1. **Consistent Indentation**: Maintain consistent indentation for readability and to avoid errors. 71 | 2. **Use Comments Wisely**: Use comments to explain complex parts of the YAML file. 72 | 3. **Avoid Excessive Nesting**: Over-nesting can make YAML files complex and hard to read. 73 | 4. **Validate Your YAML**: Use a YAML validator to ensure your syntax is correct. 74 | 5. **Be Aware of Data Types**: YAML is sensitive to data types; be mindful of strings vs. integers and other data type distinctions. 75 | 76 | -------------------------------------------------------------------------------- /notes/08_security/01_auth.md: -------------------------------------------------------------------------------- 1 | # Authentication and Authorization (Auth) 2 | Authentication is the process of verifying a user's identity, while authorization is the management of access rights to resources. 3 | 4 | ## Auth Process 5 | Authentication and authorization occur server-side, with client-side requests contributing to the process. 6 | 7 | ``` 8 | +-------------------------+ +------------------------+ 9 | | | | | 10 | | Client Side | | Server Side | 11 | | (User's Device/Browser) | | (Web Application) | 12 | | | | | 13 | +-------------------------+ +------------------------+ 14 | || || 15 | || || 16 | \/ \/ 17 | +----------------------+ +-------------------------+ 18 | | | | | 19 | | User Requests Auth | | Authentication Check | 20 | | (Login, Access Page) |----------------> | Verifies User Identity | 21 | | | | | 22 | +----------------------+ +-------------------------+ 23 | || || 24 | || || 25 | \/ \/ 26 | +----------------------+ +------------------------+ 27 | | | | | 28 | | Server Responds | | Authorization Check | 29 | | (Token, Permissions) | <--------------- | Controls Resource | 30 | | | | Access | 31 | +----------------------+ +------------------------+ 32 | ``` 33 | 34 | ## Rendering in Frontend 35 | The server responds with data that includes user auth information, which the client uses to render appropriate views. 36 | 37 | ``` 38 | +---------------------+ +-------------------------+ 39 | | | | | 40 | | Server Side | | Client Side | 41 | | (Web Application) | | (User's Device/Browser) | 42 | | | | | 43 | +---------------------+ +-------------------------+ 44 | || || 45 | || || 46 | || Sends Data with Auth Info || 47 | \/ \/ 48 | +---------------------+ +-------------------------+ 49 | | | | | 50 | | Prepares Response | | Receives Data and | 51 | | with Auth Details |-----------------> | Auth Information | 52 | | (e.g., User Roles, | | | 53 | | Permissions) | | | 54 | +---------------------+ +-------------------------+ 55 | || 56 | || Process Data 57 | \/ 58 | +----------------------+ 59 | | | 60 | | Render Appropriate | 61 | | Views Based on | 62 | | Auth Information | 63 | | | 64 | +----------------------+ 65 | ``` 66 | 67 | ## Frontend Auth Flow 68 | 69 | 1. **Initial Page Load**: User opens the page for the first time. 70 | 2. **Sign-in**: User signs in, and the server sends a secure cookie. 71 | 3. **Cookie Storage**: Client stores the secure cookie. 72 | 4. **Future Requests**: Subsequent requests include the secure cookie for authentication. 73 | 74 | ## Server-side User Authorization Flow 75 | 76 | 1. **Data Request**: User requests data from the server. 77 | 2. **Request Processing**: Server parses the user's cookie from the request. 78 | 3. **Identity Verification**: Server checks the cookie to identify the user. 79 | 4. **Authorization Check**: Server verifies if the user is authorized for the requested action. 80 | 5. **Response Handling**: Authorized requests receive data; unauthorized attempts get an error response. 81 | 82 | ## Authentication Best Practices 83 | 84 | - **Auth Methods**: Prefer JWT or OAuth over Basic Auth. 85 | - **Security Measures**: Implement maximum retry limits and account lock features against brute-force attacks. 86 | - **Data Protection**: Encrypt sensitive data. 87 | - **Framework Utilization**: Use established libraries and frameworks for token generation and password storage. 88 | 89 | ## JWT Best Practices 90 | 91 | ### Secret Key 92 | Utilize a complex, random secret key for JWT. 93 | 94 | ```python 95 | import os 96 | jwt_secret_key = os.urandom(64) 97 | ``` 98 | 99 | ### Algorithm Enforcement 100 | Explicitly specify the backend algorithm (e.g., HS256 or RS256) and avoid trusting the algorithm specified in the JWT header. 101 | 102 | ```python 103 | import jwt 104 | encoded_jwt = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256') 105 | ``` 106 | 107 | ### Token Expiration 108 | Set short expiration times for tokens to reduce the risk of misuse. 109 | 110 | ```python 111 | import datetime 112 | exp = datetime.datetime.utcnow() + datetime.timedelta(hours=1) 113 | encoded_jwt = jwt.encode({'exp': exp}, 'secret', algorithm='HS256') 114 | ``` 115 | 116 | ### Payload Security 117 | Avoid including sensitive data in the JWT payload. 118 | 119 | ```python 120 | user_data = {'user_id': user_id, 'username': username} # Do not include sensitive info 121 | encoded_jwt = jwt.encode(user_data, 'secret', algorithm='HS256') 122 | ``` 123 | 124 | ### Size Limitation 125 | Limit the data in JWT to prevent exceeding header size limits. 126 | 127 | ```python 128 | minimal_payload = {'user_id': user_id} 129 | encoded_jwt = jwt.encode(minimal_payload, 'secret', algorithm='HS256') 130 | ``` 131 | 132 | ## OAuth Best Practices 133 | 134 | ### URI Validation 135 | Perform server-side validation of redirect URIs, only allowing whitelisted URLs. 136 | 137 | ```python 138 | allowed_uris = ['https://example.com/callback', 'https://anotherdomain.com/auth'] 139 | if redirect_uri not in allowed_uris: 140 | raise ValueError('Invalid redirect URI') 141 | ``` 142 | 143 | ### Code Exchange 144 | 145 | Prefer using code exchange rather than direct token grants (avoid response_type=token). 146 | 147 | ```python 148 | from requests_oauthlib import OAuth2Session 149 | oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) 150 | authorization_url, state = oauth.authorization_url(authorization_base_url) 151 | # Redirect user to authorization_url and then exchange code for token 152 | ``` 153 | 154 | ### CSRF Prevention 155 | 156 | Utilize a random hash state parameter in OAuth authentication to prevent CSRF. 157 | 158 | ```python 159 | import os 160 | state = os.urandom(32).hex() 161 | authorization_url = f"{authorization_base_url}?response_type=code&state={state}" 162 | # Store 'state' and validate it when receiving the callback 163 | ``` 164 | 165 | ### Scope Management 166 | 167 | Clearly define default scopes and validate scope parameters for each OAuth application. 168 | 169 | ```python 170 | default_scopes = ['read', 'write'] 171 | if not all(scope in default_scopes for scope in requested_scopes): 172 | raise ValueError('Invalid scope requested') 173 | ``` 174 | -------------------------------------------------------------------------------- /notes/08_security/02_tls.md: -------------------------------------------------------------------------------- 1 | ## Transport Layer Security 2 | 3 | Transport Layer Security, commonly abbreviated as TLS, is a cryptographic protocol that protects data transmissions over computer networks. It succeeds the older SSL (Secure Sockets Layer), and though the term “SSL” is still widely used, most modern “SSL” connections are really TLS. The protocol aims to make sure that data moving between parties, such as a user’s browser and a web server, cannot be intercepted, read, or modified by anyone else. By encrypting and verifying identities through certificates, TLS helps preserve confidentiality and authenticity for a wide range of applications, from simple webpage visits to sophisticated web services. 4 | 5 | ### TLS versus SSL 6 | 7 | TLS started as a direct upgrade to SSL, improving the protocol’s security and addressing vulnerabilities. SSL is now deprecated, and recent versions of web servers and browsers rely on TLS 1.2 or TLS 1.3 for secure communications. Although people might still refer to “SSL certificates” or “SSL connections,” the underlying technology is almost always TLS. 8 | 9 | ### Concepts in TLS 10 | 11 | TLS relies on encryption and identity verification to secure communication sessions. Encryption makes sure that the transmitted data is indecipherable to eavesdroppers, while identity verification relies on digital certificates and certificate authorities to confirm the authenticity of the server (and optionally the client). Once the TLS handshake completes, both parties share session keys to encrypt and decrypt subsequent data with minimal overhead. 12 | 13 | ### TLS Handshake 14 | 15 | When a client, such as a web browser, accesses a server via HTTPS, a TLS handshake occurs to set up how data will be encrypted and to verify identities. The following ASCII diagram outlines this process: 16 | 17 | ``` 18 | Client (Browser) Server (Website) 19 | | | 20 | | 1. ClientHello ---------------------> | 21 | | (Supported TLS versions, ciphers) | 22 | | | 23 | | <--------------- 2. ServerHello ------| 24 | | (Chosen cipher, certificate) | 25 | | | 26 | | 3. Certificate Verification | 27 | | (Validate server's certificate) | 28 | | | 29 | | 4. Key Exchange --------------------> | 30 | | (Client sends encrypted pre-master)| 31 | | | 32 | | <------------ 5. Server Key Exchange | 33 | | (Both generate session keys) | 34 | | | 35 | | 6. Secure Communication --------------| 36 | | (Data encrypted with session keys) | 37 | | | 38 | | <------------- Encrypted Data --------| 39 | | (Server responses also encrypted) | 40 | ``` 41 | 42 | 1) The client initiates contact by listing its supported TLS versions and cipher suites. 43 | 2) The server responds with its chosen version, cipher suite, and a certificate. 44 | 3) The client checks that the certificate is valid. 45 | 4) The client and server perform a key exchange, often involving short-lived Diffie-Hellman or elliptic-curve cryptography, so they derive a unique session key. 46 | 5) The server confirms or finalizes the key information, and once both sides agree, the secure channel is in place. 47 | 6) All subsequent messages are encrypted with the session key. 48 | 49 | ### TLS Certificates 50 | 51 | A TLS certificate affirms the server’s identity. Certificate Authorities (CAs) issue certificates after verifying the domain ownership (and sometimes more details about the organization). The certificate embeds the public key of the server and is digitally signed by the CA, so clients can verify that no tampering or impersonation has occurred. 52 | 53 | To trust a certificate, the client checks whether the CA’s own certificate is in its trust store. Browsers ship with many trusted CAs, so any certificate signed by one of those CAs is considered valid if it passes all checks (expiration date, matching domain name, etc.). 54 | 55 | ### Why TLS Matters 56 | 57 | Security is the core motivation for TLS. By encrypting data, TLS defends against eavesdroppers who might otherwise capture sensitive information such as login credentials or payment details. Through certificates, TLS also makes sure that users connect to the intended site rather than an imposter, helping thwart man-in-the-middle attacks. Search engines and browsers often rank or flag sites based on HTTPS adoption, so deploying TLS can enhance reputation and trustworthiness. 58 | 59 | ### TLS Versions 60 | 61 | #### TLS 1.2 62 | 63 | Released in 2008, TLS 1.2 improved on older versions with more secure hashing (e.g., SHA-256), support for authenticated encryption (AEAD ciphers), and explicit negotiation of signature algorithms. Over time, several vulnerabilities arose (like BEAST, CRIME, and POODLE) that required specific mitigations or changes to cipher configurations. Despite these issues, TLS 1.2 has remained widely used and remains functional when configured securely with modern cipher suites. 64 | 65 | #### TLS 1.3 66 | 67 | Finalized in 2018, TLS 1.3 significantly simplified the handshake and removed numerous obsolete or insecure features: 68 | 69 | - **Fewer Round Trips**: The handshake requires fewer messages, speeding up the initial connection. 70 | - **Mandatory Forward Secrecy**: Short-lived key exchanges mean that even if a long-term private key leaks, old sessions remain secure. 71 | - **Removal of Weak Cryptography**: Old key exchange methods (static RSA, older Diffie-Hellman groups, etc.) and ciphers are gone, so typical pitfalls are reduced. 72 | - **0-RTT Resumption**: Allows clients to send data immediately upon reconnecting, though it must be deployed carefully to avoid replay attacks. 73 | 74 | Many servers and clients now support TLS 1.3 by default, but some older software can only use TLS 1.2 or earlier. 75 | 76 | ### Upgrading from TLS 1.2 to TLS 1.3 77 | 78 | Transitioning to TLS 1.3 can yield both performance and security benefits. However, it requires making sure that servers, clients, and libraries are ready. This might involve: 79 | 80 | - Checking that your server software (like Apache, Nginx, or a Java-based server) supports TLS 1.3. 81 | - Setting the server configuration to allow TLS 1.3 in addition to TLS 1.2 for fallback. 82 | - Enabling modern cipher suites that align with TLS 1.3. 83 | - Updating or replacing older client libraries that do not support TLS 1.3. 84 | Phased rollouts, with logging to identify any legacy clients failing to connect, help make sure a smooth transition. 85 | 86 | ### Carrying out TLS in Applications 87 | 88 | #### Obtaining a Certificate 89 | 90 | A TLS setup begins with acquiring a certificate. In many cases, you: 91 | 92 | 1) Generate a private key and a Certificate Signing Request (CSR). 93 | 2) Send the CSR to a Certificate Authority (e.g., Let’s Encrypt, DigiCert). 94 | 3) Receive the signed certificate, which includes the public key and CA signature. 95 | 96 | Below is an example command sequence using OpenSSL to create a private key and CSR: 97 | 98 | ``` 99 | openssl req -newkey rsa:2048 -nodes -keyout mysite.key -out mysite.csr 100 | ``` 101 | 102 | This prompts for information about your organization and domain, producing `mysite.key` (private key) and `mysite.csr` (CSR). You then submit `mysite.csr` to the CA. 103 | 104 | #### Installing the Certificate on the Server 105 | 106 | Once the CA returns `mysite.crt`, place it on the server along with `mysite.key`. The final steps vary by web server: 107 | 108 | **Example** (Nginx snippet): 109 | 110 | ``` 111 | server { 112 | listen 443 ssl; 113 | server_name mysite.example.com; 114 | 115 | ssl_certificate /etc/ssl/certs/mysite.crt; 116 | ssl_certificate_key /etc/ssl/private/mysite.key; 117 | 118 | # TLS 1.2 and 1.3 only 119 | ssl_protocols TLSv1.2 TLSv1.3; 120 | 121 | # A recommended set of ciphers for better security 122 | ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:..."; 123 | 124 | # Your site config here 125 | root /var/www/mysite; 126 | } 127 | ``` 128 | 129 | After reloading or restarting Nginx, requests to `https://mysite.example.com/` are secured by TLS. 130 | 131 | #### Enforcing HTTPS in the Application 132 | 133 | Switch code references to use `https://` URLs. If users visit the site via HTTP, set up redirects or use HSTS headers to push them to HTTPS. In an Nginx config, you might add: 134 | 135 | ``` 136 | server { 137 | listen 80; 138 | server_name mysite.example.com; 139 | return 301 https://mysite.example.com$request_uri; 140 | } 141 | ``` 142 | 143 | This makes sure all traffic is funneled to the secure port. 144 | 145 | #### Testing 146 | 147 | Use an external SSL checker to confirm the certificate is correctly installed and that the server’s cipher suites are modern. Tools like SSL Labs (Qualys) provide an in-depth report, highlighting potential vulnerabilities, misconfigurations, or outdated protocol versions. 148 | 149 | ### TLS Best Practices 150 | 151 | Deploying TLS effectively calls for attention to detail in configuration and key management. 152 | 153 | 1) Prefer the Latest Versions: Aim for TLS 1.2 or 1.3. 154 | 2) Use Strong Cipher Suites: Disable older ciphers like RC4 or 3DES. 155 | 3) Maintain Key Security: Keep private keys in secure directories with limited permissions. 156 | 4) Use HSTS: HTTP Strict Transport Security makes sure browsers do not attempt insecure connections. 157 | 5) Renew Certificates Promptly: Certificates expire. Monitor expiration dates and automate renewals if possible. 158 | 6) Remove Insecure Protocol Versions: Disable TLS 1.0/1.1 and all SSL versions unless strictly required by legacy systems. 159 | 7) Monitor Logs: Keep an eye on server logs for handshake failures or suspicious activity. 160 | -------------------------------------------------------------------------------- /notes/08_security/05_third_party_cookies_vulnerabilities.md: -------------------------------------------------------------------------------- 1 | ## Third-Party Cookies Vulnerabilities 2 | 3 | Third-party cookies are often inserted into a user’s browser by domains other than the website the user is directly visiting. While first-party cookies (from the visited domain) are essential for maintaining user sessions and preferences, third-party cookies commonly facilitate **cross-site tracking** and advertising. This ability to track user behavior across multiple domains introduces privacy and security concerns. 4 | 5 | ``` 6 | ASCII DIAGRAM: Basic Cookie Flow 7 | 8 | User Web Page (1st party) 3rd-Party Domain 9 | | | | 10 | | (Request page) | | 11 | +-----------------------> | | 12 | | | <--- 1st-party cookies ----> | 13 | | | | 14 | | | (Embedded 3rd-party scripts) | 15 | | | +---------------+ 16 | | (Retrieves scripts) | | 17 | | <-----------------------+ | 18 | | | | 19 | | (Loads script) | | 20 | | (Sends 3rd-party request with or sets 3rd-party cookie) 21 | |---------------------------------------> | 22 | | | | <--- 3rd-party cookies ----> 23 | | | | 24 | +--[Cookies in Browser]--+ + 25 | ``` 26 | 27 | 1. **User**: Visits a website (the “first party”). 28 | 2. **First-Party Content**: The site may embed scripts or images from another domain (a “third party”). 29 | 3. **Browser**: Automatically sends or receives cookies tied to each domain, storing them locally. 30 | 4. **Third-Party Domain**: Receives these cookie data with each request, possibly tracking the user across different first-party sites. 31 | 32 | ## Types of Cookies 33 | 34 | 1. **First-Party Cookies** 35 | - Set by the domain the user **intentionally** visits. 36 | - Essential for login sessions, shopping carts, user preferences. 37 | 38 | 2. **Third-Party Cookies** 39 | - Set by an external domain embedded on the page (e.g., an ad network, social media widget). 40 | - Commonly used for **tracking** user behavior across multiple sites and delivering targeted ads. 41 | 42 | --- 43 | 44 | ## Why Third-Party Cookies Pose Vulnerabilities 45 | 46 | 1. **Cross-Site Tracking** 47 | - A single third-party script or ad network can **recognize** a user across multiple sites. 48 | - This allows detailed profiling of user behavior, often **without** explicit consent. 49 | 50 | 2. **Privacy Concerns** 51 | - Users’ browsing histories can be **correlated** to build extensive personal profiles. 52 | - Raises compliance challenges under regulations like **GDPR** or **CCPA**. 53 | 54 | 3. **Security Risks** 55 | - Third-party cookies can be **exploited** if malicious code is injected into these external scripts or if they are misconfigured. 56 | - Potential attacks include **Session Hijacking**, **Cross-Site Request Forgery (CSRF)**, and **Tracking Pixel** abuses. 57 | 58 | 4. **Lack of Transparency** 59 | - Users often have **no clear visibility** into which external entities are setting cookies or how the data is used. 60 | 61 | ``` 62 | ASCII DIAGRAM: Cross-Site Tracking via Third-Party Cookies 63 | 64 | +----------------+ +------------------+ 65 | | Site A | | Site B | 66 | | (ads from | | (ads from | 67 | | 3rd Party) | | same 3rd Party)| 68 | +-------+--------+ +---------+--------+ 69 | | | 70 | v v 71 | +--------------+ +--------------+ 72 | | 3rd Party | | 3rd Party | 73 | | Ad Network | | Ad Network | 74 | +-------+------+ +------+-------+ 75 | ^ ^ 76 | | (Identifies user) | (Identifies user) 77 | +--------+---------------+ 78 | | 79 | +----------+ 80 | | 81 | (Aggregates tracking data) 82 | ``` 83 | 84 | ## Google’s Third-Party Cookie Phase-Out 85 | 86 | 1. **Announcement**: Google plans to phase out **third-party cookie** support in the Chrome browser. 87 | 2. **Motivation**: Addressing **privacy** concerns and shifting the industry towards more transparent ad tracking technologies. 88 | 3. **Timeline**: 89 | - Initially targeted 2022. 90 | - **Postponed** to allow websites and advertisers to explore alternative strategies (e.g., FLoC, Topics API). 91 | 92 | ``` 93 | ASCII DIAGRAM: Simplified Timeline 94 | 95 | [ 2020 ] -----> [ 2021 ] -----> [ 2022 ] -----> [ ??? ] 96 | Google announces Industry tests Implementation 97 | plan to remove alternatives timeline extended 98 | 3rd-party cookies (FLoC, etc.) 99 | ``` 100 | 101 | - **Industry Impact**: Forces **advertisers** and **analytics providers** to adopt new privacy-preserving methods for user tracking or personalization. 102 | 103 | ## Implications for Developers and Businesses 104 | 105 | 1. **Shift to First-Party Data** 106 | - Encourages collecting user data **directly** through owned platforms. 107 | - More reliance on **server-side** tracking, user logins, or contextual advertising. 108 | 109 | 2. **Emerging Privacy-Focused Tech** 110 | - Proposed solutions like **FLoC** or **Topics API** aim to **protect** user identity while still enabling ad targeting. 111 | - Some companies explore fingerprinting techniques, but that raises **further** privacy concerns. 112 | 113 | 3. **Regulatory Compliance** 114 | - With third-party cookies restricted, apps must comply with GDPR/CCPA by offering clear user consent flows. 115 | - More emphasis on **privacy-centric** design and transparent data usage policies. 116 | 117 | 4. **Adaptation Cost** 118 | - Companies deeply reliant on 3rd-party tracking for **monetization** or analytics need to restructure their tech stacks. 119 | - Potential **short-term loss** in ad revenue until new methods mature. 120 | 121 | ``` 122 | ASCII DIAGRAM: Potential Future Approach 123 | 124 | +----------+ +------------------+ +--------------+ 125 | | Site | ---> | 1st-Party Data | --> | Analytics | 126 | | Owner | | (Server side) | | & Ad Tools | 127 | +----------+ +------------------+ +--------------+ 128 | ^ ^ 129 | | (User logs in) | 130 | |------------------+ 131 | ``` 132 | 133 | - Collecting data from **logged-in** or voluntary user interactions rather than broad behind-the-scenes 3rd-party cookies. 134 | 135 | 136 | ## Best Practices to Mitigate Third-Party Cookie Risks 137 | 138 | 1. **Minimize Dependencies** 139 | - Limit the number of external services injecting scripts or cookies. 140 | - Use well-known, **trusted** third-party providers. 141 | 142 | 2. **Use Secure Cookie Settings** 143 | - **SameSite** attribute to mitigate CSRF. 144 | - **Secure** and **HttpOnly** flags to prevent theft via XSS. 145 | 146 | 3. **Implement Content Security Policies (CSP)** 147 | - Restricts which domains can run scripts, reducing the risk of **malicious** 3rd-party code. 148 | 149 | 4. **Explicit Consent Mechanisms** 150 | - GDPR-like banners asking user consent before loading non-essential third-party trackers. 151 | - Offer a **cookie preferences** panel for transparency and user control. 152 | 153 | 5. **Monitor & Audit** 154 | - Regularly scan your site for unexpected third-party scripts. 155 | - Keep track of what each embedded script does, verifying it adheres to privacy standards. 156 | 157 | -------------------------------------------------------------------------------- /notes/09_deployment/01_centos_digital_ocean.md: -------------------------------------------------------------------------------- 1 | 2 | ## Deploying CentOS VM on Digital Ocean 3 | 4 | ### Step 1: Sign Up and Log In 5 | 6 | - Sign up for a Digital Ocean account. 7 | - Log in to your account. 8 | 9 | ### Step 2: Create a New Droplet 10 | 11 | - Click "Create" and select "Droplets." 12 | - Choose CentOS as your distribution. 13 | - Select the desired version of CentOS. 14 | 15 | ### Step 3: Select Droplet Size 16 | 17 | - Choose the size of the droplet based on your requirements (CPU, RAM, and storage). 18 | - Consider selecting the right size for your budget. 19 | 20 | ### Step 4: Choose Datacenter Region 21 | 22 | - Select a datacenter region closest to your target audience. 23 | - Consider factors like latency and data privacy regulations. 24 | 25 | ### Step 5: Set Up SSH Key 26 | 27 | - Create an SSH key for secure access to your CentOS VM. 28 | - Add your public SSH key to the Digital Ocean account. 29 | 30 | ### Step 6: Configure Droplet Options 31 | 32 | - Choose additional options like monitoring, backups, and private networking. 33 | - Select the number of droplets you want to create. 34 | 35 | ### Step 7: Finalize and Create 36 | 37 | - Give your droplet a hostname. 38 | - Click "Create Droplet." 39 | 40 | ### Step 8: Access CentOS VM 41 | 42 | - After the droplet is created, you'll receive an IP address. 43 | - Use the IP address and your SSH key to access the CentOS VM through an SSH client. 44 | 45 | ### Step 9: Set Up and Configure CentOS 46 | 47 | - Update the system with the latest packages and security patches. 48 | - Install necessary software and tools. 49 | - Configure your applications and services. 50 | -------------------------------------------------------------------------------- /notes/09_deployment/02_static_python_website_netlify.md: -------------------------------------------------------------------------------- 1 | 2 | ## Deploying Static Python Website on Netlify 3 | 4 | Netlify allows you to easily deploy and manage static websites. 5 | 6 | ### Steps to Deploy 7 | 8 | 1. **Create a repository**: Create a Git repository containing your static Python website code. 9 | 10 | 2. **Sign up for Netlify**: If you don't have an account, sign up at [netlify.com](https://www.netlify.com/). 11 | 12 | 3. **Connect your repository**: Link your Git repository to Netlify. 13 | 14 | - In the Netlify dashboard, click on "New site from Git". 15 | - Choose your Git provider (GitHub, GitLab, or Bitbucket). 16 | - Select the repository with your static Python website code. 17 | 18 | 4. **Configure build settings**: Set up build settings for your website. 19 | 20 | - Specify the build command for your project, if required. 21 | - Set the publish directory (usually `dist` or `public`). 22 | - Click "Deploy site" to start the deployment process. 23 | 24 | 5. **Domain settings**: Configure your custom domain or use the auto-generated one provided by Netlify. 25 | 26 | - Go to the "Domain settings" section of your site dashboard. 27 | - Set up a custom domain or use the default Netlify subdomain. 28 | - If using a custom domain, configure DNS settings with your domain registrar. 29 | 30 | 6. **SSL/TLS**: Secure your site with HTTPS using Let's Encrypt. 31 | 32 | - Netlify provides free SSL/TLS certificates through Let's Encrypt. 33 | - In the "Domain settings" section, click "SSL/TLS certificate" to set it up. 34 | 35 | 7. **Monitor deployment**: Check the status of your deployment. 36 | 37 | - In the site dashboard, monitor the progress and status of your deployment. 38 | - Once the deployment is complete, your website is live and accessible via the specified domain. 39 | 40 | With these steps, you can easily deploy and manage your static Python website on Netlify. 41 | -------------------------------------------------------------------------------- /notes/10_distributed_systems/02_gossip_protocol.md: -------------------------------------------------------------------------------- 1 | ## Gossip Protocol 2 | 3 | The Gossip Protocol is a technique in distributed systems for sharing information across a network of nodes, especially useful when nodes frequently join or leave the network. 4 | 5 | ``` 6 | [Node 1] 7 | / \ 8 | / \ 9 | / \ 10 | [Node 2] [Node 3] 11 | \ / | \ 12 | \ / | \ 13 | \ / | \ 14 | [Node 4] | [Node 5] 15 | | 16 | [Node 6] 17 | 18 | Legend: 19 | - Each [Node] represents a network participant. 20 | - The lines depict potential paths for gossip propagation. 21 | - The network structure is irregular, symbolizing the random nature of gossip communication. 22 | ``` 23 | 24 | ## How the Gossip Protocol Works 25 | 26 | - Each node periodically selects a random node and shares its state with it. 27 | - The receiving node does the same, resulting in information dissemination across the network. 28 | 29 | ## Advantages of the Gossip Protocol 30 | 31 | - Scalability: Handles networks with large numbers of nodes without scalability issues. 32 | - Resilience: Resilient to network and node failures, as information dissemination doesn't depend on a single node or path. 33 | - Efficiency: Efficient in network bandwidth and computational resources, as nodes only share their state with a few other nodes at a time. 34 | 35 | ## Types of Gossip Protocols 36 | 37 | - Epidemic Protocol: Basic form of the Gossip Protocol, where each node gossips with a fixed number of other nodes. 38 | - Push-Sum Protocol: A Gossip Protocol variant for computing aggregate values across the network. 39 | 40 | ## Implementing the Gossip Protocol 41 | 42 | Implementation requires careful consideration of: 43 | - Network topology 44 | - Frequency of gossiping 45 | - Size of data being disseminated 46 | 47 | Popular Gossip Protocol implementations include: 48 | 49 | - Apache Cassandra: A distributed database using the Gossip Protocol for node discovery and failure detection. 50 | - Akka Cluster: A distributed computing framework using the Gossip Protocol for node discovery and communication. 51 | -------------------------------------------------------------------------------- /notes/10_distributed_systems/03_linearizability.md: -------------------------------------------------------------------------------- 1 | ## Linearizability 2 | 3 | Linearizability is a consistency model used to make it seem like there's only one copy of the data. It ensures that: 4 | 5 | - All reads reflect the latest written value. 6 | - The system appears consistent and up-to-date. 7 | - Availability and speed may be impacted. 8 | 9 | ``` 10 | Write Request Read Request Read Request 11 | | | | 12 | V V V 13 | +----------+ +----------+ +----------+ 14 | | | | | | | 15 | | Database | ----> | Database | ----> | Database | 16 | | (Latest | | (Latest | | (Latest | 17 | | Value) | | Value) | | Value) | 18 | | | | | | | 19 | +----------+ +----------+ +----------+ 20 | ``` 21 | 22 | ## Ordering 23 | 24 | To achieve linearizability, an order for data operations is required: 25 | 26 | - Use Lamport timestamps to generate sequence numbers across multiple machines. 27 | - Timestamps are tuples of the counter and the node ID. 28 | - Nodes and clients track the maximum counter value and include it in every request. 29 | - Lamport timestamps provide a total ordering but can't show concurrent operations. 30 | 31 | ## Total Order Broadcast 32 | 33 | Total order broadcast is a protocol to exchange messages between nodes: 34 | 35 | - Ensures no messages are lost. 36 | - Delivers messages to every node in the same order. 37 | - Helps solve problems like uniqueness constraints across different replicas. 38 | 39 | ## Distributed Transactions and Consensus 40 | 41 | Distributed transactions can use the two-phase commit: 42 | 43 | - Coordinator node sends writes and prepare requests to other nodes. 44 | - Nodes either commit or abort based on the coordinator's decision. 45 | - The coordinator maintains an internal log of decisions for crash recovery. 46 | 47 | ## Quorum and Consensus Algorithms 48 | 49 | Consensus algorithms use a majority (quorum) of nodes to improve availability: 50 | 51 | - New leaders are elected in subsequent epochs to prevent split-brain scenarios. 52 | - Consensus algorithms define a recovery process for nodes to reach a consistent state. 53 | - Coordination services like ZooKeeper provide replicated in-memory key-value stores for total order broadcast. 54 | -------------------------------------------------------------------------------- /notes/10_distributed_systems/04_concurrent_writes.md: -------------------------------------------------------------------------------- 1 | ## Concurrent Writes 2 | 3 | Concurrent writes happen when two clients write to a database at the same time, unaware of each other's write. This can cause inconsistencies in the replicas. 4 | 5 | ``` 6 | [Write 1] [Write 2] [Write 3] 7 | \ | / 8 | \ | / 9 | \ | / 10 | \ | / 11 | \ | / 12 | +------------------+ 13 | | Database | 14 | +------------------+ 15 | ``` 16 | 17 | ## Detecting Concurrent Writes 18 | 19 | - Both multi-leader and leaderless replication systems must detect and resolve concurrent writes. 20 | - Events may arrive in different orders at different nodes; it's important for nodes to reach a consistent state eventually. 21 | 22 | ## Last Write Wins 23 | 24 | - A common approach for concurrent writes is the "last write wins" strategy. 25 | - Writes are given an arbitrary order, and the last write is chosen as the correct one. 26 | - Easy to implement, but not durable; some writes are discarded. 27 | - Timestamps for ordering writes can be problematic due to clock skew. 28 | 29 | ## Immutable Keys 30 | 31 | - An alternative is to allow each key to be written only once, making it immutable. 32 | - No writes are lost, but may not suit all use cases. 33 | 34 | ## Version Numbers 35 | 36 | - Use version numbers to track a key's state. 37 | - Clients pass the last version number they've seen to the server, which assigns a new version number and returns it. 38 | - The server determines which data the client had access to at the time of writing. 39 | - If the client writes without relying on existing data, the server can return both versions of the data on subsequent reads. 40 | - The application can handle these two values, either merging them automatically or prompting the user to do so. 41 | 42 | ## Version Vectors 43 | 44 | - Version vectors track the state of data for multiple replicas. 45 | - A version vector includes a version number for each replica and key. 46 | - Each replica keeps track of its own version number and those of other replicas to decide which values to use. 47 | -------------------------------------------------------------------------------- /notes/10_distributed_systems/05_operational_transform.md: -------------------------------------------------------------------------------- 1 | ## Operational Transform (OT) 2 | 3 | Operational Transform is a technique in distributed systems for real-time collaborative editing of shared documents. 4 | 5 | ``` 6 | [User 1] [User 2] [User 3] 7 | | Edit | Edit | Edit 8 | | | | 9 | v v v 10 | [OT Engine]--[OT Engine]--[OT Engine] 11 | \ | / 12 | \ | / 13 | \ | / 14 | \ | / 15 | \ | / 16 | +----------------------------+ 17 | | Shared Document | 18 | | (Real-time Collaboration) | 19 | +----------------------------+ 20 | ``` 21 | 22 | ## Collaborative Editing Challenges 23 | 24 | Collaborative editing can be difficult in distributed systems because: 25 | 26 | - Multiple users can modify the document at the same time. 27 | - Coordination or synchronization is needed to prevent inconsistencies or corruption. 28 | 29 | ## How OT Works 30 | 31 | OT transforms a sequence of edits by: 32 | 33 | - Analyzing the meaning of the edits. 34 | - Identifying potential conflicts or inconsistencies. 35 | - Creating a new sequence of edits to apply without causing conflicts. 36 | 37 | ## Types of Operations 38 | 39 | OT can transform operations like: 40 | 41 | - Insertion: Adding new content to the document. 42 | - Deletion: Removing existing content from the document. 43 | - Move: Changing content position within the document. 44 | - Format: Changing the style or formatting of content. 45 | 46 | ## Implementing OT 47 | 48 | Implementing OT can be challenging due to: 49 | 50 | - The need for a suitable data model to represent the document. 51 | - The development of algorithms to transform operations. 52 | 53 | Popular OT implementations include: 54 | 55 | - Google Docs: A web-based collaborative editing platform using OT to synchronize changes. 56 | - ShareJS: An open-source OT library for custom applications. 57 | -------------------------------------------------------------------------------- /notes/10_distributed_systems/06_algorithms_summary.md: -------------------------------------------------------------------------------- 1 | 2 | ### 1. Geohash 3 | 4 | **What it is:** A string encoding of latitude/longitude into a hierarchical grid. 5 | **Why it’s important:** Enables very fast proximity searches (e.g. “find all users within 1 km”) by turning 2D spatial queries into simple prefix lookups. Interviewers often probe how you’d build location-based services (ride-share, geofencing), and Geohash shows you understand spatial indexing. 6 | 7 | --- 8 | 9 | ### 2. Quadtree 10 | 11 | **What it is:** A tree that recursively partitions 2D space into four quadrants. 12 | **Why it’s important:** Supports efficient window/region queries and dynamic spatial indexing. In system design, you might use Quadtrees to shard geospatial data across servers or accelerate map-tile rendering—knowing it demonstrates spatial-data handling at scale. 13 | 14 | --- 15 | 16 | ### 3. Consistent Hashing 17 | 18 | **What it is:** A hashing scheme that minimizes remapping when nodes join/leave the cluster. 19 | **Why it’s important:** The go-to for distributing cache entries or data partitions (e.g. in a distributed cache or DHT) so that only \~1/N keys move on topology changes. Interviewers will expect you to know how to scale caches (e.g. Memcached) without a massive cache-miss storm on resizing. 20 | 21 | --- 22 | 23 | ### 4. Leaky-Bucket 24 | 25 | **What it is:** A rate-limiting algorithm that smooths bursts by processing tokens at a fixed rate. 26 | **Why it’s important:** Illustrates how to enforce steady request throughput (e.g. API gateways). In interviews, designing a throttling layer often comes up, and Leaky-Bucket shows you can bound QPS and prevent overload. 27 | 28 | --- 29 | 30 | ### 5. Token-Bucket 31 | 32 | **What it is:** A rate-limiter that allows bursts up to a bucket size but enforces a long-term rate. 33 | **Why it’s important:** More flexible than Leaky-Bucket—lets you absorb short spikes while still capping average rate. Interviewers like to discuss fair-use policies and burst-tolerant rate limits; Token-Bucket is fundamental. 34 | 35 | --- 36 | 37 | ### 6. Trie 38 | 39 | **What it is:** A prefix tree for storing strings. 40 | **Why it’s important:** Powers lightning-fast autocomplete, IP routing tables, dictionary lookups. When you design a search-as-you-type feature or need compact prefix storage (e.g. banned words filter), Tries show you can optimize both space and lookup latency. 41 | 42 | --- 43 | 44 | ### 7. Rsync 45 | 46 | **What it is:** A delta-transfer algorithm that synchronizes files by sending only changed blocks. 47 | **Why it’s important:** Critical for efficient backups, CDN origin-pull, or database replication. Interviewers may ask how to sync large datasets over the network with minimal bandwidth; Rsync’s rolling-checksum trick is the classic answer. 48 | 49 | --- 50 | 51 | ### 8. Raft / Paxos 52 | 53 | **What it is:** Consensus protocols to agree on a single sequence of operations in a distributed cluster. 54 | **Why it’s important:** Core to building strongly consistent distributed systems (e.g. leader election, replicated logs in databases like etcd, Spanner). In any fault-tolerance discussion, you’ll need to contrast CP vs. AP (CAP theorem) and show you understand how systems stay in sync despite node failures. 55 | 56 | --- 57 | 58 | ### 9. Bloom Filter 59 | 60 | **What it is:** A space-efficient probabilistic data structure for set membership with false positives. 61 | **Why it’s important:** Used to avoid expensive lookups (e.g. “is this key in the cache?” or “have we seen this URL before?”). In interview scenarios around caching or big-data pipelines, Bloom filters demonstrate you can trade a tiny error rate for huge memory savings. 62 | 63 | --- 64 | 65 | ### 10. Merkle Tree 66 | 67 | **What it is:** A hash tree where each parent summarizes its children’s hashes. 68 | **Why it’s important:** Enables efficient, tamper-evident verification of large datasets (e.g. git, blockchain, database replicas). When designing systems that need to detect or reconcile divergent data (e.g. anti-entropy in Dynamo), Merkle trees are your tool. 69 | 70 | --- 71 | 72 | ### 11. HyperLogLog 73 | 74 | **What it is:** A streaming algorithm for cardinality estimation (count distinct) using tiny memory. 75 | **Why it’s important:** Real-time analytics often need “unique user” or “distinct search terms” counts on massive streams. In scale-out designs, HyperLogLog shows you can give approximate metrics with sub-kilobyte state. 76 | 77 | --- 78 | 79 | ### 12. Count-Min Sketch 80 | 81 | **What it is:** A probabilistic frequency-counting structure with fixed size. 82 | **Why it’s important:** Lets you track “top-k” heavy hitters (e.g. popular products, trending hashtags) in streaming data. Interviewers frequently ask how to monitor high-volume logs or metrics without storing every event; Count-Min Sketch is a key answer. 83 | 84 | --- 85 | 86 | ### 13. Hierarchical Timing Wheels 87 | 88 | **What it is:** A timer-wheel structure to manage millions of timeouts efficiently. 89 | **Why it’s important:** Critical for schedulers (e.g. TCP retransmission timers, cache-entry TTLs) at high scale. In system design, you’ll be asked how to handle huge numbers of delayed jobs or network timeouts without O(N) per-tick overhead. 90 | 91 | --- 92 | 93 | ### 14. Operational Transformation 94 | 95 | **What it is:** An algorithm for real-time collaborative editing that merges concurrent operations. 96 | **Why it’s important:** Powers Google Docs-style collaborative applications. When discussing collaborative systems or CRDTs (Conflict-Free Replicated Data Types), knowing OT shows you can handle concurrent state updates with consistency guarantees. 97 | --------------------------------------------------------------------------------