Làm chủ LVM trên Linux: Mở rộng dung lượng Zero-Downtime, Snapshot và Thin Provisioning

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

So sánh các kiến trúc lưu trữ: Phân vùng truyền thống vs. LVM tiêu chuẩn vs. Thin Pool

Sáu tháng trước, cụm cơ sở dữ liệu của chúng tôi gặp nút thắt nghiêm trọng. Chúng tôi vận hành các bảng phân vùng GPT truyền thống trên bốn node PostgreSQL chính, mỗi node sử dụng một ổ NVMe 500 GB.

Bất cứ khi nào /var/lib/postgresql chạm ngưỡng trên 90% dung lượng đĩa, việc thay đổi kích thước trở thành cơn ác mộng: phải lên lịch bảo trì lúc 11 giờ đêm, ngắt node khỏi bộ cân bằng tải, unmount volume và chạy parted trong sự lo thỏm rằng header của filesystem không bị hỏng giữa chừng. Chúng tôi mất tới hai giờ làm việc của kỹ sư mỗi tuần chỉ để xử lý việc tăng dung lượng đĩa thủ công.

Việc chuyển đổi sang Logical Volume Manager (LVM) đã giải quyết triệt để vấn đề này. Khi thiết kế lưu trữ block storage trên Linux hiện nay, bạn thường có ba lựa chọn chính:

  • Phân vùng cố định truyền thống (MBR/GPT): Ranh giới các block bị khóa chặt vào các sector liền kề trên một ổ đĩa đơn. Mở rộng phân vùng đòi hỏi dung lượng trống liền kề, chỉnh sửa bảng phân vùng thủ công và phải unmount offline.
  • LVM tiêu chuẩn (Thick Provisioning): Các ổ đĩa thô được chuyển thành Physical Volume (PV), gom vào các Volume Group (VG), rồi chia thành các Logical Volume (LV). Dung lượng khối được cấp phát trước ngay từ đầu. Dù bạn có thể mở rộng LV online, nhưng không thể dễ dàng chia sẻ dung lượng nhàn rỗi giữa các volume hoặc cấp phát vượt mức (overcommit).
  • LVM cấp phát động (LVM Thin Pools): Các volume sẽ lấy các khối dung lượng từ 64 KB đến 1 MB theo nhu cầu thực tế từ một pool vật lý dùng chung. Bạn có thể cấp phát 2 TB dung lượng ảo trên một pool vật lý chỉ 500 GB, đồng thời chụp snapshot tại từng thời điểm mà ban đầu gần như không tốn dung lượng block.

Đối với các máy chủ chạy container, môi trường staging linh hoạt và các cụm cơ sở dữ liệu cần sao lưu tức thời, LVM thin provisioning đem lại sự linh hoạt vận hành vượt trội.

Ghi chép thực tế: 6 tháng vận hành LVM trên Production

Quản lý 18 node ứng dụng và cơ sở dữ liệu trên LVM đã cho thấy rõ cả những điểm mạnh nhất lẫn những thách thức lớn nhất của nó.

Những điểm vượt trội

  • Mở rộng Online trực tiếp: Với các filesystem như ext4 và XFS, việc nới rộng một logical volume tiêu chuẩn hay thin volume đều diễn ra tức thì. Các giao dịch PostgreSQL đang thực thi và dữ liệu tải lên của người dùng vẫn tiếp tục bình thường mà không bị gián đoạn. Người dùng hoàn toàn không nhận thấy bất kỳ sự thay đổi nào.
  • Atomic Snapshot dưới một giây: Thin snapshot hoạt động dựa trên các con trỏ metadata copy-on-write (CoW). Đóng băng một volume cơ sở dữ liệu dung lượng 120 GB đang hoạt động ngay trước đợt migrate schema lớn chỉ mất khoảng 15 mili giây, nhanh hơn rất nhiều so với thời gian 8 đến 12 phút nếu sao chép file thông thường.
  • Không lãng phí dung lượng đĩa: Một microservice ở môi trường staging được cấp 50 GB thường chỉ dùng thực tế khoảng 4 GB. Thin pool chỉ ghi dữ liệu vào các sector khi có dữ liệu thật phát sinh, giúp tiết kiệm hơn 1.2 TB dung lượng chưa cấp phát trên toàn bộ hệ thống máy chủ của chúng tôi.
  • Mở rộng lưu trữ liền mạch: Khi sắp hết dung lượng lưu trữ, bạn chỉ cần gắn thêm một ổ NVMe 1 TB vào máy chủ, chạy lệnh pvcreate và gộp nó vào Volume Group hiện có mà không cần format lại các phân vùng đang chạy.

