Простые запросы SELECT (*) очень медленные в Apache Ignite

Я создаю прототип Apache Ignite для использования в новом продукте. Мне нужно хранить в памяти очень широкую матрицу и получать доступ к различным случайным строкам и столбцам. Матрица имеет 50 000 столбцов и потенциально миллионы строк. По сути, матрица будет доступна только для чтения, поэтому нас не волнует скорость записи.

Нам не нужно никогда заказывать результаты. Клиентское приложение будет запрашивать определенные строки по первичному ключу и, возможно, по определенным столбцам, а иногда и по всей строке (строкам).

Я загрузил данные в Apache Ignite в таблицу SQL, которая выглядит так:

CREATE TABLE myMatrix
name CHAR(20) PRIMARY KEY,
col1 INT,
col2 INT,
col3 INT,
...
col50000 INT

Я также проиндексировал столбец "имя"

CREATE INDEX name_index ON myMatrix(name)

Однако, когда я пытаюсь просто выбрать одну строку, на возврат результата уходит более 10 секунд. Нам нужно гораздо более быстрое время отклика - клиент будет ожидать набора строк (может быть сотни или тысячи) и столбцов (вплоть до всех столбцов) менее чем за секунду.

import pandas as pd
import pyignite
from pyignite import Client
import time

client = Client()

client.connect('127.0.0.1', 10800)

now = time.time()
result = client.sql('SELECT * FROM full_test_table WHERE      name=\'F1S4_160106_058_G01\'')
print('Got Result in')
print(time.time() - now)

Почему это так мучительно медленно? Я надеялся, что хранение всей таблицы в памяти даст более быстрые результаты. Проблема только в ширине таблицы?

База данных работает на экземпляре r4.8xlarge с 32 ядрами и 244 ГБ памяти.


person Community    schedule 25.06.2019    source источник
comment
Вы проверили использование индекса с помощью плана запроса? Также это выглядит немного странно, вам нужно создать дополнительный индекс для имени, поскольку у него уже есть первичный ключ   -  person Raymond Nijland    schedule 25.06.2019
comment
Мне не нужно было, но в то время я не был уверен, генерирует ли Ignite индексы с первичным ключом. Похоже, что используется индекс первичного ключа: __Z0.440590 AS __C0_50274, __Z0.100131879 AS __C0_50275, __Z0.79699 AS __C0_50276, __Z0.7791 AS __C0_50277, __Z0.23140 AS __C0_50277, __Z0.23140 AS __C0__ __C0__Z, __Z0.23140 AS __C0__0__50 AS __C0_50280, __Z0.150478 AS __C0_50281 FROM PUBLIC.FULL_TEST_TABLE __Z0 / * PUBLIC._key_PK_proxy: NAME = 'F1S4_160106_058_G01' * / WHERE __Z0.NAME_160106s   -  person    schedule 25.06.2019
comment
Если это так, я бы посоветовал изучить более зрелую базу данных.   -  person Raymond Nijland    schedule 25.06.2019
comment
Какие-нибудь рекомендации?   -  person    schedule 25.06.2019
comment
MySQL, MariaDB или PostgreSQL все базы данных с открытым исходным кодом и бесплатные базы данных   -  person Raymond Nijland    schedule 25.06.2019
comment
@RaymondNijland, правда, они не распространяются.   -  person alamar    schedule 26.06.2019
comment
О, вы имеете в виду, что вам нужна зрелая встроенная база данных, которую, я полагаю, вы имеете в виду с распределенной? Ну что, SQLite?   -  person Raymond Nijland    schedule 26.06.2019
comment
@RaymondNijland Distributed означает распределение данных по разным узлам на разных машинах.   -  person alamar    schedule 26.06.2019
comment
Швы, я совершенно неверно истолковываю значение слова «распределенный», я думаю, что мне очень нужен кофе во время написания @alamar, он ошибается, поскольку MySQL / MariaDB поддерживает кластеризация, которая делает то же самое ..   -  person Raymond Nijland    schedule 26.06.2019
comment
MySQL Cluster - это распределенная база данных, сочетающая линейную масштабируемость и высокую доступность. Он обеспечивает доступ в памяти в реальном времени с согласованностью транзакций между секционированными и распределенными наборами данных. Он разработан для критически важных приложений. MySQL Cluster имеет встроенную репликацию между кластерами на нескольких географических сайтах. Архитектура без общего доступа с учетом локализации данных делает ее идеальным выбором для работы на стандартном оборудовании и в глобально распределенной облачной инфраструктуре.   -  person Raymond Nijland    schedule 26.06.2019
comment
Для кластеризации PostreSQL см. Репликация, кластеризация и объединение подключений   -  person Raymond Nijland    schedule 26.06.2019


