Я новичок в базах данных, но у меня возникла проблема, которую я не могу решить. Извините заранее, если это слишком долго, я пытаюсь обобщить все мои усилия, чтобы вы точно знали, что я сделал до сих пор. У меня есть приложение с некоторой логикой, а затем выполняет 3 запроса к базе данных. Первый запрос проверяет, существует ли значение, второй проверяет, существует ли другое (связанное) значение, а третий, если он не существует, добавляет связанное значение. Думайте, что я делаю запрос на число 2, и если оно существует, я проверяю на 3 и добавляю его при необходимости Я делаю этот цикл большое количество раз (я смотрю на общие запросы, но подозреваю, что эта программа более тяжелая, чем запись). Раньше я использовал в своей программе только хеш-таблицу, но, добавив несколько процессов, у меня возникли проблемы с синхронизацией, поэтому я решил использовать базу данных, чтобы несколько ядер могли работать с ней одновременно.
Сначала я попробовал, mysql и использовал механизм хранения памяти (он мог умещаться в памяти), создал составной первичный ключ для репликации словаря, который был в моей программе, проиндексировал его, отключил блокировку, но я мог только получить 11 000 запросов в секунду от него.
Затем я попробовал redis (слышал, что это было похоже на memcache) и создал тот же ключ / значение, что и раньше (вот фактический режим Могу ли я сделать два столбца уникальными друг для друга? Или использовать составной первичный ключ в redis ? ) и удалил все, что есть в fsync, так что мы надеемся, что он никогда не попадет во ввод-вывод с жестким диском, но я все еще получаю только около 30 000 запросов в секунду. Я посмотрел на улучшения системы (я использую linux), запустив программу в ramdrive и т. Д., Но все еще схожий результат.
У меня есть сценарий установки, и я попытался сделать это на ec2 с использованием экземпляра с высоким процессором, но результат схожий (запросы не сильно увеличиваются для обоих решений). Я вроде как в своем уме, но не хочу сдаваться, потому что я читаю о людях на stackoverflow, рассказывающих о том, как они получили более 100 000 000 запросов в автономном режиме. Я чувствую, что моя модель данных очень проста (два столбца INT или я могу сделать ее одной строкой с двумя объединенными INT, но это, похоже, не замедляется), и как только данные созданы (и запрошены другим процессом), у меня есть нет необходимости в настойчивости (именно поэтому я стараюсь не писать на жесткий диск). Какие настройки мне не хватает, что позволяет разработчикам получать такую производительность? Требуется ли специальная конфигурация вне создания таблицы? или это единственный способ получить такую производительность через распределенные базы данных? Я знаю, что проблема с базой данных, потому что, когда я закрываю базу данных в середине процесса, мое приложение python достигает 100% на каждом ядре, на котором оно работает (хотя оно ничего не пишет), это заставляет меня думать, что процесс ожидания (для чтения, Я подозреваю) это то, что замедляет его (у меня много свободного процессора / памяти, поэтому мне интересно, почему его не хватает, у меня 50% процессорного времени и 80% моей памяти свободно во время этих заданий, поэтому я понятия не имею, что происходит).
У меня есть mysql, redis и hbase. надеюсь, что я смогу сделать так, чтобы одно из этих решений работало так быстро, как мне хотелось бы, но если нет, я не справлюсь ни с одним решением (на самом деле это просто временная хеш-таблица, которую могут запрашивать распределенные процессы).
Что я могу сделать?
Спасибо!
Обновление: как требуется в комментариях, вот некоторый код (после логики конкретного приложения, которая, кажется, работает нормально):
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
выше - код с 3 поисками на MySQL. Я также попытался сделать один большой поиск (но на самом деле это было медленнее):
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)))
Вот дизайн таблицы на 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)")
в Redis, его симлаир со структурой 3 запросов (поскольку он был самым быстрым, который я мог получить в MySQL, за исключением того, что мне не нужно искать, если значение существует, я просто перезаписываю его, чтобы сохранить запрос):
if r_server.sismember(s - c * x, i):
r_server.sadd(s, i + 1)
Моя структура данных для redis находится в связанном вопросе (в основном это список, 3 => 1 2 3 вместо mysql с 3 строками для представления 3 = 1, 3 = 2, 3 = 3.
Надеюсь, это поможет, любые другие вопросы, пожалуйста, дайте мне знать.