@clickhouse_ru

Страница 635 из 723
Denis
24.08.2018
13:23:22
альтернатива - увеличить max_insert_block_size временно

Александр
24.08.2018
13:24:53
разбить так, чтобы файл был меньше блока. а там он уж либо напишет ошибку, либо вставится. те, что не вставились - вставить заново.
У нас на запись может отправиться 4 сотни файлов, которые заполняются безконтрольно ( Перезаписывать их так, что бы они влезали в max_insert_block_size тоже никак. И опять таки, остается вопрос как вот исходя из этого определить что дописалось, а что нет? cat 6.t 1.t 2.t 3.t 4.t 5.t | clickhouse-client -q 'INSERT INTO t12345 FORMAT TSV' Code: 27. DB::Exception: Cannot parse input: expected \n before: afa\n5\n: (at row 10000004) Row 10000003: Column 0, name: Number, type: UInt64, parsed text: "3" Row 10000004: Column 0, name: Number, type: UInt64, ERROR: text "afa<LINE FEED>5<LINE FEED>" is not like UInt64

По факту записался файл 6.t и то, не полный, а все остальные пролетели мимо

Denis
24.08.2018
13:25:45
отправлять файлы на запись по очереди, конечно

Google
Александр
24.08.2018
13:25:48
Даже если я побью их на размер < max_insert_block_size проблема остается актуальной, т.к. КХ все равно из всего потока данных будет собирать блоки в max_insert_block_size

В файле может быть 1 строка, а может быть 1000...а КХ нужно пачками их кормить и большими

Вставляем это все через cat ... | clickhouse-client

Denis
24.08.2018
13:26:31
возможно, стоит написать какое-нибудь буферное приложение, которое бы делало ретраи. ксати, это идея

Александр
24.08.2018
13:27:07
возможно, стоит написать какое-нибудь буферное приложение, которое бы делало ретраи. ксати, это идея
Мы тоже об этом уже подумали, но пока это долго :) Думал, что есть люди с подобными проблемами и возможно даже решение есть уже

Что бы писалось либо все, либо ничего

Denis
24.08.2018
13:28:03
а точно нет варианта регулировать размер файлов? ограничить по max_insert_block_size ?

тогда ретраить проще будет гораздо. и файлы всё-таки по одному кидать,

Michal
24.08.2018
13:28:43
Что бы писалось либо все, либо ничего
Можете при каждом инсерте создавать новую таблицу. Если всё успешно - скопировать её в целевую. Если неуспешно - просто дроп.

Александр
24.08.2018
13:29:01
а точно нет варианта регулировать размер файлов? ограничить по max_insert_block_size ?
А это бесмысленно. Например у меня max_insert_block_size = 1024 Первый файл у меня 200 байт Второй 150 Третий 2048 В итоге у меня первый блок захватит первый файл, второй и часть третьего, оставшуюся часть третьего он побъет еще на два блока.

Denis
24.08.2018
13:29:38
двойная работа получается

Александр
24.08.2018
13:30:02
двойная работа получается
Да, но это хоть что-то

Google
Александр
24.08.2018
13:30:09
Долго, но блин...

Другого варианта пока нет (

Michal
24.08.2018
13:30:57
двойная работа получается
угу. В принципе можно ATTACH / DETACH чтоб избежать двойной работы. Но тогда надо будет ещё и файлах базы КХ ковыряться.

Александр
24.08.2018
13:33:15
@milovidov_an не планируется что-то типа такого функционала добавлять? Ситуация: есть много файлов с данными, которые превышают max_insert_block_size и соответственно CH бьет это дело на разные блоки в соответствии с этой настройкой. И вот у меня данных на 3 блока, один блок вставился на в середине второго блока нашлась ошибка в данных и запрос упал. В CH осталась первый блок данных, но мне нужно: либо записалось все, либо ничего. Как такого можно достичь? Кто-то сталкивался с подобной потребностью?

Может быть уже есть?

Michal
24.08.2018
13:34:47
Ну и кстати линуксовего split никто не отменял.

Александр
24.08.2018
13:37:10
@mfilimonov ^^

А это бесмысленно. Например у меня max_insert_block_size = 1024 Первый файл у меня 200 байт Второй 150 Третий 2048 В итоге у меня первый блок захватит первый файл, второй и часть третьего, оставшуюся часть третьего он побъет еще на два блока.

Я все равно не узнаю какой файл отвалился

И строки не фиксированной длинны

Michal
24.08.2018
13:40:17
Это ж линукс. Можно сделать так: сначала всем файлам добавить имя файла в начале каждой строки. Потом всё это скормить сплиту (он умеет "резать" по макс размеру, не только по количеству строк). Полученными файлами можно кормить КХ.

Тогда в начале строки будет стоять название оригинального файла.

Правда это всё звучит как-то ээээ ... слишком экзотично :)

