Я новичок в базах данных, но у меня проблема, которую я не могу понять выяснить. Заранее извините, если это слишком долго, я пытаюсь обобщить все мои усилия, чтобы вы точно знали, что я сделал до сих пор. У меня есть приложение, в котором есть некоторая логика, а затем оно выполняет 3 запроса к базе данных. Первый запрос проверяет, существует ли значение, второй проверяет, существует ли другое (связанное) значение, а третий, если не существует, добавляет связанное значение. Представьте, что я делаю запрос по номеру 2, и если он существует, я проверяю 3 и добавляю его при необходимости. Я выполняю этот цикл много раз (я просматриваю общие запросы, но подозреваю, что эта программа более тяжелая для чтения, чем для записи). Раньше я использовал в своей программе только хеш-таблицу, но когда я добавил несколько процессов, у меня возникли проблемы с синхронизацией, поэтому я решил использовать базу данных, чтобы несколько ядер могли работать над этим одновременно.
Сначала я попробовал mysql и использовал механизм хранения в памяти (все могло поместиться в памяти), сделал составной первичный ключ для репликации словаря, который был у меня в программе, проиндексировал его, отключил блокировку, но я мог только 11000 запросов в секунду от него.
Затем я попробовал redis (слышал, что это похоже на memcache) и создал тот же ключ / значение, что и раньше (вот фактический режим Могу ли я сделать два столбца уникальными друг для друга? Или использовать составной первичный ключ в redis ? ) и удалил все, что связано с fsync, поэтому, надеюсь, он никогда не попадет на ввод-вывод жесткого диска, но я все равно получаю только около 30 000 запросов в секунду. Я посмотрел на улучшения системы (я использую linux), запустив программу в ramdrive и т. Д., Но все равно получил аналогичный результат.
У меня есть сценарий установки, и я пытался сделать это на ec2 с использованием экземпляра с высоким процентом процессора, но результат был аналогичным (запросы не сильно увеличиваются для обоих решений). Я в некотором роде сошел с ума, но не хочу сдаваться, потому что я читал о людях в stackoverflow, говорящих о том, как они получили более 100 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.
Надеюсь, что это поможет, дайте мне знать, если у вас возникнут другие вопросы.