Lưu trữ hiệu quả hàng trăm triệu tệp nhỏ. Giải pháp tự lưu trữ

Lưu trữ hiệu quả hàng trăm triệu tệp nhỏ. Giải pháp tự lưu trữ

Kính gửi cộng đồng, Bài viết này sẽ tập trung vào việc lưu trữ và truy xuất hiệu quả hàng trăm triệu tệp nhỏ. Ở giai đoạn này, giải pháp cuối cùng được đề xuất cho các hệ thống tệp tương thích POSIX với sự hỗ trợ đầy đủ cho các khóa, bao gồm cả khóa cụm và dường như thậm chí không cần nạng.

Vì vậy, tôi đã viết máy chủ tùy chỉnh của riêng mình cho mục đích này.
Trong quá trình thực hiện nhiệm vụ này, chúng tôi đã giải quyết được vấn đề chính, đồng thời tiết kiệm được dung lượng ổ đĩa và RAM, thứ mà hệ thống tệp cụm của chúng tôi đã tiêu tốn không thương tiếc. Trên thực tế, số lượng tệp như vậy có hại cho bất kỳ hệ thống tệp phân cụm nào.

Ý tưởng là thế này:

Nói một cách đơn giản, các tệp nhỏ được tải lên thông qua máy chủ, chúng được lưu trực tiếp vào kho lưu trữ và cũng được đọc từ đó, còn các tệp lớn được đặt cạnh nhau. Sơ đồ: 1 thư mục = 1 kho lưu trữ, tổng cộng chúng tôi có vài triệu kho lưu trữ với các tệp nhỏ chứ không phải vài trăm triệu tệp. Và tất cả điều này được triển khai đầy đủ mà không cần bất kỳ tập lệnh nào hoặc đưa tệp vào kho lưu trữ tar/zip.

Mình sẽ cố gắng viết ngắn gọn, xin lỗi trước nếu bài viết dài.

Mọi chuyện bắt đầu với thực tế là tôi không thể tìm thấy một máy chủ phù hợp trên thế giới có thể lưu dữ liệu nhận được qua giao thức HTTP trực tiếp vào kho lưu trữ mà không có những nhược điểm vốn có trong kho lưu trữ và lưu trữ đối tượng thông thường. Và lý do tìm kiếm là cụm Origin gồm 10 máy chủ đã phát triển quy mô lớn, trong đó đã tích lũy được 250,000,000 tệp nhỏ và xu hướng tăng trưởng sẽ không dừng lại.

Đối với những người không thích đọc bài viết, một ít tài liệu sẽ dễ dàng hơn:

đây и đây.

Và docker cùng lúc, bây giờ chỉ có một tùy chọn với nginx bên trong để đề phòng:

docker run -d --restart=always -e host=localhost -e root=/var/storage 
-v /var/storage:/var/storage --name wzd -p 80:80 eltaline/wzd

Tiếp theo:

Nếu có nhiều tệp thì cần có nhiều tài nguyên và điều tồi tệ nhất là một số trong số chúng bị lãng phí. Ví dụ: khi sử dụng hệ thống tệp phân cụm (trong trường hợp này là MooseFS), tệp, bất kể kích thước thực tế của nó, luôn chiếm ít nhất 64 KB. Nghĩa là, đối với các tệp có kích thước 3, 10 hoặc 30 KB thì cần có 64 KB trên đĩa. Nếu có một phần tư tỷ tệp, chúng ta sẽ mất từ ​​2 đến 10 terabyte. Sẽ không thể tạo tệp mới vô thời hạn vì MooseFS có giới hạn: không quá 1 tỷ với một bản sao của mỗi tệp.

Khi số lượng tệp tăng lên, cần rất nhiều RAM cho siêu dữ liệu. Việc lưu trữ siêu dữ liệu lớn thường xuyên cũng góp phần làm hao mòn ổ SSD.

máy chủ wZD. Chúng tôi sắp xếp mọi thứ theo thứ tự trên đĩa.

Máy chủ được viết bằng Go. Trước hết, tôi cần giảm số lượng tập tin. Làm thế nào để làm nó? Do đang lưu trữ nhưng trong trường hợp này không nén, vì tệp của tôi chỉ là ảnh nén. BoltDB đã ra tay giải cứu nhưng vẫn phải loại bỏ những thiếu sót của nó, điều này được phản ánh trong tài liệu.

