Tuan Anh

container nerd. k8s || GTFO

A look back at 2015

I kicked off 2015 with lots of anxiety. I reconnect with my best friend from secondary school (then; wife now). For the first time in years, I really wanted to move back to Vietnam.

Early in 2015, I went back to Thailand after Tet holiday, start looking around for a job in Vietnam or any job that accept remote workers to smooth the transition. I found one later in May-June. They only require me to work in Thailand for awhile (1 month) so that I can get accustom with how they work there.

me and my wife

Got married to a beautiful girl who also happens to be my best friend from secondary school.

me and my wife

Bought a beautiful Pomeranian. Named her Min.

my dog

My family and me during Tet 2016.

Grow a little garden on the balcony

2015 had been good to me and perhaps my most important year of my life. I’m looking forward to 2016 with many goals in mind. The difference is now I got my wife to back me up 👫.


MariaDB Raises $9M More, Michael Howard Named New CEO, Monty Widenius CTO

Michael “Monty” Widenius, the man who originally created MySQL and MariaDB, is now joining the startup as CTO.

This is better than the funding round news.

link bài gốc

Chuyện tiền nong

ngồi lẩm nhẩm: mình đi làm mấy năm, nhìn lại thấy tài chính rối tung, tài sản thì chả có gì; cơ hội thì bỏ qua 1 đống.

thôi thì bây giờ học cũng chưa quá muộn.

tránh mang nợ

nói chung có thì xài, không có thì đừng có vay nợ để xài. xài thẻ debit cũng có nhiều cái hay lắm. hết tiền rồi mà muốn mua món gì đó thì phải ra ngân hàng deposit hoặc chuyển khoản từ ngân hàng khác sang. rất mất thời gian. cái này là vật cản lớn lắm nha.

nhiều lúc mình tính mua món gì mà ngại chuyển tiền. tính ngủ 1 giấc rồi đi mua thì lại chẳng còn hứng mua xài tiền nữa. nếu mà như vậy thì thực sự bạn không cần món đó, chỉ là muốn thôi.

lỡ mang nợ rồi!?

bây giờ lỡ mang nợ rồi thì sao? có 2 cách trả nợ:

  1. trả cái nào lãi suất cao nhất trước. cách này là economical nhất vì số tiền phải trả cuối cùng là nhỏ nhất.

  2. trả cái nào nhỏ nhất. cái này là dựa về mặt tâm lý. dứt được 1 món nợ sẽ thoải mái tinh thần hơn nhiều và tạo thêm động lực. 1 dạng reward cá nhân.

kiếm đâu ra tiền để trả nợ?

cái này cũng có 2 cách:

  1. cày nhiều hơn.

  2. xài ít hơn.

dù có chọn cách nào thì cũng phải xài tiền khôn hơn 1 chút. xài ngu thì kiếm bao nhiêu cũng không đủ. lương tháng nào xài tháng đó hoặc còn xài lố (credit card) nữa thì thua.

làm giàu

cách đơn giản và an toàn nhất là bỏ vào 1 cuốn sổ tiết kiệm. giả dụ mỗi ngày bạn bỏ ra 100 nghìn, 10 năm sau bạn có 100k * 365 * 10 = 365 triệu. 30 năm sau là thành tỉ phú rồi.

một cách khác nữa là đầu tư vào cái gì đó. cái này mình cực ngu. một là do không có vốn (vì lỡ xài ngu như ở trên rồi), hai là không nhìn thấy cơ hội.

cách khác nữa là đầu tư vào bản thân. mua sách học, đăng kí các khóa học thêm, etc..


hehe nói vầy thui chứ mình không phải chuyên gia tài chính gì đâu, các bạn đừng có tin.

nếu làm được mấy cái này mình đã giàu rồi, ko phải ngồi đây viết lảm nhảm như vầy đâu haha.


Better MySQL pagination

Consider this

SELECT * from Bookings LIMIT 5000,10

versus this

SELECT * from Bookings
INNER JOIN (Select id FROM BOOKING LIMIT 5000,10) AS result USING (id)

My Bookings table has merely 6000 records yet the first query takes approx ~10 seconds which is outrageous. Luckily, we can optimize this using late lookups like in query 2.

In the second query, we select id from Bookings and then join the original table back. This will make each individual row lookup less efficient but the total number of lookups will be reduced by a lot.

Also, if you could pass more condition into the select, it will greatly improve the performance as well. So instead of making your paging url like this example.com/products?page=10, you can use example.com/products?page=10&last_seen=1023. From that, you can pass WHERE id > 1023 into the pagination query making the whole thing a lot faster.

Those are what I used for optimizing pagination. If you know any other, please let me know.

Peace out, everybody.


Qmail

qmail is a mail transfer agent (MTA) that runs on Unix. It was written, starting December 1995, by Daniel J. Bernstein (djb) as a more secure replacement for the popular Sendmail program.

Một chút background: vào khoảng những năm 80,90 của thế kỷ trước, các máy chủ email và dns thường sử dụng Sendmail và BIND9. Tuy nhiên, 2 phần mềm này có cực kì nhiều lỗi. djb viết ra qmail và djbdns để thay thế 2 phần mềm này và tuyên bố 2 phần mềm này là “bug-free”. Hai phần mềm này được chạy trên hàng triệu tên miền và cực kì ổn định. Lỗi đầu tiên của qmail được tìm thấy sau gần 1 thập kỉ đủ để nói lên sự ổn định của nó. Có lẽ trong lịch sử chưa có một lập trình viên nào đạt đến ngưỡng này.

