1. Tổng quan.
Khi bạn cấu hình Swift Ring Builder bạn thường sẽ gặp các câu lệnh quen thuộc như dưới đây.
swift-ring-builder account.builder create 13 3 1
swift-ring-builder container.builder create 13 3 1
swift-ring-builder object.builder create 13 3 1
Chắc bạn sẽ đặt câu hỏi làm sao tính toán được 3 con số 13 3 1 như 3 câu lệnh trên, con số 13 ở các câu lệnh trên người ta gọi là total partition count, ở phần này chúng ta sẽ tập trung vào con số total partition count này nhé.
2. Khái niệm về con số total Partition Count.
Trong hệ thống lưu trữ Swift, Total Partition Count
là tổng số phân vùng mà Swift sẽ sử dụng để phân tán dữ liệu trên tất cả các ổ đĩa trong hệ thống.
Về dung lượng tối đa cho một phân vùng, Swift không giới hạn cụ thể dung lượng của mỗi phân vùng. Thay vào đó, Swift sẽ cố gắng chia dữ liệu thành các phân vùng nhỏ để phân tán dữ liệu trên các ổ đĩa. Dung lượng thực tế của mỗi phân vùng sẽ phụ thuộc vào dung lượng tổng cộng của dữ liệu mà bạn đang lưu trữ và số lượng phân vùng mà bạn đã chọn.
Nếu bạn muốn ước lượng dung lượng tối đa cho một phân vùng, bạn có thể chia dung lượng tổng cộng mà bạn muốn lưu trữ cho số lượng phân vùng. Tuy nhiên, hãy nhớ rằng Swift sẽ cố gắng cân nhắc dung lượng của từng ổ đĩa, vì vậy dung lượng thực tế của mỗi phân vùng có thể khác nhau.
Số HDD ban đầu: Đây là số lượng ổ đĩa cứng mà bạn có khi bắt đầu thiết lập hệ thống.
HDD mở rộng sau này: Đây là số lượng ổ đĩa cứng mà bạn dự định thêm vào hệ thống trong tương lai để mở rộng dung lượng lưu trữ.
Số partition được lưu trên 1 HDD: Đây là số lượng partition (partition là một đơn vị lưu trữ logic, mỗi partition đại diện cho một phần của không gian lưu trữ trên ổ đĩa và chứa một tập hợp các object lưu trữ) mà mỗi ổ đĩa cứng có thể lưu trữ. Số lượng này phụ thuộc vào dung lượng của ổ đĩa và kích thước mong muốn của mỗi partition.
Cách xác định số partition như sau.
Xác định số lượng partition: Bước đầu tiên là xác định số lượng partition sẽ có trong ring. Ring ở đây là cấu trúc dữ liệu mà OpenStack Swift sử dụng để quản lý và phân phối dữ liệu trên các ổ đĩa.
Số lượng partition tối thiểu trên mỗi ổ đĩa: Khuyến nghị có ít nhất 100 partition trên mỗi ổ đĩa để đảm bảo dữ liệu được phân phối đều trên tất cả các ổ đĩa.
Xác định số lượng partition tối đa: Một điểm khởi đầu tốt có thể là xác định số lượng ổ đĩa tối đa mà cluster sẽ chứa, sau đó nhân với 100 và làm tròn lên đến số mũ gần nhất của 2. Điều này giúp đảm bảo rằng có đủ partition để phân phối dữ liệu khi thêm ổ đĩa vào cluster.
Ví dụ về cách xác định số partition, với khuyến nghị có ít nhất 100 partition trên mỗi ổ đĩa, nếu có 100 HDD và replicas=2 thì số partition được xác định như sau:
Tính số lượng partition cho cụm với số lượng partition tối thiểu trên mỗi ổ đĩa là 100.
Đầu tiên, bạn nhân số lượng partition tối thiểu trên mỗi ổ đĩa (100) với tổng số ổ đĩa (100), sau đó chia cho số lượng replicas (2). Công thức là (100 (partition per HDD) * 100) / 2 = 5000 ~ 8192 (2^13)
. Tuy nhiên, số lượng partition cần phải là một số mũ của 2, vì vậy bạn làm tròn lên đến số mũ gần nhất của 2, là 8192 (2^13). Vì vậy, số 13 chính là số Total Partition Count
được sử dụng để build ring.
Giới hạn kích thước partition.
Có một số chuyên gia đã trải nghiệm cho biết dung lượng lý tưởng cho mỗi phân vùng thường từ 10G-20G và cứ thế nhân lên.
Như vậy với ổ đĩa 10TB, dung lượng thực tế có thể sử dụng khoảng 8TB (để dự phòng cho việc mở rộng và quản lý). Nếu tính 20GB cho mỗi partition, thì có khoảng 400 – 800 partition trên mỗi ổ đĩa 10TB.
Công thức để tính số lượng partition, bạn chia dung lượng tổng cộng của ổ đĩa (đã chuyển đổi sang GB) cho kích thước của mỗi partition. Trong trường hợp này, bạn có 8TB (tương đương 8192GB) và mỗi partition có kích thước 10GB.
total_disk_space_in_gb = 8 * 1024 # Convert TB to GB
partition_size_in_gb = 10
number_of_partitions = total_disk_space_in_gb / partition_size_in_gb
Thực hiện phép chia, ta có:
number_of_partitions = 8192 / 10
Kết quả là 819.2. Tuy nhiên, bạn không thể có một phần của một partition, vì vậy bạn sẽ làm tròn xuống để có số lượng partition nguyên. Vì vậy, số lượng partition bạn có thể có trên ổ đĩa này là 819.
Sau khi tính toán chúng ta thay thế giá trị vào swift-ring-builder object.builder create 13 2 1
, ở số 13 đầu tiên (tương ứng với 2^13 = 8192 partition). Trong đó, 2
là số lượng replicas (bản sao của mỗi đối tượng) và 1
là thời gian (tính bằng giờ) giữa các lần rebalance.
Ví dụ tiếp theo là tính số lượng partition (phân vùng) có trong một ổ đĩa, trong trường hợp có một ổ đĩa 14TB dung lượng thực tế của ổ đĩa là 12.7TB và mỗi partition có kích thước là 10GB, công thức sẽ như sau:
total_disk_space_in_gb = 12.7 * 1024 # Convert TB to GB
partition_size_in_gb = 10
number_of_partitions = total_disk_space_in_gb / partition_size_in_gb
Thực hiện phép chia, ta có:
number_of_partitions = 13056 / 10
Kết quả là 1305.6. Tuy nhiên, bạn không thể có một phần của một partition, vì vậy bạn sẽ làm tròn xuống để có số lượng partition nguyên. Vì vậy, số lượng partition bạn có thể có trên ổ đĩa này là 1305
3. Sử dụng kết quả đã tính được cho Swift Ring Builder.
Trong câu lệnh swift-ring-builder <ring_type>.builder create <partition> <replicas> <
, số min part hours
>partition
đại diện cho số mũ của số lượng partition trong ring.
Nếu bạn có 100 HDD và replicas=2, bạn muốn mỗi ổ đĩa cứng chứa ít nhất 100 partition và mỗi đối tượng dữ liệu được lưu trữ trên 2 ổ đĩa khác nhau. Một cách để làm điều này là nhân số lượng ổ đĩa tối đa mà hệ thống này có thể chứa (trong trường hợp này là 100) với số lượng partition tối thiểu trên mỗi ổ đĩa (100), sau đó làm tròn lên đến số mũ gần nhất của 2.
Công thức là (100 (partition per HDD) * 100) / 2 = 5000 ~ 8192 (2^13). Tuy nhiên, số lượng partition cần phải là một số mũ của 2, vì vậy bạn làm tròn lên đến số mũ gần nhất của 2, là 8192 (2^13).
Trong trường hợp này, số 5000 không phải là một số mũ của 2. Trong hệ thống lưu trữ Swift, số lượng phân vùng (Total Partition Count
) cần phải là một số mũ của 2 để đảm bảo hiệu suất và khả năng mở rộng tốt nhất.
Khi bạn nhân số lượng partition trên mỗi ổ đĩa (100) với số lượng ổ đĩa tối đa (100), bạn nhận được 10000. Tuy nhiên, vì bạn có 2 replicas, bạn chia số này cho 2 để nhận được 5000.
Số 5000 không phải là một số mũ của 2, vì vậy bạn cần làm tròn lên đến số mũ gần nhất của 2. Số mũ gần nhất lớn hơn 5000 là 8192, vì 2^13 = 8192.
Đây là lý do vì sao bạn chọn 8192 làm Total Partition Count
thay vì 5000.
Vì vậy, bạn sẽ sử dụng 13 làm số partition
trong câu lệnh swift-ring-builder <rung_type>.builder create
, như sau:
swift-ring-builder <ring_type>.builder create 13 2 1
Mỗi lệnh tạo ra một ring builder type cho một loại dữ liệu khác nhau: account
, container
và object
.
Ví dụ với ring builder type là account thì câu lệnh sẽ là:
swift-ring-builder account.builder create 13 2 1
Các con số 13, 3, 1 trong các lệnh này có ý nghĩa như sau:
13
: Đây làpart power
, là số mũ của 2 mà Swift sẽ sử dụng để chia dữ liệu thành các phần nhỏ để phân tán trên các ổ đĩa. Trong trường hợp này,part power
là 13, nghĩa là Swift sẽ tạo ra2^13
= 8192 phân vùng.2
: Đây là số lượng bản sao (replicas) của dữ liệu mà Swift sẽ lưu trữ. Trong trường hợp này, mỗi phần dữ liệu sẽ được lưu trữ 2 lần trên hệ thống để đảm bảo tính sẵn sàng và độ bền của dữ liệu.1
: Đây làmin part hours
, là số giờ tối thiểu mà Swift sẽ chờ trước khi di chuyển một phân vùng đã được di chuyển. Điều này giúp hạn chế việc di chuyển dữ liệu liên tục và giúp hệ thống ổn định hơn. Trong trường hợp này,min part hours
là 1, nghĩa là Swift sẽ chờ ít nhất 1 giờ trước khi di chuyển một phân vùng đã được di chuyển.
Tóm tắt lại một số giá trị bạn nên biết.
Bạn cần xem xét số lượng ổ đĩa tối đa (Max Drives
) và số lượng ổ đĩa tối thiểu (Min Drives
) mà bạn muốn hỗ trợ trong hệ thống của mình.
Recommended Part Power
: Đây là giá trị mà Swift sẽ sử dụng để chia dữ liệu thành các phần nhỏ để phân tán trên các ổ đĩa. Giá trị này được tính toán dựa trên số lượng ổ đĩa tối đa (Max Drives
) và số lượng ổ đĩa tối thiểu (Min Drives
) mà bạn muốn hỗ trợ. Trong trường hợp của bạn, giá trị này là 13
, vì 2^13
(8192) là số lượng phân vùng tối thiểu mà bạn cần để hỗ trợ từ 10 đến 100 ổ đĩa.
Total Partition Count
: Đây là tổng số lượng phân vùng mà Swift sẽ tạo ra. Giá trị này bằng 2^Part Power
, trong trường hợp này là 2^13
= 8192.
Max per drive
: Đây là số lượng phân vùng tối đa mà mỗi ổ đĩa sẽ chứa. Giá trị này được tính bằng cách chia Total Partition Count
cho Min Drives
, trong trường hợp này là 8192 / 10
= 819.2. Swift làm tròn giá trị này xuống số nguyên gần nhất, do đó giá trị này là 819
.
Min per drive
: Đây là số lượng phân vùng tối thiểu mà mỗi ổ đĩa sẽ chứa. Giá trị này được tính bằng cách chia Total Partition Count
cho Max Drives
, trong trường hợp này là 8192 / 100
= 81.92. Swift làm tròn giá trị này lên số nguyên gần nhất, do đó giá trị này là 82
.
4. Sử dụng Python để tính toán số lượng partition.
Đoạn code Python dưới đây được sử dụng để tạo ra một lệnh swift-ring-builder
trong OpenStack Swift dựa trên các thông số người dùng nhập vào.
Bạn hãy nhập vào số lượng ổ đĩa tối đa, số lượng phân vùng trên mỗi thiết bị, số lượng bản sao và loại builder. Mã sau đó tính toán số lượng phân vùng tối đa có thể có dựa trên các thông số này và tạo ra lệnh swift-ring-builder
tương ứng.
import math, os
os.system('clear')
# Define your parameters
# Ask the user for input
print("Enter the following values to calculate the number of partitions:\n")
max_drives = int(input("1. Enter the maximum number of drives: "))
partition_per_device = int(input("2. Enter the number of partitions per device: "))
replica_count = int(input("3. Enter the replica count: "))
builder_type = input("4. Enter the builder type: \n1. Account\n2. Container\n3. Object\n")
if builder_type == "1":
builder_type = "account"
elif builder_type == "2":
builder_type = "container"
elif builder_type == "3":
builder_type = "object"
# Print the entered values
print("Replica Count: ", replica_count)
print("Partitions Per Device: ", partition_per_device)
print("Max Drives: ", max_drives)
# Calculate the number of partitions
max_drives_part_power = int((max_drives * partition_per_device) / replica_count)
print("Max Drives Part Power: ", max_drives_part_power)
# Initialize count and max_drives_part_power_result
count = 1
max_drives_part_power_result = 2 ** count
# Increase count until max_drives_part_power_result is greater than max_drives_part_power
while max_drives_part_power_result <= max_drives_part_power:
count += 1
max_drives_part_power_result = 2 ** count
print("Adjusted Count: ", count)
print("Max Drives Part Power Result: ", max_drives_part_power_result)
print(f"Account Builder: swift-ring-builder {builder_type}.builder create {count} {replica_count} 1", )
# https://rackerlabs.github.io/swift-ppc/
Đoạn Python này thực hiện các công việc sau:
- Yêu cầu người dùng nhập vào các giá trị cần thiết để tính toán số lượng phân vùng: số lượng ổ đĩa tối đa (
max_drives
), số lượng phân vùng trên mỗi thiết bị (partition_per_device
), số lượng bản sao (replica_count
) và loại builder (builder_type
). - Dựa trên giá trị nhập vào của
builder_type
, mã sẽ xác định loại builder là “account”, “container”, hoặc “object”. - Tính toán
max_drives_part_power
bằng cách nhânmax_drives
vớipartition_per_device
và chia choreplica_count
. - Khởi tạo
count
vàmax_drives_part_power_result
với giá trị ban đầu là 1. - Tăng
count
lên cho đến khimax_drives_part_power_result
(là kết quả của phép toán 2 mũcount
) lớn hơnmax_drives_part_power
. - In ra
count
đã điều chỉnh vàmax_drives_part_power_result
. - Cuối cùng in ra lệnh
swift-ring-builder
với các tham số tương ứng. Lệnh này được sử dụng để tạo ra một builder ring trong OpenStack Swift, một hệ thống lưu trữ đối tượng phân tán. Tham sốcount
đại diện cho số lượng phân vùng,replica_count
là số lượng bản sao và1
là số lượng giờ giữa các bản sao.