Jak przechowywać 3 miliony rekordów w formacie kluczowej wartości?


10

Musimy przechowywać podstawowe informacje o 3 milionach produktów. Obecnie informacje to jeden plik CSV o rozmiarze 180 MB, który jest aktualizowany co kwartał.

Będzie dziennie około 30 000 zapytań, ale zapytania są tylko bardzo prostym magazynem kluczowych wartości. Musimy tylko sprawdzić identyfikator produktu i wyświetlić resztę informacji (wszystkie byłyby w jednym rekordzie).

To jest dla sieci, więc szybka wydajność ma kluczowe znaczenie.

Czy powinniśmy używać MySQL, chociaż tak naprawdę nie potrzebujemy relacyjnej bazy danych? Czy powinniśmy generować 3 miliony statycznych plików HTML co kwartał? Czy powinniśmy przechowywać jeden wiersz CSV dla każdego produktu na czymś takim jak Amazon S3 lub Rackspace Cloud Files? Jak najlepiej to zrobić?

Odpowiedzi:


16

Ponieważ MySQL jest tak szeroko wspierany i jest to naprawdę dość trywialna rzecz do zrobienia, sugerowałbym pójście z tym. O ile serwer nie ma co najmniej kilku GB pamięci, sugerowałbym pozostanie przy MySQL zamiast korzystania z systemu w pamięci.

Gdy zaczniesz umieszczać swoje dane w bazie danych, bez względu na to, czy jest to MySQL, czy coś innego, całkiem prawdopodobne jest, że znajdziesz dla niej więcej zastosowań. W tej chwili mówisz tylko o parach kluczowych wartości, ale reszta danych dotyczących twoich produktów musi być gdzieś przechowywana. Jeśli nie ma tego w bazie danych, nie wyobrażam sobie, aby przechowywanie danych było bardzo wydajne.

Cokolwiek robisz, nie twórz tych trzech milionów plików. Widzieliśmy już tutaj wiele pytań wynikających z problemów, które powodują tak wiele plików.


13

