15 điểm bởi GN⁺ 3 ngày trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Di chuyển hạ tầng production trị giá $1.432/tháng sang máy chủ dedicated $233/tháng, đồng thời thay cả hệ điều hành mà vẫn duy trì liên tục dịch vụ không có downtime
  • Tái dựng y hệt trên máy chủ mới với 30 cơ sở dữ liệu MySQL, 34 virtual host Nginx, GitLab EE, Neo4J, Supervisor, Gearman, rồi hoàn tất chuyển đổi bằng sao chép thời gian thực và đồng bộ gia tăng cuối cùng
  • Trọng tâm của việc di chuyển cơ sở dữ liệu là kết hợp xử lý song song bằng mydumper·myloader với MySQL replication, đồng thời xử lý cả vấn đề về schema sys và quyền phát sinh khi nâng từ MySQL 5.7 lên 8.0
  • Cutover được thực hiện theo thứ tự giảm DNS TTL, chuyển Nginx trên máy chủ cũ sang reverse proxy, rồi thay đổi hàng loạt bản ghi A, nhờ đó các yêu cầu tới IP cũ trong lúc DNS đang truyền bá vẫn được chuyển sang máy chủ mới
  • Kết quả là đạt được tiết kiệm $1.199/tháng, $14.388/năm, đồng thời nâng cấp CPU·bộ nhớ·lưu trữ và đạt 0 phút downtime

Bối cảnh di chuyển

  • Trong bối cảnh vận hành một công ty phần mềm tại Thổ Nhĩ Kỳ, lạm phát tăng mạnhđồng lira Thổ Nhĩ Kỳ suy yếu khiến gánh nặng chi phí hạ tầng tính theo đô la tăng lên đáng kể
  • Chi phí máy chủ DigitalOcean hiện tại là $1.432 mỗi tháng, với cấu hình gồm 192GB RAM, 32 vCPU, 600GB SSD, 2 block volume 1TB, kèm backup
  • Đích đến mới là máy chủ dedicated Hetzner AX162-R, với AMD EPYC 9454P 48 nhân 96 luồng, 256GB DDR5, cấu hình 1.92TB NVMe Gen4 RAID1
  • Chi phí hàng tháng giảm xuống còn $233, tương đương tiết kiệm $1.199/tháng$14.388/năm
  • Dù không có bất mãn với độ tin cậy hay trải nghiệm dành cho nhà phát triển của máy chủ cũ, nhưng với workload steady-state thì tỷ lệ giá/hiệu năng không còn hợp lý nữa

Môi trường vận hành hiện tại

  • Stack đang chạy không phải môi trường thử nghiệm đơn giản mà là môi trường production thực tế
    • 30 cơ sở dữ liệu MySQL, tổng cộng 248GB dữ liệu
    • Vận hành 34 virtual host Nginx trên nhiều domain
    • Bao gồm cả backup GitLab EE dung lượng 42GB
    • Vận hành Neo4J Graph DB dung lượng 30GB
    • Quản lý hàng chục background worker bằng Supervisor
    • Sử dụng hàng đợi tác vụ Gearman
    • Vận hành ứng dụng mobile live phục vụ hàng trăm nghìn người dùng
  • Hệ điều hành trên máy chủ cũ là CentOS 7, đã hết hỗ trợ
  • Hệ điều hành trên máy chủ mới là AlmaLinux 9.7, bản phân phối tương thích RHEL 9 và là lựa chọn kế nhiệm tự nhiên cho CentOS
  • Lần di chuyển này không chỉ để cắt giảm chi phí mà còn là cơ hội thoát khỏi hệ điều hành đã nhiều năm không nhận được bản vá bảo mật

Chiến lược không downtime

  • Không chấp nhận cách chỉ đổi DNS và khởi động lại dịch vụ, mà tiến hành di chuyển không downtime bằng quy trình 6 bước
  • Bước 1: Cài đặt toàn bộ stack trên máy chủ mới

    • Cài đặt Nginx bằng cách biên dịch từ source với cùng các flag như máy chủ cũ
    • PHP được cài qua Remi repo và áp dụng các file cấu hình .ini giống hệt máy chủ cũ
    • Cài đặt MySQL 8.0, Neo4J Graph DB, GitLab EE, Node.js, Supervisor, Gearman và cấu hình để hành vi khớp với hệ thống hiện tại
    • Trước khi đụng tới bản ghi DNS, mọi dịch vụ đã được căn chỉnh để hoạt động giống hệt máy chủ cũ
    • Chứng chỉ SSL được xử lý bằng cách sao chép toàn bộ thư mục /etc/letsencrypt/ từ máy chủ cũ qua rsync
    • Sau khi toàn bộ traffic được chuyển sang máy chủ mới, thực hiện gia hạn cưỡng bức toàn bộ chứng chỉ bằng certbot renew --force-renewal
  • Bước 2: Sao chép file web bằng rsync

    • Sao chép toàn bộ thư mục /var/www/html khoảng 65GB, 1,5 triệu file bằng rsync qua SSH
    • Dùng tùy chọn --checksum để kiểm tra tính toàn vẹn
    • Ngay trước cutover, thực hiện thêm một lần đồng bộ gia tăng cuối cùng để phản ánh các file thay đổi
  • Bước 3: Thiết lập master-slave replication cho MySQL

    • Thay vì dump rồi restore gây dừng cơ sở dữ liệu, cấu hình sao chép thời gian thực
    • Máy chủ cũ được đặt làm master, máy chủ mới là slave chỉ đọc
    • Phần nạp dữ liệu lớn ban đầu dùng mydumper, sau đó bắt đầu replication từ đúng vị trí binlog được ghi trong metadata của bản dump
    • Duy trì hai cơ sở dữ liệu ở trạng thái đồng bộ thời gian thực cho tới thời điểm cutover
  • Bước 4: Giảm DNS TTL

    • Gọi DigitalOcean DNS API bằng script để giảm TTL của toàn bộ bản ghi A/AAAA từ 3600 giây xuống 300 giây
    • MX, TXT record không thay đổi
    • Việc đổi TTL cho bản ghi mail có thể gây vấn đề về khả năng gửi nhận nên được loại trừ
    • Chờ 1 giờ để TTL cũ hết hạn trên toàn cầu, sau đó sẵn sàng cutover trong vòng 5 phút
  • Bước 5: Chuyển Nginx trên máy chủ cũ sang reverse proxy

    • Một script Python phân tích các khối server {} trong toàn bộ 34 cấu hình site Nginx
    • Cấu hình cũ được backup rồi thay bằng cấu hình proxy trỏ sang máy chủ mới
    • Nhờ vậy, trong lúc DNS đang lan truyền, các request đi vào IP cũ vẫn được chuyển lặng lẽ sang máy chủ mới
    • Theo góc nhìn người dùng, không có gián đoạn nhìn thấy được
  • Bước 6: DNS cutover và tắt máy chủ cũ

    • Gọi DigitalOcean API bằng script Python để đổi toàn bộ bản ghi A sang IP máy chủ mới chỉ trong vài giây
    • Máy chủ cũ được giữ ở trạng thái cold standby trong 1 tuần rồi mới tắt
    • Trong suốt quá trình, dịch vụ luôn được duy trì dưới dạng phản hồi trực tiếp hoặc phản hồi thông qua proxy, nên không có khoảng trống về tính sẵn sàng

Di chuyển MySQL

  • Trong toàn bộ công việc, đây là giai đoạn phức tạp nhất
  • Dump dữ liệu

    • Dùng mydumper thay cho mysqldump chuẩn
    • Tận dụng 48 CPU core trên máy chủ mới để export/import song song, rút ngắn công việc vốn mất vài ngày với mysqldump đơn luồng xuống còn vài giờ
    • Các tùy chọn chính được dùng gồm --threads 32, --compress, --trx-consistency-only, --skip-definer, --chunk-filesize 256
    • File metadata của bản dump chính ghi lại vị trí binlog tại thời điểm snapshot
      • File: mysql-bin.000004
      • Position: 21834307
    • Giá trị này được dùng làm điểm bắt đầu replication về sau
  • Truyền dump

    • Sau khi hoàn tất dump, truyền sang máy chủ mới bằng rsync qua SSH
    • Tổng cộng 248GB các chunk đã nén được truyền đi
    • Tùy chọn --compress của mydumper góp phần cải thiện tốc độ truyền qua mạng nhờ dữ liệu chunk đã được nén
  • Nạp dữ liệu

    • Dùng myloader
    • Các tùy chọn chính là --threads 32, --overwrite-tables, --ignore-errors 1062, --skip-definer
  • Vấn đề khi chuyển từ MySQL 5.7 lên 8.0

    • Do môi trường CentOS 7, máy chủ cũ vẫn đang dừng ở MySQL 5.7
    • Trước khi di chuyển, dùng mysqlcheck --check-upgrade để kiểm tra dữ liệu có tương thích với MySQL 8.0 hay không, và kết quả là không có vấn đề
    • Máy chủ mới cài MySQL 8.0 Community mới nhất
    • Thời gian thực thi truy vấn trên toàn dự án giảm đáng kể, và trong bài gốc điều này được lý giải nhờ optimizer được cải thiệncác cải tiến của InnoDB trong MySQL 8.0
    • Tuy nhiên vẫn phát sinh vấn đề do bước nhảy phiên bản
      • Sau khi import, cấu trúc cột của bảng mysql.user không phải 51 cột như mong đợi mà chỉ có 45 cột
      • Kết quả là thiếu mysql.infoschema và phát sinh lỗi xác thực người dùng
    • Lần thử sửa đầu tiên dùng các lệnh sau
      • systemctl stop mysqld
      • mysqld --upgrade=FORCE --user=mysql &
    • Lần thử đầu tiên thất bại với lỗi ERROR: 'sys.innodb_buffer_stats_by_schema' is not VIEW
    • Nguyên nhân là schema sys đã bị import thành bảng thường thay vì view
    • Cách giải quyết là chạy DROP DATABASE sys; rồi chạy lại nâng cấp
    • Sau đó hoàn tất bình thường

