ROUTINE LOAD

description

  1. 例行导入(Routine Load)功能,支持用户提交一个常驻的导入任务,通过不断的从指定的数据源读取数据,将数据导入到 Doris 中。
  2. 目前仅支持通过无认证或者 SSL 认证方式,从 Kakfa 导入文本格式(CSV)的数据。

语法:

  1. CREATE ROUTINE LOAD [db.]job_name ON tbl_name
  2. [load_properties]
  3. [job_properties]
  4. FROM data_source
  5. [data_source_properties]
  6. 1. [db.]job_name
  7. 导入作业的名称,在同一个 database 内,相同名称只能有一个 job 在运行。
  8. 2. tbl_name
  9. 指定需要导入的表的名称。
  10. 3. load_properties
  11. 用于描述导入数据。语法:
  12. [merge_type],
  13. [column_separator],
  14. [columns_mapping],
  15. [where_predicates],
  16. [delete_on_predicates],
  17. [partitions]
  18. 1. column_separator:
  19. 指定列分隔符,如:
  20. COLUMNS TERMINATED BY ","
  21. 默认为:\t
  22. 2. columns_mapping:
  23. 指定源数据中列的映射关系,以及定义衍生列的生成方式。
  24. 1. 映射列:
  25. 按顺序指定,源数据中各个列,对应目的表中的哪些列。对于希望跳过的列,可以指定一个不存在的列名。
  26. 假设目的表有三列 k1, k2, v1。源数据有4列,其中第124列分别对应 k2, k1, v1。则书写如下:
  27. COLUMNS (k2, k1, xxx, v1)
  28. 其中 xxx 为不存在的一列,用于跳过源数据中的第三列。
  29. 2. 衍生列:
  30. col_name = expr 的形式表示的列,我们称为衍生列。即支持通过 expr 计算得出目的表中对应列的值。
  31. 衍生列通常排列在映射列之后,虽然这不是强制的规定,但是 Doris 总是先解析映射列,再解析衍生列。
  32. 接上一个示例,假设目的表还有第4 v2v2 k1 k2 的和产生。则可以书写如下:
  33. COLUMNS (k2, k1, xxx, v1, v2 = k1 + k2);
  34. 3. where_predicates
  35. 用于指定过滤条件,以过滤掉不需要的列。过滤列可以是映射列或衍生列。
  36. 例如我们只希望导入 k1 大于 100 并且 k2 等于 1000 的列,则书写如下:
  37. WHERE k1 > 100 and k2 = 1000
  38. 4. partitions
  39. 指定导入目的表的哪些 partition 中。如果不指定,则会自动导入到对应的 partition 中。
  40. 示例:
  41. PARTITION(p1, p2, p3)
  42. 5. merge_type
  43. 数据的合并类型,一共支持三种类型APPENDDELETEMERGE 其中,APPEND是默认值,表示这批数据全部需要追加到现有数据中,DELETE 表示删除与这批数据key相同的所有行,MERGE 语义 需要与delete on条件联合使用,表示满足delete 条件的数据按照DELETE 语义处理其余的按照APPEND 语义处理, 语法为[WITH MERGE|APPEND|DELETE]
  44. 6. delete_on_predicates
  45. 表示删除条件,仅在 merge type MERGE 时有意义,语法与where 相同
  46. 4. job_properties
  47. 用于指定例行导入作业的通用参数。
  48. 语法:
  49. PROPERTIES (
  50. "key1" = "val1",
  51. "key2" = "val2"
  52. )
  53. 目前我们支持以下参数:
  54. 1. desired_concurrent_number
  55. 期望的并发度。一个例行导入作业会被分成多个子任务执行。这个参数指定一个作业最多有多少任务可以同时执行。必须大于0。默认为3
  56. 这个并发度并不是实际的并发度,实际的并发度,会通过集群的节点数、负载情况,以及数据源的情况综合考虑。
  57. 例:
  58. "desired_concurrent_number" = "3"
  59. 2. max_batch_interval/max_batch_rows/max_batch_size
  60. 这三个参数分别表示:
  61. 1)每个子任务最大执行时间,单位是秒。范围为 5 60。默认为10
  62. 2)每个子任务最多读取的行数。必须大于等于200000。默认是200000
  63. 3)每个子任务最多读取的字节数。单位是字节,范围是 100MB 1GB。默认是 100MB
  64. 这三个参数,用于控制一个子任务的执行时间和处理量。当任意一个达到阈值,则任务结束。
  65. 例:
  66. "max_batch_interval" = "20",
  67. "max_batch_rows" = "300000",
  68. "max_batch_size" = "209715200"
  69. 3. max_error_number
  70. 采样窗口内,允许的最大错误行数。必须大于等于0。默认是 0,即不允许有错误行。
  71. 采样窗口为 max_batch_rows * 10。即如果在采样窗口内,错误行数大于 max_error_number,则会导致例行作业被暂停,需要人工介入检查数据质量问题。
  72. where 条件过滤掉的行不算错误行。
  73. 4. strict_mode
  74. 是否开启严格模式,默认为关闭。如果开启后,非空原始数据的列类型变换如果结果为 NULL,则会被过滤。指定方式为 "strict_mode" = "true"
  75. 5. timezone
  76. 指定导入作业所使用的时区。默认为使用 Session timezone 参数。该参数会影响所有导入涉及的和时区有关的函数结果。
  77. 6. format
  78. 指定导入数据格式,默认是csv,支持json格式。
  79. 7. jsonpaths
  80. jsonpaths: 导入json方式分为:简单模式和匹配模式。如果设置了jsonpath则为匹配模式导入,否则为简单模式导入,具体可参考示例。
  81. 8. strip_outer_array
  82. 布尔类型,为true表示json数据以数组对象开始且将数组对象中进行展平,默认值是false
  83. 9. json_root
  84. json_root为合法的jsonpath字符串,用于指定json document的根节点,默认值为""
  85. 5. data_source
  86. 数据源的类型。当前支持:
  87. KAFKA
  88. 6. data_source_properties
  89. 指定数据源相关的信息。
  90. 语法:
  91. (
  92. "key1" = "val1",
  93. "key2" = "val2"
  94. )
  95. 1. KAFKA 数据源
  96. 1. kafka_broker_list
  97. Kafka broker 连接信息。格式为 ip:host。多个broker之间以逗号分隔。
  98. 示例:
  99. "kafka_broker_list" = "broker1:9092,broker2:9092"
  100. 2. kafka_topic
  101. 指定要订阅的 Kafka topic
  102. 示例:
  103. "kafka_topic" = "my_topic"
  104. 3. kafka_partitions/kafka_offsets
  105. 指定需要订阅的 kafka partition,以及对应的每个 partition 的起始 offset
  106. offset 可以指定从大于等于 0 的具体 offset,或者:
  107. 1) OFFSET_BEGINNING: 从有数据的位置开始订阅。
  108. 2) OFFSET_END: 从末尾开始订阅。
  109. 如果没有指定,则默认从 OFFSET_END 开始订阅 topic 下的所有 partition
  110. 示例:
  111. "kafka_partitions" = "0,1,2,3",
  112. "kafka_offsets" = "101,0,OFFSET_BEGINNING,OFFSET_END"
  113. 4. property
  114. 指定自定义kafka参数。
  115. 功能等同于kafka shell "--property" 参数。
  116. 当参数的 value 为一个文件时,需要在 value 前加上关键词:"FILE:"
  117. 关于如何创建文件,请参阅 "HELP CREATE FILE;"
  118. 更多支持的自定义参数,请参阅 librdkafka 的官方 CONFIGURATION 文档中,client 端的配置项。
  119. 示例:
  120. "property.client.id" = "12345",
  121. "property.ssl.ca.location" = "FILE:ca.pem"
  122. 1.使用 SSL 连接 Kafka 时,需要指定以下参数:
  123. "property.security.protocol" = "ssl",
  124. "property.ssl.ca.location" = "FILE:ca.pem",
  125. "property.ssl.certificate.location" = "FILE:client.pem",
  126. "property.ssl.key.location" = "FILE:client.key",
  127. "property.ssl.key.password" = "abcdefg"
  128. 其中:
  129. "property.security.protocol" "property.ssl.ca.location" 为必须,用于指明连接方式为 SSL,以及 CA 证书的位置。
  130. 如果 Kafka server 端开启了 client 认证,则还需设置:
  131. "property.ssl.certificate.location"
  132. "property.ssl.key.location"
  133. "property.ssl.key.password"
  134. 分别用于指定 client public keyprivate key 以及 private key 的密码。
  135. 2.指定kafka partition的默认起始offset
  136. 如果没有指定kafka_partitions/kafka_offsets,默认消费所有分区,此时可以指定kafka_default_offsets指定起始 offset。默认为 OFFSET_END,即从末尾开始订阅。
  137. 值为
  138. 1) OFFSET_BEGINNING: 从有数据的位置开始订阅。
  139. 2) OFFSET_END: 从末尾开始订阅。
  140. 示例:
  141. "property.kafka_default_offsets" = "OFFSET_BEGINNING"
  142. 7. 导入数据格式样例
  143. 整型类(TINYINT/SMALLINT/INT/BIGINT/LARGEINT):1, 1000, 1234
  144. 浮点类(FLOAT/DOUBLE/DECIMAL):1.1, 0.23, .356
  145. 日期类(DATE/DATETIME):2017-10-03, 2017-06-13 12:34:03
  146. 字符串类(CHAR/VARCHAR)(无引号):I am a student, a
  147. NULL值:\N

