Как мне увеличить количество запросов чтения в секунду для моей базы данных?

Я новичок в базах данных, но у меня проблема, которую я не могу понять выяснить. Заранее извините, если это слишком долго, я пытаюсь обобщить все мои усилия, чтобы вы точно знали, что я сделал до сих пор. У меня есть приложение, в котором есть некоторая логика, а затем оно выполняет 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.

Надеюсь, что это поможет, дайте мне знать, если у вас возникнут другие вопросы.

9
задан Community 23 May 2017 в 02:07
поделиться