2016-06-11 5 views
0

В настоящее время я работаю над системой отслеживания данных. Система представляет собой несколько процессов приложения, написанные на Python и работает следующим образом:Эффективное решение для решения системных задач

  1. каждый S секунды она выбирает N наиболее соответствующие задачи из базы данных (в настоящее время Postgres) и находит данные для него
  2. если есть нет задач, он создает N новых задач и возвращается к (1).

Проблема следующая - в настоящее время у меня около. 80 ГБ данных и 36 М задач, а запросы к таблице задач начинают работать медленнее и медленнее (наиболее популярная и наиболее часто используемая таблица).

Основное узкое место производительности является отслеживание задачи запрос:

LOCK TABLE task IN ACCESS EXCLUSIVE MODE; 
SELECT * FROM task WHERE line = 1 AND action = ANY(ARRAY['Find', 'Get']) AND (stat IN ('', 'CR1') OR stat = 'ERROR' AND (actiondate <= NOW() OR actiondate IS NULL)) ORDER BY taskid, actiondate, action DESC, idtype, date ASC LIMIT 36; 

            Table "public.task" 
    Column |   Type    |     Modifiers 
------------+-----------------------------+------------------------------------------------- 
number  | character varying(16)  | not null 
date  | timestamp without time zone | default now() 
stat  | character varying(16)  | not null default ''::character varying 
idtype  | character varying(16)  | not null default 'container'::character varying 
uri  | character varying(1024)  | 
action  | character varying(16)  | not null default 'Find'::character varying 
reason  | character varying(4096)  | not null default ''::character varying 
rev  | integer      | not null default 0 
actiondate | timestamp without time zone | 
modifydate | timestamp without time zone | 
line  | integer      | 
datasource | character varying(512)  | 
taskid  | character varying(32)  | 
found  | integer      | not null default 0 
Indexes: 
    "task_pkey" PRIMARY KEY, btree (idtype, number) 
    "action_index" btree (action) 
    "actiondate_index" btree (actiondate) 
    "date_index" btree (date) 
    "line_index" btree (line) 
    "modifydate_index" btree (modifydate) 
    "stat_index" btree (stat) 
    "taskid_index" btree (taskid) 

           QUERY PLAN       
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Limit (cost=312638.87..312638.96 rows=36 width=668) (actual time=1838.193..1838.197 rows=36 loops=1) 
    -> Sort (cost=312638.87..313149.54 rows=204267 width=668) (actual time=1838.192..1838.194 rows=36 loops=1) 
     Sort Key: taskid, actiondate, action, idtype, date 
     Sort Method: top-N heapsort Memory: 43kB 
     -> Bitmap Heap Scan on task (cost=107497.61..306337.31 rows=204267 width=668) (actual time=1013.491..1343.751 rows=914586 loops=1) 
       Recheck Cond: ((((stat)::text = ANY ('{"",CR1}'::text[])) OR ((stat)::text = 'ERROR'::text)) AND (line = 1)) 
       Filter: (((action)::text = ANY ('{Find,Get}'::text[])) AND (((stat)::text = ANY ('{"",CR1}'::text[])) OR (((stat)::text = 'ERROR'::text) AND ((actiondate <= now()) OR (actiondate IS NULL))))) 
       Rows Removed by Filter: 133 
       Heap Blocks: exact=76064 
       -> BitmapAnd (cost=107497.61..107497.61 rows=237348 width=0) (actual time=999.457..999.457 rows=0 loops=1) 
        -> BitmapOr (cost=9949.15..9949.15 rows=964044 width=0) (actual time=121.936..121.936 rows=0 loops=1) 
          -> Bitmap Index Scan on stat_index (cost=0.00..9449.46 rows=925379 width=0) (actual time=117.791..117.791 rows=920900 loops=1) 
           Index Cond: ((stat)::text = ANY ('{"",CR1}'::text[])) 
          -> Bitmap Index Scan on stat_index (cost=0.00..397.55 rows=38665 width=0) (actual time=4.144..4.144 rows=30262 loops=1) 
           Index Cond: ((stat)::text = 'ERROR'::text) 
        -> Bitmap Index Scan on line_index (cost=0.00..97497.14 rows=9519277 width=0) (actual time=853.033..853.033 rows=9605462 loops=1) 
          Index Cond: (line = 1) 
Planning time: 0.284 ms 
Execution time: 1838.882 ms 
(19 rows) 

Конечно, все задействованные поля индексируются. Я в настоящее время думать в двух направлениях:

  1. как оптимизировать запрос и он будет на самом деле дать мне повышение производительности на перспективу или нет (в настоящее время она занимает около 10 секунд на запрос, который неприемлем в динамическом отслеживания задач.)
  2. где и как было бы более эффективно хранить данные задачи - может быть, я должен использовать другую БД для таких целей - Cassandra, VoltDB или другое хранилище больших данных?

Я думаю, что данные должны быть как-то предварительно упорядочены, чтобы как можно быстрее выполнять реальные задачи.

А также помните, что мой текущий том 80G, скорее всего, является минимальным, а не максимальным для такой задачи.

Заранее благодарен!

+1

1) Вам действительно нужны все эти огромные поля varchar, если вы не переместите их на отдельные таблицы? 2) Особенно первичный ключ, а поля с низкой мощностью (статус, тип, действие) могут быть уплотнены для целочисленных типов. 3) для * типичных * запросов, подобных этому, можно использовать неполные (* составные *) индексы. 4) смысл таблицы не ясен, он, похоже, объединяет (статус, действие, протоколирование) виды фактов. – wildplasser

ответ

0

Я не совсем понимаю ваш прецедент, но мне не кажется, что ваши индексы работают слишком хорошо. Похоже, что запрос опирается главным образом на индекс статистики. Я думаю, вам нужно посмотреть в составной индекс что-то вроде (action, line, stat).

Другим вариантом является очертить ваши данные на нескольких таблицах, разбивая их на некоторый ключ с низкой мощностью. Я не использую postgres, но я не думаю, что поиск другого решения db будет работать лучше, если вы точно не знаете, для чего вы оптимизируете.

+0

Не могли бы вы немного объяснить последнее предложение? – Severogor

+0

Другие базы, о которых вы упомянули, хороши в некоторых вещах и плохо в других. Лично я думаю, что postgres легче всего научиться сначала оптимизировать, поэтому я бы придерживался этого, если у вас нет действительно веской причины для переключения. (Ответ на stackoverflow не даст вам достаточно информации, чтобы знать, если вы хотите, если вы уже не знаете, что спросить). –

Смежные вопросы