Apache Kudu медленная вставка, большое время ожидания
Я использовал Spark Data Source для записи в Kudu из Parquet, и производительность записи ужасна: около 12000 строк / секунд. Каждый ряд примерно 160 байтов.
У нас есть 7 узлов куду, 24 ядра + 64 ГБ ОЗУ каждый + 12 дисков SATA каждый. Похоже, что ни один из ресурсов не является узким местом: использование ЦП сервера ~3-4 ядра, ОЗУ 10 ГБ, отсутствие перегрузки диска.
Тем не менее, я вижу, что большую часть времени запросы на запись зависали в очереди. Любые идеи приветствуются.
W0811 12:34:03.526340 7753 rpcz_store.cc:251] Call kudu.tserver.TabletServerService.Write from 10.60.170.18:10000 (ReqId={client: 81ae6f3c6e1b4d9493ea95f87ccd1dfa, seq_no=9365, attempt_no=1}) took 13255ms (client timeout 10000).
W0811 12:34:03.526489 7753 rpcz_store.cc:255] Trace:
0811 12:33:50.270477 (+ 0us) service_pool.cc:163] Inserting onto call queue
0811 12:33:50.270497 (+ 20us) service_pool.cc:222] Handling call
0811 12:34:03.526316 (+13255819us) inbound_call.cc:157] Queueing success response
Related trace 'txn':
0811 12:34:03.328337 (+ 0us) write_transaction.cc:101] PREPARE: Starting
0811 12:34:03.328563 (+ 226us) write_transaction.cc:268] Acquiring schema lock in shared mode
0811 12:34:03.328564 (+ 1us) write_transaction.cc:271] Acquired schema lock
0811 12:34:03.328564 (+ 0us) tablet.cc:400] PREPARE: Decoding operations
0811 12:34:03.328742 (+ 178us) tablet.cc:422] PREPARE: Acquiring locks for 24 operations
0811 12:34:03.447163 (+118421us) lock_manager.cc:377] Waited 118408us for lock on <redacted>
0811 12:34:03.447203 (+ 40us) tablet.cc:426] PREPARE: locks acquired
0811 12:34:03.447203 (+ 0us) write_transaction.cc:126] PREPARE: finished.
0811 12:34:03.447361 (+ 158us) write_transaction.cc:136] Start()
0811 12:34:03.447366 (+ 5us) write_transaction.cc:141] Timestamp: P: 1533965643563964 usec, L: 6
0811 12:34:03.447674 (+ 308us) log.cc:582] Serialized 64909 byte log entry
0811 12:34:03.449561 (+ 1887us) write_transaction.cc:149] APPLY: Starting
0811 12:34:03.526238 (+ 76677us) tablet_metrics.cc:365] ProbeStats: bloom_lookups=48,key_file_lookups=48,delta_file_lookups=24,mrs_lookups=0
0811 12:34:03.526260 (+ 22us) log.cc:582] Serialized 237 byte log entry
0811 12:34:03.526268 (+ 8us) write_transaction.cc:309] Releasing row and schema locks
0811 12:34:03.526280 (+ 12us) write_transaction.cc:277] Released schema lock
0811 12:34:03.526300 (+ 20us) write_transaction.cc:196] FINISH: updating metrics
Metrics: {"child_traces":[["txn",{"apply.queue_time_us":11,"cfile_cache_hit":205,"cfile_cache_hit_bytes":21900627,"num_ops":24,"prepare.queue_time_us":13057291,"prepare.run_cpu_time_us":1017,"prepare.run_wall_time_us":119378,"raft.queue_time_us":71,"raft.run_cpu_time_us":303,"raft.run_wall_time_us":304,"replication_time_us":2170,"row_lock_wait_count":1,"row_lock_wait_us":118408,"spinlock_wait_cycles":45824}]]}
2 ответа
Оказывается, это связано с дублированием наших данных. Мы используем поле, которое содержит около 1,2 миллиона строк с тем же значением (которое является пустой строкой) и первичным ключом в Kudu. Таким образом, Куду обновлял тот же ключ 1,2 миллиона раз, и каждый раз, когда ему нужно было получить блокировку, отсюда и снижение скорости приема со временем.
Мы удалили дублированные строки ключей, и скорость приема пищи увеличилась до 10x.
Первая проблема заключалась в том, что потребовалось целое время, чтобы вставить 23-метровую таблицу строк с 200 столбцами в Kudu (4 хеш-раздела по первичному ключу). Точно, это заняло колоссальные 58 минут, что означает 63 строки в секунду. Я не мог поверить, что Куду был таким медленным, и мы дважды проверили документы по установке и настройке. К сожалению, мы доверяли значениям по умолчанию, и, как я узнал на слабом канале Kudu (спасибо, Уилл Беркли!), Есть два параметра, которые необходимо настроить. В частности:
memory_limit_hard_bytes
контролирует общий объем памяти, который должен использовать демон Kudu.
maintenance_manager_num
количество потоков обслуживания, рекомендуемое значение 1/3 от количества дисков, используемых для Kudu
Значения по умолчанию с CDH-посылкой Kudu были довольно ужасными - Kudu был ограничен 1 ГБ памяти и использовал только 1 поток обслуживания. Мы устанавливаем последний на 4 (12 дисков / 3) и первый на 0 (динамическое распределение). CM не хотел принимать 0 для memory_limit_hard_bytes
и мы должны были использовать предохранительный клапан CM, чтобы переопределить его. Как только это было сделано и Куду перезапустился, моя первая таблица 23M была закончена за 240 секунд (~95k строк в секунду) - намного лучше! CTAS от Импалы до паркета Импалы заняла всего 60 секунд.