Tổng cộng, thay vì một phần tư tỷ tệp, trong trường hợp của tôi chỉ còn lại 10 triệu kho lưu trữ Bolt. Nếu tôi có cơ hội thay đổi cấu trúc tệp thư mục hiện tại, có thể giảm nó xuống còn khoảng 1 triệu tệp.

Tất cả các tệp nhỏ được đóng gói vào kho lưu trữ Bolt, kho lưu trữ này tự động nhận tên của các thư mục chứa chúng và tất cả các tệp lớn vẫn ở bên cạnh kho lưu trữ; không cần thiết phải đóng gói chúng, điều này có thể tùy chỉnh. Những cái nhỏ được lưu trữ, những cái lớn được giữ nguyên. Máy chủ hoạt động minh bạch với cả hai.

Kiến trúc và tính năng của máy chủ wZD.

Lưu trữ hiệu quả hàng trăm triệu tệp nhỏ. Giải pháp tự lưu trữ

Máy chủ hoạt động trên các hệ điều hành Linux, BSD, Solaris và OSX. Tôi chỉ thử nghiệm kiến ​​trúc AMD64 trong Linux, nhưng nó sẽ hoạt động với ARM64, PPC64, MIPS64.

Những đặc điểm chính:

  • Đa luồng;
  • Multiserver, cung cấp khả năng chịu lỗi và cân bằng tải;
  • Tính minh bạch tối đa cho người dùng hoặc nhà phát triển;
  • Các phương thức HTTP được hỗ trợ: GET, HEAD, PUT và DELETE;
  • Kiểm soát hành vi đọc và viết thông qua tiêu đề máy khách;
  • Hỗ trợ máy chủ ảo linh hoạt;
  • Hỗ trợ tính toàn vẹn dữ liệu CRC khi ghi/đọc;
  • Bộ đệm bán động để tiêu thụ bộ nhớ tối thiểu và điều chỉnh hiệu suất mạng tối ưu;
  • Nén dữ liệu hoãn lại;
  • Ngoài ra, trình lưu trữ đa luồng wZA được cung cấp để di chuyển tệp mà không cần dừng dịch vụ.

Kinh nghiệm thực tế:

Tôi đã phát triển và thử nghiệm máy chủ và bộ lưu trữ trên dữ liệu trực tiếp trong một thời gian khá dài, hiện tại nó đang hoạt động thành công trên một cụm bao gồm 250,000,000 tệp nhỏ (hình ảnh) nằm trong 15,000,000 thư mục trên các ổ đĩa SATA riêng biệt. Một cụm gồm 10 máy chủ là máy chủ Origin được cài đặt phía sau mạng CDN. Để phục vụ nó, 2 máy chủ Nginx + 2 máy chủ wZD được sử dụng.

Đối với những người quyết định sử dụng máy chủ này, sẽ là khôn ngoan nếu lập kế hoạch cấu trúc thư mục, nếu có, trước khi sử dụng. Hãy để tôi đặt trước ngay rằng máy chủ không có ý định nhồi nhét mọi thứ vào kho lưu trữ 1 Bolt.

Kiểm tra năng suất:

Kích thước của tệp nén càng nhỏ thì các thao tác GET và PUT được thực hiện trên đó càng nhanh. Hãy so sánh tổng thời gian để ghi ứng dụng khách HTTP vào các tệp thông thường và kho lưu trữ Bolt cũng như việc đọc. Làm việc với các tệp có kích thước 32 KB, 256 KB, 1024 KB, 4096 KB và 32768 KB được so sánh.

Khi làm việc với kho lưu trữ Bolt, tính toàn vẹn dữ liệu của mỗi tệp được kiểm tra (CRC được sử dụng), trước khi ghi và cả sau khi ghi, việc đọc và tính toán lại nhanh chóng xảy ra, điều này đương nhiên gây ra sự chậm trễ, nhưng điều chính là bảo mật dữ liệu.

Tôi đã tiến hành kiểm tra hiệu năng trên ổ SSD, vì các thử nghiệm trên ổ SATA không cho thấy sự khác biệt rõ ràng.

Đồ thị dựa trên kết quả thử nghiệm:

