paint-brush
Tại sao bạn không nên đặt hệ thống tập tin lên trên kho lưu trữ đối tượngtừ tác giả@minio
6,908 lượt đọc
6,908 lượt đọc

Tại sao bạn không nên đặt hệ thống tập tin lên trên kho lưu trữ đối tượng

từ tác giả MinIO7m2023/11/14
Read on Terminal Reader

dài quá đọc không nổi

Khi các tổ chức lớn cần lưu trữ và truy cập vào đại dương dữ liệu để học sâu, AI và các trường hợp sử dụng chuyên sâu về dữ liệu khác, POSIX không có khả năng hoặc khả năng mở rộng để đáp ứng những nhu cầu này.
featured image - Tại sao bạn không nên đặt hệ thống tập tin lên trên kho lưu trữ đối tượng
MinIO HackerNoon profile picture
0-item
1-item

Khi mua bộ nhớ, người ta thường chú trọng đến phương tiện truyền thông, nhưng điều quan trọng hơn nữa là phải xem xét các phương pháp truy cập. Bạn sẽ cần phải tính đến các giao thức lưu trữ khi thiết kế và mua sắm cơ sở hạ tầng, đặc biệt là khi bạn để lại bộ nhớ cũ để di chuyển sang bộ nhớ đối tượng gốc trên nền tảng đám mây. Tuy nhiên, bộ lưu trữ đối tượng dựa vào API S3 để liên lạc, trong khi khối lượng công việc cũ dựa vào POSIX, Giao diện hệ điều hành di động cung cấp một bộ tiêu chuẩn được phát triển vào những năm 1980 để cho phép các ứng dụng có thể di động giữa các hệ điều hành Unix. Rất có thể hầu hết các doanh nghiệp đã có ứng dụng được phát triển để chạy trên POSIX trong nhiều thập kỷ. Rất có thể các kỹ sư đã nhận thức được hiệu suất kém của POSIX.


Điều đó có nghĩa là, khi bạn có các hệ thống cũ chỉ có thể nhập dữ liệu ở một định dạng nhất định hoặc từ một nguồn nhất định, các tùy chọn của bạn có thể bị hạn chế và bạn có thể không có lựa chọn nào khác ngoài việc triển khai giao thức lỗi thời hoặc viết lại mã của mình. Ví dụ: nếu bạn chỉ có thể nhập từ đĩa cục bộ có hệ thống tệp chứ không phải bằng API RESTful được truy cập qua mạng thì trước tiên bạn phải cung cấp dữ liệu đó trên đĩa trước khi ứng dụng của bạn có thể sử dụng dữ liệu đó. Tuy nhiên, việc sử dụng kho lưu trữ đối tượng làm hệ thống tệp có một số tác động tiêu cực nghiêm trọng khi nói đến hiệu suất, khả năng tương thích, tính toàn vẹn dữ liệu và bảo mật.


Hãy chứng minh điều này bằng một số thử nghiệm thực tế bằng cách sử dụng một tiện ích nhỏ có tên s3fs-fuse . Tiện ích này cho phép bạn gắn thùng S3 dưới dạng hệ thống tệp cục bộ. Nó là viết tắt của Hệ thống tệp S3 (Dịch vụ lưu trữ đơn giản) - FUSE (Hệ thống tệp trong không gian người dùng). Đây là một dự án nguồn mở tận dụng giao diện FUSE (Hệ thống tệp trong không gian người dùng) để hiển thị giao diện giống hệ thống tệp cho S3.


Sau khi gắn một vùng lưu trữ S3 bằng cách sử dụng s3fs-fuse , bạn có thể tương tác với vùng lưu trữ đó như thể đó là một hệ thống tệp cục bộ. Điều này có nghĩa là bạn có thể sử dụng các thao tác tệp thông thường (như đọc, ghi, di chuyển, v.v.) trên các tệp trong bộ chứa của mình. Điều này nghe có vẻ tiện lợi một cách đáng kinh ngạc và chúng ta có thể tranh luận rằng nó giúp đơn giản hóa việc phát triển ứng dụng. Nhưng hệ thống tệp và lưu trữ đối tượng vốn có những khác biệt cơ bản sẽ ảnh hưởng đến nhóm s3 được gắn dưới dạng hệ thống tệp.


Chúng ta hãy dành chút thời gian quay lại tiện ích s3fs-fuse để thảo luận về lý do thực sự tại sao việc coi lưu trữ đối tượng như một hệ thống tệp lại không tối ưu. Vấn đề lớn hơn nhiều so với s3fs-fuse và bao gồm các tiện ích khác như Mountpoint dựa trên Rust cho Amazon S3 , một ứng dụng khách tệp dịch các lệnh gọi API hệ thống tệp cục bộ sang các lệnh gọi API đối tượng S3. Lý do đầu tiên là tất cả các tiện ích này đều dựa vào POSIX để vận hành hệ thống tệp. POSIX không hiệu quả và nó không bao giờ được thiết kế để làm việc với các tệp rất lớn qua mạng.