Проще починить файлы чтоб инсерты не ломались :)

Konstantin
24.08.2018
13:42:34
коллеги, подскажите. С переходом с версии с 385 на 18.10.3 отвалился драйвер odbc к psql. до этого стоял и работал без проблем. в логи КХ падает такое: 2018.08.24 13:36:03.651668 [ 12 ] <Error> ExternalDictionaries: Failed reloading 'advertisers' external dictionary: Poco::Exception. Code: 1000, e.code() = 0, e.displayText() = Connection attempt failed: Connection:Not applicable Server:DBNAME =========================== ODBC Diagnostic record #1: =========================== SQLSTATE = 01000 Native Error Code = 0 [unixODBC][Driver Manager]Can't open lib 'psqlodbcw.so' : file not found , e.what() = Connection attempt failed Хотя сам файл psqlodbcw.so есть. Посмотрел по чейнжлогам - вроде ничего не меняли в работе с ODBC. кто нить сталкивался с такой петрушкой?

Michal
24.08.2018
13:44:19
Я все равно не узнаю какой файл отвалился
Например я таким трехстрочником в питоне переформатировал файлы чтоб КХ был счастлив. https://gist.github.com/filimonov/57e270104a3e48d7fd6f70a3d4ec2b95

Александр
24.08.2018
13:46:13
А по диску как? Просто мы с синтетической нагрузкой и всякими мерджами файлов и пр диск жрем на 100% и начинается веселье. Нагрузка порядка 2 000 000 пользователей в сутки

И нам лишние операции на диске боком вылезают

Google
Александр
24.08.2018
13:47:01
В плане подготовки данных для отправки в кх, можно конечно это ограничивать, но может забиваться все это дело

Michal
24.08.2018
13:48:19
А по диску как? Просто мы с синтетической нагрузкой и всякими мерджами файлов и пр диск жрем на 100% и начинается веселье. Нагрузка порядка 2 000 000 пользователей в сутки
Ну тот скриптик на который линка дал ничего никуда не пишет, тупо для использования в пайпе предназначен. Берет строку из STDIN, переформатирует, отправляет в STDOUT.

Александр
24.08.2018
13:49:12
Ща гляну

Michal
24.08.2018
13:50:48
Но он там только форматирование CSV поправлял чтоб КХ все понимал. Т.е. только косметические изменения - типа кавычкек, бекслешей и т.п.

Konstantin
24.08.2018
13:55:06
Да, там что-то ломалось с ODBC в последних версиях. Выше писали что-то про дефисы.
Увидел проблему с - ? но это не мой случай, у нас этого нет.

Denis
24.08.2018
13:56:21
Кстати...отличная идея!
мы все льем через временные tinylog или memory, max_insert_block_size и max_block_size выставляем по кол-ву строк во временной.

Denis
24.08.2018
14:01:59
в строках

Александр
24.08.2018
14:02:42
в строках
А льете по http? Просто мы используем clickhouse-client, а он сам бьет данные на блоки