example

  1. 1. example_db example_tbl 创建一个名为 test1 Kafka 例行导入任务。指定列分隔符和 group.id client.id,并且自动默认消费所有分区,且从有数据的位置(OFFSET_BEGINNING)开始订阅
  2. CREATE ROUTINE LOAD example_db.test1 ON example_tbl
  3. COLUMNS TERMINATED BY ",",
  4. COLUMNS(k1, k2, k3, v1, v2, v3 = k1 * 100)
  5. PROPERTIES
  6. (
  7. "desired_concurrent_number"="3",
  8. "max_batch_interval" = "20",
  9. "max_batch_rows" = "300000",
  10. "max_batch_size" = "209715200",
  11. "strict_mode" = "false"
  12. )
  13. FROM KAFKA
  14. (
  15. "kafka_broker_list" = "broker1:9092,broker2:9092,broker3:9092",
  16. "kafka_topic" = "my_topic",
  17. "property.group.id" = "xxx",
  18. "property.client.id" = "xxx",
  19. "property.kafka_default_offsets" = "OFFSET_BEGINNING"
  20. );
  21. 2. example_db example_tbl 创建一个名为 test1 Kafka 例行导入任务。导入任务为严格模式。
  22. CREATE ROUTINE LOAD example_db.test1 ON example_tbl
  23. COLUMNS(k1, k2, k3, v1, v2, v3 = k1 * 100),
  24. WHERE k1 > 100 and k2 like "%doris%"
  25. PROPERTIES
  26. (
  27. "desired_concurrent_number"="3",
  28. "max_batch_interval" = "20",
  29. "max_batch_rows" = "300000",
  30. "max_batch_size" = "209715200",
  31. "strict_mode" = "false"
  32. )
  33. FROM KAFKA
  34. (
  35. "kafka_broker_list" = "broker1:9092,broker2:9092,broker3:9092",
  36. "kafka_topic" = "my_topic",
  37. "kafka_partitions" = "0,1,2,3",
  38. "kafka_offsets" = "101,0,0,200"
  39. );
  40. 3. 通过 SSL 认证方式,从 Kafka 集群导入数据。同时设置 client.id 参数。导入任务为非严格模式,时区为 Africa/Abidjan
  41. CREATE ROUTINE LOAD example_db.test1 ON example_tbl
  42. COLUMNS(k1, k2, k3, v1, v2, v3 = k1 * 100),
  43. WHERE k1 > 100 and k2 like "%doris%"
  44. PROPERTIES
  45. (
  46. "desired_concurrent_number"="3",
  47. "max_batch_interval" = "20",
  48. "max_batch_rows" = "300000",
  49. "max_batch_size" = "209715200",
  50. "strict_mode" = "false",
  51. "timezone" = "Africa/Abidjan"
  52. )
  53. FROM KAFKA
  54. (
  55. "kafka_broker_list" = "broker1:9092,broker2:9092,broker3:9092",
  56. "kafka_topic" = "my_topic",
  57. "property.security.protocol" = "ssl",
  58. "property.ssl.ca.location" = "FILE:ca.pem",
  59. "property.ssl.certificate.location" = "FILE:client.pem",
  60. "property.ssl.key.location" = "FILE:client.key",
  61. "property.ssl.key.password" = "abcdefg",
  62. "property.client.id" = "my_client_id"
  63. );
  64. 4. 简单模式导入json
  65. CREATE ROUTINE LOAD example_db.test_json_label_1 ON table1
  66. COLUMNS(category,price,author)
  67. PROPERTIES
  68. (
  69. "desired_concurrent_number"="3",
  70. "max_batch_interval" = "20",
  71. "max_batch_rows" = "300000",
  72. "max_batch_size" = "209715200",
  73. "strict_mode" = "false",
  74. "format" = "json"
  75. )
  76. FROM KAFKA
  77. (
  78. "kafka_broker_list" = "broker1:9092,broker2:9092,broker3:9092",
  79. "kafka_topic" = "my_topic",
  80. "kafka_partitions" = "0,1,2",
  81. "kafka_offsets" = "0,0,0"
  82. );
  83. 支持两种json数据格式:
  84. 1){"category":"a9jadhx","author":"test","price":895}
  85. 2)[
  86. {"category":"a9jadhx","author":"test","price":895},
  87. {"category":"axdfa1","author":"EvelynWaugh","price":1299}
  88. ]
  89. 5. 精准导入json数据格式
  90. CREATE TABLE `example_tbl` (
  91. `category` varchar(24) NULL COMMENT "",
  92. `author` varchar(24) NULL COMMENT "",
  93. `timestamp` bigint(20) NULL COMMENT "",
  94. `dt` int(11) NULL COMMENT "",
  95. `price` double REPLACE
  96. ) ENGINE=OLAP
  97. AGGREGATE KEY(`category`,`author`,`timestamp`,`dt`)
  98. COMMENT "OLAP"
  99. PARTITION BY RANGE(`dt`)
  100. (PARTITION p0 VALUES [("-2147483648"), ("20200509")),
  101. PARTITION p20200509 VALUES [("20200509"), ("20200510")),
  102. PARTITION p20200510 VALUES [("20200510"), ("20200511")),
  103. PARTITION p20200511 VALUES [("20200511"), ("20200512")))
  104. DISTRIBUTED BY HASH(`category`,`author`,`timestamp`) BUCKETS 4
  105. PROPERTIES (
  106. "storage_type" = "COLUMN",
  107. "replication_num" = "1"
  108. );
  109. CREATE ROUTINE LOAD example_db.test1 ON example_tbl
  110. COLUMNS(category, author, price, timestamp, dt=from_unixtime(timestamp, '%Y%m%d'))
  111. PROPERTIES
  112. (
  113. "desired_concurrent_number"="3",
  114. "max_batch_interval" = "20",
  115. "max_batch_rows" = "300000",
  116. "max_batch_size" = "209715200",
  117. "strict_mode" = "false",
  118. "format" = "json",
  119. "jsonpaths" = "[\"$.category\",\"$.author\",\"$.price\",\"$.timestamp\"]",
  120. "strip_outer_array" = "true"
  121. )
  122. FROM KAFKA
  123. (
  124. "kafka_broker_list" = "broker1:9092,broker2:9092,broker3:9092",
  125. "kafka_topic" = "my_topic",
  126. "kafka_partitions" = "0,1,2",
  127. "kafka_offsets" = "0,0,0"
  128. );

