Instagram đã sinh ra ID trong database của họ như thế nào

Đối với những hệ thống nhỏ chỉ cần 1 Database thì chắc chẳng mấy ai quan tâm đến việc tạo ra ID cho bản ghi. Vì dùng auto increment trong MySQL là có thể làm được rồi, chẳng cần phải làm gì thêm.

Thế nhưng với dữ liệu càng ngày càng to ra thì hệ thống chỉ có 1 database duy nhất có thể sẽ không thể đáp ứng được. Bởi vì traffic đang tập trung hết vào database đó.

Để giải quyết bài toán đó thì người ta đã tách database ra thành nhiều database khác nhau, và mỗi database đó sẽ chứa 1 phần dữ liệu. Ví dụ db01 chứa thông tin user từ 1 đến 1000, db02 chứa thông tin user từ 1001 đến 2000 chẳng hạn. Và khi query sẽ tìm xem user thuộc database nào và thực hiện truy vấn.

Và kĩ thuật này người ta gọi là sharding.

Thế nhưng có vấn đề xảy ra ở đây là làm thế nào sinh ra ID cho user mà không bị trùng lặp giữa các database đó? Dùng auto increment mặc định của database có giải quyết được không? Làm thế nào để từ 2 ID có thể phán đoán cái nào được sinh ra trước, cái nào được sinh ra sau?

Vậy cùng đọc bài này xem các kĩ sư Instagram đã giải quyết bài toán này thế nào nhé.

Mục tiêu bài viết:

  • Hiểu thêm được 1 cơ chế sinh ID mới.
  • Có thể áp dụng vào các bài toán sharding data trong database.

Bối cảnh

Instagram là 1 trong những mạng xã hội chia sẻ ảnh nổi tiếng nhất cái hành tinh này.

Theo thống kê năm 2016 thì cứ mỗi giây sẽ có 915 photos, 1k post được tạo ra. Quá khủng khiếp phải không nào.

Khi dữ liệu tăng lên kinh khủng như thế thì 1 database sẽ không thể lưu trữ hết được dữ liệu, cùng với tốc độ truy vấn sẽ trở nên ì ạch và tốn nhiều dung lượng bộ nhớ.

Để đảm bảo tất cả dữ liệu quan trọng luôn được lưu trữ trên memory, và sẵn sàng trả về kết quả nhanh nhất cho người dùng thì Instagram bắt đầu thực hiện Sharding dữ liệu.

Ảnh bên dưới là 1 ví dụ về sharding trong database. Database sẽ được tách ra thành nhiều database khác nhau, mỗi database sẽ chứa 1 phần dữ liệu. Như ví dụ bên dưới là tách bảng user ra thành nhiều database, mỗi database sẽ chứa 1 phần dữ liệu của bảng user.

Người ta gọi mỗi database tách biệt này là ”Shard“.

sharding database

Tuy nhiên tại thời điểm này có 1 bài toán được đặt ra. Làm thế nào có thể sinh ra ID duy nhất trên từng shard mà không sợ bị trùng lặp (Ví dụ như mỗi photo được upload vào trong hệ thống)? Cùng đi đọc tiếp phần tiếp theo nhé.

Yêu cầu về mặt chức năng

Trước khi đi vào giải quyết bài toán bên trên, thì cùng xem hệ thống Instagram yêu cầu những gì về ID của từng shard nhé.

  • ID được tạo ra phải được sắp xếp theo thời gian. Ví dụ như với 2 ID thì có thể phán đoán được ID nào tạo ra trước, ID nào tạo ra sau.
  • ID sẽ bao gồm 64 bits. (Vì sao lại cần 64 bits? Vì nó tương thích với các hệ thống như Redis …)
  • Thuật toán sinh ra ID phải đơn giản, dễ hiểu và đặc biệt không được làm thay đổi architecture server của Instagram.

1 số giải pháp generate ID

Hiện tại có rất nhiều giải pháp cho việc sinh ra ID unique. Cụ thể như:

Sử dụng auto increment trong database

Về chức năng này thì ai cũng biết rồi. Lúc tạo bảng chỉ cần khai báo auto increment là xong.

Ưu điểm: *Cách dùng đơn giản.

Nhược điểm:

  • Chỉ tập trung vào 1 database và không thể phân chia sang database khác được.
  • Không thể đảm bảo rằng việc sinh ID ở nhiều database là không bị trùng nhau.

Sử dụng UUID Đây cũng là 1 cách khá hay để giải quyết bài toán. UUID là 1 chuẩn chung nhằm sinh ra chuỗi random không trùng nhau (xác suất gần như bằng 0). Ví dụ như: b875d561-20fd-498d-8452-5d5ffa879856.

Thế nhưng cùng xem nó có ưu điểm nhược điểm gì nhé.

Ưu điểm:

Cho dù chạy trên nhiều máy tính cùng thời điểm đi chăng nữa thì xác suất các string đó trùng nhau dường như gần bằng 0.

Nhược điểm:

  • Nó bao gồm 128 bits nên hơi to, không phù hợp với yêu cầu của hệ thống (là 64 bits)
  • Với 2 ID thì không thể phân biệt ID nào tạo trước, ID nào tạo sau.

Snowflake

