@clickhouse_ru

Страница 230 из 723
papa
09.08.2017
10:12:30
еще можно nested (keys: array (string), values array(string))

Alex
09.08.2017
10:13:08
а массивы нельзя в MergeTree :(

Alan
09.08.2017
18:35:02
всем привет, подскажите как имея таблицу hits_all от logs api с date и datetime у каждого хита посчитать среднюю продолжительность нахождения на сайте? принцип, ссылки, или может запрос есть под рукой - все пригодится

Andrew
09.08.2017
18:39:33
@miptgirl Будет непросто. Может лучше сразу скачать вместо хитов визиты?

Google
Alan
09.08.2017
18:46:24
@miptgirl Будет непросто. Может лучше сразу скачать вместо хитов визиты?
да) благодарю не углядел что там есть длительность визита

Alexey
09.08.2017
19:02:21
а массивы нельзя в MergeTree :(
Не понял, что имеется ввиду. Конечно массивы можно иметь в таблицах типа MergeTree.

Alexey
09.08.2017
19:05:27
По поводу, почему данные могут занимать меньше в ORC формате. Это может зависить от настроек сжатия. Если при использовании ORC, сжатие более сильное, чем lz4 - займёт меньше. Чтобы включить в ClickHouse более сильное сжатие, можно поменять настройку compression в config,xml, например, так: <compression> <case> <method>zstd</method> </case> </compression> - включит сжатие zstd при всех фоновых мержах.

Вторая возможная причина - изменение самой структуры данных. 450 таблиц - это плохо. 450 таблиц типа MergeTree будут работать, а при использовании ReplicatedMergeTree, на таком количестве могут постепенно начаться всякие проблемы. Дело в том, что каждая таблица типа ReplicatedMergeTree - довольно тяжёлый объект.

Полностью динамические свойства можно хранить в Nested(name String, value String). Но если атрибутов всё-таки не слишком много (сотни), то можно держать отдельные столбцы для каждого. Не стоит беспокоиться, если значения будут сильно разреженными.

Насколько оправдано будет хранить такие данные в колонке в виде сериализованного json?
JSON обычно неоправданно, так как неудобно доставать оттуда всякое. Оправданно в редких случаях - если изначально был JSON и мы совсем не можем заранее разобрать его структуру, и для нас более-менее без разницы, что внутри.

Vladimir
09.08.2017
19:09:23
А есть ли разница в части загрузки КХ и ЗК 1 таблица из 100 реплицируемых шард или 100 таблиц с одной реплицируемой шардой ?

Alexey
09.08.2017
19:11:01
А есть ли разница в части загрузки КХ и ЗК 1 таблица из 100 реплицируемых шард или 100 таблиц с одной реплицируемой шардой ?
Не полностью понял вопрос. Имеется ввиду по одной таблице на каждом сервере, но вопрос в том, делать ли много шардов или много реплик?

Vladimir
09.08.2017
19:15:49
Вопрос такой что есть 200 серверов. Я могу сделать 100 таблиц каждая по 2 реплики и 1 шарде А могу сделать 1 таблицу со 100 шардами и 2 репликами. (понятно что это просто по 1 локальной таблице в итоге на сервере) так вот будет ли разной нагрузка на КХ и ЗК или нет

Alexey
09.08.2017
19:17:11
Тоже не совсем понятно. Дело в том, что нет понятия "шарда для таблицы". Таблицы на разных шардах живут независимо и работают вместе лишь при запросах из Distributed таблицы.

Vladimir
09.08.2017
19:18:08
понял, значит ответ на мой некорректный вопрос - нагрузка будет одинакова тк физичести это будет все теже 100 таблиц с 2 репликами в обоих случаях

Alexey
09.08.2017
19:24:39
Да.

Google
Alexander
09.08.2017
21:29:44
А я правильно понимаю, что в запакованном блоке mark может указывать на любую позицию по сути. т.е. mark in compressed file вовсе не возрастающий? так как архиватор может перемешать блоки? Я пока просто блоки пытаюсь выставить последовательно (не part)

Alexey
09.08.2017
21:34:40
Засечки в индексе строго возрастают. Mark представляет собой пару: - смещение в файле до начала сжатого фрейма, где есть искомые данные; - смещение в разжатом фрейме до данных.

Alexander
09.08.2017
21:37:30


Но mark.in_compressed не может служить идентификатором очередности? Я просто ожидал, что он расти будет. Что-то не так понял видимо.

Alexey
09.08.2017
21:41:11
Для разных столбцов в засечках разные смещения. Если рассматривать один столбец: - в нём у каждой следующей засечки смещение в сжатом файле больше или равно предыдущему. А пара (смещение в сжатом файле, смещение в разжатом фрейме) лексикографически больше. Для разных кусков данных (parts) будут разные файлы, и смещения в них никак не связаны. При параллельной обработке запроса, даже один файл может читаться сразу в разных местах.

Alexander
09.08.2017
21:43:17
Ок, спасибо, я понял что оно все же должно расти, попытаюсь понять почему не вижу этого. Я выбрал только по одной нитке вроде.

Alexey
09.08.2017
21:43:58
Да, [ 13 ] - это номер потока. Он один. В остальном я не понял, что вы вывели.

Alexander
09.08.2017
21:45:29
Я в seekToMark вывел mark.offset_in_compressed. остальные строчки - не важно. Надо наверное ещё индекс марка посмотреть сейчас, может в нём дело.



Ага, спасибо, немного понятнее, сами индексы Марков не последовательно.

Alexey
09.08.2017
21:51:23
mark.offset_in_uncompressed - для мелких столбцов часто равен нулю за счёт "выравнивания сжатых блоков по засечкам". В остальном никакого утверждения о монотонности нет. Пример, что такое засечка. Все несжатые данные файла: [-------------------------------] ^ ^ индекс указывает сюда. Данные сжимаются. Вот такие получились фреймы для сжатия: [---------][---------][---------] ^ ^ Они сжались как-то так: [~~~][~~~~~~][~~] ^ ^ offset_in_compressed_file будет указывать сюда - на начала сжатых фреймов в файле. [---------] ^ [---------] ^ А offset_in_decompressed_block будет указывать сюда - на позицию данных внутри фрейма.

Alexander
09.08.2017
21:53:11
Я извиняюсь, опечатался тут в чате. Я в compressed смотрел. И его имел ввиду, да, uncompressed 0

Могут две засечки указывать на один фрейм?

Например одинаковые данные и упаковалось в один блок. Или будет два блока? Те три блока выше упаковаться в два.

Alexey
09.08.2017
21:57:05
Могут. Есть минимальный размер сжатого фрейма - 64 KB и максимальный - 1 MB. Допустим, столбец имеет тип UInt8, index_granularity = 8192. Тогда в один сжатый фрейм попадут целых 8 засечек.

Alexander
09.08.2017
21:58:48
Но они будут иметь разный uncompressed. А могут ли непоследовательные marks указывать на один in_compressed? Если могут - то это все усложняет.

Alexey
09.08.2017
22:01:52
> Но они будут иметь разный uncompressed. > А могут ли непоследовательные marks указывать на один in_compressed? Не совсем корректный вопрос. Могут ли marks для одного part, для одного столбца быть не монотонными, если рассматривать лексикографическое сравнение - нет. Попробуйте посмотреть .mrk файлы напрямую. Эти файлы не сжаты. Там подряд уложены пары offset_in_compressed_file, offset_in_decompressed_block. И то, и другое - это UInt64, little endian.

Alexander
09.08.2017
22:05:49
Ага. Спасибо что ответили, так как вникнуть во внутренности быстро и легко пока не удалось.

Павел Максимов
10.08.2017
05:51:01


Александр
10.08.2017
06:11:02
Уберите из запроса format tsv, надо что бы остался только create database test1

Google
Alex
10.08.2017
07:37:55
Не понял, что имеется ввиду. Конечно массивы можно иметь в таблицах типа MergeTree.
Спасибо за ответ, Алексей! Перечитал доку, там написано про многомерные

Павел Максимов
10.08.2017
07:59:56
@FacedSID спасибо

f1yegor
10.08.2017
08:46:35
привет. как сделать SELECT arrayJoin([1, 2, 3] AS src) AS dst, 'Hello', src но чтобы если массив пустой - строчка не пропадала, а было как при left join?

Александр
10.08.2017
08:59:41
Можно попробовать так, но в таком случае на пустых массивах будет одна строчка с empty, но на этот случай можно сделать проверку далее в запросе

papa
10.08.2017
09:03:34
select 'hello',z from system.one left array join range(rand()%3) as z

f1yegor
10.08.2017
09:06:05
спасибо, отлично

Oleg
10.08.2017
10:52:01
Добрый день! Подскажите, можно ли как-то выбрать последние вставленные N строк? Если делать order by time|date DESC, то он фуллскан делает, сортировку точнее на весь набор данных, это долго понятно

Roman
10.08.2017
10:57:39
а если лимит по дате поставить, к примеру, за последний день/час, тогда скан будет только по последним партам.

как я понимаю, ch читает данные с диска (и других нод) параллельно из многих мест сразу. с учетом этого понять что из прочитанного - последние N строк, но без сортировки, довольно затруднительно.

Vladimir
10.08.2017
19:20:49
Это пример, как создать базу данных, в которой автоматически содержатся таблицы для словарей.
И что с этим делать?) Алексей где можно посмотреть прочесть более подробно

