#python-3.x #h2 #ignite
#python-3.x #h2 #ignite
Вопрос:
ОС: Ubuntu 18.04
Apache Ignite: 2.9.0 (последняя версия)
Загруженные данные: (набор данных электронной коммерции в Бразилии из Kaggle)
2 таблицы:
заказы: 100 тыс. записей
order_payments: 100 тыс. записей
Индексированные столбцы:
order_payments: CREATE INDEX idx_order_payments ON order_payments (id, order_id, payment_type)
заказы: CREATE INDEX idx_orders ON orders (order_id,customer_id,order_status,order_purchase_timestamp)
В общей сложности занимает ~ 400 МБ места в Ignite вне кучи и постоянства.
Я выполняю простой SQL-запрос:
SELECT orders.order_status,
order_payments.payment_type,
SUM(order_payments.payment_value) AS total_payments
FROM order_payments
JOIN orders ON orders.order_id = order_payments.order_id
GROUP BY orders.order_status, order_payments.payment_type
ORDER BY total_payments DESC
Я запускаю Apache Ignite в контейнере docker.
Это конфигурация шаблона кэша:
<property name="cacheConfiguration">
<list>
<bean abstract="true" class="org.apache.ignite.configuration.CacheConfiguration"
id="cache-template-bean">
<!-- when you create a template via XML configuration, you must add an asterisk to
the name of the template -->
<property name="name" value="tbl_pll*"/>
<property name="cacheMode" value="PARTITIONED"/>
<property name="backups" value="1"/>
<property name="queryParallelism" value="4"/>
<!-- Other cache parameters -->
</bean>
<bean abstract="true" class="org.apache.ignite.configuration.CacheConfiguration"
id="cache-template-bean">
<!-- when you create a template via XML configuration, you must add an asterisk to
the name of the template -->
<property name="name" value="tbl_hf_pll*"/>
<property name="cacheMode" value="PARTITIONED"/>
<property name="backups" value="1"/>
<property name="queryParallelism" value="2"/>
<!-- Other cache parameters -->
</bean>
</list>
</property>
Когда я использую tbl_pll
шаблон кэша для таблиц, результирующий набор (для запроса) составляет приблизительно (1 / queryParallelism) * Количество значений в таблице.
Таким образом, в tbl_pll
случае s он возвращает примерно 1/4 ожидаемого результата.
Я попробовал то же самое с queryParallelism=2
, и это дает мне примерно 1/2-й результат.
Я также попытался не использовать какой-либо шаблон кэша, используя значение queryParallelism
параметра по умолчанию, т.е. 1, и это вернуло полный результат.
Ожидаемый полный результат (и вывод, когда queryParallelism=1
):
[['delivered', 'credit_card', 12101094.87999937]
['delivered', 'boleto', 2769932.57999998]
['delivered', 'voucher', 343013.19]
['delivered', 'debit_card', 208421.12]]
С queryParallelism=4
:
[['delivered', 'credit_card', 4064387.2800000096],
['delivered', 'boleto', 918272.54],
['delivered', 'voucher', 110648.45000000004],
['delivered', 'debit_card', 64584.53000000001]]
С queryParallelism=2
:
[['delivered', 'credit_card', 6129872.129999977],
['delivered', 'boleto', 1360427.3799999985],
['delivered', 'voucher', 168392.55999999976],
['delivered', 'debit_card', 107637.38999999996]]
Что я подозреваю:
параллелизм запросов использует сегментированный индекс, вывод основан на том, что было в последнем / первом сегменте индекса.
Либо сокращение не работает должным образом, и выходные данные не объединяются из всех потоков, либо Ignite запускает только один поток и возвращает выходные данные после сокращения.
Поскольку я добавил столбец payment_type для order_payments в индекс, результат, похоже, почти идеально делится на количество потоков / сегментов индекса.
Что я делаю не так и как я могу это исправить?
Редактировать: я запускаю только 1 экземпляр Apache Ignite.
Кроме того, вывод ключевого слова EXPLAIN:
SELECT
__Z1.ORDER_STATUS AS __C0_0,
__Z0.PAYMENT_TYPE AS __C0_1,
SUM(__Z0.PAYMENT_VALUE) AS __C0_2
FROM PUBLIC.ORDERS __Z1
/* PUBLIC.ORDERS.__SCAN_ */
INNER JOIN PUBLIC.ORDER_PAYMENTS __Z0
/* PUBLIC.IDX_ORDER_PAYMENTS: ORDER_ID = __Z1.ORDER_ID */
ON 1=1
WHERE __Z1.ORDER_ID = __Z0.ORDER_ID
GROUP BY __Z1.ORDER_STATUS, __Z0.PAYMENT_TYPE'], ['SELECT
__C0_0 AS ORDER_STATUS,
__C0_1 AS PAYMENT_TYPE,
CAST(CAST(SUM(__C0_2) AS DOUBLE) AS DOUBLE) AS TOTAL_PAYMENTS
FROM PUBLIC.__T0
/* PUBLIC."merge_scan" */
GROUP BY __C0_0, __C0_1
ORDER BY 3 DESC
Комментарии:
1. как вы создаете кеш? Как вы выполняете запрос? как предположение: вам нужно либо совместно разместить свои данные, либо включить распределенные соединения.
2. Я создаю с помощью Ignite SQL ddl команду CREATE TABLE для создания кэша, и я запускаю один экземпляр / узел Apache Ignite.
3. Affinity colocation не сработал. Однако настройка
distributed_joins=True
при выполнении запроса выполнила и вернула правильный результат. Однако время, затраченное на запрос сqueryParallelism
= 4, совпадает со временем, затраченным при параллелизме по умолчанию, равном 1.
Ответ №1:
Убедитесь, что таблицы расположены совместно. Используйте affinityKey
параметр CREATE TABLE
команды, чтобы сгруппировать данные вместе.
Кроме того, убедитесь, что механизм Ignite SQL выбирает наилучший индекс. Как правило, как только вы устанавливаете affinityKey
указатель на order_id
столбец, тогда order_id
индекс должен быть выбран во время объединения.
Комментарии:
1. Я использую один узел Ignite, и запрос, похоже, выбирает правильный индекс. Я попробую использовать affinitykey и коллокацию, однако я не уверен, требуются ли они, если я запускаю экземпляр с одним узлом.
2. Я попробовал affinity colocation и установил ключ (по умолчанию используется primary key col), однако это не сработало (документы заставляют думать, что это должно работать), и единственное, что сработало, это установка
distributed_joins=True
в качестве параметра при выполнении запроса. Однако время, затрачиваемое при установке параллелизма запросов на 4, теперь совпадает с временем, затрачиваемым одним потоком.