1 điểm bởi GN⁺ 2025-02-26 | 1 bình luận | Chia sẻ qua WhatsApp
  • Việc dọn dẹp tệp trùng lặp trên Mac thường mặc định là phải xóa, nhưng Hyperspace dùng APFS clone để cho các tệp có cùng nội dung chia sẻ dữ liệu, nhờ đó lấy lại dung lượng mà vẫn giữ nguyên tệp
  • Copy-on-write clone của APFS cho phép, giống như tính năng “Duplicate” trong Finder, không cần ghi lại toàn bộ dữ liệu mà vẫn chia sẻ với bản gốc, nên ngay cả khi nhân bản tệp lớn quá trình này cũng gần như hoàn tất tức thì
  • Khi ổ đĩa của mình gần đầy, nhà phát triển đã tạo một script Perl để tìm các tệp có cùng nội dung nhưng không phải clone, và phát hiện có thể tiết kiệm được hàng chục GB, từ đó phát triển thành ứng dụng
  • Ứng dụng có thể được tải miễn phí để quét và kiểm tra dung lượng có thể tiết kiệm, nhưng để thực sự thu hồi dung lượng thì cần thanh toán
  • Vì ứng dụng chỉnh sửa các tệp mà nó không tự tạo ra hoặc không sở hữu nên rủi ro khá lớn, nhưng đổi lại nó có thể mang lại ích lợi thực tế cho rất nhiều người dùng Mac

Thu hồi dung lượng mà vẫn giữ nguyên tệp bằng APFS clone

  • Khi các tệp có cùng nội dung không ở quan hệ clone với nhau, Hyperspace sẽ chuyển chúng thành APFS clone để chỉ còn chia sẻ một bản dữ liệu trên đĩa
  • Các ứng dụng tìm tệp trùng lặp trên Mac trước đây thường tiết kiệm dung lượng bằng cách tìm và xóa tệp trùng, nhưng Hyperspace thu hồi dung lượng mà không cần loại bỏ tệp
  • Những tính năng cốt lõi của APFS gồm có snapshot theo thời điểm và copy-on-write clone
    • Snapshot được dùng để giúp bản sao lưu Time Machine ổn định và hiệu quả hơn
    • Copy-on-write clone dựa trên cấu trúc linh hoạt giữa directory entry và nội dung tệp
  • Khi nhân bản tệp bằng lệnh “Duplicate” trong Finder, nội dung tệp thực tế không bị sao chép lại mà một tệp clone chia sẻ dữ liệu với bản gốc sẽ được tạo ra
    • Nhờ cấu trúc này, việc nhân bản trong Finder gần như hoàn tất ngay lập tức bất kể kích thước tệp

Cách phát hành và ghi chú phát triển

  • Vào cuối năm 2024, khi ổ đĩa trên máy Mac của mình gần đầy, nhà phát triển đã viết một script Perl để tìm các tệp không phải clone nhưng có cùng nội dung và chuyển chúng thành clone
    • Script này gọi một công cụ dòng lệnh viết bằng C và một công cụ dòng lệnh viết bằng Swift
    • Kết quả chạy cho thấy có thể tiết kiệm được hàng chục GB dung lượng, và sau đó nó được phát triển thành ứng dụng Mac
  • Hyperspace có mặt trên Mac App Store
  • Về mặt phát triển, Hyperspace là ứng dụng Mac dùng SwiftUI thứ hai của nhà phát triển, và là ứng dụng đầu tiên dùng SwiftUI life cycle
    • Đây cũng là ứng dụng thứ hai dùng Swift 6
    • Việc dùng Swift 6 ngay từ giai đoạn đầu phát triển dễ hơn rất nhiều so với chuyển một ứng dụng đã phát hành sang Swift 6
    • Swift 6 vẫn còn khá nhiều điểm thô ráp và nhà phát triển kỳ vọng sẽ được cải thiện trong tương lai
  • Hyperspace chỉnh sửa các tệp mà ứng dụng không tạo ra và cũng không sở hữu, tương tự như quá trình chuyển đổi từ HFS+ sang APFS
    • Nhà phát triển gọi đây là ứng dụng nguy hiểm nhất mà mình từng tạo ra
    • Đồng thời, ông cũng cho rằng đây có thể là ứng dụng hữu ích nhất với nhiều người nhất