Alexey
10.08.2017
19:25:59
И что с этим делать?) Алексей где можно посмотреть прочесть более подробно
Движок таблиц Dictionary предназначен для интроспекции - чтобы можно было удобно посмотреть содержимое словаря. А также полезен для запросов, где нужно найти что-нибудь в словаре необычным образом.

Alexey
10.08.2017
19:28:58
Таблицы типа Dictionary можно создать двумя способами: 1. По отдельности, с помощью CREATE TABLE ... ENGINE = Dictionary(dict_name). 2. Таблицы для всех словарей сразу. Это работает с помощью создания специальной базы данных. CREATE DATABASE name ENGINE = Dictionary Это самый простой способ, так как никаких аргументов указывать не нужно.

Сами словари должны быть заранее объявлены в конфигурационных файлах, как обычно.

Vladimir
10.08.2017
19:29:28
Огромное спасибо!

f1yegor
10.08.2017
23:23:59
+1

Google
Дмитрий
11.08.2017
06:25:37
Всем привет. А кто-то вливал в обычную таблицу с MergeTree через JDBC драйвер больше 2кк строчек в секунду? Я конечно еще не до конца разобрался куда уперся в моем случае, пока гоняю тесты и подкручиваю связку в разных местах, но хочется понять, это потолок, или можно выше прыгнуть? Лью через RowBinaryStream, косяки с лонгами обошел, сериализацию и отправку стрингов на своей стороне подкрутил, и на первый взгляд проблем больше нет. Строчки по 66 байт, но на локалхосте результаты примерно такие же, поэтому кажется что это не диск и не сеть, чуть позже проверю точнее.