Những đánh đổi cần lưu ý

  • Cạm bẫy cạn kiệt Thin Pool: Overprovisioning cho phép bạn cam kết 1 TB dung lượng ảo trên một pool vật lý chỉ có 400 GB. Tuy nhiên, nếu lượng dữ liệu tăng vọt khiến thin pool chạm mức 100%, kernel sẽ lập tức dừng mọi tác vụ ghi. Hiện tượng nghẽn ghi không được xử lý kịp thời có nguy cơ làm hỏng filesystem nghiêm trọng.
  • Phục hồi Metadata phức tạp: Thin pool phụ thuộc vào cặp sub-volume nội bộ chứa data và metadata. Việc cứu metadata bị hỏng bằng thin_check và thin_repair đòi hỏi kỹ năng xử lý sự cố lưu trữ chuyên sâu hơn nhiều so với việc sửa một phân vùng hỏng trên /dev/sdb1.
  • Độ trễ trong lần ghi đầu tiên: Do thin pool phải cấp phát các chunk động khi dữ liệu bắt đầu ghi vào các sector mới, thông lượng ghi ngẫu nhiên (random-write) ban đầu có thể giảm từ 3% đến 7% so với các block đã được cấp phát trước trên thick provisioning.

Cấu hình Production đã qua thử lửa

Sau sự cố suýt gây gián đoạn hệ thống do log tăng đột biến làm nghẽn một pool không được theo dõi, chúng tôi đã chuẩn hóa quy chuẩn lưu trữ Linux dựa trên các nguyên tắc sau:

  • Luôn giữ 20% dung lượng trống trong mỗi Volume Group: Tuyệt đối không cấp phát 100% dung lượng extent của VG ngay từ đầu. Dự phòng từ 50 GB đến 100 GB cho phép bạn mở rộng volume bị đầy chỉ trong vài giây hoặc tạo bản clone tạm thời khi cần ứng phó sự cố.
  • Chọn ext4 khi cần khả năng thu nhỏ (shrink): Mặc dù XFS xử lý tải đồng thời lớn rất tốt, nhưng nó chỉ có thể mở rộng chứ không thể thu nhỏ. Nếu khối lượng công việc của bạn có các đợt tăng đột biến tạm thời và cần thu hồi lại không gian đĩa sau đó, ext4 là lựa chọn lý tưởng vì hỗ trợ cả mở rộng online lẫn thu nhỏ offline.
  • Kích hoạt tự động mở rộng Pool bằng dmeventd: Đừng bao giờ dựa vào việc kiểm tra thủ công để quản lý dung lượng pool. Hãy bật tính năng giám sát dmeventd trong /etc/lvm/lvm.conf. Thiết lập thin_pool_autoextend_threshold = 75 và thin_pool_autoextend_percent = 20 để hệ thống tự động nới rộng pool trước khi tác vụ ghi bị khóa lại.
  • Tách biệt phân vùng gốc của hệ điều hành khỏi các Dynamic Pool: Giữ filesystem gốc (/) trên một LV thick-provisioned truyền thống. Cô lập dữ liệu ứng dụng, Docker volume và thư mục cơ sở dữ liệu vào các thin pool riêng biệt để tình trạng tràn log không làm sập các tiện ích cốt lõi của hệ điều hành.

Trên các máy chủ cơ sở dữ liệu Ubuntu 22.04 LTS của chúng tôi (16 vCPU, 64 GB RAM, 2 ổ NVMe chạy RAID 1), cấu hình này đã giảm 40% chi phí vận hành cấp phát đĩa và biến các đợt bảo trì kéo dài hàng giờ thành các thao tác điều chỉnh 5 phút không hề có downtime.

Hướng dẫn triển khai từng bước

Thực hiện chính xác theo trình tự sau để đăng ký các block device vật lý thô, thiết lập thin pool, mở rộng filesystem online và quản lý atomic snapshot.

Bước 1: Khởi tạo Physical Volume (PV) và Volume Group (VG)

Kiểm tra ổ đĩa lưu trữ phụ (ví dụ: /dev/sdb) bằng lệnh lsblk. Chuyển thiết bị thô này thành một LVM Physical Volume, sau đó gán nó vào một Volume Group mới có tên là vg_production:

# Khởi tạo thiết bị ổ đĩa thô
sudo pvcreate /dev/sdb

# Tạo Volume Group với kích thước physical extent mặc định 4MB
sudo vgcreate vg_production /dev/sdb