Cấu hình MySQL replication

  • Sau khi nạp xong dump trên cả hai máy chủ, máy chủ mới được cấu hình thành replica của máy chủ cũ
  • Trong câu lệnh CHANGE MASTER TO, chỉ định IP máy chủ cũ, người dùng replication, cổng 3306, MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=21834307
  • Sau đó chạy START SLAVE;
  • Gần như ngay lập tức, replication dừng lại với error 1062 Duplicate Key
  • Nguyên nhân là bản dump được thực hiện thành hai đợt, và giữa hai đợt có phát sinh ghi lên một số bảng, khiến dữ liệu trong dump đã import và dữ liệu phát lại từ binlog cố chèn trùng cùng một dòng
  • Để xử lý, áp dụng các thiết lập sau
    • SET GLOBAL slave_exec_mode = 'IDEMPOTENT';
    • START SLAVE;
  • Chế độ IDEMPOTENT sẽ âm thầm bỏ qua lỗi duplicate key và missing row
  • Tất cả cơ sở dữ liệu quan trọng đều đồng bộ không lỗi, và chỉ trong vài phút giá trị Seconds_Behind_Master đã giảm về 0

Kiểm tra trước cutover

  • Trước khi đụng tới bản ghi DNS, cần xác nhận rằng mọi dịch vụ trên máy chủ mới hoạt động chính xác
  • Cách kiểm tra là tạm thời chỉnh file /etc/hosts trên máy local để ánh xạ domain sang IP máy chủ mới
  • Trình duyệt và Postman sẽ gửi request tới máy chủ mới, trong khi người dùng bên ngoài vẫn tiếp tục truy cập máy chủ cũ
  • Kiểm tra endpoint API, admin panel và trạng thái phản hồi của từng dịch vụ
  • Sau khi xác nhận mọi hạng mục, mới tiến hành cutover thực tế

Vấn đề về quyền SUPER

  • Sau khi master-slave replication đã đồng bộ hoàn toàn, phát hiện trên máy chủ mới rằng dù read_only = 1, các câu lệnh INSERT vẫn thành công
  • Nguyên nhân là mọi user ứng dụng PHP đều được cấp quyền SUPER
  • Trong MySQL, quyền SUPER có thể bỏ qua read_only
  • Kết quả SHOW GRANTS FOR 'some_db_user'@'localhost'; cho thấy có bao gồm quyền SUPER
  • Lặp lại REVOKE SUPER ON *.* FROM 'some_db_user'@'localhost'; cho tổng cộng 24 user ứng dụng
  • Sau đó chạy FLUSH PRIVILEGES;
  • Từ thời điểm đó, read_only = 1 mới chặn đúng các thao tác ghi của user ứng dụng, trong khi replication vẫn tiếp tục được phép

Chuẩn bị DNS

  • Tất cả domain đều được quản lý bằng DigitalOcean DNS, còn nameserver được kết nối từ GoDaddy
  • Công việc giảm TTL được script hóa để chạy với DigitalOcean API
  • Phạm vi thay đổi chỉ giới hạn ở bản ghi A, AAAA
  • MX, TXT record không bị đụng tới
    • Do lo ngại khả năng phát sinh vấn đề với việc gửi nhận của Google Workspace, TTL của các bản ghi liên quan tới mail được giữ nguyên
  • Sau khi chờ 1 giờ để TTL cũ hết hạn, hệ thống sẵn sàng cutover