Đây chính là 1 công cụ sinh ra ID random được phát triển bởi Twitter. Cái này sử dụng Apache Zookepper để phối hợp với các node để tạo ID 64 bit duy nhất.

Ưu điểm:

  • Snowflake ID có 64 bit
  • Có thể sử dụng time trong component đầu tiên của ID nên có thể sắp xếp được

Nhược điểm:

  • Phải đưa ZooKeeper, Snowflake vào trong kiến trúc của Instagram.

Giải pháp của Instagram

Những giải pháp trên đều không đáp ứng được yêu cầu của Instagram nên họ quyết định tự xây dựng cho mình 1 giải pháp riêng.

Họ sẽ dùng thuật toán đơn giản để sinh ra 1 chuỗi ID random duy nhất từ 1 số input đầu vào. Và từ chuỗi ID đó có thể decode ngược lại để lấy ra được input.

ID ở đây chính là ID của photo, ID của posts chẳng hạn.

Database họ sử dụng là PostgreSQL.

Cụ thể như sau.

ID có độ dài 64 bits, sẽ bao gồm những bộ phận sau:

  • 41 bits để lưu thời gian (đơn vị milliseconds). Khoảng thời gian này sẽ được tính từ ngày 2011/01/01 00:00.
  • 13 bits để lưu shard ID. (tối đa có thể tạo ra được 2^13 = 8192 shard)
  • 10 bits để lưu auto-incrementing sequence, sau đó module 1024. (Vì sao lại là 1024 vì tối đa có 10 bit thôi, mà 2^10 = 1024). Điều đó có nghĩa là có thể tạo ra 1024 IDs trên 1 shard, trên millisecond.

Câu hỏi đặt ra là nếu tạo upload quá 1024 bức ảnh trong 1ms có được không?

Câu trả lời là không nhé. Vì lúc đó thằng thứ 1025 sinh ra ID sẽ bị trùng với thằng thứ 1. Với cả ID là khoá chính nên khi insert vào sẽ bị lỗi. Nên lúc đó chỉ cần try cach đoạn đó là ok.

Công thức sinh ID như sau:

ID = (time << 23) | (shardID << 10) | (seqId <<0)

Trong đó:
・time    = now - instagram_epoch_time (2011/01/01 00:00)
・shardId = userId % 2000
・seqId   = (currentSeqID + 1) % 1024

Từ công thức trên ta có thể thấy ID được tạo ra bằng cách:

ID = (Dịch trái time sang trái 23 bit) bitwise OR (dịch trái shardID 10 bit) bitwise OR (dịch trái seqID 0 bit)

Để mình tổng hợp lại kiến thức về bitwise cho mọi người hiểu nhé:

  • Dịch trái, dịch phải nó cũng giống như chúng ta kéo cảnh cửa sang trái, sang phải thôi. Nếu dịch trái n bit tức là sẽ điền n số 0 vào sau số đó. Ví dụ như dịch trái số 7 (dạng nhị phân là 110) sang trái 5 bit, khi đó nó sẽ thành: 11000000
  • bitwise OR tức là thực hiện OR từng bit 1 của 2 số từ phải sang trái. Nếu 2 bit đều là 1 thì sẽ cho kết quả là 1, ngược lại sẽ cho kết quả là 0. Ví dụ như 7 (dạng nhị phân là 110) OR 8 (dạng nhị phân là 111) khi đó kết quả là: 110 OR 111 = 110.

Ví dụ:

Giả sử như người dùng có user_id là 5001, post bức ảnh lên instagram vào thời điểm 2019/05/19 00:00. Tại thời điểm đó sequence hiện tại của table đang là 9000.

Cách tính:

Do thời gian được tính từ ngày 2011/01/01 00:00 nên từ thời điểm đó đến ngày 2019/05/19 00:00 có time = 264384000000 ms.

=> ID = 264384000000 << 23 (dịch sang trái 23 bit)

Do user_id = 5001, và instagram chỉ có 2000 shard. Nên shardId = 5001 % 2000 = 1001

=> ID |= 1001 << 10

sequence hiện tại của table đang là 9000, khi đó nextsequenceid là 9001. vậy seqId = 9001 % 1024 = 809

=> ID |= (809) << 0

Sau khi tính chúng ta ra kết quả ID = 2217813737473025832.

Vậy làm thế nào mà từ số 2217813737473025832 chúng ta có thể decode ngược lại ra time là 264384000000, shardId là 1001, seqId là 809?

Đây có lẽ là phần mình thấy hay nhất. Chúng ta cùng xem tiếp nhé:

Time      = (2217813737473025832 >> 23) & 0x1FFFFFFFFFF = 264384000000
Shard ID  = (2217813737473025832 >> 10) & 0x1FFF = 1001
seqID     = (2217813737473025832 >>  0) & 0x3FF = 809

Từ công thức trên ta có thể thấy được:

  • Time sẽ được tính bằng cách dịch sang phải ID 23 bit, sau đó thực hiện AND với 1 số 41 bit toàn số 1. Cái số 41 bit toàn số 1 này chuyển sang dạng hex sẽ là 0x1FFFFFFFFFF.
  • ShardID và seqId cũng được decode tương tự. Đây là 1 example về encode và decode mình đã chuẩn bị được. Dành cho ai muốn test:
