# EnqueueZero Techshack 2019-05

Kia ora! I am the creator of Enqueue Zero (https://enqueuezero.com), a site that explains code principles to Developers/DevOps/Sysadmins. This site is updated under a single man team since 2018. The `EnqueueZero Techshack` series is comprised of a bunch of interesting posts I wrote or found on the Internet. More importantly, I hope these posts would please you.

Please follow Twitter account @enqueuezero for the updates. Happy exploring!

# Our Software Dependency Problem

swtch.com (opens new window)

  • A dependency is additional code that you want to call from your program. Adding a dependency avoids repeating work already done: designing, writing, testing, debugging, and maintaining a specific unit of code.
  • A dependency manager (sometimes called a package manager) automates the downloading and installation of dependency packages.
  • When consuming software dependencies,
    • Recognize the problem.
    • Establish best practices for today.
    • Develop better dependency technology for tomorrow.

# Systemd as tragedy

lwn.net (opens new window)

Historically, people had opinionated voices about systemd. Some said it's against UNIX philosophy of doing one thing do it right; some said it supports only Linux. The article discussed these from historical and functional views.

# Finding Kafka’s throughput limit in Dropbox infrastructure

blogs.dropbox.com (opens new window)

This article presented a systematic approach to understanding Kafka’s limits.

  1. Use spark to host Kafka clients, producing and consuming traffic on an arbitrary scale.
  2. Set up three Kafka clusters of different sizes
  3. Create a Kafka topic to generate the producing and consuming traffic for the test and spread the traffic evenly across brokers.
  4. Create the testing topic with ten times as many partitions as the number of brokers. Each broker has a leader for exactly ten partitions.

There is a rich set of factors that can affect a Kafka cluster’s workload: number of producers, number of consumer groups, initial consumer offsets, message per second, size of each message, and the number of topics and partitions involved, to name a few. But the dominant factors to consider are the basic components of throughout: the number of messages per second (mps) produced and the byte size per message (bpm).

# Highly Available MySQL Clusters at WePay

wecode.wepay.com (opens new window)

Core components are Orchestrator, Consul, HAProxy, and pt-heartbeat.

  • Orchestrator is for detecting failures and role transition.
  • There are two layers of HAProxy.
    • The first layer of HAProxy sits on the client machines and connects to the remote (second layer) of HAProxy.
    • The second layer of HAProxy is distributed across multiple Google zones that connect to the same set of MySQL servers
  • Consul is the KV store.
  • Heartbeat runs on every host.

# CockroachDB's Consistency Model

cockroachlabs.com (opens new window)

CockroachDB’s consistency model is more than serializable, less than strict serializability. CockroachDB implements and only implements the serializable isolation level for transactions, as specified by the SQL standard. (Quote crdb authors, any lower level is just asking for pain.)

It’s probably easiest to qualify it by understanding the anomaly that it allows — “causal reverse” — and the limited set of circumstances under which it can occur. In the majority of cases where one might be wondering about the semantics of reads and writes in CRDB, the slogan “no stale reads” should settle most discussions.

Further reading: CockroachDB on RocksDB cockroachlabs.com (opens new window).

# It’s Time to Move on from Two-Phase Commit

dbmsmusings.blogspot.com (opens new window)

However, in modern times, where many systems need to scale to multiple machines that can fail independently of each other, these assumptions require expensive coordination and commit protocols such as 2PC. The performance problems of 2PC have been a major force behind the rise of non-ACID compliant systems that give up important guarantees to achieve better scalability, availability, and performance. 2PC is just too slow --- it increases the latency of all transactions --- not only by the length of the protocol itself but also by preventing transactions that access the same set of data from running concurrently. 2PC also limits scalability (by reducing concurrency) and availability (the blocking problem we discussed above). The way forward is clear: we need to reconsider antiquated assumptions when designing our systems and say “good-bye” to two-phase commit!

# Selecting a Software Architecture

www.javacodegeeks.com (opens new window)

The architecture defines the model of the software, how it will function and define the problems you might encounter when it comes to implementation, for major paradigms are layered architecture, microservices, SOA, event sourcing.

# A Lifetime of Systems Thinking

thesystemsthinker.com (opens new window)

Here is a very small sample of the obvious things I have found to be wrong:

  • Improving the performance of the parts of a system taken separately will necessarily improve the performance of the whole.
  • Problems are disciplinary.
  • The best thing that can be done to a problem is to solve it.

# Lessons learned scaling PostgreSQL database to 1.2bn records/month

medium.com (opens new window)

With so many options like Google Cloud SQL, Amazon RDS, Aiven.io, "All this time I was trying to avoid the unavoidable - managing the database ourselves. Now we are renting our hardware and maintain the database.".


  • Control the pg version.
  • Install any pg plugin.
  • A lot better hardware than any cloud providers could offer.
  • Cheaper enough to hire a freelance DBA to check in.

The other PG takeaways:

  • PostgreSQL materialized views are a great feature for small datasets.
  • Plan by using a combination of granular materialized views and materialized table columns as the dataset grows.


  • For a simple database that will not grow into billions of records and does not require custom extensions, choose cloud service.
  • Plan for what features you will require in the future.

# Programming paradigms for dummies: what every programmer should know

blog.acolyer.org (opens new window) | Concepts, Techniques, and Models of Computer Programming: www.info.ucl.ac.be (opens new window)

  • Programming paradigms are approaches based on a mathematical theory or a particular set of principles, each paradigm supporting a set of concepts.


  • Solving a programming problem requires choosing the right concepts, and many problems require different sets of concepts for different parts. Moreover, many programs have to solve more than one problem! Missing a paradigm for the problem could let your program ugly.

state The four ways of organize a data abstraction

  • Each paradigm has its own “soul” that can only be understood by actually using the paradigm. We recommend that you explore the paradigms by actually programming in them.

# High-Performance in Python with Zero-Copy and the Buffer Protocol

julien.danjou.info (opens new window)

The takeaway is by using function memoryview(bytes) to avoid copying. The theory is a new memoryview object, by implementing the buffer protocol (PEP 3118), references the original object memory.

Basic usage is like below. The slice variable holds a slice of original read data.

content = source.read(1024 * 10000)
slice = memoryview(content)[1024:]

# PostgreSQL on Kubernetes the Right Way

Part I: medium.com (opens new window) | Part II: medium.com (opens new window)


  • High Availability
  • Load Balancing
  • Synchronization Between Instances
  • Scaling Up and Down
  • Automated Backup, Recovery from Backup
  • Rolling Upgrades/Downgrades
  • Health Monitoring, Debugging

PostgreSQL follows the master-slave pattern. There’s a single authoritative primary server (master) and some number of standby servers (slaves) that mirror the primary. This distributed architecture serves two purposes:

  • Failover — If the primary fails, a standby can take its place.
  • Load Balancing — Standbys can handle read-only requests, reducing the load on the primary.

Additionally, the primary continuously archives its write-ahead log (WAL) and periodically creates backups of its entire state (called base backups).

In Kubernetes, there are Primary and Standby Pods

  • Primary — Typically only one instance, used for reads and writes.
  • Standby — Many of these, used for reads, can be promoted to primary

# Scaling Azure Functions to Make 500,000 Requests to Weather.com in Under 3 Minutes

madeofstrings.com (opens new window)

  • The challenges: pull 50k data and complete the process in 5 min; repeat every 15 min.
  • Overall Design: overall design
    • Coordinates are stored in Azure Table Storage. Records are immutable.
    • Durable Functions are used to populate a group of Storage Queues with the coordinates from the table. Each message represents a pending request to the weather service.
    • An Azure Function is invoked for each message in the queue.
    • Requests are made to the 3rd party service to get the forecast details.
    • The results of the forecast requests are published to Event Hubs for further processing.
  • To make the queue-triggered function run faster, the loads (data fetching requests) are distributed to multiple queues. load balancing
  • Data partitioning: In short, every set of 1,000 records was given a unique partition key that had the following naming convention: {queue-number}-{partition-count}. So the first 1,000 records for queue #1 would have the partition key 1-0. The next 1,000 records would be assigned the key 1-1.

# Serverless at Scale: Serving StackOverflow-like Traffic

blog.binaris.com (opens new window)

  • Function-as-a-Service is a great model to build applications that can work for low-usage scenarios, high-load applications, and even spiky workloads.
  • Scalability limits do exist, so if you anticipate high growth in the application’s usage, run a simple load test to see how it behaves.
  • Always test in combination with your non-serverless dependencies. If you use a database or a third-party service, it’s quite likely they will hit the scalability limit much earlier than the serverless compute.

# Why we use Ruby on Rails to build GitLab

about.gitlab.com (opens new window)

  • The Ruby on Rails ecosystem allows you to shape a lot of functionality at a high quality.
  • There's a great ecosystem around it with gems that can make assumptions about how you're doing things.
  • Some critical backend components are written in Go, and some frontend components are written in Vue.
  • In every kitchen you enter, you never know where the knives and plates are located. But with Ruby on Rails, you enter the kitchen and it's always in the same place, and we want to stick to that. (My thought, same rule applies to Django, React, ...)

# websocketd - Turn any program that uses STDIN/STDOUT into a WebSocket server. Like inetd, but for WebSockets.

github.com (opens new window)

Example script count.sh:

for ((COUNT = 1; COUNT <= 10; COUNT++)); do
  echo $COUNT
  sleep 1
$ websocketd --port=8080 ./count.sh

# Develop New Features v/s Maintain

twitter.com (opens new window)

It's a few weeks that I code RESP3 and ACLs without caring much about the issues in the Redis repository. I'm doing my best with ACLs, I like the code and how the feature is exposed from an UX perspective. It's a joy to code, while dealing with issues / PRs is stressful. However there is no way out, from time to time one need to focus on the issues / PRs. I guess that I'm just a better coder than a better maintainer. I'll continue my context switch like in the past years, but for me to don't care about issues from time to time is a key thing. The odd thing is that a project becomes popular because you can write some code and design some things. And suddenly your job becomes checking other people's code and designs: the project ends being less and less about your work quality, unless you say no 99% of times