json数据格式: [ {“category”:”11”,”title”:”SayingsoftheCentury”,”price”:895,”timestamp”:1589191587}, {“category”:”22”,”author”:”2avc”,”price”:895,”timestamp”:1589191487}, {“category”:”33”,”author”:”3avc”,”title”:”SayingsoftheCentury”,”timestamp”:1589191387} ] 说明: 1)如果json数据是以数组开始,并且数组中每个对象是一条记录,则需要将strip_outer_array设置成true,表示展平数组。 2)如果json数据是以数组开始,并且数组中每个对象是一条记录,在设置jsonpath时,我们的ROOT节点实际上是数组中对象。

  1. 6. 用户指定根节点json_root
  2. CREATE ROUTINE LOAD example_db.test1 ON example_tbl
  3. COLUMNS(category, author, price, timestamp, dt=from_unixtime(timestamp, '%Y%m%d'))
  4. PROPERTIES
  5. (
  6. "desired_concurrent_number"="3",
  7. "max_batch_interval" = "20",
  8. "max_batch_rows" = "300000",
  9. "max_batch_size" = "209715200",
  10. "strict_mode" = "false",
  11. "format" = "json",
  12. "jsonpaths" = "[\"$.category\",\"$.author\",\"$.price\",\"$.timestamp\"]",
  13. "strip_outer_array" = "true",
  14. "json_root" = "$.RECORDS"
  15. )
  16. FROM KAFKA
  17. (
  18. "kafka_broker_list" = "broker1:9092,broker2:9092,broker3:9092",
  19. "kafka_topic" = "my_topic",
  20. "kafka_partitions" = "0,1,2",
  21. "kafka_offsets" = "0,0,0"
  22. );