Denis
24.08.2018
14:04:26
только clickhouse-client. Цель атомарность, мне как раз не надо бить на блоки. tsv -> clickhouse-client -> memory_table (clickhouse-client insert select) -> mergetree --- max_block_size - это рекомендация, какого размера блоки (в количестве строк) загружать из таблицы. https://clickhouse.yandex/docs/ru/operations/settings/settings/#max_block_size -- выставлять надо оба параметра, для insert select

Denis
24.08.2018
14:58:27
max_insert_block_size для вставки с клиента, max_block_size для insert into t select .. from for i in seq 1 20000000; do echo $i; done > x.tsv echo xxx >> x.tsv for i in seq 1 2000; do echo $i; done >> x.tsv drop table i; create table i(a Int64) ENGINE=MergeTree PARTITION by tuple() order by tuple(); cat x.tsv |clickhouse-client --max_insert_block_size 30000000 -q 'insert into i format TSV' Code: 27. DB::Exception: Cannot parse input..... select count() from i; 0 rows in set. Elapsed: 0.001 sec.

Alexey
24.08.2018
15:13:22
Инструкция №3 ————————————————————— Как настроить TCP балансировку ClickHouse. В случае если ваше приложение обращается к ClickHouse не через http 8123, а tcp 9000, настроить балансировку ClickHouse серверов используя Nginx просто так не получится. Нужно пересобрать Nginx из исходного кода, указав большое количество нужных параметров, так как в стандартном билде nginx не умеет работать с tcp трафиком. А собрать нужный вариант nginx'a дело не быстрое и лучше не тратьте на это время... Есть намного более простой и быстрый способ, далее команды под рутом: 1) yum install haproxy -y 2) systemctl enable haproxy 3) systemctl start haproxy 4) vi /etc/haproxy/haproxy.cfg 5) запишем в этот файл: global user haproxy group haproxy daemon maxconn 50000 defaults mode tcp balance leastconn timeout client 30000ms timeout server 30000ms timeout connect 3000ms retries 0 frontend from bind 0.0.0.0:9000 default_backend to backend to server srv1 192.168.1.151:9000 maxconn 20000 server srv2 192.168.1.152:9000 maxconn 20000 6) Сохраним файл и выйдем из него 7) systemctl restart haproxy 8) Готово Примечание 1: Проверял на Centos 7.5.1804 (4.18.1-1.el7.elrepo.x86_64) Примечание 2: Перед началом настройки балансировщика haproxy обязательно настройте и стартаните ClickHouse на обеих нодах. Про настройку. Главное сетевые настройки укажите, чтобы можно было подключатся с другого компьютера, и пользователь чтобы существовал которому разрешено подключатся к ClickHouse серверу. И только после этого настраивайте и стартуйте балансировщик haproxy. Теги для поиска: #manual #loadbalance #balancing #инструкция #балансировка #балансировщик #tcp #haproxy #medov_alexey

Stanislav
24.08.2018
15:22:34
Или взять дебиан 9 и поставить пакет https://packages.debian.org/stretch/libnginx-mod-stream

Без дополнительного сервиса на балансировщике

И без пересборок чего-либо :)

Alexey
24.08.2018
15:25:05
И без пересборок чего-либо :)
У меня стоял пакет nginx-mod-stream.x86_64 1:1.12.2-2.el7 Но это не помогло.

Stanislav
24.08.2018
15:25:41
подключить, значит, надо

Alexey
24.08.2018
15:27:15
Google
Alexey
24.08.2018
15:27:20
Prerequisites Latest open source NGINX built with the --with-stream configuration flag, or latest NGINX Plus (no extra build steps required)

Вот что сказазано для поддержки TCP требуется

короче я обошелся без nginx

Stanislav
24.08.2018
15:29:14
Заодно и http через haproxy можно

А вообще - load_module в помощь

В дебиане включение модуля - симлинк в modules-enabled на файл в modules-available

Yuri
24.08.2018
15:49:01
у таблы нет своей конфигурации подключения с сервертом итд? на десктопе она при выборе DSN дает отдельно понастраивать все остальные параметры
Tableau читает параметры из DSN, а значит надо явно прописать SERVER (и прочая) в соответствующей секции файла odbc.ini на хосте, где поднят Tableau Server.