Lưu trữ hiệu quả hàng trăm triệu tệp nhỏ. Giải pháp tự lưu trữ
Lưu trữ hiệu quả hàng trăm triệu tệp nhỏ. Giải pháp tự lưu trữ

Như bạn có thể thấy, đối với các tệp nhỏ, sự khác biệt về thời gian đọc và ghi giữa các tệp được lưu trữ và không được lưu trữ là rất nhỏ.

Chúng tôi nhận được một bức tranh hoàn toàn khác khi thử nghiệm đọc và ghi các tệp có kích thước 32 MB:

Lưu trữ hiệu quả hàng trăm triệu tệp nhỏ. Giải pháp tự lưu trữ

Sự khác biệt về thời gian giữa các tệp đọc là trong khoảng 5-25 ms. Với ghi âm, mọi thứ còn tệ hơn, chênh lệch là khoảng 150 ms. Nhưng trong trường hợp này không cần thiết phải tải lên các tập tin lớn; làm như vậy đơn giản là vô ích; chúng có thể tồn tại tách biệt khỏi các kho lưu trữ.

*Về mặt kỹ thuật, bạn có thể sử dụng máy chủ này cho các tác vụ yêu cầu NoSQL.

Các phương pháp làm việc cơ bản với máy chủ wZD:

Đang tải một tập tin thông thường:

curl -X PUT --data-binary @test.jpg http://localhost/test/test.jpg

Tải tệp lên kho lưu trữ Bolt (nếu không vượt quá tham số máy chủ fmaxsize, xác định kích thước tệp tối đa có thể được đưa vào kho lưu trữ; nếu vượt quá, tệp sẽ được tải lên như bình thường bên cạnh kho lưu trữ):

curl -X PUT -H "Archive: 1" --data-binary @test.jpg http://localhost/test/test.jpg

Tải xuống một tệp (nếu có các tệp có cùng tên trên đĩa và trong kho lưu trữ, thì khi tải xuống, mặc định ưu tiên cho tệp chưa được lưu trữ):

curl -o test.jpg http://localhost/test/test.jpg

Tải xuống tệp từ kho lưu trữ Bolt (bắt buộc):

curl -o test.jpg -H "FromArchive: 1" http://localhost/test/test.jpg

Mô tả về các phương pháp khác có trong tài liệu.

Tài liệu wZD
Tài liệu wZA

Máy chủ hiện chỉ hỗ trợ giao thức HTTP, chưa hoạt động với HTTPS. Phương thức POST cũng không được hỗ trợ (vẫn chưa quyết định có cần thiết hay không).

Ai đào sâu vào mã nguồn sẽ tìm thấy butterscotch ở đó, không phải ai cũng thích đâu, nhưng tôi không gắn mã chính với các chức năng của web framework, ngoại trừ trình xử lý ngắt, nên sau này tôi có thể nhanh chóng viết lại cho hầu hết mọi thứ. động cơ.

ToDo:

  • Phát triển trình sao chép và phân phối + địa lý của riêng bạn để có khả năng sử dụng trong các hệ thống lớn không có hệ thống tệp cụm (Mọi thứ dành cho người lớn)
  • Khả năng khôi phục ngược hoàn toàn siêu dữ liệu nếu nó bị mất hoàn toàn (nếu sử dụng nhà phân phối)
  • Giao thức gốc cho khả năng sử dụng các trình điều khiển và kết nối mạng liên tục cho các ngôn ngữ lập trình khác nhau
  • Các khả năng nâng cao để sử dụng thành phần NoSQL
  • Nén các loại khác nhau (gzip, zstd, snappy) cho các tệp hoặc giá trị bên trong kho lưu trữ Bolt và cho các tệp thông thường
  • Mã hóa các loại khác nhau cho các tệp hoặc giá trị bên trong kho lưu trữ Bolt và cho các tệp thông thường
  • Chuyển đổi video phía máy chủ bị trì hoãn, bao gồm cả trên GPU

Tôi có tất cả mọi thứ, tôi hy vọng máy chủ này sẽ hữu ích cho ai đó, giấy phép BSD-3, bản quyền kép, vì nếu không có công ty nơi tôi làm việc thì máy chủ đã không được viết. Tôi là nhà phát triển duy nhất. Tôi sẽ biết ơn nếu bạn tìm thấy bất kỳ lỗi và yêu cầu tính năng nào.

Nguồn: www.habr.com

Thêm một lời nhận xét