<?php

$uuid = 0;

$userId = 5001;
$currentSequenceId = 9000;
$time = 264384000000;

// ENCODE

$shardId = $userId % 2000;
$seqId = ($currentSequenceId + 1) % 1024;

$uuid = $time << 23;
$uuid = $uuid | ($shardId << 10);
$uuid = $uuid | ($seqId);

echo $uuid . PHP_EOL;

// DECODE

$time = ($uuid >> 23) & 0x1FFFFFFFFFF;
$shardId = ($uuid >> 10) & 0x1FFF;
$seqId = ($uuid >> 0) & 0x3FF;

echo $time . PHP_EOL;
echo $shardId . PHP_EOL;
echo $seqId . PHP_EOL;

Sau khi lấy được shardId là chúng ta có thể dễ dàng truy cập vào từng shard để lấy ra record dựa vào ID (photoid, postid …) được rồi. Mà chẳng phải tốn công đi join, select làm gì cho mệt cả.

Hơn nữa nó thao tác giữa các bit nên cứ gọi là nhanh đừng hỏi.

Và đây là ví dụ về PL/PGSQL trong PostgreSQL:

CREATE OR REPLACE FUNCTION insta5.next_id(OUT result bigint) AS $
DECLARE
    our_epoch bigint := 1293843600000;
    seq_id bigint;
    now_millis bigint;
    shard_id int := 5;
BEGIN
    SELECT nextval('insta5.table_id_seq') %% 1024 INTO seq_id;
    SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
    result := (now_millis - our_epoch) << 23;
    result := result | (shard_id <<10);
    result := result | (seq_id);
END;
    $ LANGUAGE PLPGSQL;

Khi tạo bảng sẽ làm như sau:

CREATE TABLE insta5.our_table (
    "id" bigint NOT NULL DEFAULT insta5.next_id(),
    ...rest of table schema...
  )

Kết luận

Từ 1 con số mà có thể dễ dàng decode nó ra để lấy các thông tin bên trong nó. Đoạn này mình thấy thật vi diệu.

Đúng là mấy anh kĩ sư có kinh nghiệm về design mấy bo mạch, chip các thứ áp dụng vào thấy nó khác bọt thật.

Hi vọng qua bài này sẽ giúp các bạn có 1 kiến thức mới về việc sinh ra ID random, và decode ngược lại.

Tham khảo:

Docker

I. Docker là gì ?

Docker – đây là một công cụ tạo môi trường được “đóng gói” (còn gọi là Container) trên máy tính mà không làm tác động tới môi trường hiện tại của máy, môi trường trong Docker sẽ chạy độc lập.

VM vs Containers

1. Container là gì ?

Các phần mềm, chương trình sẽ được Container Engine ( là một công cụ ảo hóa tinh gọn được cài đặt trên host OS) đóng gói thành các container.

Container hiểu nom na giống như những file class đã được build từ những file java. Để những file class chạy được thì cần phải có JVM. Container muốn chạy được thì phải có Container Engine.

Docker hỗ trợ nhiều nền tảng hệ điều hành khác nhau bao gồm Linux, Windows và cả Mac. Ngoài ra, Docker còn hỗ trợ nhiều dịch vụ điện toán đám mây nổi tiếng như Microsoft Azure hay Amazon Web Services.

Docker được xây dựng trên nền tảng Linux. Vì Docker cần can thiệp vào phần lõi, nhân Kernel vì Linux là mã nguồn mở.

Cho tới hiện tại khi cài Docker trên Windows hay Mac thì Docker sẽ cài một máy ảo Linux trên máy thật và Docker hoạt động dựa trên máy ảo Linux đó. Còn tương lai về sau thì chưa biết.

2. Docker Image:

Docker image là nền tảng của container, có thể hiểu Docker image như khung xương giúp định hình cho container, nó sẽ tạo ra container khi thực hiện câu lệnh chạy image đó. Liên tưởng đến Java thì Docker image là class, còn container là thực thể (instance, thể hiện) của class đó.

Image: Tương tự như file .gho để ghost win mà mấy ông cài win dạo hay dùng.

Image này không phải là một file vật lý mà nó chỉ được chứa trong Docker.

Một image bao gồm hệ điều hành (Windows, CentOS, Ubuntu, …) và các môi trường lập trình được cài sẵn (httpd, mysqld, nginx, python, git, …).

Docker hub là nơi lưu giữ và chia sẻ các file images này (hiện có hơn 100.000 container images)

Bạn có thể tìm tải các image mọi người chia sẻ sẵn trên mạng hoặc có thể tự tạo cho mình một cái image như ý.

3. Dockerfile

Dockerfile là một file dạng text, không có đuôi (extension) tập hợp các câu lệnh để xây dựng (build) ra một Image tùy biến của riêng mình.

Document về Dockerfile: https://docs.docker.com/engine/reference/builder

 

4. Docker compose:

Làm micro-service nên build mỗi service là một container, các services này cần tương tác (call) qua lại lẫn nhau. docker-compose để kết nối các container riêng lẻ với nhau.

docker-compose.yml, dùng để khai báo và điều phối hoạt động của các containers trong projects

