Ухудшение производительности импорта базы данных PostgreSQL - PullRequest
0 голосов
/ 12 февраля 2020

Привет PostgreSQL гуру!

Я ищу несколько советов по поводу производительности PostgreSQL в отношении импорта "больших" пакетов данных.

Весь процесс довольно прост. У меня есть база данных BigQuery, которую я загружаю в базу данных sqlite3. А затем после некоторой обработки мне нужно закачать данные в PostgreSQL. Я использую Python 3.6.9 для извлечения данных из базы данных sqlite3 в кадр данных (используя read_sql_query) ... это занимает секунды - 12 с для самого большого набора записей из 3.388.566 записей - в настоящее время работает в течение 11 часов и до сих пор не законченный. Затем я использую многопоточность Python, чтобы порождать 8 потоков, каждый из которых загружает 1/8 данных в 8192 больших кусках.

На основании исследований и тестов, которые я провел с Python против PostgreSQL импорта Я использую метод с StringIO, который «записывает» dataframe.to_csv, а затем copy_from для подачи в базу данных PostgreSQL.

Все это прекрасно работало, пока я не начал использовать индексы. Я прекрасно понимал, что это повлияет на производительность нагрузки, но без них производительность запросов была просто ужасна, поэтому мне нужно их использовать. Данные являются данными события и, таким образом, содержат метку времени с полем tz, пару полей uuid, некоторые поля varchars и dbl pre c. Всего 11 полей, 5 из них проиндексированы (1 отметка времени и 4 поля uuid). Средняя длина записи составляет ок. 170 байт. В таблице есть приложение. 3,4 ГБ размера и 20,3 млн записей. И кстати, автоматический вакуум включен.

