По Digoal
Потоковые вычисления можно использовать в различных сценариях, но в электронной коммерции часто возникают проблемы из-за тайм-аутов доставки и возврата средств. Но один вопрос заключается в том, как сделать так, чтобы предупреждения о потоковой передаче подходили даже для этих сценариев? Ответ, который я представлю в этом блоге, — это решение, основанное на сочетании операций тайм-аута и планирования с использованием PostgreSQL.
PostgreSQL выгоден для наших нужд в этом руководстве, потому что он использует гибкий синтаксис общего табличного выражения (CTE), общий для языков SQL, и частичные индексы, которые не записывают ненужные данные. Кроме того, он использует операторы языка манипулирования данными (DML), которые могут быть возвращены и использованы вместе с синтаксисом CTE, чтобы свести к минимуму интерактивные вычисления, и использует сканирование растровых изображений с несколькими индексами, которое объединяет несколько индексов для сканирования, что позволяет нам комбинировать индексы нескольких полей для сканирования при использовании условия ИЛИ.
Подводя итог, в этом руководстве я покажу вам, как вы можете создать пример решения этих проблем с помощью комбинации тайм-аута и операций планирования с помощью PostgreSQL.
Создать демонстрационный дизайн
Чтобы создать демонстрационное решение, сначала необходимо спроектировать структуру отслеживаемой таблицы. В этой таблице будет записано время ожидания обработки заказов и событий возврата, а также количество уведомлений об истечении времени ожидания, время следующего уведомления и статусы завершения. Для этого вы можете использовать следующую команду в PostgreSQL:
create table tbl (
id int8,
-- ... Other fields, such as the completion status
state int, -- Completion status (1 indicates Completed)
deadts timestamp, -- Timeout
nts interval, -- Timeout interval, used to update the next notification time, for example, one notification per day
notify_times int default 0, -- Number of notifications
deadts_next timestamp -- Next notification time
);
Далее вам нужно создать частичный индекс. Этот индекс предназначен для того, чтобы пользователи уведомлялись только о незавершенных заявках, которые, скорее всего, их больше всего беспокоят. Используя частичный индекс, мы можем уменьшить размер индекса и увеличить скорость. Для этого введите этот код:
create index idx_tbl_1 on tbl (deadts) where notify_times=0 and state<>1;
create index idx_tbl_2 on tbl (deadts_next) where deadts_next is not null and state<>1;
Далее, как часть этого, нам нужно получить соответствующие данные от пользователей, которые будут включать данные уведомлений и обновлять количество уведомлений и время следующего уведомления. Вы можете сделать это, запустив этот код:
with tmp1 as (
update tbl set
deadts_next=now()+nts,
notify_times=notify_times+1
where ctid = any (array(
select ctid from tbl where
( deadts < now() and notify_times=0 and state<>1)
union all
select ctid from tbl where
( deadts_next < now() and deadts_next is not null and state<>1)
limit 10000 -- Obtains 10,000 timeout data records at a time.
))
returning *
)
select * from tmp1;
Затем выполните план следующим образом:
CTE Scan on tmp1 (cost=18163.25..18163.45 rows=10 width=48)
CTE tmp1
-> Update on tbl tbl_2 (cost=18151.05..18163.25 rows=10 width=54)
InitPlan 1 (returns $0)
-> Limit (cost=0.13..18151.03 rows=10000 width=6)
-> Append (cost=0.13..764699.60 rows=421301 width=6)
-> Index Scan using idx_tbl_1 on tbl (cost=0.13..169527.13 rows=369766 width=6)
Index Cond: (deadts < now())
-> Index Scan using idx_tbl_2 on tbl tbl_1 (cost=0.43..590959.46 rows=51535 width=6)
Index Cond: (deadts_next < now())
-> Tid Scan on tbl tbl_2 (cost=0.01..12.21 rows=10 width=54)
TID Cond: (ctid = ANY ($0))
(12 rows)
Создание показателей эффективности
Если предположить, что записано 0,1 миллиарда записей данных, у вас может возникнуть вопрос: сколько времени занимает одновременная обработка одного миллиона записей данных? Что ж, рассмотрим следующее:
-- Processing of 0.1 billion data records is completed.
insert into tbl select id, 1, now(), '5 min', 0, null from generate_series(1,100000000) t(id);
-- Processing of one million data records times out.
insert into tbl select id, 0, now(), '5 min', 0, null from generate_series(1,1000000) t(id);
Как видно из приведенного выше кода, производительность уведомлений, например, генерирует уведомление каждый раз, когда истекает время обработки 10 000 записей.
После этого извлекается небольшой пакет данных, а время ожидания обновляется, чтобы можно было ввести AutoVacuum для сбора мусора в режиме реального времени. Рассмотрим следующее:
with tmp1 as (
update tbl set
deadts_next=now()+nts,
notify_times=notify_times+1
where ctid = any (array(
select ctid from tbl where
( deadts < now() and notify_times=0 and state<>1)
union all
select ctid from tbl where
( deadts_next < now() and deadts_next is not null and state<>1)
limit 10000 -- Obtains 10,000 timeout data records at a time.
))
returning *
)
select * from tmp1;
-- Planning
CTE Scan on tmp1 (cost=18163.25..18163.45 rows=10 width=48) (actual time=39.092..78.707 rows=10000 loops=1)
Output: tmp1.id, tmp1.state, tmp1.deadts, tmp1.nts, tmp1.notify_times, tmp1.deadts_next
Buffers: shared hit=75094 read=49 dirtied=49
CTE tmp1
-> Update on public.tbl tbl_2 (cost=18151.05..18163.25 rows=10 width=54) (actual time=39.089..74.637 rows=10000 loops=1)
Output: tbl_2.id, tbl_2.state, tbl_2.deadts, tbl_2.nts, tbl_2.notify_times, tbl_2.deadts_next
Buffers: shared hit=75094 read=49 dirtied=49
InitPlan 1 (returns $0)
-> Limit (cost=0.13..18151.03 rows=10000 width=6) (actual time=31.265..36.899 rows=10000 loops=1)
Output: tbl.ctid
Buffers: shared hit=11395
-> Append (cost=0.13..764699.60 rows=421301 width=6) (actual time=31.264..35.354 rows=10000 loops=1)
Buffers: shared hit=11395
-> Index Scan using idx_tbl_1 on public.tbl (cost=0.13..169527.13 rows=369766 width=6) (actual time=0.014..0.014 rows=0 loops=1)
Output: tbl.ctid
Index Cond: (tbl.deadts < now())
Buffers: shared hit=1
-> Index Scan using idx_tbl_2 on public.tbl tbl_1 (cost=0.43..590959.46 rows=51535 width=6) (actual time=31.249..33.870 rows=10000 loops=1)
Output: tbl_1.ctid
Index Cond: (tbl_1.deadts_next < now())
Buffers: shared hit=11394
-> Tid Scan on public.tbl tbl_2 (cost=0.01..12.21 rows=10 width=54) (actual time=39.017..43.529 rows=10000 loops=1)
Output: tbl_2.id, tbl_2.state, tbl_2.deadts, tbl_2.nts, (tbl_2.notify_times + 1), (now() + tbl_2.nts), tbl_2.ctid
TID Cond: (tbl_2.ctid = ANY ($0))
Buffers: shared hit=21395
Planning time: 0.301 ms
Execution time: 79.905 ms
Как видите, данные обрабатываются плавно.
Time: 79.905 ms
Вывод
Подводя итог, в этом руководстве я представил метод, с помощью которого вы можете решить проблему мониторинга данных тайм-аута в сценариях электронной коммерции, который не только решает эту проблему, но и обеспечивает хорошую производительность.
Оригинальный источник
Как мы можем отслеживать исключения данных «Нет входящих сообщений?
digoal 6 сентября 2019 г. 521 Потоковые вычисления можно использовать в различных сценариях, но в электронной коммерции , часто это может…www.alibabacloud.com»