document về docker-compose: https://docs.docker.com/compose/reference/overview/

Cài Docker trên macos:

$brew install docker

Cài virtualbox, có một vài lưu ý

$brew install virtualbox

Sau khi download xong, install sẽ cần phải nhập password login vào máy. Nếu install thất bại thì vào

docker security privacy

Chọn allow rồi install lại.

Tạo docker machine với tên là default

$docker-machine create --driver virtualbox default

Xem danh sách docker machine

$docker-machine ls

Chúc mừng bạn đã install docker thành công, giờ bạn có thể thoải mái test docker của mình rồi.

$docker run hello-world

Nhớ stop docker-machine khi không cần dùng docker nữa

$docker-machine stop default

Một số lệnh docker machine

$docker-machine config
$docker-machine env
$docker-machine inspect
$docker-machine ip
$docker-machine kill
$docker-machine provision
$docker-machine regenerate-certs
$docker-machine restart
$docker-machine ssh
$docker-machine start
$docker-machine status
$docker-machine stop
$docker-machine upgrade                                          
$docker-machine url

Muốn cài trực tiếp thì vào link này: https://docs.docker.com/docker-for-mac/install/

II. Các lệnh cơ bản ?

Google để tìm kiếm images trên docker hub: docker image for tomcat

docker pull tomcat

Sau khi pull image tomcat về muốn run image với default setting

docker run -it --rm tomcat:9.0

Muốn custom port lại thì

docker run -it --rm -p 8888:8080 tomcat:9.0

Sau đây là những lệnh list List images đang có

docker images

List những containers đang start hay off

docker ps

Build image, để build được image thì cần phải có file: Dockerfile

$docker build image -t <image_name> .

 

III. Docker Postgres

Bây giờ thử cài posgres với docker thì như thế nào nhé. Đầu tiên ta lấy image postgres từ hub docker về

$docker pull postgres

Ở đây mình lấy version mới nhất, còn muốn lấy version cũ hơn thì

$docker pull postgres:[tag]
$docker pull postgres:9.6.17

Còn muốn biết tag bao nhiêu thì vào đây: https://hub.docker.com/_/postgres?tab=tags

Tạo folder để mapping data ở trong docker postgres ra ngoài thư mục dễ truy xuất.

$mkdir -p $HOME/docker/volumes/postgres9

Chạy postgres container

$docker run —name <some-postgres> -e POSTGRES_PASSWORD=<mysecretpassword> -d postgres

$docker run --name postgres-9 -e POSTGRES_PASSWORD=12345 -d -p 5432:5432 -v $HOME/docker/volumes/postgres9:/var/lib/postgresql/data  postgres
$docker ps

Chui vào con docker

$docker exec -it postgres-9 bash
$psql -U postgres
$postgres=# \i /var/abc.sql
$postgres=# \q
$exit

Xoá container khi không chơi với nó nữa.

$docker rm -f postgres-9

Tham khảo:

Fibonacci

Dãy Fibonacci là dãy vô hạn các số tự nhiên bắt đầu bằng hai phần tử 0 và 1 hoặc 1 và 1, các phần tử sau đó được thiết lập theo quy tắc mỗi phần tử luôn bằng tổng hai phần tử trước nó. Công thức truy hồi của dãy Fibonacci là:

Công thức Fibonacci

f(0) = 0

Dãy số fibonacci: 0, 1, 1, 2, 3, 5, 8, 13. Con số 13 = 8 + 5 (tổng 2 số trước)

n: f(n)
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8   
7: 13 = 8 + 5

Cách viết đệ quy

public static long fibonacci(int n) {
    if (n <= 1) return n;
    return fibonacci(n-1) + fibonacci(n-2);
}

Cách viết không đệ quy

public static int fibonacci(int n) {		
	int first = 0;
	int next = 1;
	for (int i=1; i <= n; ++i ) {
		int sum = first + next;
		first = next;
		next = sum;
	}		
	return first;
}

Spring boot | application.properties vs application.yml

1/ .properties

# Mail server 
spring.mail.host=smtp.office365.com
spring.mail.port=587
spring.mail.username=admin@quachson.com
spring.mail.password=fkd%^865
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

Cấu trúc của properties là không cấp bặc và dùng =

Spring profiles: phải tách ra mổi profile là 1 file properties: local.propertiesstaging.propertiesprod.properties

2/ .yml

spring:
  mail:
    host:smtp.office365.com
    port:587
    username=admin@quachson.com
    password=fkd%^865
    properties:
      mail:
        smtp:
          auth:true
          starttls:
            enable:true

Cấu trúc của yml thì có cấp bậc và dùng :

Spring profiles: cấu hình nhiều profiles trong 1 file yml

Khi dùng yml file thì chú ý, sẽ support @PropertySource để đọc file yml (Mình thì hem thích dùng chung 1 file sẽ làm file dài ra, khó đọc)

Nhiều người khuyên nên dùng yml, nào là thế này, nào là thế kia, chém gió theo lý thuyết, theo cộng đồng Cá nhân mình thì cái nào quen, thuận mắt thì dùng, vì 2 cách cũng như nhau mà thôi.


Dùng @Value cho biến và @ConfigurationProperties cho class để load toàn bộ properties hay load theo prefix như spring.mail. * để load value.