Eugene
11.08.2017
06:34:38
Всем привет. Подскажите, можно ли сделать materialized-вьюху, которая будет аккумулировать в себе данные двух таблиц по одному и тому же where ?

Admin
ERROR: S client not available

Виктор
11.08.2017
07:20:32
@neiwick Порядок данных важен? Если нет то пробовал ли ты разбить данные на куски и пихать в несколько потоков? Мы так у себя справились с задержками. В безопасные 190 потоков льем кучу данных

Дмитрий
11.08.2017
07:25:52
Абсолютно не важен, спасибо! При таком способе заливки получается утилизировать сеть?

Kirill
11.08.2017
09:06:43
Всем привет. Подскажите, можно ли сделать materialized-вьюху, которая будет аккумулировать в себе данные двух таблиц по одному и тому же where ?
Смотря как делать, по сути ClickHouse просто создаст таблицу с именем (.inner.ваше_вью) и как в таблицу так и во вью можно будет сделать insert и записать туда данные. Когда происходит insert в целевую таблицу, то берется вставляемый блок данных и к нему применяется ваш запрос, поэтому теоретически (и не совсем понятно для чего) можно вставить данные, но, опятьже, там местами всё поломано, например https://github.com/yandex/ClickHouse/issues/127

Eugene
11.08.2017
09:08:47
Kirill
11.08.2017
09:09:55
материализованное вью не читают данные из таблиц

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

Eugene
11.08.2017
09:32:31
а обычное view вполне себе можно создать
ну как устроены вьюхи я представляю, я о другом говорил - как сделать как раз в рамках запроса в одну вьюху результаты из двух таблиц

M
11.08.2017
09:32:59
А через UNION данные не заходят?