Tốc độ của các hệ thống dựa trên POSIX giảm khi nhu cầu, đặc biệt là nhu cầu đồng thời, tăng lên. Khi các tổ chức lớn cần lưu trữ và truy cập vào đại dương dữ liệu để học sâu, AI và các trường hợp sử dụng chuyên sâu về dữ liệu khác, POSIX không có khả năng hoặc khả năng mở rộng để đáp ứng những nhu cầu này. Mặc dù các mảng toàn Flash đã giữ POSIX trong trò chơi, nhưng khả năng mở rộng và API RESTful (dấu hiệu nổi bật của đám mây) giống như kryptonite.


Do đó, việc chạy POSIX trên kho đối tượng là chưa tối ưu. Chúng ta hãy xem xét một số lý do tại sao:


  1. Hiệu suất: Giao diện POSIX FS vốn tập trung vào IOPS. Chúng rất hay nói, đắt tiền và khó mở rộng quy mô. API RESTful S3 giải quyết vấn đề này bằng cách chuyển IOPS thành vấn đề về thông lượng. Thông lượng dễ dàng hơn và rẻ hơn để mở rộng quy mô. Đây là lý do tại sao việc lưu trữ đối tượng có hiệu suất cao ở quy mô lớn. Việc phân lớp POSIX trên S3 sẽ không mở rộng quy mô vì POSIX quá phức tạp để có thể thực hiện qua giao diện HTTP RESTful.


  2. Ngữ nghĩa: Bởi vì các hoạt động của đối tượng là nguyên tử và bất biến nên không có cách nào để đảm bảo tính chính xác nhất quán. Điều này có nghĩa là bạn có thể mất dữ liệu không được cam kết trong trường hợp xảy ra sự cố hoặc gặp sự cố hỏng hóc trong trường hợp gắn kết được chia sẻ.


  3. Tính toàn vẹn dữ liệu : Việc ghi hoặc bất kỳ đột biến nào vào tệp sẽ không xuất hiện trong không gian tên cho đến khi nó được cam kết. Điều này có nghĩa là quyền truy cập đồng thời trên các ngàm được chia sẻ sẽ không thấy các sửa đổi. Nó không hữu ích cho việc truy cập chia sẻ.


  4. Kiểm soát truy cập: Các quyền POSIX và ACL còn sơ khai và không tương thích với cách xử lý các chính sách quản lý quyền truy cập và danh tính của API S3. Không thể triển khai quản lý truy cập POSIX một cách an toàn trên các API S3 hàng đầu.


POSIX cũng thiếu hầu hết chức năng mà các nhà phát triển yêu thích ở S3, chẳng hạn như mã hóa cấp đối tượng, lập phiên bản, tính bất biến – những chức năng này đơn giản là không có chức năng tương đương trong thế giới POSIX và không có gì có thể dịch chúng.

Điểm đau POSIX

Những ví dụ này minh họa vấn đề và ý nghĩa của nó. Để bắt đầu, chúng tôi sẽ sử dụng tệp CSV này có dung lượng khoảng 10 GB và có 112 hàng.


Lưu ý: Chúng tôi sẽ cho rằng s3fs-fuse đã được cài đặt và bạn đã gắn một trong các nhóm từ bộ lưu trữ đối tượng vào hệ thống tệp của mình. Nếu không, hãy làm theo hướng dẫn tại đây .


Trong các ví dụ này, chúng tôi sẽ giả sử tên nhóm là test-bucket và tên tệp là taxi-data.csv nằm trong thư mục /home/user/ và s3fs-fuse bucket được gắn tại /home/user/test-bucket/

Sao chép thao tác

Trước tiên, chúng tôi sẽ thử điều gì đó đơn giản và thử sao chép tệp CSV vào nhóm thử nghiệm của chúng tôi bằng cách sử dụng lệnh mc và ghi lại thời gian thực hiện

time mc cp /home/user/taxi-data.csv minio/test-bucket/taxi-data.csv


Việc này sẽ không mất nhiều thời gian và tệp sẽ được sao chép vào bộ chứa của chúng tôi. Bây giờ hãy thử làm tương tự với s3fs-fuse

time cp /home/user/taxi-data.csv /home/user/test-bucket/taxi-data.csv


Thời gian cần thiết trong quá trình thử nghiệm


 real 1m36.056s user 0m14.507s sys 0m31.891s


Trong trường hợp của tôi, tôi chỉ có thể sao chép một phần tệp vào nhóm và thao tác không thành công với lỗi sau


 cp: error writing '/home/user/test-bucket/taxi-data.csv': Input/output error cp: failed to close '/home/user/test-bucket/taxi-data.csv': Input/output error


Sau nhiều lần thử đã thành công


 real 5m3.661s user 0m0.053s sys 2m35.234s


Như bạn có thể thấy, do số lượng lệnh gọi API mà tiện ích cần thực hiện và chi phí chung của các hoạt động, tiện ích trở nên không ổn định và hầu hết các hoạt động thậm chí không kết thúc.