@Value("${app.description: default value}}")

Agile plan

Nói đến Agile thì ai cũng đã nghe qua, cũng đã biết nhưng rất ít người thật sự hiểu rõ và áp dụng đúng.

  • 1 sprint: thường là 2 tuần, 1 tuần thì quá ngắn dành cho mấy project nhỏ, 1 tuần thì dùng Kanban cho rồi, hem cần dùng scrum.
  • Team size: ít nhất là 5 người (ít hơn thì ko nên có scrum master tốn mất 1 resource) , nhiều nhất là 10 người thì team hoạt động mới hiểu quả.

Sau đây là ví dụ cơ bản planing sprint cho 2 tuần có gì, có thể bổ xung thêm hoạt động vào thời gian trống.

T2: Retrospective, Knowledge sharing

T3: Planing 2 (How)

T4: Dán task ticket lên board, Vẽ burn chart, Cool Stuff, Start Code

T5: Daily meeting, Code

T6: Daily meeting, Code

T2: Daily meeting, Code

T3: Daily meeting, Code

T4: Daily meeting, Planing 1 (What), Code

T5: Daily meeting, Code

T6: Prepare demo, Review sprint goal, Cool stuff, Demo for PO

  • Knowledge sharing: chia sẽ về business, về tính năng, về kỹ thuật mà mình làm trong sprint, về project cho người nào chưa biết.
  • Cool Stuff: là một buổi chia sẽ kiến thức, học tập lẫn nhau.
  • Planing 1 (What): PO sẽ nói về những tính năng nào cần làm, cần hoàn thành, và độ ưu tiên trong sprint, giải thích về business.
  • Planing 2 (How): Sẽ hem có PO tham gia, Toàn team sẽ phân tích, tạo tasks, estimation tasks, vote points cho độ phức tạp của taks, Task sẽ được làm như thế nào.Nếu chưa hiểu về business, còn thắc mắc thì note lại, hoặc gọi cho PO để làm rõ.
  • Code, unit tests, cross code review, convention code, … tùy vào từng team mà áp dụng.
  • Scrum Master: là người chịu trách nhiệm thiết lập nhóm, thiết lập cuộc họp trong các giai đoạn phát triển và loại bỏ các vật cản ảnh hưởng đến sự phát triển
  • Product owner: tạo ra backlog sản phẩm, đưa ra thứ tự ưu tiên cho backlog và chịu trách nhiệm cho việc phát hành các tính năng ở mỗi giai đoạn.
  • Daily meeting: không được quá 15p, đứng xung quanh bảng được dán tasks, cập nhật tình hình tasks với mọi  người trong team, có khó khăn gì không, nếu có sẽ tạo meeting riêng để thảo luận vấn đề này vê team hoặc người làm trong story.
  • Thứ tự ưu tiên của tasks sẽ được dán từ trên xuống dưới, tập trung hoàn thành từng story một, không nên làm, mở quá nhiều story mà cái nào cũng không xong.

JMeter và BlazeMeter chrome extension

BlazeMeter chrome extension này rất tiện, như một vị cứu tinh dành cho jMeter, dùng để record lại những thao tác trên website . Xây dựng sẵn khung sườn cho jMeter, vì là tự động nên sẽ có nhiều request dư thừa và chưa chính xác nhưng còn tốt hơn là phải viết và xây dựng từ đầu.

Còn cách sử dụng thì rất dễ, vào chrome extensions cài vào, bấm records, thao tác trên web, bấm stop, export ra file jMeter.

SSL Lets Encrypt With Beanstalk ElasticSearch Amazon

Ngữ cảnh:

  • Có 1 domain staging.quachson.com được đăng ký ở trang abc
  • Có 1 instance beanstalk của amazon tên là aabbcc-09-amazon.com đang chạy nodejs (reactjs), cần cấu hình ssl (https) cho domain staging.quachson.com chỏ vào.
  • Cấn https để test, thử nghiệm này nọ, ko có tính chất thương mại điện hay fintech này nọ nên nhu cầu dùng free ssl

Cách làm:

  • Tạo SSH
    • Tạo pair key
    • Add pair key vào beanstalk instance
    • Open port 22 cho SSH
  • Cấu hình ngnix, install letsencrypt
    • Map domain port 80
    • Install certbot.
    • Add cronjob 90 ngày.

Chi Tiết:

  • Tạo SSH
    • Tạo pair key: Services/ec2/NETWORK & SECURITY/ Key Pairs / Create Key Pairmlqflfsvzt
    • Sau khi tạo pair key xong, key sẽ được download về, mất key phải tạo key mới, không thể download lại
    • Add pair key vào beanstalk instance: Services/elasticbeanstalk/ chọn instance / Configuration / Security / Modifygettingstarted-dashboardaeb-env-config-security-page (1)
    • Open port 22 cho SSH: Services/ec2/Security Groups/ chọn group / Inbound / Editztzcpcxhdbwxygtxgutf
    • Chọn connect, không phải image vì hình lấy trên net.tkv-ec2-create-ami-menu2node-connection (1)
    • Nếu dùng macOS hay ubuntu thì cần chmod 400, nếu windows thì khỏi.
  • Cấu hình nginx, install letsencrypt
    • From domain staging.quachson.com –> dns record type: A tới IP host.
    • From hosting: Maping domain với port 80, tạo mới file: allow-ssl-domain.config, copy vào /etc/nginx/conf.d/elastic-beanstalk