prll
24.08.2018
15:51:32
а какая odbc либа использовалась? если libiodbc то у нее могут быть немного другой формат конфига и расположение

Yuriy
24.08.2018
16:00:49
/stat@combot

Combot
24.08.2018
16:00:50
combot.org/c/-1001080295593

prll
24.08.2018
16:16:38
ах еще и макос? тогда там конфиг совсем далеко

вопрос с чем clickhouse-odbc.dylib собирали unixodbc или libiodbc

Рулон
24.08.2018
17:34:22
Щас облако запустят, и администрировать не придётся)))

Denis
24.08.2018
19:39:50
А кто-нибудь пользуется engine=Merge ? Я тестирую этот движок и вроде все хорошо с ним. Хочется переименовать старую таблицу X в X_old и начать писать в новую X_new с другим партриционированием и другой сортировкой и накрыть их X engine=Merge. (переложить тяжело, в старой данных очень много, со временем просто они дропнутся).

Denis
24.08.2018
19:47:38
ну у меня будет 2 таблицы. _old _new

Google
molo4ko
24.08.2018
20:06:41
как посчитать среднее время “сессии”, если в таблицу с событиями пишутся login/logout? что-то на замену lag

Bulat
24.08.2018
20:33:48
join таблицы с собой не работает?

select user_id, a.ts as start, min(b.ts) as end from my_table a join my_table b on a.user_id = b.user_id where a.ts < b.ts and a.type = 'login' and b.type = 'logout' group by user_id, a.ts

molo4ko
24.08.2018
20:39:11
ну хотелось бы не джойнить) наверное, попробую какой-то комбинацией groupArray и дальше руками

Bulat
24.08.2018
20:40:51
ага, если гарантировать, что данные не терялись, то можно собрать в два массива логины и логауты)

Александр
24.08.2018
20:47:13
ну у меня будет 2 таблицы. _old _new
В таком случае ничего страшного не произойдет

Mike
24.08.2018
21:40:48
поищите, выше есть ссылка на SO, вокруг неё какое-то обсуждение было

Alexey
24.08.2018
22:36:11
@milovidov_an не планируется что-то типа такого функционала добавлять? Ситуация: есть много файлов с данными, которые превышают max_insert_block_size и соответственно CH бьет это дело на разные блоки в соответствии с этой настройкой. И вот у меня данных на 3 блока, один блок вставился на в середине второго блока нашлась ошибка в данных и запрос упал. В CH осталась первый блок данных, но мне нужно: либо записалось все, либо ничего. Как такого можно достичь? Кто-то сталкивался с подобной потребностью?
Каждый раз держим возможность реализации этой функциональности "в уме", но ещё не запланировали и пока не собирались делать. По-сути, это - вставка данных в одной транзакции. Уже сейчас ClickHouse работает так, что вставляемые данные пишутся во временные куски, которые затем атомарно добавляются в рабочий набор. Можно было бы сделать такое для многих кусков. Но есть следующие мелкие сложности: 1. Надо сделать минимальную поддержку транзакций, чтобы атомарно переименовать более одной директории. То есть, писать лог в файл, fsync его, восстанавливаться при старте. Это небольшая проблема. 2. За один INSERT может добавиться много временных кусков. Потом они все сразу попадут в рабочий набор. Например, в рабочий набор в один момент попадает 1000 кусков - и сразу же возникает большая нагрузка из-за мержей, а следующие INSERT-ы отваливаются из-за Too many parts. А в худшем случае очень большого INSERT-а будет плохо файловой системе. Вывод - надо мержить вставляемые куски ещё до того, как завершён INSERT. 3. Есть связанная задача - выполнять несколько SELECT-ов из одного консистентного снэпшота. Например, сделать два запроса - для таблицы и для графика в отчёте - и чтобы они показывали одинаковые данные, когда данные постоянно обновляются. В ClickHouse внутри уже есть нужная функциональность - по сути, SELECT берёт снэпшот из таблицы, а потом из него читает. Обычный синтаксис BEGIN/COMMIT почти подходит для всего, что перечислено, но всё-таки не совсем. Если есть несколько запросов из разных таблиц, то мы хотим создать снепшот для всех на один момент времени. И ещё есть мелочь - надо создавать снепшот не для всей таблицы, а для той части (тех партиций), которые будем читать.