Конфигурация сервера: DigitalOcean CPU-оптимизированный дроплет

  • 8 выделенных виртуальных ЦП (Intel Xeon Skylake (2,7 ГГц, 3,7 ГГц турбо)
  • 16 ГБ ОЗУ
  • 25 ГБ SSD плюс том 50 ГБ SSD (подключен, но не используется
  • ОС - Ubuntu 18
  • PostgreSQL Версия сервера - 11,6 (Ubuntu 11,6- 1.pgdg18.04 + 1)

Сервер работает на 100% -ной загрузке ЦП - все 8 ЦП усердно работают, чтобы выполнить работу. И они работали хорошо, пока БД не получила немного больше См. результаты ниже:

Date        Records  Duration Seconds Recs/Sec
01.11.19     53 761  00:00:05       5   10 043
10.11.19     20 314  00:00:06       6    3 233
20.11.19     23 278  00:00:13      14    1 683
30.11.19     12 495  00:00:11      11    1 133
10.12.19     25 771  00:00:20      20    1 286
20.12.19     52 448  00:00:52      52    1 007
30.12.19     29 872  00:00:44      44      674
10.01.20     32 852  00:00:56      57      578
20.01.20     45 569  00:01:26      86      530
21.01.20    558 118  00:02:24     144    3 876
22.01.20  2 472 590  01:11:26   4 286      577
23.01.20  3 873 271  05:11:53  18 713      207
24.01.20  2 126 177  03:44:25  13 465      158
25.01.20  1 486 789  03:35:42  12 942      115
26.01.20  1 367 299  04:04:45  14 685       93
27.01.20  2 648 854  10:20:30  37 230       71
28.01.20  3 276 999  16:17:44  58 664       56

Переход от 10K записей в секунду до 50 записей в секунду заставляет меня думать, что я, должно быть, сделал что-то не так! Я просмотрел много рекомендаций и страниц об импорте и изменил конфигурацию БД исходя из этого (только отличие от значения по умолчанию):

max_connections = 20
shared_buffers = 2GB
work_mem = 1GB
maintenance_work_mem = 10GB
max_worker_processes = 16
max_parallel_maintenance_workers = 1
max_parallel_workers_per_gather = 1
max_parallel_workers = 16
max_wal_size = 16GB
min_wal_size = 4GB
effective_cache_size = 8GB

Я решил использовать разбиение таблиц, но потом прочитал, что это более актуально для больших баз данных, таких как 100 ГБ +. это т Если бы я разбил данные по метке времени с помощью tz, что (согласно моим прочтениям) усложнилось. Но я бы так и сделал. Просто подумайте, что 3,5 ГБ данных приложения. 20M записей недостаточно для этого.

Может кто-нибудь, пожалуйста, посоветовать, как управлять таким импортом? В настоящее время количество записей составляет от 2 до 4 миллионов записей в день. Но это может резко возрасти очень скоро, и я хочу иметь возможность сделать эту передачу данных как можно быстрее. Данные не изменятся! Поэтому я испытывал желание выключить WAL, но был разочарован тем, что после cra sh я потеряю все данные.

В идеальной ситуации я хотел бы достичь хотя бы начальных 10K записей / se c на этой машине. ;) Есть идеи, как этого добиться?

Кстати: это не обязательно должно быть Python, sqlite3, dataframe, et c. Просто все, что подойдет!

Большое спасибо заранее, том. +

PS: Может быть, PostgreSQL тоже не подходящая БД.

Обновление от 13 февраля 2020 г .: УКАЗАТЬ И УСТРАНИТЬ ПОВТОРНЫЕ ИНДЕКСЫ - процесс необходимо запускать повторно. Это не единственный выстрел. Моя идея - запускать его хотя бы раз в час. Поэтому я не могу удалить индексы и заново создавать их каждый раз. Это было бы (я полагаю) довольно неэффективно.

Чтобы использовать ЦП, я использовал top:

top - 21:12:21 up  1:32,  3 users,  load average: 6.31, 2.42, 2.00
Tasks: 169 total,   9 running,  92 sleeping,   0 stopped,   0 zombie
%Cpu(s): 69.6 us, 29.9 sy,  0.0 ni,  0.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 16424524 total,  6811228 free,  1309644 used,  8303652 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 13289704 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 3574 postgres  20   0 2348648 1.448g 1.445g R  99.3  9.2   1:43.13 postgres
 3562 postgres  20   0 2348648 1.418g 1.415g R  99.0  9.1   1:43.18 postgres
 3567 postgres  20   0 2348648 1.448g 1.445g R  99.0  9.2   1:43.09 postgres
 3573 postgres  20   0 2348644 1.448g 1.445g R  99.0  9.2   1:43.15 postgres
 3566 postgres  20   0 2348644 1.447g 1.444g R  98.7  9.2   1:42.54 postgres
 3570 postgres  20   0 2348648 1.448g 1.445g R  98.7  9.2   1:43.04 postgres
 3564 postgres  20   0 2348648 1.448g 1.445g R  98.3  9.2   1:42.96 postgres
 3569 postgres  20   0 2348648 1.448g 1.445g R  98.3  9.2   1:42.36 postgres
 1088 root      20   0 9966.9m 990.8m  30208 S   0.3  6.2   1:56.49 java

Вывод vmstat 1:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 8  0      0 6813372  29668 8272692    0    0   170     4  541 1014 19 20 61  0  0
 8  0      0 6813116  29668 8272716    0    0     0     0 2309 46147 77 23  0  0  0
 8  0      0 6813116  29668 8272732    0    0     0     0 2308 45379 76 24  0  0  0
 8  0      0 6812992  29676 8272764    0    0     0    76 2289 45297 75 25  0  0  0
 8  0      0 6812992  29676 8272840    0    0     0     0 2297 45654 74 26  0  0  0
 8  0      0 6812992  29676 8272864    0    0     0     0 2310 40172 72 28  0  0  0
 8  0      0 6812992  29676 8272872    0    0     0     0 2360 35028 66 34  0  0  0
 8  0      0 6812992  29676 8272880    0    0     0     0 2295 36441 71 29  0  0  0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...