server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name staging.quachson.com;
}

  • Install certbot and ssl
    • sudo mkdir -p /opt/certbot
    • sudo wget https://dl.eff.org/certbot-auto -O /opt/certbot/certbot-auto;sudo chmod a+x /opt/certbot/certbot-auto
    • [nodejs] sudo /opt/certbot/certbot-auto certonly –debug –non-interactive –email son.quach.aavn@gmail.com –agree-tos –domains staging.quachson.com –keep-until-expiring –webroot -w /var/app/current/public
    • [java] sudo /opt/certbot/certbot-auto –nginx -d staging.quachson.com
    • sudo ln -sf /etc/letsencrypt/live/staging.quachson.com /etc/letsencrypt/live/ebcert
    • openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname root
    • Sau khi install ssl xong, xoá allow-ssl-domain.config vì phải config forward port 80 sang https và SSL chỏ vào file key
  • Configuration SSL
    • Tạo folder .ebextensions, hỗ trợ .conf và .yaml
    • Cấu trúc thư mục cho react project
    • Cấu trúc thư mục cho spring boot (Java SE), zip folder  .ebextensions  và  file  example-api-2.3.jar  ->  deployment.zip (tên gì cũng dc)
    • Cấu hình cho nginx, nên upload config file lên server rồi restart nginx để test, test thành công thì mới copy vào .ebextensions, upload deployment.zip lên test lại.

Một vài lưu ý:

  • /etc/nginx
  • /etc/letsencrypt/live
  • /var/www/html
  • sudo service nginx start | stop | restart
  • Command check java heap (bytes)
    • java -XX:+PrintFlagsFinal {your-java-program} | grep HeapSize
uintx InitialHeapSize             := 536870912       {product}
 uintx MaxHeapSize                 := 1073741824      {product}
uintx PermSize                     := 67108864        {pd product}  
uintx MaxPermSize                  := 134217728       {pd product}  
intx ThreadStackSize               := 512             {pd product}

Nguồn:

https://quachson.com/ssl-lets-encrypt/

Microservices Authentication and Authorization Solutions

  • Authentication: who you are.
  • Authorization: what you can do.
  1. Distributed Session Management
    1. Sticky session: Bảo đảm rằng tất cả requests của users sẽ trên cùng server giống như request ban đầu, sẽ phụ thuộc là load balancer. Session sẽ bị mất nếu requests không đi đúng servers ban đầu có chứ session vì bất kỳ lý do nào đó như server chứa session đó bị chết, bị quá tải…nên phải đổi servers khác.
    2. Session replication: Nhân rộng session, mỗi instance đều có session giống nhau và đồng bộ hoá thông qua network nên có thể gây tắt nghẽn băng thông. Mỗi khi có 1 session được thay đổi thì phải thay đổi đồng bộ lại trên tất cả instance. Cồng kềnh, nặng nề, tốn nhiều chi phí
    3. Centralized session storage: Xây dựng 1 hệ thống lưu trữ session độc lập riêng. Tất cả microservice sẽ truy xuất vào hệ thống này để lấy session. Nhược điểm là cần phải có giao thức bảo mật giữa các microservice và Distribution Session Store.UNADJUSTEDNONRAW_thumb_3.jpg
  2. Client Token: JWT (Json Web Token)
  3. Single sign-on: chỉ cần login 1 lần là có thể dùng cho mọi hệ thống. Dùng cách nào cũng được miễn thoả mãn khái niệm này là dc. Cách hay dùng là token, JWT, ….
  4. Client Token with API Gateway: Gateway giống cơ chế 1 cửa, chỉ cần biết và gọi 1 API Gateway, đằng sau cánh cửa đó sẽ gọi hàng chục APIs khác để trả về kết quả cuối cùng. Nên user sẽ không biết đến những APIs phía sau cánh cửa.UNADJUSTEDNONRAW_thumb_4.jpg
  5. Third-party application access
    1. API Token: – Được add vào header của requests – Dùng token để truy xuất vào hệ thống thay thế cho username/password, nếu có lộ token thì cũng không biết password để thay đổi. – Những hệ thống hay dùng API Token: Github, Bitbucket, Gitlab, Facebook, Twitter..
    2. OAuth2: grant authorization, trao quyền truy xuất, trao access token.
      A: Tao muốn truy xuất vào facebook của mày để lấy thông tin profile, contacts dc hem.
      B: OK, để tao login vào facebook lấy access token cho mày, có token này thì mày có thể vào nhưng sẽ không thay đổi được password. Tao cho mày vào 1 tuần tao sẽ remove token này.
      UNADJUSTEDNONRAW_thumb_5.jpg
  6. Mutual Authentication: Xác thực lẫn nhau. Trước hết server chứa tài nguyên kiểm tra “giấy phép truy cập” của client, sau đó client kiểm tra lại “giấy phép cấp tài nguyên” của server. Điều này giống như khi bạn giao dịch với bank thì bạn cần kiểm tra xem server bank đó là thật hay không, hay là 1 cái bẫy của hacker giăng ra và ngược lại server bank sẽ kiểm tra bạn.