Дмитрий
11.08.2017
09:52:09
Всем привет! Скажите, кто-то работал с КХ из go? Наткнулся на вроде как баг, не пойму чей он. Вроде на КХ запросы выполняются, поэтому подозреваю, что это на его стороне. Пытаюсь сделать мультилайн-инсерт (4 строки по 5 полей). if transaction, err = db.ClickHouseClient.Begin(); err != nil { log.Error(fmt.Errorf("Can't start transaction: %v", err)) return } if stmt, err = transaction.Prepare(sql); err != nil { log.Error(fmt.Errorf("Can't prepare statment (%s): %v", sql, err)) transaction.Rollback() return } if _, err = stmt.Exec(data...); err != nil { log.Error(fmt.Errorf("Can't execute statment (%s) with data (%v): %v", sql, data, err)) transaction.Rollback() return } если data - это []interface{} из 20 элементов, то получаю ответ, что ожидается 5 [clickhouse][begin] tx=false, data=false [clickhouse][prepare] INSERT INTO events (uid, pid, event, geodata, created_at) FORMAT VALUES (?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?) [clickhouse][send query] INSERT INTO events (uid, pid, event, geodata, created_at) FORMAT VALUES [clickhouse][rollback] tx=true, data=true [clickhouse]-> ping 2017/08/11 12:05:56 [err] Can't execute statment (INSERT INTO events (uid, pid, event, geodata, created_at) FORMAT VALUES (?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?)) with data ([WXOsS2b6HKVar5J3 10 h_view RU74Челябинск 2017-08-11 12:05:44.144234036 +0300 +03 WXOsS2b6HKVar5J3 1 h_view RU74Челябинск 2017-08-11 12:05:45.216646508 +0300 +03 WXOsS2b6HKVar5J3 10 h_view RU74Челябинск 2017-08-11 12:05:46.242552452 +0300 +03 WXOsS2b6HKVar5J3 1 h_view RU74Челябинск 2017-08-11 12:05:47.160877142 +0300 +03]): block: expected 5 arguments (columns: uid, pid, event, geodata, created_at), got 20 [clickhouse][stmt] close а если передаю не правильное количество аргументов (слайс слайсов интерфейсов 5х4), то он уже ожидает 20, а получил 4 `

Т.е. стейтмент не меняется, но КХ ожидает то 5, то 20

Can't execute statment (INSERT INTO events (uid, pid, event, geodata, created_at) FORMAT VALUES (?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?)) with data ([[WXOsS2b6HKVar5J3 1 h_view RU74Челябинск 2017-08-11 11:41:16.08478083 +0300 +03] [WXOsS2b6HKVar5J3 10 h_view RU74Челябинск 2017-08-11 11:41:17.096437511 +0300 +03] [WXOsS2b6HKVar5J3 1 h_view RU74Челябинск 2017-08-11 11:41:17.983410114 +0300 +03] [WXOsS2b6HKVar5J3 10 h_view RU74Челябинск 2017-08-11 11:41:18.864966974 +0300 +03]]): sql: expected 20 arguments, got 4

разные куски кода проверяют разные вещи block: expected 5 arguments, got 20 sql: expected 20 arguments, got 4 и вот это go проверяет или КХ?

Ivan
11.08.2017
10:00:39
Привет! Заметил странное поведение. Когда заливаю данные через Distributed (insert into some_distibuted select * from other_table), одним большим батчем, то происходит OutOfMemory. Distributed связан с SummingMergeTree. Если заливать по частям, то происходит некоректный подсчет Summing поля, если не дождаться пока Distributed не закончит рассылку по всем нодам и начать заливку следующего батча. Из документации не понятно данное поведение (и OutOfMemory и неправильный подсчет Summing поля), поэтому предполагаю что это бага

Kirill
11.08.2017
10:00:45
это Go проверяет, сейчас посмотрю