Ví dụ về gấu trúc

Chúng tôi đã cho bạn xem một ví dụ cp đơn giản, có thể thuyết phục hoặc không thuyết phục, bởi vì hãy đối mặt với sự thật, bạn có thể nghĩ rằng time cp khá thô sơ.


Vì vậy, đối với những người cần thêm bằng chứng thực nghiệm, hãy viết một đoạn mã Python để kiểm tra điều này. Chúng ta sẽ làm một ví dụ Pandas đơn giản với cả gói s3fs-fuse và gói python s3fs và xem tác động hiệu suất


 import timeit import os import fsspec import s3fs import pandas as pd # Write a dummy CSV file to test-bucket df = pd.DataFrame({"column1": ["new_value1"], "column2": ["new_value2"]}) df.to_csv("s3://test-bucket/data/test-data.csv", index=False) def process_s3(): # add fsspec for pandas to use `s3://` path style and access S3 buckets directly fsspec.config.conf = { "s3": { "key": os.getenv("AWS_ACCESS_KEY_ID", "minioadmin"), "secret": os.getenv("AWS_SECRET_ACCESS_KEY", "minioadmin"), "client_kwargs": { "endpoint_url": os.getenv("S3_ENDPOINT", "https://play.min.io") } } } s3 = s3fs.S3FileSystem() for i in range(100): # Read the existing data print(i) df = pd.read_csv('s3://test-bucket/data/test-data.csv') # Append a new row new_df = pd.concat([df, pd.DataFrame([{"column1": f"value{i}", "column2": f"value{i}"}])], ignore_index=True) # Write the data back to the file new_df.to_csv('s3://test-bucket/data/test-data.csv', index=False) execution_time = timeit.timeit(process_s3, number=1) print(f"Execution time: {execution_time:.2f} seconds")


Thời gian thực hiện trong quá trình thử nghiệm

 Execution time: 8.54 seconds


Bây giờ hãy thử tương tự với s3fs-fuse


 import timeit import pandas as pd # Write a dummy CSV file to test-bucket df = pd.DataFrame({"column1": ["new_value1"], "column2": ["new_value2"]}) df.to_csv("s3://test-bucket/data/test-data.csv", index=False) def process_s3fs(): for i in range(100): # Read the existing data print(i) df = pd.read_csv('/home/user/test-bucket/data/test-data.csv') # Append a new row new_df = pd.concat([df, pd.DataFrame([{"column1": f"value{i}", "column2": f"value{i}"}])], ignore_index=True) # Write the data back to the file new_df.to_csv('/home/user/test-bucket/data/test-data.csv', index=False) execution_time = timeit.timeit(process_s3fs, number=1) print(f"Execution time: {execution_time:.2f} seconds")



Thời gian thực hiện trong quá trình thử nghiệm

 Execution time: 9.59 seconds


Những ví dụ này thể hiện khả năng đọc và ghi liên tục vào tệp S3. Hãy tưởng tượng điều này được thực hiện đồng thời bởi nhiều khách hàng – độ trễ tăng lên đáng kể.

Loại bỏ chi phí chung!

Như bạn có thể thấy, sự khác biệt giữa việc sử dụng bản dịch POSIX để coi các đối tượng là tệp và sử dụng API trực tiếp để làm việc với các đối tượng là ngày và đêm. Đơn giản là không có sự so sánh nào khi nói đến bảo mật, hiệu suất, tính toàn vẹn dữ liệu và khả năng tương thích. MinIO có SDK để tích hợp với hầu hết mọi ngôn ngữ lập trình phổ biến và có thể chạy trên hầu hết mọi nền tảng như Kubernetes, bare metal Linux, bộ chứa Docker – và nhiều nền tảng khác.


MinIO bảo mật các đối tượng bằng mã hóa ở trạng thái nghỉ và trong quá trình truyền, kết hợp với PBAC để điều chỉnh quyền truy cập và xóa mã hóa để bảo vệ tính toàn vẹn của dữ liệu. Bạn sẽ đạt được hiệu suất tốt nhất có thể, bất kể bạn chạy MinIO ở đâu, vì nó tận dụng phần cứng cơ bản (xem Chọn phần cứng tốt nhất để triển khai MinIO của bạn ) để mang lại hiệu suất cao nhất có thể. Chúng tôi đã đo điểm chuẩn của MinIO ở mức 325 GiB/s (349 GB/s) trên GET và 165 GiB/s (177 GB/s) trên PUT chỉ với 32 nút SSD NVMe có sẵn.


Đơn giản là không cần tiện ích hệ thống tập tin ở giữa MinIO và ứng dụng của bạn! Mọi lợi thế mà ứng dụng cũ có thể nhận được sẽ bị bù đắp bởi tổn thất của POSIX.


Nếu bạn có bất kỳ câu hỏi nào về việc sử dụng bản dịch POSIX cho ứng dụng của mình, hãy nhớ liên hệ với chúng tôi trên Slack !


Cũng được xuất bản ở đây .