json数据格式: { “RECORDS”:[ {“category”:”11”,”title”:”SayingsoftheCentury”,”price”:895,”timestamp”:1589191587}, {“category”:”22”,”author”:”2avc”,”price”:895,”timestamp”:1589191487}, {“category”:”33”,”author”:”3avc”,”title”:”SayingsoftheCentury”,”timestamp”:1589191387} ] } 7. 为 example_db 的 example_tbl 创建一个名为 test1 的 Kafka 例行导入任务。并且删除与v3 >100 行相匹配的key列的行

  1. CREATE ROUTINE LOAD example_db.test1 ON example_tbl
  2. WITH MERGE
  3. COLUMNS(k1, k2, k3, v1, v2, v3),
  4. WHERE k1 > 100 and k2 like "%doris%"
  5. DELETE ON v3 >100
  6. PROPERTIES
  7. (
  8. "desired_concurrent_number"="3",
  9. "max_batch_interval" = "20",
  10. "max_batch_rows" = "300000",
  11. "max_batch_size" = "209715200",
  12. "strict_mode" = "false"
  13. )
  14. FROM KAFKA
  15. (
  16. "kafka_broker_list" = "broker1:9092,broker2:9092,broker3:9092",
  17. "kafka_topic" = "my_topic",
  18. "kafka_partitions" = "0,1,2,3",
  19. "kafka_offsets" = "101,0,0,200"
  20. );

keyword

  1. CREATE,ROUTINE,LOAD