Всем привет! Скажите, кто-то работал с КХ из go? Наткнулся на вроде как баг, не пойму чей он. Вроде на КХ запросы выполняются, поэтому подозреваю, что это на его стороне. Пытаюсь сделать мультилайн-инсерт (4 строки по 5 полей). if transaction, err = db.ClickHouseClient.Begin(); err != nil { log.Error(fmt.Errorf("Can't start transaction: %v", err)) return } if stmt, err = transaction.Prepare(sql); err != nil { log.Error(fmt.Errorf("Can't prepare statment (%s): %v", sql, err)) transaction.Rollback() return } if _, err = stmt.Exec(data...); err != nil { log.Error(fmt.Errorf("Can't execute statment (%s) with data (%v): %v", sql, data, err)) transaction.Rollback() return } если data - это []interface{} из 20 элементов, то получаю ответ, что ожидается 5 [clickhouse][begin] tx=false, data=false [clickhouse][prepare] INSERT INTO events (uid, pid, event, geodata, created_at) FORMAT VALUES (?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?) [clickhouse][send query] INSERT INTO events (uid, pid, event, geodata, created_at) FORMAT VALUES [clickhouse][rollback] tx=true, data=true [clickhouse]-> ping 2017/08/11 12:05:56 [err] Can't execute statment (INSERT INTO events (uid, pid, event, geodata, created_at) FORMAT VALUES (?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?)) with data ([WXOsS2b6HKVar5J3 10 h_view RU74Челябинск 2017-08-11 12:05:44.144234036 +0300 +03 WXOsS2b6HKVar5J3 1 h_view RU74Челябинск 2017-08-11 12:05:45.216646508 +0300 +03 WXOsS2b6HKVar5J3 10 h_view RU74Челябинск 2017-08-11 12:05:46.242552452 +0300 +03 WXOsS2b6HKVar5J3 1 h_view RU74Челябинск 2017-08-11 12:05:47.160877142 +0300 +03]): block: expected 5 arguments (columns: uid, pid, event, geodata, created_at), got 20 [clickhouse][stmt] close а если передаю не правильное количество аргументов (слайс слайсов интерфейсов 5х4), то он уже ожидает 20, а получил 4 `
Как говорил Джобс: "Вы держите его неправильно" делайте INSERT INTO events VALUES (?, ?, ?, ?, ?) Далее в цикле забиваете данные через execute (у вас получится 4 итерации по 5 значений) и Commit который отошлет блок данных на сервер

Дмитрий
11.08.2017
10:08:06
а как же рекомендация из мануала при использовании репликации вставлять данные пачками не чаще раза в секунду? 4 инсерта по одной строке - это ж не 1 инсерт 4х строк

Google
Kirill
11.08.2017
10:09:36
нет, он копит данные в буфере, рулится настройкой block_size, если "строк" больше бъет на блоки и отправляет до финального commit, commit зафаксирует все данные которые остались в буфере

Дмитрий
11.08.2017
10:15:25
иными словами: на стороне КХ в пределах одной транции 1 инсерт N строк и N инсертов по 1 строке - это одно и то же. Я верно понял?

Kirill
11.08.2017
10:17:53
нет, это все рулится на стороне драйвера, в большинстве случаев (до установленноего размера block_size) данные на сервер передадутся 1-м блоком в котором будет n-е количество строк

Дмитрий
11.08.2017
10:20:13
надо поснифить трафик

Kirill
11.08.2017
10:21:14
зачем ?

Дмитрий
11.08.2017
10:23:23
потому что если драйвер отправит одним блоком insert();insert();insert() а не insert(),(),() это будет не то. На сколько я знаю.

Kirill
11.08.2017
10:24:58
он не отправит insert (), (), () там данные не в текстовом формате передаются

Дмитрий
11.08.2017
10:26:35
Оо... Тогда тем более надо )

Kirill
11.08.2017
10:29:53
Если вам интересно что там я могу рассказать и сэкономить вам время ;)

Дмитрий
11.08.2017
11:38:17
С удовольствием послущаю! ))

Lex
11.08.2017
11:52:34
+1

Kirill
11.08.2017
12:04:47
Если гошный драйвер используется через стандартный интерфейс Го, то при вызове Begin не создается транзакция, просто соединение закрепляется за стейтментом, при Prepare запрос "обрезается" до VALUES и отправляется на сервер, сервер передает метаинформацию о колонках которые он ожидает, Execute пишет в буферы колонок которые при Commit или при приделе размера блока (в строках) сливаются в один бинарный блок данных и отправляются на сервер, Commit отправляет данные из беферов, если там еще что-то осталось и шлет "пустой" блок данных чтоб сообщить серверу что все данные отправлены

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