Jest taka architektura:
- aplikacja Spring Boot (wiele instancji, wiele serwerów)
- baza danych ScyllaDB (Cassandra przepisana na C++)
- load balancer (kieruje ruch na losowy serwer z aplikacją)
Potrzebuję przechowywać duże pliki, w tym upload z możliwością wznawiania i download.
Jednym ze sposobów jest podzielenie plików na małe fragmenty:
CREATE TABLE IF NOT EXISTS files
(
id UUID,
file_name TEXT STATIC,
size_bytes INT STATIC,
chunk_no UUID,
data BLOB,
PRIMARY KEY (id, chunk_no)
);
Jednak nasuwają się pewne wątpliwości:
-
Kompaktowanie w Cassandrze/Scylli może doprowadzić do gwałtownego wzrostu zajmowanego miejsca.
-
Czy nie dojdzie do zablokowania wątków, jeśli aplikacja Spring Boot będzie pośredniczyć zarówno przy uploadzie jak i przy downloadzie plików? Algorytm pobierania działałby tak:
- policz liczbę kawałków na podstawie rozmiaru pliku
- dla każdego pozostałego kawałka (to może trwać bardzo długo):
- pobierz kawałek z bazy
- wrzuć go do odpowiedzi (w Springu prawdopodobnie przez StreamingResponseBody)
Jeśli mamy 10 wątków i zablokujemy w ten sposób wszystkie wątki, to możemy doprowadzić, że aplikacja przestanie być dostępna dla innych użytkowników?
Jakie są jeszcze inne wady takiego rozwiązania?
Jak powinno się prawidłowo zrealizować rozproszony system plików? Czy istnieją gotowe rozwiązania open source? Istotne jest też, aby dało się ograniczyć dostęp do plików na podstawie informacji zapisanych w bazie danych (czyli sprawdzamy, czy użytkownik, który chce pobrać plik, ma dostęp do elementów powiązanych tym plikiem).