Ответы (3)


Я пробовал запустить пример, очень похожий на ваш, и оказалось, что SQL-синтаксический анализатор Ignite (на основе синтаксического анализатора H2 SQL) имеет квадратичную сложность производительности по количеству столбцов ответа. Это означает, что невозможно иметь 50 000 столбцов в таблице в Ignite или что-то большее, чем несколько десятков в этом отношении. Я постараюсь подать жалобу на трекер ошибок H2.

Предыдущий ответ:

У тебя настойчивость есть, или все в оперативке? Я просто не понимаю, почему это заняло так много времени. Может быть, возникла какая-то проблема с встраиванием - вы пробовали CREATE INDEX name_index ON myMatrix(name) INLINE_SIZE 25?

Во-вторых, наличие 50 000 столбцов не является оптимальным. Лучше использовать массив.

person alamar    schedule 26.06.2019
comment
Единственная проблема с использованием массива заключается в том, что нам нужно получить весь массив, прежде чем получать из него отдельные значения. Часто нас будет интересовать только небольшое подмножество массива. - person ; 26.06.2019
comment
Внутренне Ignite все равно придется десериализовать весь объект, когда вы к нему обращаетесь. Передача массива по сети, вероятно, будет более эффективной, чем передача отдельных столбцов. - person alamar; 26.06.2019
comment
Итак, в таком случае не следует ли хранить его в таблице SQL так же, как хранить массивы? SQL обеспечивает большую простоту использования и удобочитаемость. - person ; 26.06.2019
comment
Нет, SQL также имеет много метаданных / обработки для каждого столбца, что может оказаться очень медленным. - person alamar; 27.06.2019
comment
Спасибо за анализ. Это интересно, потому что Ignite и Casandra рекламируют себя для «масштабирования до миллиардов строк и миллионов столбцов», хотя на самом деле они борются с тысячами строк и десятками тысяч столбцов ... - person ; 28.06.2019
comment
Я не совсем уверен, что Ignite рекламирует миллионы столбцов где-либо, но если это так, я непреклонен, это нужно исправить. Есть ссылки? - person alamar; 29.06.2019

Это не совсем ответ, но я видел ваш предыдущий вопрос, а теперь вижу, что вы используете панды. Что, если вы просто обработаете свою матрицу (NumPy / pandas Array, я полагаю) и поместите ее в кеш Ignite как ByteArrayObject, а затем перед использованием распакуйте ее до pandas.Array? Решит ли это вообще ваш вопрос?

Вот небольшое замечание, если будет. ByteArrayObject в текущем выпуске работает очень медленно, но я уже внес улучшения, и исправления ждут, чтобы их включить в следующие версии. Напишите мне, если они вам понадобятся в упаковке.

Также существует список рассылки Apache Ignite Users. Здесь вы можете подписаться и обсудить свою задачу.

person Jock Tanner    schedule 26.06.2019

Основываясь на анализе @ alamar, если вы действительно не можете отказаться от тысяч столбцов, я бы рекомендовал вам использовать API kv: https://apacheignite.readme.io/docs/python-thin-client-key-value

При этом, отсутствие 50 000 столбцов в кэше / таблице было бы лучшим решением.

person Stephen Darlington    schedule 28.06.2019