<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ifkarsyah</title><link>https://ifkarsyah.tech/authors/ifkarsyah/</link><atom:link href="https://ifkarsyah.tech/authors/ifkarsyah/index.xml" rel="self" type="application/rss+xml"/><description>Ifkarsyah</description><generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>en-us</language><lastBuildDate>Mon, 10 Aug 2020 00:00:00 +0000</lastBuildDate><image><url>img/map[gravatar:%!s(bool=false) shape:circle]</url><title>Ifkarsyah</title><link>https://ifkarsyah.tech/authors/ifkarsyah/</link></image><item><title>Book Notes: Operating System: Three Easy Pieces</title><link>https://ifkarsyah.tech/post/notes-os-three-easy-pieces/</link><pubDate>Mon, 10 Aug 2020 00:00:00 +0000</pubDate><guid>https://ifkarsyah.tech/post/notes-os-three-easy-pieces/</guid><description>&lt;p>&lt;a href="https://www.student.cs.uwaterloo.ca/~cs350/F14/reading.html">https://www.student.cs.uwaterloo.ca/~cs350/F14/reading.html&lt;/a>&lt;/p>
&lt;h2 id="part-1-virtualizing-the-cpu">Part 1: Virtualizing the CPU&lt;/h2>
&lt;p>Virtualizing the CPU means creating illusion such that each application think it has its own CPU to use,
although there&amp;rsquo;s only one.&lt;/p>
&lt;hr>
&lt;h3 id="ch-1-process-kernel-system-calls">Ch 1: Process, Kernel, System Calls&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-intro.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-intro.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-api.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-api.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-mechanisms.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-mechanisms.pdf&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch-2-scheduling">Ch 2: Scheduling&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-sched.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-sched.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-sched-mlfq.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-sched-mlfq.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-sched-lottery.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-sched-lottery.pdf&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="part-2-virtualizing-the-memory">Part 2: Virtualizing the Memory&lt;/h2>
&lt;hr>
&lt;h3 id="ch-1-virtual-memory">Ch 1: Virtual Memory&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-intro.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/vm-intro.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-api.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/vm-api.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-mechanism.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/vm-mechanism.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-segmentation.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/vm-segmentation.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-paging.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/vm-paging.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-tlbs.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/vm-tlbs.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-smalltables.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/vm-smalltables.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-beyondphys.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/vm-beyondphys.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-beyondphys-policy.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/vm-beyondphys-policy.pdf&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="part-3-concurrency">Part 3: Concurrency&lt;/h2>
&lt;hr>
&lt;h3 id="ch1-threads">Ch1: Threads&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-intro.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/threads-intro.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-api.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/threads-api.pdf&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch2-synchronization">Ch2: Synchronization&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-locks.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/threads-locks.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-locks-usage.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/threads-locks-usage.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-sema.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/threads-sema.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-bugs.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/threads-bugs.pdf&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="part-4-persistance">Part 4: Persistance&lt;/h2>
&lt;hr>
&lt;h3 id="ch-1-filesystem">Ch 1: Filesystem&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/file-implementation.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/file-implementation.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/file-journaling.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/file-journaling.pdf&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch-2-io">Ch 2: IO&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/file-devices.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/file-devices.pdf&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/file-disks.pdf">http://pages.cs.wisc.edu/~remzi/OSTEP/file-disks.pdf&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="part-5-security">Part 5: Security&lt;/h2></description></item><item><title>Book Notes: Design Data Intensive Application</title><link>https://ifkarsyah.tech/post/notes-data-intensive/</link><pubDate>Thu, 06 Aug 2020 00:00:00 +0000</pubDate><guid>https://ifkarsyah.tech/post/notes-data-intensive/</guid><description>&lt;h2 id="part-1-foundations-of-data-systems">Part 1: Foundations of Data Systems&lt;/h2>
&lt;hr>
&lt;h3 id="ch-1-reliable-scalable-and-maintainable-applications">Ch 1: Reliable, Scalable, and Maintainable Applications&lt;/h3>
&lt;h4 id="a-reliability">A. Reliability&lt;/h4>
&lt;p>A system is reliable only if it &lt;strong>Fault Tolerant&lt;/strong>.&lt;/p>
&lt;p>Fault ≠ Failure. &lt;strong>Fault&lt;/strong> is when a system component deviates from its spec.
Whereas &lt;strong>Failure&lt;/strong> is when system as a whole stops providing required service.&lt;/p>
&lt;p>System designer&amp;rsquo;s goal is to prevent faults from turning into failure.&lt;/p>
&lt;p>Fault can happen in many ways:&lt;/p>
&lt;ul>
&lt;li>Hardware fault: hardisk crash, network failure
&lt;ul>
&lt;li>Alleviated by adding redundancy to the hardware component&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Human error: design error, config error
&lt;ul>
&lt;li>Alleviated by following best practice, thorough automated testing, CI/CD, etch&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="b-scalability">B. Scalability&lt;/h4>
&lt;p>A system is scalable if it can handle increased load.&lt;/p>
&lt;p>System load is described by &lt;strong>load parameters&lt;/strong>, which depends on the purpose of a system.
For example, requests per second, simultaneous active connections, hits for cache, etc.&lt;/p>
&lt;p>&lt;strong>Performance&lt;/strong> can be viewed in two ways:&lt;/p>
&lt;ul>
&lt;li>increase load parameter and keep the system resource, see how the system is affected&lt;/li>
&lt;li>increase load parameter, see ow much resource is need to keep system performance unchanged&lt;/li>
&lt;/ul>
&lt;p>Percentile is usually used to measure request response time. &lt;strong>Service level object (SLO)&lt;/strong> and &lt;strong>service level argreement (SLA)&lt;/strong> are used to define expected performance. Percentile is usually to define such goals, like 99&amp;amp; of uses should have X response time.&lt;/p>
&lt;p>Two ways to cope with load:&lt;/p>
&lt;ul>
&lt;li>Vertical scaling (more powerful machine)&lt;/li>
&lt;li>Horizontal scaling (more nodes)&lt;/li>
&lt;/ul>
&lt;h4 id="c-maintainability">C. Maintainability&lt;/h4>
&lt;ul>
&lt;li>Operability: make it easy for ops/infra teams
&lt;ul>
&lt;li>Ex: Monitor system health.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Simplicity: make it easy for new engineers&lt;/li>
&lt;li>Evolvability: make it easy to make changes.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch-2-data-models-and-query-languages">Ch 2: Data Models and Query Languages&lt;/h3>
&lt;h4 id="a-relational-model-vs-document-model">A. Relational Model vs. Document Model&lt;/h4>
&lt;h5 id="consideration">Consideration&lt;/h5>
&lt;ul>
&lt;li>Restrictive schema or no schema(actually: schema-on-read) ?&lt;/li>
&lt;/ul>
&lt;h5 id="relational-model">Relational Model&lt;/h5>
&lt;ul>
&lt;li>Pro&lt;/li>
&lt;li>Cons
&lt;ul>
&lt;li>There&amp;rsquo;s &lt;strong>object-relational mismatch&lt;/strong>, that is when application language is OOP but datastore is relational.
So, you need to have a &amp;ldquo;translation layer&amp;rdquo;. This problem is partially solved by ORM library like
&lt;a href="http://gorm.io" target="_blank" rel="noopener">gorm.io&lt;/a>
or
&lt;a href="https://hibernate.org/orm/" target="_blank" rel="noopener">hibernate&lt;/a>
.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Use when:
&lt;ul>
&lt;li>Many-to-Many relationships are needed.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Example
&lt;ul>
&lt;li>VM: MySQL&lt;/li>
&lt;li>DBaaS
&lt;ul>
&lt;li>GCP: Cloud SQL, Cloud Spanner&lt;/li>
&lt;li>AWS: RDS, Aurora, Redshift&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h5 id="document-model">Document Model&lt;/h5>
&lt;ul>
&lt;li>Pro&lt;/li>
&lt;li>Cons&lt;/li>
&lt;li>Use when:
&lt;ul>
&lt;li>The data has document-like structure(a tree), where tipycally the entire tree is loaded at once.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Example
&lt;ul>
&lt;li>VM: MongoDB&lt;/li>
&lt;li>DBaaS
&lt;ul>
&lt;li>GCP: Firestore&lt;/li>
&lt;li>AWS: DocumentDB, DynamoDB&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="b-query-languages-for-data">B. Query Languages for Data&lt;/h4>
&lt;ul>
&lt;li>Declarative: SQL&lt;/li>
&lt;li>MapReduce Querying&lt;/li>
&lt;/ul>
&lt;h4 id="c-graph-like-model">C. Graph-Like Model&lt;/h4>
&lt;ul>
&lt;li>Property Graphs&lt;/li>
&lt;li>The Cypher Query Language&lt;/li>
&lt;li>Graph Queries in SQL&lt;/li>
&lt;li>Triple-Stores and SPARQL&lt;/li>
&lt;li>The Foundation: Datalog&lt;/li>
&lt;li>Example
&lt;ul>
&lt;li>VM: Neo4J&lt;/li>
&lt;li>DBaaS
&lt;ul>
&lt;li>GCP&lt;/li>
&lt;li>AWS: Neptune&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="why-theres-no-key-value-model">(Why there&amp;rsquo;s no) Key-Value Model&lt;/h4>
&lt;ul>
&lt;li>Why there&amp;rsquo;s no? Maybe too simple&lt;/li>
&lt;li>Example
&lt;ul>
&lt;li>VM: Redis, Memcached&lt;/li>
&lt;li>DBaaS
&lt;ul>
&lt;li>GCP: Memorystore&lt;/li>
&lt;li>AWS: ElastiCache for Redis, ElastiCache for Memcached
fs&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="why-theres-no-timeseries">(Why there&amp;rsquo;s no) Timeseries&lt;/h4>
&lt;ul>
&lt;li>Why there&amp;rsquo;s no?&lt;/li>
&lt;li>Example
&lt;ul>
&lt;li>VM: InfluxDB, Prometheus, TimescaleDB, Graphite&lt;/li>
&lt;li>DBaaS
&lt;ul>
&lt;li>GCP:&lt;/li>
&lt;li>AWS: Timestream&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="why-theres-no-wide-column">(Why there&amp;rsquo;s no) Wide-Column&lt;/h4>
&lt;ul>
&lt;li>Why there&amp;rsquo;s no? Later&lt;/li>
&lt;li>Example
&lt;ul>
&lt;li>VM: Cassandra&lt;/li>
&lt;li>DBaaS
&lt;ul>
&lt;li>GCP: Bigtable&lt;/li>
&lt;li>AWS: Keyspace for Cassandra&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="why-theres-no-ledger">(Why there&amp;rsquo;s no) Ledger&lt;/h4>
&lt;ul>
&lt;li>Why there&amp;rsquo;s no? Read on blockchain specific book&lt;/li>
&lt;li>Example
&lt;ul>
&lt;li>VM:&lt;/li>
&lt;li>DBaaS
&lt;ul>
&lt;li>GCP:&lt;/li>
&lt;li>AWS: QLDB&lt;/li>
&lt;li>All cryptocurrency is backed by ledger&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch-3-storage-and-retrieval">Ch 3: Storage and Retrieval&lt;/h3>
&lt;h4 id="a-data-structures-that-power-your-database">A. Data Structures That Power Your Database&lt;/h4>
&lt;p>Many databases internally use a &lt;strong>log&lt;/strong>, which is an append-only data file.
In order to efficiently find the value for a particular key in the database, we need a different data structure: an &lt;strong>index&lt;/strong>.
Indexes speed up read queries, but slows down writes.&lt;/p>
&lt;h5 id="hash-indexes">Hash Indexes&lt;/h5>
&lt;ul>
&lt;li>What is it? A &lt;code>unordered_map[key]value&lt;/code> where key is mapped to a byte offset in the datafile&lt;/li>
&lt;li>Pro
&lt;ul>
&lt;li>simple, easy to implement&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Cons
&lt;ul>
&lt;li>has memory constraint that the hash table must fit in memory&lt;/li>
&lt;li>range queries are not efficient since hashed key are not put next to each other&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Used by: Riak,
&lt;a href="https://arpitbhayani.me/blogs/bitcask" target="_blank" rel="noopener">Bitcask&lt;/a>
&lt;/li>
&lt;/ul>
&lt;h5 id="sorted-string-tablesstable--log-structured-merge-treelsm-trees">Sorted String Table(SSTable) &amp;amp; Log-Structured Merge Tree(LSM-Trees)&lt;/h5>
&lt;ul>
&lt;li>What is it?
&lt;ul>
&lt;li>A &lt;code>ordered_map[key]value&lt;/code> backed with Red-Black trees or AVL trees (memtable)&lt;/li>
&lt;li>If database crashes, memtable can be recovered by LSM-Trees&amp;rsquo;s log&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Used by: LevelDB, RockDB&lt;/li>
&lt;/ul>
&lt;h5 id="b-trees">B-Trees&lt;/h5>
&lt;ul>
&lt;li>What is it?
&lt;ul>
&lt;li>A &lt;code>ordered_map[key]value&lt;/code> like SSTable&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Used by: almost all relational DB&lt;/li>
&lt;/ul>
&lt;h4 id="b-oltp-vs-olap">B. OLTP vs. OLAP&lt;/h4>
&lt;h5 id="data-warehousing">Data Warehousing&lt;/h5>
&lt;p>Data warehouse is a database that data people can query without affecting OLTP.
Data Engineer &lt;strong>etracted&lt;/strong> data from OLTP, &lt;strong>transformed&lt;/strong> it to certain structure optimized for analytics query, and then &lt;strong>load&lt;/strong> it to the OLAP.&lt;/p>
&lt;h5 id="stars-and-snowflakes-schemas-for-olap">Stars and Snowflakes: Schemas for OLAP&lt;/h5>
&lt;p>TODO&lt;/p>
&lt;h5 id="column-oriented-storage">Column-Oriented Storage&lt;/h5>
&lt;p>In OLTP databases, storage is laid out in a row-oriented fashion.
Whereas, in column-oriented storage, all the values from each column is stored together instead.
&lt;img src="wide-column.png" alt="wide">&lt;/p>
&lt;p>Data warehouse queries often involve an aggregate function (SUM, AVG&amp;hellip;), on subset of column.
It might have sense to cache the results of such functions.  One way of creating such a cache is a &lt;strong>materialized view&lt;/strong>.&lt;/p>
&lt;p>A common special case of a materialized view is known as a &lt;strong>data cube&lt;/strong> or OLAP cube which is a grid of aggregates grouped by different dimensions.&lt;/p>
&lt;hr>
&lt;h3 id="ch-4-encoding-and-evolution">Ch 4: Encoding and Evolution&lt;/h3>
&lt;h4 id="a-formats-for-encoding-data">A. Formats for Encoding Data&lt;/h4>
&lt;h5 id="language-specific-formats">Language-Specific Formats&lt;/h5>
&lt;ul>
&lt;li>Example: python&amp;rsquo;s pickle, golang&amp;rsquo;s gob, java serialization&lt;/li>
&lt;li>Cons: don&amp;rsquo;t support multilanguage apps, not CPU efficient&lt;/li>
&lt;/ul>
&lt;h5 id="text-variant">Text Variant&lt;/h5>
&lt;ul>
&lt;li>Pro: human-readable&lt;/li>
&lt;li>Cons: size inefficient, don&amp;rsquo;t differentiate integer &amp;amp; float&lt;/li>
&lt;li>Example: JSON, XML&lt;/li>
&lt;/ul>
&lt;h5 id="binary-variant">Binary Variant&lt;/h5>
&lt;ul>
&lt;li>Thrift&lt;/li>
&lt;li>Protobuf&lt;/li>
&lt;li>Avro&lt;/li>
&lt;li>Reference
&lt;ul>
&lt;li>
&lt;a href="https://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html" target="_blank" rel="noopener">Martin Kleppmann&amp;rsquo;s: Schema Evolution in Avro, Protobuf, &amp;amp; Thrift&lt;/a>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="b-modes-of-dataflow">B. Modes of Dataflow&lt;/h4>
&lt;h5 id="dataflow-through-databases">Dataflow Through Databases&lt;/h5>
&lt;ul>
&lt;li>Data structure in-memory encoded to written bytes stored in persistent storage&lt;/li>
&lt;li>Need to maintain forward compatibility to avoid data loss&lt;/li>
&lt;/ul>
&lt;h5 id="dataflow-through-services-rest-and-rpc">Dataflow Through Services: REST and RPC&lt;/h5>
&lt;ul>
&lt;li>REST&lt;/li>
&lt;li>RPC
&lt;ul>
&lt;li>Tries to make network request look the same as calling local function&lt;/li>
&lt;li>RPC is fundamentally flawed 
&lt;ul>
&lt;li>local function call is predictable, but network request is unpredictable&lt;/li>
&lt;li>Hard to pass complex objects via network request, because you have to encode everything into bytes first&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>SOAP&lt;/li>
&lt;/ul>
&lt;h5 id="message-passing-dataflow">Message-Passing Dataflow&lt;/h5>
&lt;ul>
&lt;li>Message Broker
&lt;ul>
&lt;li>Ex: Kafka, RabbitMQ&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="kafka-broker.png" alt="Kafka Broker">&lt;/p>
&lt;hr>
&lt;h2 id="part-2-distributed-data">Part 2: Distributed Data&lt;/h2>
&lt;hr>
&lt;h3 id="ch-5-replication">Ch 5: Replication&lt;/h3>
&lt;p>Replication means keeping a copy of our data in many machines that are connected with each other using a network.
The goal is to increase system availibity, and also reducing latency by keeping data geographically close to users(ex: CDN).&lt;/p>
&lt;h4 id="a-leaders-and-followers">A. Leaders and Followers&lt;/h4>
&lt;ul>
&lt;li>Workflow
&lt;ol>
&lt;li>Initial condition: &lt;strong>leader_node&lt;/strong>(age = 30), &lt;strong>follower_nodes&lt;/strong> = { node1(age = 20), node2(age = 20), node3(age = 20)}&lt;/li>
&lt;li>&lt;strong>Client&lt;/strong> writes(age = 15) to &lt;strong>leader_node&lt;/strong>&lt;/li>
&lt;li>&lt;strong>leader_node&lt;/strong> changed its age to 15&lt;/li>
&lt;li>&lt;strong>leader_node&lt;/strong> notify the change to its follower by sending a &lt;strong>replication log&lt;/strong>&lt;/li>
&lt;li>&lt;strong>follower_nodes&lt;/strong>.apply(&lt;strong>replication log&lt;/strong>)&lt;/li>
&lt;li>Final condition: &lt;strong>leader_node&lt;/strong>(age = 15), &lt;strong>follower_nodes&lt;/strong> = { node1(age = 15), node2(age = 15), node3(age = 15)}
&lt;a href="https://www.brainstobytes.com/db-replication-i-introduction-to-database-replication/" target="_blank" rel="noopener">Ref.&lt;/a>
&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Synchronous Versus Asynchronous Replication
&lt;ul>
&lt;li>Sync
&lt;ul>
&lt;li>only writes &lt;strong>after&lt;/strong> all follower has the copy&lt;/li>
&lt;li>Pros: system in consistent state&lt;/li>
&lt;li>Cons: 99% impractical, if one follower nodes is down(&lt;strong>fault&lt;/strong>), the leader must block the write operations until the nodes up again, means &lt;strong>system failure&lt;/strong>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Async
&lt;ul>
&lt;li>Pro : fault tolerant&lt;/li>
&lt;li>Cons: if one node down, system in inconsistent state&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Setting Up New Followers
&lt;ul>
&lt;li>
&lt;a href="https://www.brainstobytes.com/db-replication-i-introduction-to-database-replicationdb-replication-ii-failure-recovery-fundamentals/" target="_blank" rel="noopener">Ref.&lt;/a>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Handling Node Outages
&lt;ul>
&lt;li>
&lt;a href="https://www.brainstobytes.com/db-replication-i-introduction-to-database-replicationdb-replication-ii-failure-recovery-fundamentals/" target="_blank" rel="noopener">Ref.&lt;/a>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Implementation of Replication Logs
&lt;ul>
&lt;li>Statement-based replication
&lt;ul>
&lt;li>Workflow:
&lt;ol>
&lt;li>client writes &lt;code>query_stmt = INSERT INTO transactions VALUES(V...)&lt;/code> to leaders&lt;/li>
&lt;li>leader write to its log the &lt;code>query_stmt&lt;/code> and send the log to its follower&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Need to handling nondeterministic function such as &lt;code>NOW()&lt;/code> to get current timestamp&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Write-ahead log&lt;/li>
&lt;li>Logical log replication&lt;/li>
&lt;li>Triger-based replication&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="b-problems-with-replication-lag">B. Problems with Replication Lag&lt;/h4>
&lt;ul>
&lt;li>Reading Your Own Writes&lt;/li>
&lt;li>Monotonic Reads&lt;/li>
&lt;li>Consistent Prefix Reads&lt;/li>
&lt;li>Solutions for Replication Lag&lt;/li>
&lt;/ul>
&lt;h4 id="c-multi-leader-replication">C. Multi-Leader Replication&lt;/h4>
&lt;ul>
&lt;li>Use Cases for Multi-Leader Replication
&lt;ul>
&lt;li>Multi-datacenter operation: each datacenter has its own leader.&lt;/li>
&lt;li>Client with offline operation: every client has a local database that acts as a leader&lt;/li>
&lt;li>Real-time collaborative editing:
&lt;ul>
&lt;li>when one user edits a document,&lt;/li>
&lt;li>then the changes are instantly applied to their local replica&lt;/li>
&lt;li>then asynchronously replicated to the server and any other users who are editing the same document.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Handling Write Conflicts&lt;/li>
&lt;li>Multi-Leader Replication Topologies&lt;/li>
&lt;/ul>
&lt;h4 id="d-leaderless-replication">D. Leaderless Replication&lt;/h4>
&lt;ul>
&lt;li>Writing to the Database When a Node Is Down&lt;/li>
&lt;li>Limitations of Quorum Consistency&lt;/li>
&lt;li>Sloppy Quorums and Hinted Handoff&lt;/li>
&lt;li>Detecting Concurrent Writes&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch-6-partitioningsharding">Ch 6: Partitioning/Sharding&lt;/h3>
&lt;h4 id="a-partitioning-and-replication">A. Partitioning and Replication&lt;/h4>
&lt;p>HDFS is an example of system that does both partition and replication.
Workflow:&lt;/p>
&lt;ol>
&lt;li>Initial condition: data = {a, b, c, d}, let say HDFS has 4 nodes = { {}, {}, {}, {} }&lt;/li>
&lt;li>Set replica level = 2, and partition data accross the whole HDFS cluster node&lt;/li>
&lt;li>Final condition: nodes = { {a, b}, {c, d}, {a, c}, {b, d} }&lt;/li>
&lt;/ol>
&lt;h4 id="b-partitioning-of-key-value-data">B. Partitioning of Key-Value Data&lt;/h4>
&lt;ul>
&lt;li>Partitioning by Key Range&lt;/li>
&lt;li>Partitioning by Hash of Key&lt;/li>
&lt;li>Skewed Workloads and Relieving Hot Spots&lt;/li>
&lt;/ul>
&lt;h4 id="c-partitioning-and-secondary-indexes">C. Partitioning and Secondary Indexes&lt;/h4>
&lt;ul>
&lt;li>Partitioning Secondary Indexes by Document&lt;/li>
&lt;li>Partitioning Secondary Indexes by Term&lt;/li>
&lt;/ul>
&lt;h4 id="d-rebalancing-partitions">D. Rebalancing Partitions&lt;/h4>
&lt;ul>
&lt;li>Strategies for Rebalancing&lt;/li>
&lt;li>Operations: Automatic or Manual Rebalancing&lt;/li>
&lt;/ul>
&lt;h4 id="e-request-routing">E. Request Routing&lt;/h4>
&lt;ul>
&lt;li>Parallel Query Execution&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch-7-transactions">Ch 7: Transactions&lt;/h3>
&lt;h4 id="a-the-slippery-concept-of-a-transaction">A. The Slippery Concept of a Transaction&lt;/h4>
&lt;ul>
&lt;li>The Meaning of ACID
&lt;ul>
&lt;li>Atomicity : execute all operation or none&lt;/li>
&lt;li>Consistency : transaction should not make database to turn into inconsistent state&lt;/li>
&lt;li>Isolation : concurrent operation all isolated&lt;/li>
&lt;li>Durability : once transaction is commited, it will remain commited even if there&amp;rsquo;s system failure&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Single-Object and Multi-Object Operations&lt;/li>
&lt;/ul>
&lt;h4 id="b-weak-isolation-levels">B. Weak Isolation Levels&lt;/h4>
&lt;p>Databases have tried to hide concurrency problems from application developers by providing transaction isolation.
In practice, it is not that simple. The perfect isolation is &lt;strong>Serializable isolation&lt;/strong>, but that comes with the price of worst performance.
For that reason database systems implement weaker levels of isolation.&lt;/p>
&lt;p>One practices that ensure the ACID properties is &lt;strong>Read Commited&lt;/strong>.
That is no dirty reads that means read data only after the data has been committed.
And, no dirty writes that means write/overwrite data only after the data has been committed.&lt;/p>
&lt;ul>
&lt;li>Snapshot Isolation by Multiversion Concurrency Control(MVCC)&lt;/li>
&lt;/ul>
&lt;p>The &lt;strong>lost update problem&lt;/strong> can happen if two transactions write data concurrently,
one of the updates might be lost because the second update does not have the first modification.
To prevent the &lt;strong>lost update problem&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Atomic write&lt;/strong> operations avoid the necessity of reading first from the database to modify a value.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The application can &lt;strong>lock&lt;/strong> the objects that are going to be modified rejecting the second update.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Preventing lost update&lt;/p>
&lt;ul>
&lt;li>Lost update can happen if two transcctions write to the same data concurrently,&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Preventing Write Skew and Phantoms&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h4 id="c-serializability">C. Serializability&lt;/h4>
&lt;p>Serializable isolation is the strongest isolation level.
It guarantees even transactions run in parallel, the result will be as if they had executed one at a time.
These are serializability isolation technique:&lt;/p>
&lt;ul>
&lt;li>Actual (only run) Serial Execution
&lt;ul>
&lt;li>Cons: don&amp;rsquo;t scale&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Two-Phase Locking (2PL)
&lt;ul>
&lt;li>Cons: don&amp;rsquo;t perform well&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Serializable Snapshot Isolation (SSI)
*&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch-8-the-trouble-with-distributed-systems">Ch 8: The Trouble with Distributed Systems&lt;/h3>
&lt;h4 id="a-unreliable-networks">A. Unreliable Networks&lt;/h4>
&lt;ul>
&lt;li>Network Faults in Practice, ex:
&lt;ul>
&lt;li>The request has been lost.&lt;/li>
&lt;li>The request may have been queued and will be delivered later.&lt;/li>
&lt;li>The remote node may have temporarily stopped responding.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Detecting Faults&lt;/li>
&lt;li>Timeouts and Unbounded Delays&lt;/li>
&lt;li>Synchronous Versus Asynchronous Networks&lt;/li>
&lt;/ul>
&lt;h4 id="b-unreliable-clocks">B. Unreliable Clocks&lt;/h4>
&lt;p>Each machine/component on distributed system has it own time. And, communicating through network take times.
Then, for some like &lt;code>NOW()&lt;/code> in SQL query between 2 machine, how could we ensure that the time stored in database is exactly same in those 2 machine?&lt;/p>
&lt;ul>
&lt;li>Monotonic Versus Time-of-Day Clocks&lt;/li>
&lt;li>Clock Synchronization and Accuracy&lt;/li>
&lt;li>Relying on Synchronized Clocks&lt;/li>
&lt;li>Process Pauses&lt;/li>
&lt;/ul>
&lt;h4 id="c-knowledge-truth-and-lies">C. Knowledge, Truth, and Lies&lt;/h4>
&lt;ul>
&lt;li>The Truth (on Distributed System) Is Defined by the Majority&lt;/li>
&lt;li>But, there is a risk that nodes may lie, it’s known as &lt;strong>Byzantine fault&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch-9-consistency-and-consensus">Ch 9: Consistency and Consensus&lt;/h3>
&lt;h4 id="a-consistency-guarantees">A. Consistency Guarantees&lt;/h4>
&lt;p>All durable data systems provide &lt;strong>eventual consistency&lt;/strong>, but their implementations of the &lt;strong>&amp;ldquo;eventually&amp;rdquo;&lt;/strong> part differ.
Consistency is a difficult topic, and it&amp;rsquo;s one wrapped up in all of the other concerns of distributed systems.&lt;/p>
&lt;p>
&lt;a href="http://liujunming.top/2018/10/07/Designing-Data-Intensive-Applications-%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0-Consistency-and-Consensus/" target="_blank" rel="noopener">Ref.&lt;/a>
&lt;a href="https://github.com/ResidentMario/designing-data-intensive-applications-notes/blob/master/Chapter%209%20---%20Consistency%20and%20Consensus.ipynb" target="_blank" rel="noopener">Ref.&lt;/a>
&lt;/p>
&lt;h4 id="b-linearizability">B. Linearizability&lt;/h4>
&lt;ul>
&lt;li>What Makes a System Linearizable?
&lt;ul>
&lt;li>all operations are atomic&lt;/li>
&lt;li>no stale operations&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Relying on Linearizability&lt;/li>
&lt;li>Implementing Linearizable Systems&lt;/li>
&lt;li>The Cost of Linearizability&lt;/li>
&lt;/ul>
&lt;h4 id="c-ordering-guarantees">C. Ordering Guarantees&lt;/h4>
&lt;ul>
&lt;li>Ordering and Causality&lt;/li>
&lt;li>Sequence Number Ordering&lt;/li>
&lt;li>Total Order Broadcast&lt;/li>
&lt;/ul>
&lt;h4 id="d-distributed-transactions-and-consensus">D. Distributed Transactions and Consensus&lt;/h4>
&lt;ul>
&lt;li>Atomic Commit and Two-Phase Commit (2PC)
&lt;ul>
&lt;li>Background
&lt;ul>
&lt;li>There are several situations in which it is important for nodes to reach &lt;strong>consensus&lt;/strong> such as leader election and atomic commit in database.&lt;/li>
&lt;li>2PC is the most common way for achieving atomic transaction commit across multiple nodes.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>What it is?
&lt;ul>
&lt;li>2PC ≠ Two-Phase Locking&lt;/li>
&lt;li>2PC relies on a &lt;strong>coordinator&lt;/strong>, usually a separate process, which performs a pre-flight check on all of the nodes involving, asking if they can perform the op.&lt;/li>
&lt;li>The nodes check and reply yes or no. If any nodes say no, the state change is aborted. If all nodes say yes, the coordinator sends a green light.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Why 2PC is bad for consensus algorithm?
&lt;ul>
&lt;li>if the &lt;strong>coordinator&lt;/strong> goes down after all nodes ack but before it can send a green or red light,&lt;/li>
&lt;li>it&amp;rsquo;s non-obvious how to recover (restarting the coordinator, sure, but that takes time).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Distributed Transactions in Practice
&lt;ul>
&lt;li>Pros: provide safety guarantee&lt;/li>
&lt;li>Cons: slow performance&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Fault-Tolerant Consensus
&lt;ul>
&lt;li>Example of algorithm: Paxos, Raft, Zab, VSR&lt;/li>
&lt;li>How these algorithm solve 2PC weaknesses?
&lt;ul>
&lt;li>The consensus algorithms are all designed around epochs and strict quoroms.&lt;/li>
&lt;li>Each time a leader loss occurs, a quorom of nodes is gathered to vote on a new leader. The new leader increments the epoch number.&lt;/li>
&lt;li>Every time a leader wants to perform an action, it checks whether or not another leader with a higher epoch number exists.&lt;/li>
&lt;li>To do this, it asks a quorom of nodes what the highest epoch number they have seen is.
&lt;ul>
&lt;li>The insight: within a strict quorom, at least one of the nodes, at a minimum, was present in the most recent vote!&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>But, it still has its own weakness:
&lt;ul>
&lt;li>Consensus algorithms implement synchronous replication. Totally ordered atomic broadcast, we thus learn, requires we be synchronous.&lt;/li>
&lt;li>Therefore it is very slow, particularly if the network is bad.&lt;/li>
&lt;li>Additionally, certain network partitions can lead to very bad worst-case behavior, such as continuous elections.&lt;/li>
&lt;li>Designing consensus algorithms that are more robust to network failures is an ongoing area of research.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Example of solution implementing that algorithm: ZooKeeper, etcd&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Membership and Coordination Services&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="part-3-derived-data">Part 3: Derived Data&lt;/h2>
&lt;hr>
&lt;h3 id="ch-10-batch-processing">Ch 10: Batch Processing&lt;/h3>
&lt;p>
&lt;a href="https://itiskj.hatenablog.com/entry/2018/10/31/105237" target="_blank" rel="noopener">Ref&lt;/a>
&lt;/p>
&lt;h4 id="a-batch-processing-with-unix-tools">A. Batch Processing with Unix Tools&lt;/h4>
&lt;ul>
&lt;li>Simple Log Analysis&lt;/li>
&lt;li>The Unix Philosophy&lt;/li>
&lt;/ul>
&lt;h4 id="b-mapreduce-and-distributed-filesystems">B. MapReduce and Distributed Filesystems&lt;/h4>
&lt;ul>
&lt;li>What is MapReduce
&lt;ul>
&lt;li>MapReduce is a bit like Unix tools, but distributed across potentially thousands of machines.&lt;/li>
&lt;li>While Unix tools use stdin and stdout as input and output, MapReduce jobs read and write files on a distributed filesystem like Google’s GFS.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Reduce-Side Joins and Grouping&lt;/li>
&lt;li>Map-Side Joins&lt;/li>
&lt;li>The Output of Batch Workflows&lt;/li>
&lt;li>Comparing Hadoop to Distributed Databases&lt;/li>
&lt;/ul>
&lt;h4 id="c-beyond-mapreduce">C. Beyond MapReduce&lt;/h4>
&lt;ul>
&lt;li>Materialization of Intermediate State&lt;/li>
&lt;li>Graphs and Iterative Processing&lt;/li>
&lt;li>High-Level APIs and Languages&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="ch-11-stream-processing">Ch 11: Stream Processing&lt;/h3>
&lt;h4 id="a-transmitting-event-streams">A. Transmitting Event Streams&lt;/h4>
&lt;ul>
&lt;li>Messaging Systems&lt;/li>
&lt;li>Partitioned Logs&lt;/li>
&lt;/ul>
&lt;h4 id="b-databases-and-streams">B. Databases and Streams&lt;/h4>
&lt;ul>
&lt;li>Keeping Systems in Sync&lt;/li>
&lt;li>Change Data Capture&lt;/li>
&lt;li>Event Sourcing&lt;/li>
&lt;li>State, Streams, and Immutability&lt;/li>
&lt;/ul>
&lt;h4 id="c-processing-streams">C. Processing Streams&lt;/h4>
&lt;ul>
&lt;li>Uses of Stream Processing&lt;/li>
&lt;li>Reasoning About Time&lt;/li>
&lt;li>Stream Joins&lt;/li>
&lt;li>Fault Tolerance&lt;/li>
&lt;/ul>
&lt;hr></description></item></channel></rss>