OAuthJWT được sử dụng nhiều và phổ biến nhất bởi vì nó nhẹ và gọn và không cần transaction. Dĩ nhiên là tuỳ vào trường hợp mà nên áp dụng loại nào cho phù hợp.

Visa F-1, CPT, OPT, H1B là gì ?

Chủ yếu là có keywords để google tìm hiểu thêm.

F-1: là visa dành cho học sinh, sinh viên du học ở trường trung học tư và tất cả trường đại học ở Mỹ.

CPT: Curricular Practical Training: Đào tạo thực hành ngoại khoá. Thường có thời hạn 2 năm.

OPT: Optional Practical Training: Đào tạo thực hành tuỳ chọn. Tốt nghiệp đi làm. Hầu hết cho các ngành là 12 tháng (1 năm) ngoài trừ những ngành được liệt kê vào STEM (Science, Technology, Engineering, and Maths – Khoa học, công nghệ, kỹ thuật và Toán học ) thì được gia hạn thêm 17 tháng nữa (STEM extension). Tổng cộng 12 + 17 = 29 tháng, tức là hơn 2 năm rưỡi.

OPT phải liên quan đến ngành học của mình và hoàn thành trong vòng 14 tháng.

Pre-completion và Post-completion OPT: Pre-completion OPT có thể được dùng trong lúc còn đi học trước khi tốt nghiệp. Nếu vẫn còn trong học kì, sinh viên không được đi làm part-time quá 20 tiếng một tuần. Nhưng nếu trong kì nghỉ theo lịch của trường, sinh viên có thể đi làm full-time. Nếu bạn chọn Pre-completion OPT, thời gian Post-completion OPT sẽ bị trừ đi 1 tháng với mỗi 2 tháng bạn làm part-time Pre-completion OPT tính đến thời điểm tốt nghiệp. Vì vậy nếu bạn có ý định dùng Post-completion OPT để ở ại Mỹ và đi làm một thời gian sau khi tốt nghiệp thì nên suy nghĩ kĩ xem nên dùng bao nhiêu thời gian cho Pre-completion OPT.

Mỗi trường đại học đều có văn phòng chịu trách nhiệm về tư vấn và làm giấy tờ cho sinh viên. Ngay khi đặt chân đến trường, điều cần nhất là đến gặp các counselors ở đây để làm quen, dự orientation, và trang bị cho bản thân những kiến thức cần thiết trước khi học kì đầu tiên bắt đầu. Bạn sẽ không phải hối tiếc về điều này. Đã có không thiếu trường hợp sinh viên không nắm rõ luật lệ và đi làm không xin phép hay trái phép và bị buộc phải về nước. Bạn có thể tìm hiểu thêm về OPT trên website của USCIS tại đây.

H1B: là dạng visa có tài trợ từ công ty (sponsor) dành cho lao động trình độ cao (highly skilled labor) thường có thời hạn 3 năm, được gia hạn thêm 1 lần nên tổng cộng là 6 năm. Từ H1B có thể xin thẻ xanh 2 năm. Nói dễ ăn vậy thì ai cũng có thể vào Mỹ hết rồi.

Mỗi năm chính phủ Mỹ có quota cho việc cấp visa H-1B và OTP, khoảng 85,000 cho H-1B. Trong đó 20,000 chổ dành riêng cho người có bằng cao học trở lên (Thạc sỹ, Tiến sỹ, Bác sỹ, dược sỹ, …) và 6,800 chổ dành cho công dân Singapore và Chile dưới dạng H-1B. Những chổ còn lại dành cho tất cả mọi người nhưng mình thấy 80% là người Ấn độ. Số lượng visa thì có hạn, những mỗi năm số người muốn xin vào visa ngày càng cao.
Loại visa này được phép bắt đầu nộp đơn ngày 1 tháng 4 mỗi năm. Chính phủ Mỹ sẽ nhận đơn và giải quyết đến khi nào hết 85,000 chổ đó thì thôi nhưng chỉ vài ngày (khoảng 3,4 ngày) thì chính phủ phải ra lệnh thôi nhận đơn vì số lượng quá nhiều nên họ đưa qua chương trình “xổ số” (lottery system) để chọn ngẩu nhiên. Sau khi nộp tháng 4 thì ngày 1 tháng 10 visa mới có hiệu lực.
Nếu làm việc cho các trường đại học thì việc xin H-1B rất đơn giản vì không có giới hạn quota.

Nếu không xin được visa H-1B thì sao ?
Hết hạn OPT thì mỗi người có 60 ngày grace period để thu dọn đồ đạc và theo đuổi những lựa chọn như là:

  • Đi làm việc ở nước khác:
  • Đi học tiếp: Mỗi cấp chỉ dùng được OPT 1 lần (BS, Master, PhD), Nếu bạn đang làm OTP Master thì bạn xin trường update lên OPT PhD.
  • Về nước.

 

Links tham khảo:
https://www.uscis.gov/opt
Đi làm ở Mỹ không dễ (Phần 1)- CPT và OPT