molo4ko
24.08.2018
23:57:44
В какую сторону копать при таких записях в replication_queue? shard_1 table_name node0 279 queue-0004917503 MERGE_PARTS 2018-08-22 01:52:38 0 REDACTED 20180801_20180820_678552_681247_1319 ['20180801_20180820_678552_681240_1318','20180819_20180820_681241_681247_2'] 0 0 105 Poco::Exception. Code: 1000, e.code() = 0, e.displayText() = Timeout: connect timed out: REDACTED:9009, e.what() = Timeout 2018-08-24 23:55:08 186659 Not merging into part 20180801_20180820_678552_681247_1319 because part 20180801_20180820_678552_681240_1318 is not ready yet (log entry for that part is being processed). 2018-08-24 23:55:38

Sergey
25.08.2018
06:32:10
А может вам через Buffer таблицу вставлять по одному файлу? Buffer внутри успешные вставки объединит.
Это очень специфический engine с рядом неприятных моментов, включая потерю данных при падении сервера.

Александр
25.08.2018
08:21:56
Каждый раз держим возможность реализации этой функциональности "в уме", но ещё не запланировали и пока не собирались делать. По-сути, это - вставка данных в одной транзакции. Уже сейчас ClickHouse работает так, что вставляемые данные пишутся во временные куски, которые затем атомарно добавляются в рабочий набор. Можно было бы сделать такое для многих кусков. Но есть следующие мелкие сложности: 1. Надо сделать минимальную поддержку транзакций, чтобы атомарно переименовать более одной директории. То есть, писать лог в файл, fsync его, восстанавливаться при старте. Это небольшая проблема. 2. За один INSERT может добавиться много временных кусков. Потом они все сразу попадут в рабочий набор. Например, в рабочий набор в один момент попадает 1000 кусков - и сразу же возникает большая нагрузка из-за мержей, а следующие INSERT-ы отваливаются из-за Too many parts. А в худшем случае очень большого INSERT-а будет плохо файловой системе. Вывод - надо мержить вставляемые куски ещё до того, как завершён INSERT. 3. Есть связанная задача - выполнять несколько SELECT-ов из одного консистентного снэпшота. Например, сделать два запроса - для таблицы и для графика в отчёте - и чтобы они показывали одинаковые данные, когда данные постоянно обновляются. В ClickHouse внутри уже есть нужная функциональность - по сути, SELECT берёт снэпшот из таблицы, а потом из него читает. Обычный синтаксис BEGIN/COMMIT почти подходит для всего, что перечислено, но всё-таки не совсем. Если есть несколько запросов из разных таблиц, то мы хотим создать снепшот для всех на один момент времени. И ещё есть мелочь - надо создавать снепшот не для всей таблицы, а для той части (тех партиций), которые будем читать.
Спасибо за развернутый ответ! Я полагаю, что не мы одни будем с нетерпением ждать этой фичи! Вы справитесь с этими сложностями, я уверен! :)

А может вам через Buffer таблицу вставлять по одному файлу? Buffer внутри успешные вставки объединит.
Мы уже использовали буфер движок, в какой-то момент начались пляски. Нам важно, что бы вся порция данных попадала в БД. Данные размазаны по 20 таблицам и если хотя бы в одну из них что-то не записалось, то эти «битые» данные не попадают в ротацию запросов на выборку. Битые же данные удаляются раз в час. После успешной вставки мы меняем version параметр конкретному пользователю и все данные в таблицы помечены этой версией. Таким образом мы стараемся поддерживать некое подобие транзакционности на уровне приложения. Без ролбэка, конечно же, но с гарантией, что версия обновится только тогда, когда все данные успешно записались в КХ.

Страница 635 из 723