1 bình luận

 
GN⁺ 2025-02-26
Ý kiến trên Hacker News
  • Trước đây tôi từng tạo một tiện ích dòng lệnh dedup làm việc tương tự
    Nó có chế độ dry-run, chọn nguồn clone tối ưu một cách “thông minh”, hiểu hard link và các clone khác, bảo toàn metadata, và xử lý đúng cả các tệp nén HFS
    Dữ liệu của tôi thì chưa từng bị làm hỏng, nhưng như mọi công cụ hệ thống tệp khác, dùng là tự chịu rủi ro
    0 - https://github.com/ttkb-oss/dedup

    • Nếu chỉ mới quét thử mà chưa thực hiện khử trùng lặp, trên một workspace 7,6GB gồm disk image, binary chương trình và biểu diễn trung gian, có thể thấy khác biệt khá rõ
      Về cơ bản Hyperspace không quét tất cả tệp mà chỉ xem các tệp trong allowlist, và có vẻ được thiết kế theo kiểu phải hiểu nội dung tệp. Với tư cách người dùng cuối, tôi không biết họ phân biệt tệp Text và tệp Source Code như thế nào; lần quét mặc định chỉ tìm được 360MB có thể khử trùng lặp, nhưng khi cho phép mọi tệp thì tăng lên 842MB
      Mặc định nó cũng không quét các tệp dưới 100KB; khi tắt giới hạn kích thước và cho phép mọi tệp thì tăng lên 1,1GB. Với điều kiện mọi tệp và không giới hạn kích thước, Hyperspace quét 67.309 trên 68.874 tệp, còn dedup quét 67.426 tệp
      Hyperspace nói có 29.522 tệp có thể khử trùng lặp, còn dedup tìm được 29.447 tệp. Có chênh lệch một phần vì 76 tệp đã được khử trùng lặp sẵn, nhưng tôi không rõ nguyên nhân chính xác
      Thời gian quét của Hyperspace khoảng 50 giây, còn dedup là 14 giây. Có vẻ Hyperspace quét hệ thống tệp, rồi tính toán trùng lặp, sau đó mới khử trùng lặp; tôi không hiểu vì sao hai bước đầu không được làm cùng lúc. Tôi đã cho đưa metadata hệ thống tệp vào hàng đợi trong lúc quét và bắt đầu tính trùng lặp song song; phần lớn trường hợp có thể lọc bỏ các tệp không khớp chỉ bằng thông tin kích thước nhận được “miễn phí” khi duyệt thư mục bằng fts_read
      Hyperspace nói có thể tiết kiệm 1,1GB, còn dedup tìm thấy 1,04GB cùng 882MB đã được tiết kiệm sẵn. Tôi không định mua Hyperspace nên không biết thời gian khử trùng lặp thực tế, khả năng bảo toàn metadata hay cách xử lý các tệp kỳ lạ ra sao, nhưng với dedup, tổng thời gian quét và khử trùng lặp là 31 giây
      Sau khi khử trùng lặp bằng dedup, Hyperscan vẫn cho rằng còn 2 tệp có thể khử trùng lặp. Hyperspace dường như cũng xử lý các tệp có nhiều hard link, tệp rỗng và nhiều ngoại lệ mà dedup kiểm tra. Việc bảo toàn ACL hay các thuộc tính khác thì không thể kiểm thử nếu không trả tiền, nhưng nhìn qua strings thì có vẻ có xử lý; còn nén HFS là một ca biên khó nên tôi vẫn chưa xác nhận được quá trình quét của Hyperspace xử lý ra sao
    • Tôi chạy thử trên những nơi có rất nhiều tệp gần giống nhau, như thư mục phát triển Postgres, và tiết kiệm được khoảng 1,7GB
      Dự án chưa có license, nên nếu được thì mong bạn gắn license mà bạn muốn. Tôi cũng đã tạo pull request để cải thiện một chút bước cài đặt: https://github.com/ttkb-oss/dedup/pull/6
    • Tôi vừa dùng thử và nó hoạt động tốt. Chỉ đến khi thấy thực sự có bao nhiêu bản trùng lặp trong một số loại tệp nhất định, đặc biệt là trong node_modules, tôi mới nhận ra tiềm năng của kỹ thuật này
      Chỉ nhìn vào một số thư mục con cụ thể cũng không hiếm khi thấy 50 bản sao của một tệp JS được thay bằng một tệp duy nhất. Tuy vậy, vì đây là “pre-release” và số sao GitHub còn khá ít, mà công cụ kiểu này nếu có bug thì khá đáng sợ, nên tôi tò mò về độ ổn định của nó
    • Tài liệu rất tốt, và việc make kết thúc gần như ngay lập tức cũng rất ấn tượng
    • Có thể xem danh sách các lựa chọn thay thế trong phần bình luận tại https://news.ycombinator.com/item?id=38113396
      Trước đây tôi từng dùng https://github.com/sahib/rmlint và không có gì phàn nàn đáng kể
  • Khi đọc đoạn “Hyperspace không có cách nào phối hợp với tất cả các ứng dụng khác hay chính macOS để điều phối thời điểm an toàn cho việc thay thế tệp, và cũng không có cách nào cưỡng ép kiểm soát độc quyền tệp đó”, tôi tự hỏi vì sao bản thân hệ thống tệp không chạy một quy trình khử trùng lặp tương tự ở nền
    Ở mức trừu tượng như vậy thì có vẻ có thể quản lý các vấn đề an toàn này, nên tôi tự hỏi nếu việc này tự động diễn ra bên trong APFS thì sẽ có nhược điểm gì

    • Với ZFS, nó dùng rất nhiều RAM. Có lẽ vì ZFS xử lý ở cấp khối, nên khi một khối mới được ghi, nó phải theo dõi rất nhiều khối để so sánh
      Nếu triển khai ở cấp tệp thì có thể giảm mức dùng tài nguyên, nhưng không rõ việc triển khai sẽ đơn giản hơn hay phức tạp hơn. Ngoài ra, việc chỉ thay đổi 1 byte trong một tệp lớn cũng buộc hệ thống tệp phải sao chép lại tệp đó, gây nhiều hoạt động đĩa, là điều có thể không trực quan
    • Trên các thiết bị lưu trữ khối, việc này thường được làm cùng với nén. Tất nhiên nếu hệ thống tệp mã hóa các khối gửi xuống thiết bị thì sẽ thất bại
      Khử trùng lặp ở tầng này có lợi vì có thể khử trùng lặp trên nhiều hệ thống tệp. Ví dụ, nếu có một nghìn hệ thống có cùng các tệp hệ điều hành, có thể tiết kiệm dung lượng lưu trữ cực lớn, và khác biệt thường chỉ là các thiết lập riêng theo hệ thống như khóa host hoặc hostname. Một hệ thống tệp đơn lẻ không thể nhận ra sự tương đồng này
      Tuy nhiên, sẽ có vấn đề nếu khử trùng lặp làm giảm số bản sao của các tệp có mức sử dụng lớn. Trong ví dụ trên, nếu khởi động đồng thời một nghìn máy, ảnh kernel có thể chịu tải I/O khổng lồ
    • Trên Linux, đây là API khử trùng lặp tiêu chuẩn dùng trong btrfs và XFS
      Bạn lịch sự yêu cầu hệ điều hành khử trùng lặp một tập các vùng đã chỉ định; OS sẽ khóa các vùng đó, xác minh chúng thực sự giống nhau rồi mới khử trùng lặp. Vì cũng nhận lại được trong một trường số byte đã được khử trùng lặp ở từng vùng, nên chương trình ở user space không có cách nào làm hỏng tệp
    • ZFS thực sự làm việc này: https://www.truenas.com/docs/references/zfsdeduplication/
    • Windows Server cũng cung cấp tính năng này trên các volume NTFS và ReFS
      Tôi từng dùng khá nhiều trên ReFS chạy Hyper-V VM và hiệu quả rất ấn tượng. Khi đó phần lớn là các VM pha trộn Windows Server 2016/2019, và mức sử dụng lưu trữ giảm khoảng 45%
  • Tôi thích mô hình quét miễn phí để xem có lợi hay không, rồi chỉ trả tiền cho kết quả thực tế
    Tôi cũng thuộc kiểu hay tích trữ tệp, nên đã chạy thử và thấy có thể thu hồi 7GB, nhưng với tôi thì mức đó chưa đáng để trả tiền. Dù vậy, thật tốt khi có một công cụ như thế này

    • Trong podcast, họ từng giải thích mô hình này. Vì nhiều người dùng sẽ mua nó, chạy một lần, tiết kiệm vài GB rồi thôi, nên thuê bao không hợp lý lắm
      Dù sao thì mỗi tháng bạn có thể vô tình tạo ra bao nhiêu tệp trùng lặp hoàn toàn giống nhau chứ?
      Cũng có tùy chọn thuê bao hoặc mua vĩnh viễn cho những người thực sự dùng thường xuyên, nhưng với nhiều người, một khoản mua trong ứng dụng dùng một lần cho phép sử dụng trong thời gian giới hạn là khá hợp lý. Và bạn luôn có thể chạy lại miễn phí để xem đã tích lũy đủ nhiều đến mức đáng trả tiền lần nữa chưa
    • Giá trị của loại ứng dụng khử trùng lặp này với tôi thiên về không để lại tệp trùng lặp hơn là tiết kiệm dung lượng
      Tôi không tạo ra số lượng khổng lồ, nhưng nếu gộp một phần hoặc toàn bộ lại thì có thể xuất hiện các tệp trùng lặp lớn. Điều này thường xảy ra trong những tình huống lạ, như phải đối chiếu kết quả khôi phục ổ cứng với các tệp ở vị trí khác, hoặc phải khớp một thư mục tải xuống bừa bộn với một vị trí đích đã được sắp xếp
      Ví dụ, từng có lần bản sao lưu Time Machine đẩy ra các phiên bản cũ của những tệp mà tôi thậm chí không biết mình còn có bản ghi và tưởng đã mất từ lâu, nhưng nó làm hỏng tên thư mục và cũng làm rối nội dung ở mức nào đó. Có hàng nghìn thư mục đặt tên bằng số, bên trong có thể có các tệp tôi muốn giữ, nhưng rất khó biết tôi đã có chúng chưa và chúng nằm ở đâu vì hoàn toàn không có cấu trúc. Ngược lại, cũng có nhiều trường hợp chỉ chứa một tệp văn bản của cùng một hệ thống build, nên dĩ nhiên có thể bỏ đi
    • Tôi tự hỏi có phải mình đã già đến mức còn nhớ rằng chỉ 10 năm trước hầu hết phần mềm đều như thế này không
      Có phải mọi người đã quá quen với bẫy thuê bao đến mức cảm thấy đây là một mô hình mới không
    • Tôi thật sự thích mô hình định giá này
      Giá mà các phần mềm khác cũng dễ làm như vậy, nhưng thường thì đường cong học tập lại cản trở trước khi người dùng thấy được giá trị
    • Cách này mới mẻ hơn nhiều so với “dùng thử miễn phí” mà bạn phải nhớ hủy
      Mẹo nhỏ là với những bản dùng thử như vậy, nếu dùng thẻ ảo có thể khóa thì dù quên hủy, khoản thanh toán cũng bị chặn. Nhưng tôi tò mò không biết có ai tìm ra giá giấy phép thực sự trên website chưa
  • Tôi tò mò ứng dụng dùng thuật toán nào để xác định hai tệp có giống nhau hay không
    Có nhiều cách thú vị như hash, so sánh từng bit, v.v., nhưng mỗi cách đều có nhược điểm. Khi có rất nhiều tệp thì cách tốt nhất là gì

    • Tôi không biết chính xác Siracusa làm gì, nhưng có thể đoán
      Với mỗi tệp ứng viên, cần có một “khóa” để kiểm tra nó có giống tệp ứng viên khác hay không. Vì có thể có hàng triệu tệp, khóa phải nhỏ và tạo nhanh, nhưng đồng thời không được có dương tính giả
      Câu trả lời obvious ngày nay là hash SHA256 của nội dung tệp. Nó rất nhanh, kích thước 32 byte cũng không quá lớn, và xác suất dương tính giả hay va chạm thấp đến mức thế giới có lẽ sẽ kết thúc trước khi bạn thực sự gặp phải. SHA256 gần như là chuẩn thực tế cho mục đích này, nên nếu họ dùng thứ khác thì tôi sẽ khá ngạc nhiên
    • Tôi nhớ đến https://en.wikipedia.org/wiki/Venti_(software)
      Đó là một hệ thống tệp định địa chỉ theo nội dung dùng hash để khử trùng lặp, và vì hash được tính tại thời điểm ghi nên chi phí hiệu năng được phân tán
    • Tôi sẽ hash 1024 byte đầu tiên của mọi tệp, và chỉ khi có va chạm mới tiếp tục phần tiếp theo
      Như vậy không cần hash toàn bộ các tệp lớn, chỉ cần xem thêm những tệp có cùng hash
  • Apple cung cấp kèm một lệnh cp đã chỉnh sửa, hỗ trợ cờ -c để có thể dùng tính năng clone của APFS

    • Nếu cp bạn dùng không hỗ trợ điều đó, bạn cũng có thể gọi bằng Python
      Ví dụ như import Foundation; Foundation.NSFileManager.defaultManager().copyItemAtPath_toPath_error_(...)
  • Nếu tệp A nằm ở hai vị trí và sau khi chạy công cụ này rồi sửa A_0, tôi thắc mắc liệu A_1 cũng thay đổi theo, hay chỉ trạng thái mới của A_0 được hiện thực hóa còn A_1 vẫn giữ nguyên

  • Điều khiến tôi chú ý là trước khi Apple công bố APFS tại WWDC 2017, trong một phần của bản cập nhật iOS 10.x, họ đã âm thầm thử chuyển đổi tất cả iPhone sang APFS rồi quay lại HFS+
    Tôi thắc mắc làm sao có thể quay lại khi thay đổi hệ thống tệp gặp lỗi. Có thể kiểm chứng mã đủ kỹ, nhưng nếu có vấn đề gì đó thì trông có vẻ không thể rút lại

    • Nếu tôi nhớ đúng, việc di trú từ HFS+ sang APFS có thể thực hiện mà không cần đụng tới các block dữ liệu, và các block metadata cùng superblock của APFS được ghi song song lên đĩa
      Trong lần di trú thử nghiệm của Apple, họ thực hiện toàn bộ quá trình, bao gồm cả tạo superblock APFS, nhưng dừng lại ngay trước bước commit thay thế vĩnh viễn superblock HFS+ bằng superblock APFS. Khi quay lại, chỉ cần “đơn giản” dọn các superblock và block metadata APFS đã tạo
    • Tôi đã xem phần đó trong bài trình bày [0], nhưng gần như không có chi tiết nào ngoài việc họ nói đó là một bài kiểm thử tính nhất quán
      Từng làm hỏng nhiều thứ trong môi trường production, tôi không chắc mình có dám bấm nút nếu được yêu cầu chạy một cuộc di trú lớn như vậy không
      [0] https://www.youtube.com/watch?v=IcyaadNy9Jk&t=1670s
    • Có vẻ là thiếu trí tưởng tượng. Đây không phải công nghệ báu vật vương miện chỉ Apple mới làm được
      Trong thế giới mã nguồn mở cũng có công cụ chuyển đổi hệ thống tệp ext sang btrfs, và (1) có thể hoàn tác, (2) vẫn có thể mount hệ thống tệp ext gốc trong khi đang dùng hệ thống tệp btrfs
  • Bắt đầu bằng một câu chuyện, thu hẹp thành vấn đề, rồi cho thấy giải pháp xử lý vấn đề đó như có phép màu
    Đây là một ví dụ rất hay về marketing xuất sắc

  • Tôi đã thử chạy trên một thư mục dự án NodeJS khổng lồ, nhưng kết quả cho biết chỉ tiết kiệm được 1GB trên thư mục 8.1GB
    Tôi chạy lại bao gồm cả thư mục home của người dùng, nhưng với 731K tệp, 127K thư mục và 2.755 tệp mục tiêu, tổng cộng chỉ tiết kiệm được 1,3GB. Chỉ tăng thêm khoảng 300MB so với khi chỉ chạy trên thư mục NodeJS
    Tôi cũng thử quét System và Library, nhưng bị từ chối do vấn đề quyền. Có vẻ vì tôi dùng pnpm làm trình quản lý gói nên mức sử dụng đĩa vốn đã gần tối ưu rồi
    Ý tưởng thì hay, nhưng với mức giá hiện tại thì khó biện minh; nếu nó chạy như một tiến trình nền khoảng mỗi tháng một lần thì sẽ tốt hơn

    • 1GB trên 8.1GB nghĩa là 12% dung lượng đang dùng bị lãng phí, không phải sao? Không biết tôi có đọc đúng không
    • pnpm hướng tới việc thay thế npm theo kiểu drop-in, và tự động khử trùng lặp
    • macOS có sealed volume, nên bạn thấy lỗi quyền trong System và Library
      https://support.apple.com/guide/security/signed-system-volum...
    • Tôi chưa có thời gian tự thử, nhưng trong ảnh chụp màn hình App Store rõ ràng có tùy chọn kích thước tệp tối thiểu cần xét
      Có vẻ tùy chọn này được đưa vào để giảm bộ đệm so sánh, và có khả năng các tệp trong node_modules nằm dưới ngưỡng này nên không được xét đến
    • Tôi không biết giá là bao nhiêu. Có vẻ không được công khai ở đâu cả
  • Tôi từng viết một script tương tự nhưng đơn giản hơn, đổi các tệp có cùng nội dung thành hard link
    Động lực chính là các package trong môi trường ảo Python. Thường có nhiều package tương tự được cài, và dù khác phiên bản thì nhiều tệp vẫn trùng khớp. Một số package như Numpy, PyTorch, TensorFlow khá lớn, nên có thể tiết kiệm đáng kể dung lượng đĩa
    https://github.com/albertz/system-tools/blob/master/bin/merg...

    • Công cụ này không dùng hard link hay symbolic link, mà dùng tính năng tạo clone copy-on-write của hệ thống tệp [1]
      [1] https://en.wikipedia.org/wiki/Apple_File_System#Clones
    • uv làm việc này theo mặc định
      Tôi nghĩ các công cụ khác như poetry, hatch, pdm cũng vậy, nhưng tôi chưa dùng đủ nhiều để biết rõ chi tiết hoạt động