insert-segment-to-db是可以将segment信息插入Druid元数据库的工具。 当我们需要手动将segment从一个集群迁移到另一集群时,它可用于更新元数据库中的segment表。 它也可以用于插入丢失的segment到Druid中,甚至通过告知segment的存储位置来恢复元数据存储。
该工具仅扫描深层存储目录即可重建元数据条目,以用于定位和标识每个segment。它不需要知道这些segment是否应真的需要写入元数据库。 在某些情况下,这可能导致出现不是所希望的或不符的结果。 需要注意是:
丢弃的数据源将重新启用Druid将加载每个segment的最新版本,在某些场景下,该版本可能不是你所想好要的。 例如,当一个生成segment的压缩任务出现错误了,那么就需要手动地在元数据表中删除该版本。 如果还没有从深度存储中删除这些段,则它们将被导回到元数据表中,并掩盖正确的版本。诸如Kafka索引服务之类的某些索引器可能会生成不止一组segment IDx相同但内容不同的分段。 首次写入元数据时,将引用正确的segment集合,而其他集合会深度存储中删除。 但是,未处理的异常可能会导致多个segment集合,而同一分段ID仍保留在深度存储中。由于此工具不知道使用哪个segment集合是“正确的”一个,因此它只会选择最新的segment集合,而忽略其他版本。 如果选择了错误的segment集合,则Kafka索引服务的一次语义将不再成立,并且可能会重复或删除事件。考虑到这些注意事项,建议通过直接导出原始元数据存储来完成数据迁移,因为这是确定的群集状态。 如果无法直接导出,则应将此工具用作最后的手段。该工具希望用户使Druid集群以“安全”模式运行,在该模式下没有活动任务会干扰要插入的段。 用户可以选择关闭群集,以100%确保没有干扰。
为了使其工作,用户必须通过Java JVM参数或runtime.properties文件提供元数据存储凭证和深度存储类型。 具体来说,此工具需要了解:
druid.metadata.storage.type druid.metadata.storage.connector.connectURI druid.metadata.storage.connector.user druid.metadata.storage.connector.password druid.storage.type除了上面的属性之外,您还需要指定存储段的位置以及是否要更新descriptor.json (用于HDFS数据存储的partitionNum_descriptor.json)。 这两个可以通过命令行参数提供。
–workingDir(必填)
存储segment的目录URI。 该工具将递归地查找该目录下的segment并在元信息库中插入/更新这些segment信息。注意:workDir必须是完整的URI,这意味着它必须以方案类型作为前缀。 例如,hdfs://主机名:端口/段目录
–updateDescriptor (可选)
if set to true, this tool will update `loadSpec` field in `descriptor.json` (`partitionNum_descriptor.json` for HDFS data storage) if the path in `loadSpec` is different from where `desciptor.json` (`partitionNum_descriptor.json` for HDFS data storage) was found. Default value is `true`.还需要使用的元数据和深度存储加载不同的Druid扩展(extensions)。 例如,如果将mysql用作元数据存储,将HDFS用作深度存储,则应加载mysql-metadata-storage和druid-hdfs-storage扩展。
假设元数据存储为mysql,并且您已将某些段迁移到HDFS中的目录中,并且该目录如下所示,
Directory path: /druid/storage/wikipedia ├── 2013-08-31T000000.000Z_2013-09-01T000000.000Z │ └── 2015-10-21T22_07_57.074Z │ ├── 0_descriptor.json │ └── 0_index.zip ├── 2013-09-01T000000.000Z_2013-09-02T000000.000Z │ └── 2015-10-21T22_07_57.074Z │ ├── 0_descriptor.json │ └── 0_index.zip ├── 2013-09-02T000000.000Z_2013-09-03T000000.000Z │ └── 2015-10-21T22_07_57.074Z │ ├── 0_descriptor.json │ └── 0_index.zip └── 2013-09-03T000000.000Z_2013-09-04T000000.000Z └── 2015-10-21T22_07_57.074Z ├── 0_descriptor.json └── 0_index.zip要将所有这些段加载到mysql中,您可以触发以下命令,
java -Ddruid.metadata.storage.type=mysql -Ddruid.metadata.storage.connector.connectURI=jdbc\:mysql\://localhost\:3306/druid -Ddruid.metadata.storage.connector.user=druid -Ddruid.metadata.storage.connector.password=diurd -Ddruid.extensions.loadList=[\"mysql-metadata-storage\",\"druid-hdfs-storage\"] -Ddruid.storage.type=hdfs -cp $DRUID_CLASSPATH org.apache.druid.cli.Main tools insert-segment-to-db --workingDir hdfs://host:port//druid/storage/wikipedia --updateDescriptor true在此示例中,mysql和深度存储类型通过Java JVM参数提供,您可以选择将它们全部放入runtime.properites文件中,并将其包含在Druid类路径中。 注意,我们在扩展列表中还包括了mysql-metadata-storage和druid-hdfs-storage。
运行此命令后,mysql中的segments表应为我们刚刚插入的每个segment存储新位置。 请注意,对于存储在HDFS中的段,由于该新位置与相对路径一起存储,因此druid config必须包含Druid文档中所述的core-site.xml。
举例
java -Ddruid.metadata.storage.type=mysql -Ddruid.metadata.storage.connector.connectURI=jdbc:mysql://localhost :3306/druiddb -Ddruid.metadata.storage.connector.user=druid -Ddruid.metadata.storage.connector.password=mars -Ddruid.extensions.loadList=[\"mysql-metadata-storage\",\"druid-hdfs-storage\"] -Ddruid.storage.type=hdfs -cp "conf/druid/_common:/data/br/base/druid/lib/*" org.apache.druid.cli.Main tools insert-segment-to-db --workingDir hdfs://mars/druid/segments/kafka_test/ --updateDescriptor true