Chuyển Nginx trên máy chủ cũ sang reverse proxy

  • Thay vì chỉnh tay 34 file cấu hình, tác giả tự động chuyển đổi bằng script Python
  • Script phân tích các khối server {} trong mọi file cấu hình, xác định content block chính rồi thay bằng cấu hình proxy
  • Cấu hình gốc được backup dưới dạng file .backup
  • Trong cấu hình ví dụ có áp dụng proxy_pass https://NEW_SERVER_IP;, proxy_set_header Host $host;, proxy_set_header X-Real-IP $remote_addr;, proxy_read_timeout 150;
  • Tùy chọn quan trọng là proxy_ssl_verify off
    • Vì chứng chỉ SSL trên máy chủ mới hợp lệ với domain nhưng không hợp lệ với địa chỉ IP
    • Do môi trường này kiểm soát cả hai đầu nên có thể chấp nhận tắt xác minh trong trường hợp này

Quy trình cutover

  • Điều kiện ngay trước cutover là độ trễ replication ở mức Seconds_Behind_Master: 0 và reverse proxy đã sẵn sàng
  • Trình tự thực hiện như sau
    • Trên máy chủ mới chạy STOP SLAVE;
    • Trên máy chủ mới chạy SET GLOBAL read_only = 0;
    • Trên máy chủ mới chạy RESET SLAVE ALL;
    • Trên máy chủ mới chạy supervisorctl start all
    • Trên máy chủ cũ chạy nginx -t && systemctl reload nginx để kích hoạt proxy
    • Trên máy chủ cũ chạy supervisorctl stop all
    • Trên máy Mac local chạy python3 do_cutover.py để đổi toàn bộ bản ghi A trong DNS sang IP máy chủ mới
    • Chờ khoảng 5 phút để lan truyền
    • Trên máy chủ cũ comment toàn bộ mục crontab
  • Script DNS cutover gọi DigitalOcean API để thay toàn bộ bản ghi A trong khoảng 10 giây

Công việc bổ sung sau cutover

  • Sau khi hoàn tất di chuyển, phát hiện nhiều webhook của các dự án GitLab vẫn đang trỏ tới IP máy chủ cũ
  • Viết và áp dụng script quét toàn bộ project qua GitLab API rồi cập nhật hàng loạt webhook

Kết quả cuối cùng

  • Chi phí hàng tháng giảm từ $1.432 xuống $233
  • Số tiền tiết kiệm mỗi năm là $14.388
  • Về hiệu năng cũng có được máy chủ mạnh hơn
    • CPU tăng từ 32 vCPU lên 96 logical CPU
    • RAM tăng từ 192GB lên 256GB DDR5
    • Lưu trữ chuyển từ cấu hình hỗn hợp khoảng 2.6TB sang 2TB NVMe RAID1
    • Downtime là 0 phút
  • Toàn bộ quá trình di chuyển mất khoảng 24 giờ
  • Không có ảnh hưởng tới người dùng

Bài học quan trọng

  • MySQL replication là công cụ cốt lõi cho di chuyển không downtime
    • Thiết lập sớm, cho nó bắt kịp đầy đủ rồi mới cutover
  • Quyền của user MySQL cần được kiểm tra kỹ trước khi di chuyển
    • Nếu có quyền SUPER, read_only có thể bị bỏ qua và môi trường slave thực tế không còn là chỉ đọc
  • Việc script hóa cập nhật DNS, chỉnh cấu hình Nginx, sửa webhook là rất quan trọng
    • Nếu xử lý thủ công hơn 34 site thì sẽ tốn thời gian và tăng khả năng sai sót
  • Tổ hợp mydumper + myloader nhanh hơn rất nhiều so với mysqldump trên dataset lớn
    • Với dump·restore song song 32 luồng, công việc từ vài ngày rút xuống vài giờ
  • Với workload steady-state, nhà cung cấp cloud có thể khá đắt đỏ, còn máy chủ dedicated có thể mang lại hiệu năng cao hơn với chi phí thấp hơn

Script GitHub

  • Toàn bộ script Python dùng cho lần di chuyển đã được công khai trên GitHub
  • Danh sách script bao gồm
    • do_list_domains_ttl.py
      • Truy vấn toàn bộ bản ghi A, IP và TTL của các domain trên DigitalOcean
    • do_ttl_update.py
      • Giảm hàng loạt TTL của mọi bản ghi A/AAAA xuống 300 giây
    • do_to_hetzner_bulk_dns_records_import.py
      • Di chuyển toàn bộ DNS zone từ DigitalOcean sang Hetzner DNS
    • do_cutover_to_new_ip.py
      • Chuyển toàn bộ bản ghi A từ IP máy chủ cũ sang IP máy chủ mới
    • nginx_reverse_proxy_update.py
      • Chuyển toàn bộ cấu hình site nginx sang cấu hình reverse proxy
    • mysql_compare.py
      • So sánh row count của mọi bảng trên toàn bộ hai máy chủ MySQL
    • final_gitlab_webhook_update.py
      • Cập nhật webhook của mọi dự án GitLab sang IP máy chủ mới
    • mydumper
      • Thư viện mydumper
  • Mọi script đều hỗ trợ chế độ DRY_RUN = True để xem trước an toàn trước khi áp dụng thực tế