Możesz użyć dedykowanej bazy danych NoSQL typu Key-Value, która jest zoptymalizowana do tego rodzaju zadań. Spójrz na:

  • Redis - Redis to otwarty, zaawansowany sklep kluczy i wartości. Często nazywany jest serwerem struktury danych, ponieważ klucze mogą zawierać ciągi, skróty, listy, zestawy i zestawy posortowane.
  • MemcacheDB - MemcacheDB jest rozproszonym systemem przechowywania kluczy i wartości zaprojektowanym z myślą o trwałości.
  • inne (jedną z takich list można znaleźć tutaj: http://nosql-database.org/ )

Oczywiście można użyć MySQL lub jakiejkolwiek innej relacyjnej bazie danych, ale rozwiązań specjalnie zaprojektowanych dla typu klucz-wartość danych ma być lepsza (inaczej, co jest punktem projektując je w pierwszej kolejności, z wyjątkiem być może fakt, że w przyszłości będzie znacznie mniejszy (pod względem rozwiązania RAM i HDD).


Możemy użyć Redis, ale czy uważasz, że to zadziałałoby na P4 z 2 gigabajtami pamięci RAM?
Phil

@Phil Biorąc pod uwagę, że plik CSV ma około 180 MB - powinno być w porządku. Chociaż użyliśmy go w projekcie (dotychczas tylko raz) z około 200 000 rekordów, a serwer miał 8 GB pamięci RAM, więc trudno mi to porównać.
LazyOne

6

A teraz coś z zupełnie innej beczki:

Dany:

  • Produkty 180 MB / 3M = średnio 62 bajty / produkt.
  • 30 000 zapytań dziennie = 0,34 zapytania na sekundę
  • Aktualizowane kwartalnie = zasadniczo dane statyczne

Rozwiązanie poza pudełkiem:

Zrzuć każdy produkt jako rekord zasobu TXT i zapisz go w DNS, np .:

$origin products.example.com.

product_1_name IN TXT "product 1 description"
product_2_name IN TXT "product 2 description"
...
product_3000000_name IN TXT "product 3000000 description"

Korzyści:

  • wyjątkowo niezawodny i zaufany (już na nim polegasz)
  • może być zbudowany na prawie każdej platformie
  • prawie każdy język obsługuje zapytania DNS w takiej czy innej formie
  • serwery open source i komercyjne obsługują różne rodzaje baz danych zaplecza
  • może być w prosty sposób replikowany (wystarczy podać wiele serwerów nazw)
  • obsługuje aktualizacje atomowe, nawet w przypadku replikacji na kilkunastu serwerach
  • może być podpisany kryptograficznie, aby zapewnić integralność danych
  • potrafi obsłużyć wyższe wielkości zapytań na sekundę (10 000 zapytań na sekundę można łatwo obsłużyć sprzętem towarowym)

Powody, dla których może to być zły pomysł:

  • musisz przeszukać dane (DNS to wyszukiwanie klucza / wartości)
  • musisz ukryć dane (DNS nie ma poufności)

1
Gdybym mógł dać premię za oryginalność, uzyskałbym mój głos. Nie powiedziałbym jednak, że DNS jest w ogóle niezawodny, ponieważ w typowej sieci domowej wydaje się magią, jeśli działa, a przekleństwem, jeśli nie działa.
Martin Vilcans

1
Jestem zaintrygowany. Naprawdę podoba mi się ten pomysł, ale dla mnie wybrałbym coś bardziej wypróbowanego / przetestowanego, jak CouchDB
Tom O'Connor

Oglądałeś Monty Pythona?
Mark Henderson

Przypuszczalnie byłoby to w ramach sieci przedsiębiorstw. Niezawodność DNS staje się problemem, gdy pakiety muszą odważnie dzić się w Internecie. Ponieważ domyślnie DNS używa UDP, musisz polegać na zasadach retransmisji DNS w przypadku odrzucenia pakietu. W sieci korporacyjnej szanse na uzyskanie znacznej utraty pakietów są (prawdopodobnie) znikome. I zawsze możesz zmusić DNS do korzystania z TCP (aczkolwiek przy trafieniu w wydajność, uważane w tym przypadku za nieistotne). I gwarantuję, że DNS dostaje więcej wyszukiwań niż wszystkie połączone instalacje CouchDB :-).
Theobroma Cacao

Kapitan Hindsight tutaj. Jedno słowo: blockchain.
datashaman

4

MySQL z MyISAM i kilka dobrych indeksów brzmi idealnie do tego. Istnieje oczywiście wiele innych opcji, ale MySQL jest bardzo szeroko (jeśli nie powszechnie) obsługiwany na każdym komercyjnym hoście internetowym. W zależności od wymaganej prędkości warto również przyjrzeć się memcached , ale bez znajomości wielkości każdej pary klucz / wartość przechowywanie 3 milionów z nich w pamięci może być jeszcze gorszym pomysłem niż plik CSV 180 Mb (och, czekaj, to plik CSV 180 Mb, więc wiemy, jak duże są. Muszą to być dość małe pary, aby memcached mógł być jeszcze lepszy).

Zdajesz nie chce 3 miliony statycznych plików HTML, będzie bolało filesystemu źle. Jednowierszowy plik CSV, nawet na S3, będzie miał ten sam problem. Nikt nie chce 3 milionów plików w folderze.


Są to dość małe pary ... to bardzo podstawowe dane, takie jak cena, data produkcji, numer magazynu itp. Mniej niż 10 kolumn. Więc myślisz, że MySQL jest naprawdę dobry? Serwer, na którym będzie działał, to P4 z 2 gigabajtami pamięci RAM. Myślę, że powinno być dobrze?
Phil

@Phil - So you think MySQL is the way to go, really?- nie, nie bardzo, ale jest bardzo elastyczny i, jak wspomniałem, obsługiwany prawie powszechnie. Jednak LazyOne opublikował kilka dobrych alternatyw powyżej. Nie pamiętałem terminu NoSQL, ale gdzieś unosił się w moim mózgu
Mark Henderson

4

Możesz użyć bazy danych Berkeley, która robi dokładnie takie rzeczy, nawet jeśli nie była modna od zarania Perl5. Berkeley obsługuje tylko pary klucz-wartość, a ty przywiązujesz całą bazę danych do skrótu i ​​uzyskujesz do niej dostęp.

Korzystanie z Berkeley jest szczegółowo opisane w wielu starszych referencjach Perla siedzących na twojej półce lub wypróbuj Perldoc dla modułu CPAN BerkeleyDB . Zasadniczo unikam korzystania z Berkeley DB (chociaż mój pracodawca ma bardzo stary kod, w którym gra w znaczący sposób, a niektóre DB są tak duże jak twoje), ponieważ nie jest zabawnie, gdy twoje dane stają się bardziej złożone.


2
BDB to stary skool, ale bardzo skuteczny i odpowiedni do tej sytuacji.
womble

Uwaga na licencję dla Berkely DB en.wikipedia.org/wiki/Sleepycat_license wymaga, aby WSZYSTKIE kody źródłowe były udostępniane nie tylko część DB.
WolfmanJM

4

Oznacziłeś swoje pytanie jako Amazon S3.

Chciałbym zwrócić uwagę na jeden z ich innych powiązanych produktów o nazwie Amazon SimpleDB.
Wygląda na to, że model danych SimpleDB dobrze pasowałby do Twojego typu aplikacji.

To nie jest wtyczka, ale warto przyjrzeć się zwłaszcza, jeśli planujesz korzystać z usług chmurowych Amazon.

Model danych SDB przypomina arkusz kalkulacyjny.

Zobacz tutaj, aby uzyskać więcej informacji na ten temat: http://aws.amazon.com/simpledb/ Oraz model danych: http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/


SimpleDB jest drogi. Boleśnie, w wielu przypadkach.
Tom O'Connor

1

Chociaż 180 MB danych może być łatwo obsłużone przez dowolną relacyjną bazę danych, gorąco polecam MongoDB ( http://www.mongodb.org/) powyżej MySQL, Redis, MemcacheDB i innych prostszych magazynów klucz-wartość lub relacyjnych baz danych. Powodem jest to, że w przypadku tego rodzaju problemu MongoDB jest najszybszym, najbardziej ekspresyjnym systemem w użyciu, umożliwiającym superszybkie dynamiczne aktualizacje bez ograniczeń schematu, dzięki czemu dokumenty mogą mieć różne formaty, jeśli chcesz. Pewnego dnia byłem na prezentacji ze strony guardian.co.uk, a oni podjęli decyzję o zakazie wszystkich relacyjnych baz danych i używali MongoDB wyłącznie do udostępniania swoich wiadomości. Możesz dowiedzieć się, jak szybka jest ich strona internetowa i która jest dostępna od 1995 roku (najstarsza gazeta internetowa w Wielkiej Brytanii). W przeszłości przeszli przez wiele różnych wąskich gardeł z powodu relacyjnych baz danych. W przypadku 180 MB, MongoDB będzie obsługiwał wszystko z pamięci, więc prawdopodobne są czasy ładowania sub-ms.


0

Będzie dziennie około 30 000 zapytań, ale zapytania są tylko bardzo prostym magazynem kluczowych wartości. Musimy tylko sprawdzić identyfikator produktu i wyświetlić resztę informacji (wszystkie byłyby w jednym rekordzie).

Powiedziałeś, że twoje zapytania są po prostu prostymi wyszukiwaniem kluczy, z wyszukiwaniem binarnym potrzebujesz 21 iteracji w najgorszym przypadku, z hashowanymi kluczami twoje zapytania są jeszcze szybsze. Trzy miliony rekordów są małe, o ile unikasz łączenia (lub innych kartezjańskich operacji typu produktu) i wyszukiwania liniowego.

Odważyłbym się powiedzieć, że prawie wszystko by się udało. Twoje obciążenie wynosi 30000 zapytań dziennie oznacza, że ​​(zakładając, że obciążenie jest stałe w ciągu dnia), masz jedno zapytanie co 20 sekund; nie aż tak źle.

Polecam zaimplementowanie w technologii, którą znasz najlepiej, a następnie zmierzenie, czy to naprawdę wąskie gardło systemu.


0

Najlepszy sposób na zrobienie tego naprawdę zależy od jakości i charakteru twoich danych i zapytań. Na początek 180 MB danych w jednej tabeli dla produktów nie stanowi problemu, bez względu na to, jak na to spojrzysz. A 30 000 zapytań dziennie to jeszcze mniejszy problem. Przy odpowiednio skonfigurowanej bazie danych każdy stary pulpit może obsłużyć to obciążenie.

Inni wskazali już dwie główne opcje, MySQL lub bazę danych noSQL.

Jeśli masz pewną liczbę atrybutów, które istnieją dla każdego produktu (takie jak producent, cena, numer magazynu itp.), Najlepszą opcją jest posiadanie kolumn dla tych atrybutów i konwersja par klucz / wartość na format płaskiej tabeli, z identyfikatorem produktu jako kluczem podstawowym dla tej tabeli. Będzie to działało bardzo dobrze, nawet jeśli niektóre kolumny są używane tylko przez połowę wierszy, ponieważ w przypadku większości produktów wystarczy uruchomić 1 zapytanie, aby pobrać wszystkie ich atrybuty. to są dane o produktach, sądzę, że jest to całkiem prawdopodobne, że taka jest struktura twoich danych.

Jeśli atrybuty różnią się znacznie w zależności od obecności i typu danych, być może lepiej będzie użyć bazy danych noSQL, która obsługuje ten scenariusz bardziej wydajnie niż tradycyjne bazy danych SQL.

Jeśli chodzi o wydajność: wcześniej pracowałem w firmie e-commerce, w której przez długi czas strona była zaopatrywana w dane z serwera MySQL. Ten serwer miał 2 GB pamięci RAM, w sumie baza danych wynosiła ok. Rozmiar 5 GB i przy maksymalnym obciążeniu serwer obsługiwał kilka tysięcy zapytań na sekundę. Tak, przeprowadziliśmy wiele optymalizacji zapytań, ale jest to zdecydowanie wykonalne.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.