Singapore và các loại passport làm việc

  1. Nhóm chuyên gia: phải có bằng đại học
    1. Employment Pass: lương tối thiểu $3,600 đô la 1 tháng. Dạng này đi rất nhiều. http://www.mom.gov.sg/passes-and-permits/employment-pass/key-facts Có thể mang gia đình và con cái theo (dưới 21t) và được học ở các trường của Singapore. Có thể xin thường trú tại Sing phải sau 2 năm làm việc. Thường dành cho những người có 2, 3 năm kinh nghiệm và phải tốt nghiệp mấy trường top ở VN hoặc có nhiều năm kinh nghiêm, trên 10 năm là vượt khung rồi nên vô tư. Công ty nào apply vào cũng được không bị giới hạn như S-Pass.
    2. Entre Pass: dành cho những ai muốn mở Cty ở Singapore.
    3. Personalised Employment Pass: có giá trị cao hơn E-Pass.
  2. Nhóm lao động nghề: Trung cấp
    1. S Pass: lương tối thiểu $2,200/tháng. Visa có hiệu lực tối đa 2 năm. Dành cho người mới tốt nghiệp hoặc có dưới 2 năm kinh nghiệm. Để apply S-Pass thì công ty phải có ít nhất 6 người Singaporean hoặc Permanance Resident (Thường trú nhân). Để có cơ hội apply vào S-Pass thì Cty phải lớn và Cty đóng thuế rất cao cho S-Pass, bù lại lương sẽ thấp. Hôm trước có bạn tuyển dụng người Việt offer mình sang Singapore làm 1 năm với mức lương này mới ghê chứ. Không biết bạn ấy có hiểu gì về luật của Singapore không. Mức lương = Bằng ĐH của trường nào + số tuổi + số năm kinh nghiệm làm việc. Chính phủ Singapore không cho phép doanh nghiệp thuê người nước ngoài với mức lương rẻ mạt hơn công dân Singapore với cùng điều kiện.
    2. Work Permit (có 4 loại): dành cho lao động phổ thông như: xây dựng, sản xuất, hàng hải, làm quán bar, khách sạn, club. Loại này chính phủ Singapore không cấp cho Vietnam nên không quan tâm nhiều cũng dc.
  3. Nhóm sinh viên và thực tập sinh.
    1. Training Employment Pass: lương tối thiểu $3000/tháng
    2. Work Holiday Programme: Cấp cho học sinh, sinh viên đã tốt nghiệp từ 18 – 25 tuổi, muốn làm việc và kết hợp du lịch – nghỉ hè tại Singapore trong thời gian tối đa 6 tháng.
    3. Training Work Permit: thời gian tối đa 6 tháng.
  4. Nhóm gia đình, người thân
    1. Dependant’s Pass: Cấp cho vợ/chồng/con của người nhập cảnh có E-Pass hoặc S-Pass. Bạn cần có mức thu nhập tối thiểu 5000 SGD/ tháng để có thể mang theo gia đình (vợ/ chồng/ con) sang định cư ở Singapore. Lúc này, vợ/ chồng/ con của bạn đều sẽ được cấp Thẻ phụ thuộc này.
    2. Long Term Visit Pass.
Passport dạng S-Pass (S)

S-Pass
Passport dạng E-Pass thì chữ E.
Hiện giờ để xin 1 công việc ở Singapore không phải là quá khó với ngành IT nữa, English chỉ cần giao tiếp là được, còn về Cty thì cũng còn tuỳ vào Cty, nhưng đa số công việc thì cũng bình thường như ở VN mà thôi. Cách dễ nhất để xin visa là apply vào những Cty Agency lớn để được bảo lãnh. Mấy Cty Sing thường hay thích dùng codity để check.
Liệt kê các loại về visa để cho biết thôi, thật sự quan tâm thì chỉ có 2 loại: S-Pass và E-Pass.
CV ở Sing thường nên có thêm ảnh thẻ và mức lương mong muốn.
Job Board: Job Street, Monster Singapore, JobDB, JobBank, …
  • Levy: là thuế do lao động nước ngoài làm việc tại Singapore phải đóng cho chính phủ.
  • S-Pass: phải đóng 2 loại thuế: quota (kim ngạch lao động) và Levy. Vào trang web MOM xem thêm chi tiết
  • BHYT: Cty phải đóng khoản phí này cho nhân viên. Mức thấp nhất cho S-Pass: 15,000 SGD / năm = $10,100 đô Mỹ.
  • 100$ = 136.5 SGD = 2tr3 VND
Reference:
http://www.mom.gov.sg : Ministry of ManPower – Cơ quan nhập cư Singapore (MON), rất quan trọng nên tìm hiểu hết thông tin và mọi dịch vụ ở trang này.
https://services.mom.gov.sg/sat/satservlet : Self Assessment Tool for Employment / S Pass. Trang web dùng để tự đánh giá mức lương dựa vào bằng cấp ĐH, tuổi và số năm kinh nghiệm làm việc.

Các số điện thoại cần thiết

  • Đại sứ quán Việt Nam – Vietnam Embassy +656 462 5938
  • Cứu hoả/ xe cứu thương – Fire/Ambulance +65 995
  • Cảnh sát – Police +65 999
  • Cấp cứu tại nạn – 24-hour Emergency Road Service +656 748 9911