Daniel Julius Bernstein (sometimes known simply as djb; born October 29, 1971) is a German-American mathematician, cryptologist, programmer, and professor of mathematics and computer science at the Eindhoven University of Technology and research professor at the University of Illinois at Chicago. He is the author of the computer software programs qmail, publicfile, and djbdns.

link bài gốc

Performance at Rest

TL;DR

Benchmarking frameworks is fucking stupid.

link bài gốc

Explicit over clever

I always prefer explicit over clever, hacky hack. Explicit make the code looks clearer, more maintainable and leaning toward a more predictable behavior (aka junior developers will be less likely to mess it up).

Take an example of this code where I have a folder called providers. This here below is the content of the index.js file which basically read all the files in that folder (except index.js), require them and then module.exports that. It seems simple enough right?

var fs = require('fs');
var path = require('path');
var basename = path.basename(module.filename);
var providers = {};
var extension = '.js';

fs
    .readdirSync(__dirname)
    .filter(function(file) {
        return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === extension);
    })
    .forEach(function(file) {
        var provider = require(path.join(__dirname, file));
        var key = makeKey(file,extension)
        providers[key] = provider;
    });

/* ... */

Now, take a look at this code where I explicitly require all the files in that folder (sounds exhausting right?)

let providers = {
    Auth: require('./auth'),
    User: require('./user'),
    Health: require('./health')
}
/* ... */
module.exports = providers

Now, say if you were a newly joined member of the project, which looks less intimidating to you? I’m not saying we can’t achieve both explicit and clever at the same time; but if I need to make a choice selecting one over another, I would always go with explicit.


Step by step how to install Deis on AWS

Deis (pronounced DAY-iss) is an open source PaaS that makes it easy to deploy and manage applications on your own servers. Deis builds upon Docker and CoreOS to provide a lightweight PaaS with a Heroku-inspired workflow.

I struggled installing Deis and it took me several times to get it right. Deis’s documentation is correct but not very straight forward so I decided to write this to help others that struggle like me. This steps works for me as of version 1.12.2

Preparation

  • Install deisctl. This is needed for provision script.
$ cd ~/bin
$ curl -sSL http://deis.io/deisctl/install.sh | sh -s <latest-version-here>
$ # on CoreOS, add "sudo" to install to /opt/bin/deisctl
$ curl -sSL http://deis.io/deisctl/install.sh | sudo sh -s <latest-version-here>
  • Install AWS Command line interface and configure it
$ pip install awscli
$ pip install pyyaml
$ aws configure
AWS Access Key ID [None]: ***************
AWS Secret Access Key [None]: ************************
Default region name [None]: us-west-1
Default output format [None]:
  • Generate and upload keys to AWS. Also add it to ssh-agent so that it can use during provisioning the cluster.
$ ssh-keygen -q -t rsa -f ~/.ssh/deis -N '' -C deis
$ aws ec2 import-key-pair --key-name deis --public-key-material file://~/.ssh/deis.pub
$ eval `ssh-agent -s`
$ ssh-add ~/.ssh/deis
  • If you want to use more than 3 instances (default), just export DEIS_NUM_INSTANCES
$ export DEIS_NUM_INSTANCES=5

Provision the cluster

  • Clone the repo, git checkout the latest tag. At repo root, run this command below to create discovery url. Forget to do this will result in etcd not configured properly.
$ make discovery-url
  • Next, go to folder contrib/aws/ in deis repo, create a file name cloudformation.json in order to override default values. You can take a look at the template file deis.template.json.

  • Run the provision script

$ cd contrib/aws
$ ./provision-aws-cluster.sh
Creating CloudFormation stack deis
{
    "StackId": "arn:aws:cloudformation:us-east-1:69326027886:stack/deis/1e9916b0-d7ea-11e4-a0be-50d2020578e0"
}
Waiting for instances to be created...
Waiting for instances to be created... CREATE_IN_PROGRESS
Waiting for instances to pass initial health checks...
Waiting for instances to pass initial health checks...
Waiting for instances to pass initial health checks...
Instances are available:
i-5c3c91aa  203.0.113.91    m3.large        us-east-1a      running
i-403c91b6  203.0.113.20    m3.large        us-east-1a      running
i-e36fc6ee  203.0.113.31    m3.large        us-east-1b      running
Using ELB deis-DeisWebE-17PGCR3KPJC54 at deis-DeisWebE-17PGCR3KPJC54-1499385382.us-east-1.elb.amazonaws.com
Your Deis cluster has been successfully deployed to AWS CloudFormation and is started.
Please continue to follow the instructions in the documentation.

Install platform

$ export DEISCTL_TUNNEL=<ip-address-of-any-of-the-cluster-node>
$ deisctl config platform set sshPrivateKey=~/.ssh/deis
$ deisctl config platform set domain=deis.example.com # create a CNAME point this to the load balancer
$ deisctl install platform
$ deisctl start platform

After this, you should have a proper configured Deis cluster. Just install the client, register an account and you should be ready to deploy your very first application on Deis.


Metalsmith - a static site generator written in Node.js

An extremely simple, pluggable static site generator.

Metalsmith works in three simple steps:

  • Read all the files in a source directory.

  • Invoke a series of plugins that manipulate the files.

  • Write the results to a destination directory!

Very simple yet powerful. Metalsmith is like gulp but made for static website/content.

link bài gốc

Snapp

Drag a window up to the menubar to maximize it, or drag a window to the side to resize it to the corresponding screen half.

Demo

link bài gốc