1 bình luận

 
Ý kiến Hacker News
  • Vài tháng trước tôi đã chuyển hai máy chủ từ Linode và DO sang Hetzner, và cắt giảm chi phí rất đáng kể theo kiểu cùng mặt bằng. Điều ấn tượng hơn là đó là một mớ stack hỗn loạn gồm hàng chục trang web, nhiều ngôn ngữ khác nhau, thư viện cũ, cả MySQL lẫn Redis đan xen vào nhau. Thế mà Claude Code đã chuyển hết đống đó, thậm chí còn viết lại một phần mã để xử lý các thư viện không còn tồn tại. Giờ kiểu migration phức tạp thế này đã dễ hơn nhiều, nên tôi nghĩ về sau tính di động giữa các nhà cung cấp sẽ còn cao hơn nữa

    • Theo tôi, thứ mọi người trả tiền không phải là compute thần kỳ mà là để khỏi phải động vào đống glue code vá víu suốt 10 năm. Nhưng nếu các agent bắt đầu nuốt luôn phần glue đó, thì moat của các nhà cung cấp hiện tại sẽ mỏng đi rất nhanh
    • Thành thật mà nói, cảm giác như đây là quảng cáo cho Claude lồng bên trong quảng cáo cho Hetzner. Tôi tự hỏi nó sẽ còn lồng đến mức nào nữa
    • Tôi thấy không phải câu chuyện nào cũng cần phải kéo về thành chuyện AI
    • Tôi cũng dự định rời Linode trong vài tháng tới. Tôi đã dùng hơn 10 năm và còn giới thiệu cho nhiều khách hàng, nhưng họ cứ tăng giá mãi, đến mức giờ ở nơi như Hetzner tôi có thể nhận được RAM gấp 8 lần, NVMe riêng, CPU riêng với giá rẻ hơn. Đúng là sẽ mất bớt vài ưu điểm như khả năng di chuyển dễ của máy chủ ảo, nhưng ngay cả khi có sự cố thì đội hỗ trợ của Hetzner vẫn luôn phản hồi nhanh và xử lý tốt
    • Tôi cũng đang ngày càng dùng Claude cho DevOps. Tôi chạy VM bằng Proxmox trên dàn bare metal của mình, và Claude tối ưu cũng như cấu hình một mạng mới trải trên nhiều máy rất nhanh, đến mức gần như thấy nó như đồng đội hay một sysadmin lương cao
  • Tôi đang lên kế hoạch chuyển từ AWS sang Hetzner. Amazon đôi khi tính giá đắt gấp 20 lần đối thủ, lại ép cam kết dài hạn nếu muốn có mức giá tạm ổn, và còn làm cho việc di chuyển dữ liệu ra ngoài trở nên cực kỳ đắt đỏ, nên tôi thấy rất thù địch với khách hàng. Họ có thể nghĩ phí egress sẽ giữ chân người dùng, nhưng thực tế nó lại tạo áp lực rằng chỉ cần chuyển một phần sang đối thủ là rồi sẽ phải chuyển cả hệ thống đi hết. Dù vậy, tôi chưa xây nền tảng của mình trên các dịch vụ độc quyền của Amazon, nên việc chuyển đi cũng dễ hơn phần nào

    • Phần này trước đây đúng, nhưng từ tháng 1/2024 thì GCP đã ra chính sách miễn phí egress, nên không khí đã đổi khác, rồi vài tháng sau AWS cũng đưa ra chính sách tương tự. Tôi không định thuyết phục bạn ở lại, chỉ muốn nói rằng về mặt kỹ thuật thì có thể gửi yêu cầu waiver. Thực tế được áp dụng đến đâu thì tôi cũng không chắc, và nhìn vào câu chữ của AWS thì có vẻ còn chịu ảnh hưởng của EU Data Act nữa
  • Mỗi khi đọc những bài như thế này, tôi lại thấy lạ vì mọi người ít khi nói về dự phòng hay load balancer. Nếu một máy chủ chết thì nhiều dịch vụ có thể cùng sập theo, nên tôi không rõ mọi người thật sự thấy điều đó là ổn hay sao. Có thể đã tiết kiệm được tiền, nhưng lại tốn thêm thời gian bảo trì và đau đầu về sau

    • Tôi nghĩ điều này phụ thuộc vào tính chất dịch vụ và mức độ quan trọng của nó. Nếu một máy chủ chạy suốt 10 năm mà tổng downtime trong quãng đó chỉ khoảng 1 tuần đến 1 tháng, thì trong nhiều trường hợp hoàn toàn chấp nhận được. Với doanh nghiệp nhỏ, trang web sở thích, diễn đàn hay blog nơi website không phải nghiệp vụ cốt lõi, một quãng downtime ngắn có thể không phải vấn đề lớn. Thực ra cái đuôi dài của những website ít traffic kiểu này có thể mới là phần đông của web. Không phải mọi thứ đều cần high availability, và nếu muốn thì các nhà cung cấp như vậy cũng có các tính năng như load balancer
    • Tôi nghĩ lý do những bài kiểu này được quan tâm là vì chúng thường làm lộ ra sự lệch nhau giữa yêu cầu và giải pháp. Nếu đó là dự án cá nhân hay doanh nghiệp nhỏ nhưng lại bị over-engineer bằng kiến trúc cấp enterprise, thì trong khi thỉnh thoảng downtime một ngày cũng chẳng sao, bộ cloud đầy đủ có thể là không cần thiết. Tuy nhiên bài này hơi lạ ở chỗ nhấn mạnh migration không downtime, nhưng cấu trúc đích đến thì lại không có vẻ chịu lỗi cao. Có cảm giác chỉ cần bổ sung thêm một ít kiến trúc ở phía Hetzner là đã cải thiện đáng kể rồi
    • Với nhiều workload thì mức chuẩn bị như thế là không cần thiết. Và cũng đừng đánh giá thấp độ tin cậy của sự đơn giản. Tôi làm Linux sysadmin đã lâu, và downtime tôi thấy ở các hệ thống phức tạp nhiều hơn hẳn so với hệ thống đơn giản. Ở đâu đó giữa lý thuyết và thực tế, tôi có ấn tượng rằng trong đa số trường hợp, phương án đơn giản cuối cùng lại bền hơn
    • Nói công bằng thì ban đầu họ cũng chỉ đang dùng một VM đơn lẻ trên DigitalOcean, nên thực ra không hưởng nhiều lợi thế của cloud provider. Thường những bài như thế này chia làm hai loại: có trường hợp lên cloud vì lý do sai và đáng ra nên quay về vật lý, còn có trường hợp mà làm vậy sẽ thành thảm họa; vụ này có vẻ gần với loại đầu hơn. Nếu cấu hình đó đã chạy ổn trên DO, thì ở Hetzner chỉ cần thêm chính sách DR phù hợp là vẫn ổn
    • Có lẽ quyết định này đến từ việc thực tế họ chưa từng trải qua nhiều địa ngục bảo trì hay những rắc rối tương lai kéo dài
  • lithus.eu, chúng tôi đã nhiều lần chuyển khách hàng từ nhiều cloud khác nhau sang Hetzner. Thường thì chúng tôi dựng nhiều máy chủ, đôi khi là multi-AZ, rồi dùng Kubernetes để phân tán workload nhằm cung cấp HA. Với một node đơn thì Kubernetes có thể là quá tay, nhưng khi có nhiều node thì hợp lý hơn hẳn. Về backup, chúng tôi dùng cả Velero lẫn backup ở cấp ứng dụng; ví dụ với Postgres thì có cả backup WAL để hỗ trợ PITR. Dữ liệu trạng thái được đặt trên ít nhất hai node để đảm bảo HA. Về hiệu năng, bare metal nhìn chung cũng tốt hơn, và khá nhiều lần độ trễ phản hồi giảm một nửa so với AWS. Theo tôi, lý do không hẳn nằm ở bản thân ảo hóa mà ở những yếu tố xung quanh như NVMe, độ trễ mạng thấp hơn, và ít cache contention hơn. Tôi cũng đã viết thêm về chuyện này trong một bài HN trước đây

    • Tôi cũng đã tự đo vài năm trước, và từ đó không còn muốn nhìn lại máy chủ ảo nữa. CPU time không được reserved như RAM, nên hiệu năng so với phần cứng thật tệ hơn rất nhiều. Bài đo đạc này cũng đáng tham khảo
    • Tôi thấy triển khai k8s rất thuận tiện để mang đi nơi khác. Nó ít bị khóa nhà cung cấp hơn so với các managed service của nhiều cloud. Stack của tôi cũng chỉ là k8s, hosted Postgres và kiểu storage giống s3, nên Postgres lúc nào cũng có thể tự host được, cuối cùng chỉ còn k8s và s3 là cốt lõi. Hình như Hetzner cũng có thứ na ná s3, nhưng tôi chưa xem kỹ, mà chuyển 100TB thì chắc là một việc khá lớn
    • Nhân tiện, HA là viết tắt của high availability
    • Bài viết nhìn chung hợp lý, nhưng đoạn để email ở cuối làm tôi thấy hơi giống lời quảng bá
  • Bài này khá khó đọc. Cảm giác như Claude làm migration xong rồi lại để Claude viết luôn bản báo cáo. Nếu nhờ LLM mà tiết kiệm được như vậy thì rất tuyệt, nhưng đã công khai thành bài viết thì ít nhất cũng nên biên tập lại để bỏ bớt trùng lặp và giọng văn kiểu LLM

    • Tôi biết nhiều người không đọc nguyên tác, nhưng bài lần này thật sự khó đọc đến mức đau đớn
  • Tôi nghĩ nên cẩn thận với Hetzner. Trước đây tôi rất thích họ nhưng gần đây đã chuyển đi. Họ tắt toàn bộ khoảng 30 VM dùng trong pipeline CI/CD của chúng tôi chỉ vì một tranh chấp hóa đơn 36 đô la. Chúng tôi đã gửi bằng chứng thanh toán đầy đủ, kể cả sao kê ngân hàng, nhưng họ còn chẳng thèm xem, và trong lúc chúng tôi cố liên lạc khẩn cấp thì họ vẫn khóa sạch quyền truy cập. Giờ chúng tôi đã chuyển sang Scaleway

    • Tôi thấy dịch vụ khách hàng của họ đôi khi khá thù địch. Dù vậy tôi vẫn còn dùng cho những việc không quan trọng
    • Khâu billing của Hetzner khá tự động hóa, nhưng thông thường ngay cả khi thẻ bị từ chối thì họ vẫn cho khất khoảng một tháng mới phải thanh toán
  • Vài tháng trước khi tìm phương án thay AWS cho một side project SaaS nhỏ, ban đầu tôi đã nghiêm túc cân nhắc Hetzner để tiết kiệm chi phí và ủng hộ cloud ở EU. Tôi sẵn sàng chấp nhận việc phải tự làm nhiều hơn, nhưng cuối cùng uy tín IP lại là thứ chặn đường. Một trong các rule của firewall AWS managed mà công ty tôi dùng đã chặn khá nhiều, thậm chí có thể là toàn bộ, dải IP Hetzner; ngay cả trên laptop công việc của tôi thì các website host trên IP Hetzner cũng không mở được vì chính sách IT. Dùng thứ như Cloudflare có thể đỡ hơn, nhưng tôi cũng từng thấy nói là bảo vệ DDoS của họ yếu. Cuối cùng tôi chọn DO App Platform ở vùng EU, và tùy chọn DB managed cũng là một lợi thế lớn

    • Nếu Amazon chặn đối thủ kiểu này thì đúng là một cách quá tiện lợi cho họ
    • Tôi không rõ bạn đang nói tới rule firewall nào, nhưng việc DO đáng tin hơn Hetzner thì khá bất ngờ với tôi. Mỗi khi gặp scraper hay hacker, tôi cũng thấy ASN của DO xuất hiện khá thường xuyên, nên cảm giác bên đó rồi cũng có ngày bị chặn thôi
    • Theo trải nghiệm của tôi thì IP của DO còn tệ hơn. Tôi cũng đã rời DO chính vì lý do đó
    • Tôi từng nhắc đến vấn đề này trong một thảo luận về Tor. Tôi đoán Hetzner khá thân thiện với Tor, nên điều đó có thể ảnh hưởng đến uy tín IP, nhưng lúc đó cũng có người trả lời rằng họ không gặp vấn đề gì về reputation. Tuy nhiên nhìn vào tài liệu của Tor Project thì có vẻ Hetzner chiếm khoảng 7% mạng Tor, nên câu chuyện có lẽ không đơn giản đến vậy
    • Trớ trêu thay, tôi đã giải quyết 99% vấn đề bot chỉ bằng cách chặn AWS và Azure. Không có người dùng thật nào bị ảnh hưởng, nên giờ tôi còn đang nghĩ biết đâu có thể bán riêng tính năng chặn này thành dịch vụ
  • Việc chia sẻ trải nghiệm migration như thế này khá hữu ích, tôi rất cảm kích. Tôi nhìn sự so sánh giữa DO và Hetzner như trade-off giữa việc mở DoorDash/UberEats và tự nấu bữa tối. Tỷ lệ chênh lệch chi phí cũng na ná như vậy. Tôi làm việc với cả ba hyperscaler và cả on-prem, nhưng với các việc lặt vặt hay test PoC thì tôi vẫn quay lại console của DigitalOcean. Cái sự tiện lợi kiểu chỉ vài nút bấm là có server hay bucket, có sane default, backup bật bằng một checkbox, rõ ràng rất có giá trị nếu tính cả thời gian

    • Tôi không dám chắc mình hiểu hoàn toàn ý bạn, nhưng tôi thấy console của Hetzner cũng khá giống vậy
    • Có hai điểm trong bài này làm tôi thấy thú vị. Một là chính quy trình chuyển đổi không downtime, và phần đó có thể tham khảo rộng rãi. Hai là quyết định đổi từ cloud instance sang bare metal; trong trường hợp đó, cùng với khoản tiết kiệm chi phí, bạn cũng phải tính luôn cái giá của failover chậm và rủi ro mất backup. Nếu là tôi, tôi sẽ chi thêm khoảng 200 đô để có một hot spare, rồi vài ngày lại đảo vai primary/secondary để xác minh cả hai đều hoạt động tốt. Với chi phí tương đối nhỏ, có thể giảm mạnh rủi ro sự cố nghiêm trọng
    • Điều bạn vừa mô tả thật ra gần như chính là trải nghiệm mà Hetzner Cloud đã cung cấp suốt nhiều năm nay. Hơn nữa họ còn có Hetzner Cloud API, nên có thể dựng toàn bộ bằng IaC mà chẳng cần bấm nút nào cả
    • Với tôi thì cài Coolify lên server Hetzner là đã có trải nghiệm gần như one-click service rồi
    • Đọc tình huống này tôi chỉ nghĩ ngay đến xkcd này
  • Tôi khá tò mò họ backup DB kiểu gì. Có replica hay standby không, hay chỉ backup theo giờ thôi. Với kiểu cấu hình một máy chủ như thế này, nếu gặp lỗi phần cứng như SSD chết thì ứng dụng có thể dừng ngay, và nhất là nếu SSD hỏng thì có khi phải downtime vài giờ hoặc vài ngày trong lúc dựng lại

    • Hetzner thường quảng cáo máy chủ phần cứng với 2x 1TB SSD, và khuyến nghị rất mạnh việc cấu hình SW RAID1 để có 1TB usable; ngay cả trình cài image cũng mặc định thiên về hướng đó. Nếu vài năm sau chiếc SSD đầu tiên chết mà monitoring phát hiện kịp, bạn có thể chuyển sang máy mới, dùng phương án trung gian/replica, hoặc cầm cự trên đĩa còn lại rồi chờ hot-swap. Dĩ nhiên khi chuyển sang máy vật lý thì bạn mất đi một phần dự phòng của cloud, nên phải đưa điều đó vào mô hình rủi ro cùng với khoản tiết kiệm. Và nếu đến cả backup hằng ngày ra remote storage cũng không có thì theo tôi là quá liều. Điều này trong cloud cũng vậy thôi, chỉ khác là cấu hình dễ hơn
    • Có khi downtime lâu như vậy cũng chẳng ai thực sự quan tâm. Ví dụ như app di động của hội HOA chỗ tôi có sập cả tuần thì tôi cũng không bận tâm lắm. Không phải thứ gì cũng cần luôn luôn hoạt động
    • Tôi cũng có cùng lo ngại. Bài viết này cho cảm giác tác giả chủ yếu nhìn vào cắt giảm chi phí quyết liệt mà chưa suy nghĩ đủ. VM trên DigitalOcean có lẽ hỗ trợ live migration và snapshot, còn ở Hetzner thì những thứ đó chỉ có ở gói cloud. Với bare metal của Hetzner, nếu đĩa hay linh kiện chết thì là chết thật; họ có thể thay đĩa nhưng việc phục hồi thì người dùng phải tự làm lại từ đầu. Hetzner cũng nói rất rõ điều này ở nhiều nơi
    • Thứ dễ nhất tôi từng làm là phía MongoDB, vì replication, sharding và failover của nó rất đơn giản. Gần đây với PostgreSQL tôi cũng triển khai pg_auto_failover với 1 monitor, 1 primary và 1 replica; sau khi quen với cách cấu hình và vài cái bẫy thì nó cũng khá dễ. Theo kinh nghiệm của tôi, chuyển đổi không downtime cũng làm được
    • Nếu họ đã quyết định chấp nhận những trade-off đó thì tôi không nghĩ có thể khẳng định là sai. Không phải ứng dụng nào cũng cần sẵn sàng 24/7, và đa số website không bị ảnh hưởng nghiêm trọng nếu downtime vài giờ. Nếu phần tiết kiệm lớn hơn rủi ro thì đó hoàn toàn có thể là một quyết định kinh doanh hợp lý. Điều tôi tò mò hơn là chiến lược backup/phục hồi của họ là gì, và những gì đã thay đổi sau khi chuyển sang Hetzner
  • Ảnh meme trên phần header là do tôi làm. Tôi từng dùng nó trong bài này, nên thấy nó được dùng tới hai lần như vậy cũng vui