Jestem nowicjuszem w bazach danych, ale mam problem, którego nie mogę wymyślić. Przepraszam z góry, jeśli to zbyt długo, staram się podsumować wszystkie moje wysiłki, aby dokładnie wiedzieć, co zrobiłem do tej pory. Moja aplikacja ma pewną logikę, a następnie wykonuje 3 zapytania do bazy danych. Pierwsze zapytanie sprawdza, czy istnieje wartość, drugie sprawdza, czy istnieje inna (powiązana) wartość, a trzecia, jeśli nie istnieje, dodaje powiązaną wartość. Pomyśl o tym, że robię zapytanie na numer 2, a jeśli istnieje, sprawdzam 3 i dodam go w razie potrzeby. Robię tę pętlę wiele razy (patrzę na ogólne zapytania, ale podejrzewam, że ten program jest bardziej ciężki niż zapis). Kiedyś używałem tylko hashtable w moim programie, ale gdy dodałem wiele procedur, które miałem problemy z synchronizacją, zdecydowałem się użyć bazy danych, aby wiele rdzeni pracowało nad tym w tym samym czasie.Jak mogę zwiększyć liczbę zapytań do odczytu/sekundę w mojej bazie danych?
Najpierw spróbowałem, mysql i użyłem silnika pamięci (może to wszystko zmieścić się w pamięci), wykonałem złożony klucz podstawowy, aby zreplikować słownik, który miałem w swoim programie, zindeksowałem go, zablokowałem blokadę, ale mogłem tylko dostać około 11 000 zapytań/sekundę od tego.
Potem wypróbowałem redis (usłyszałem, że to było jak memcache) i utworzyłem ten sam klucz/wartość, którą miałem wcześniej (tutaj jest aktualny tryb Can I make two columns unique to each other? or use composite primary key's in redis?) i usunąłem wszystkie rzeczy fsync, więc mam nadzieję, że nigdy nie uderzę w dysk twardy, ale ja wciąż dostaje około 30 000 zapytań/sekundę. Spojrzałem na ulepszenia systemu (używam linuxa), uruchamiając program w ramdrive itp., Ale nadal podobny wynik.
Mam skrypt instalacyjny i próbowałem zrobić to na ec2 przy użyciu instancji wysokiego cpu, ale wynik jest podobny (zapytania nie idą w górę dla obu rozwiązań). Jestem w pewnym sensie na końcu rozumu, ale nie chcę się poddawać, ponieważ czytam ludzi na stackoverflow, mówiących o tym, jak dostali 100 000 000 zapytań na wolnostojące. Czuję, że mój datamodel jest bardzo prosty (dwie kolumny INT lub I mogą uczynić go jednym ciągiem z obydwoma połączonymi INT, ale to nie wydawało się spowalniać ani w dół) i po utworzeniu danych (i zapytaniu przez inny proces) mam nie ma potrzeby utrzymywania (dlatego też staram się nie pisać na dysk twardy). Jakiej konfiguracji brakuje, aby programiści mogli uzyskać tego rodzaju wydajność? Czy jest wymagana specjalna konfiguracja poza tworzeniem tabeli? czy jest to jedyny sposób na uzyskanie tego rodzaju wydajności przez rozproszone bazy danych? Wiem, że problem jest związany z bazą danych, ponieważ kiedy zamykam proces pośredni w bazie danych, moja aplikacja pytona trafia w 100% na każdy rdzeń jej działania (chociaż nic nie pisze), to sprawia, że myślę, że proces oczekiwania (dla odczytów, Podejrzewam, że to jest to, co spowalnia (mam dużo wolnego procesora/pamięci, więc zastanawiam się, dlaczego to nie max'ing, mam 50% procesora i 80% mojej wolnej pamięci podczas tych prac, więc nie mam pojęcia co się dzieje).
Mam mysql, redis i hbase. Mam nadzieję, że jest coś, co mogę zrobić, aby jedno z tych rozwiązań działało tak szybko, jak bym chciał, ale jeśli nie jest, to nie ma problemu z jakimkolwiek rozwiązaniem (jest to po prostu tymczasowy termostat, który może rozpytywać rozproszone procenty).
Co mogę zrobić?
Dzięki!
Aktualizacja: zgodnie z wnioskiem w komentarzach, oto niektóre kodu (po specyficznej logiki aplikacji, która wydaje się, że będzie w porządku):
cursor.execute(""" SELECT value1 FROM data_table WHERE key1='%s' AND value1='%s' """ % (s - c * x, i))
if cursor.rowcount == 1:
cursor.execute(""" SELECT value1 FROM data_table WHERE key1='%s' AND value1='%s' """ % (s, i+1))
if cursor.rowcount == 0:
cursor.execute (""" INSERT INTO data_table (key1, value1) VALUES ('%s', '%s')""" % (s, i+1))
conn.commit() #this maybe not needed
#print 'commited ', c
powyżej jest kod z 3 wyszukiwań na mysql.Próbowałem też zrobić jeden wielki odnośnika (ale to było w rzeczywistości wolniejsze):
cursor.execute ("""
INSERT INTO data_table (key1, value1)
SELECT '%s', '%s'
FROM dual
WHERE (SELECT COUNT(*) FROM data_table WHERE key1='%s' AND value1='%s')
= 1
AND NOT EXISTS
(SELECT * FROM data_table WHERE key1='%s' AND value1='%s')
""" % ((s), (i+1), (s - c * x), (i), (s), (i+1)))
oto projekt stół na MySQL:
cursor.execute ("DROP TABLE IF EXISTS data_table")
cursor.execute ("""
CREATE TABLE data_table(
key1 INT SIGNED NOT NULL,
value1 INT SIGNED NOT NULL,
PRIMARY KEY (key1,value1)
) ENGINE=MEMORY
""")
cursor.execute("CREATE INDEX ValueIndex ON data_table (key1, value1)")
na Redis, jego simlair do struktury 3 zapytania (od to był najszybszy mogę dostać na mysql, z wyjątkiem nie trzeba zrobić odnośnika jeśli wartość nie istnieje, po prostu zastąpić go zapisać kwerendę):
if r_server.sismember(s - c * x, i):
r_server.sadd(s, i + 1)
Moja struktura danych dla REDiS jest połączony pytanie (w zasadzie jego al ist, 3 => 1 2 3 zamiast mysql mającego 3 wiersze do ponownego wysłania 3 = 1, 3 = 2, 3 = 3.
Nadzieję, że pomaga, wszelkie inne pytania proszę dać mi znać.
Być może uda się to osiągnąć za pomocą jednego zoptymalizowanego zapytania, co pozwoli zaoszczędzić na wycieczkach do bazy danych. Potrzebujemy więcej informacji, takich jak zapytania, schemat i logika. –
@MarcusAdams Dzięki za komentarz. Zaktualizowałem to pytanie za pomocą mojego kodu mysql i redis. – Lostsoul