# Kiểm tra dung lượng tổng và các extent còn trống
sudo vgs

Bước 2: Mở rộng Logical Volume đang hoạt động với Zero Downtime

Khi một volume hiện có sắp hết dung lượng, bạn không cần dừng ứng dụng hay unmount thư mục. Tùy chọn -r (hoặc --resizefs) sẽ chỉ định LVM nới rộng ranh giới logical đồng thời thay đổi kích thước filesystem bên dưới cùng một lúc:

# Thêm 20GB vào volume đang hoạt động và resize filesystem trong cùng một bước
sudo lvextend -r -L +20G /dev/vg_production/lv_appdata

# Hoặc cấp phát 80% dung lượng extent còn trống trong Volume Group
sudo lvextend -r -l +80%FREE /dev/vg_production/lv_appdata

Kiểm tra lại dung lượng volume sau khi nâng cấp bằng lệnh df -h /var/www. Dung lượng mới sẽ xuất hiện ngay lập tức mà không làm rớt bất kỳ kết nối nào.

Bước 3: Thiết lập Thin Pool và Mount Volume cấp phát theo nhu cầu

Để triển khai thin provisioning, hãy tạo một thin pool dùng chung bên trong Volume Group của bạn. Pool này đóng vai trò là kho dự trữ block vật lý chung cho nhiều ổ đĩa ảo.

# Cấp phát thin pool vật lý 80GB có tên 'pool_thin' trong 'vg_production'
sudo lvcreate -L 80G -T vg_production/pool_thin

# Khởi tạo một volume ảo 200GB trên thin pool 80GB đó
sudo lvcreate -V 200G -T vg_production/pool_thin -n lv_webdata

# Định dạng volume ảo với hệ thống tập tin ext4
sudo mkfs.ext4 /dev/vg_production/lv_webdata

# Mount phân vùng vào thư mục ứng dụng của bạn
sudo mkdir -p /var/www/uploads
sudo mount /dev/vg_production/lv_webdata /var/www/uploads

Hệ điều hành sẽ ghi nhận một phân vùng dung lượng 200 GB, nhưng volume này thực tế chiếm 0 byte dung lượng physical pool cho đến khi ứng dụng của bạn bắt đầu ghi file.

Bước 4: Chụp Snapshot tức thì để triển khai an toàn

Trước khi phát hành một bản cập nhật phần mềm lớn hoặc thực hiện migration cơ sở dữ liệu chưa kiểm thử, hãy chụp ảnh snapshot tại thời điểm đó. Nhờ cơ chế copy-on-write theo dõi thay đổi thông qua con trỏ, việc tạo thin snapshot chỉ mất vài mili giây mà không chiếm dụng dung lượng đĩa dự phòng:

# Chụp nhanh thin snapshot tức thì của volume đang hoạt động
sudo lvcreate -s --name snap_webdata_pre_upgrade /dev/vg_production/lv_webdata

# Kiểm tra dung lượng cấp phát và độ lệch dữ liệu của snapshot
sudo lvs vg_production

Khi quá trình triển khai đã vượt qua các bài kiểm tra xác thực (smoke test), hãy xóa snapshot để giải phóng các diff block đang được theo dõi:

# Xóa snapshot sau khi xác minh triển khai thành công
sudo lvremove -y /dev/vg_production/snap_webdata_pre_upgrade

Nếu migration thất bại và làm hỏng dữ liệu trong bảng, bạn có thể rollback về trạng thái trước khi triển khai. Hãy unmount volume, thực hiện thao tác merge và mount lại:

# Unmount volume để tránh xung đột file descriptor đang mở
sudo umount /var/www/uploads

# Khôi phục volume về chính xác trạng thái tại thời điểm snapshot
sudo lvconvert --merge /dev/vg_production/snap_webdata_pre_upgrade

# Mount lại dữ liệu sạch ban đầu
sudo mount /dev/vg_production/lv_webdata /var/www/uploads

Giám sát trạng thái hoạt động của Thin Pool

Hãy theo dõi sát sao dung lượng thin pool của bạn. Lệnh sudo lvs sẽ hiển thị mức tiêu thụ hiện tại trong cột Data%. Đưa số liệu này vào Prometheus node_exporter hoặc thiết lập webhook cảnh báo để thông báo cho đội ngũ kỹ sư khi chạm ngưỡng 75% dung lượng. Việc này tạo khoảng đệm an toàn giúp bạn kịp thời gắn thêm ổ NVMe và mở rộng pool trước khi các tác vụ ghi bị tắc nghẽn.

Share: