Apache doris使用问题记录

spark 写入doris太慢方案解决 最近公司用到了spark读写doris,因为doris其实就是mysql协议,在读取数据时候速度还是可以的,但是写入时候就发生了数据写入特别慢,几千条的数据甚至要用几十分钟,这不是可以接受的。 经过调研查询发现因为连接参数没有指定,数据都是单条写入,改造前写入方式: userLogDF .write .format("jdbc") .mode(SaveMode.Append) .option("dr 阅读详情
AI摘要

本文探讨了在Apache Doris中插入数据时遇到的丢数问题,主要原因是字段长度超限。解决办法包括设置插入严格校验、调整插入批次大小和使用PreparedStatement批量插入。通过实例展示了如何避免数据丢失并提高写入速度。

插入数据丢数

可能原因之一

某个字段的值超长了,doris会把这条数据丢弃。

坑:如果同时插入多条,默认情况下只要有一条插入成功了,doris就会返回成功。

可以再插入数据前设置临时变量:SET enable_insert_strict = true 来开启插入时严格校验,这样只要有一条插入失败doris就会返回失败。

见官网:Insert Into - Apache Doris

案例:从mysql 同步至doris时有两个varchar字段超长导致部分数据被丢弃。

原因:varchar(n) 再mysql中的n是字符数量,doris中的字节数量,所以如果在mysql中是varchar(n)在doris中varchar(3*N) 三倍,doris中是按照utf-8字节数计算的

插入数据慢

现象描述:项目框架springboot mybatisplus, 通过mysql协议链接doris,写入时刚开始快,随后马上就慢下来了。整体写入非常慢。

问题分析:

参考官网:使用 Insert 方式同步数据 - Apache Doris

对于 Doris 来说,一个 INSERT 命令就是一个完整的导入事务。因此不论是导入一条数据,还是多条数据,我们都不建议在生产环境使用这种方式进行数据导入。高频次的 INSERT 操作会导致在存储层产生大量的小文件,会严重影响系统性能。

解决方案:

我们建议一批次插入条数在尽量大,比如几千甚至一万条一次。或者可以通过下面的程序的方式,

1、使用 PreparedStatement 来进行批量插入。

2、在mysql链接后面增加rewriteBatchedStatements=true,开启doris批量提交。(rewriteBatchedStatements=true 会确保 Driver 执行批处理)

改造示例如下:

package demo.doris;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DorisJDBCDemo {

    private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    private static final String DB_URL_PATTERN = "jdbc:mysql://%s:%d/%s?rewriteBatchedStatements=true";
    private static final String HOST = "127.0.0.1"; // Leader Node host
    private static final int PORT = 9030;   // query_port of Leader Node
    private static final String DB = "demo";
    private static final String TBL = "test_1";
    private static final String USER = "admin";
    private static final String PASSWD = "my_pass";

    private static final int INSERT_BATCH_SIZE = 10000;

    public static void main(String[] args) {
        insert();
    }

    private static void insert() {
        // 注意末尾不要加 分号 ";"
        String query = "insert into " + TBL + " values(?, ?)";
        // 设置 Label 以做到幂等。
        // String query = "insert into " + TBL + " WITH LABEL my_label values(?, ?)";

        Connection conn = null;
        PreparedStatement stmt = null;
        String dbUrl = String.format(DB_URL_PATTERN, HOST, PORT, DB);
        try {
            Class.forName(JDBC_DRIVER);
            conn = DriverManager.getConnection(dbUrl, USER, PASSWD);
            stmt = conn.prepareStatement(query);

            for (int i =0; i < INSERT_BATCH_SIZE; i++) {
                stmt.setInt(1, i);
                stmt.setInt(2, i * 100);
                stmt.addBatch();
            }

            int[] res = stmt.executeBatch();
            System.out.println(res);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null) {
                    stmt.close();
                }
            } catch (SQLException se2) {
                se2.printStackTrace();
            }
            try {
                if (conn != null) conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
    }
}

实际应用

简单改造示例:改造为可以被其他service调用的方法,这里异步插入doris,缓存超过5000提交一次

import com.tank.monitoringdata.entity.Datas;
import lombok.extern.slf4j.Slf4j;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class PreparedStatementTool {

    private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    private static final String DB_URL_PATTERN2 = "jdbc:mysql://10.0.0.210:9030/prod?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false";
    private static final String USER = "s****od";
    private static final String PASSWD = "do*****ja";
    private static Integer bacthInsertSize = 5000;

    private static final String query = "insert into datas_new ( dataDate, pointerID, cDataID, dataPackID, dataID, data, timestamp ) values(?, ?, ?, ?, ?, ?, ?)";
    ;
    private static Connection conn = null;
    private static List<Datas> cacheList = new ArrayList<>();


    public static synchronized void insert(List<Datas> datas) {
        log.info("insert:{},{}", datas.size(), cacheList.size());
        cacheList.addAll(datas);
        if (cacheList.size() >= bacthInsertSize) {
            PreparedStatement stmt = null;
            try {
                Class.forName(JDBC_DRIVER);
                if (conn == null) {
                    conn = DriverManager.getConnection(DB_URL_PATTERN2, USER, PASSWD);
                }
                stmt = conn.prepareStatement(query);
                for (int i = 0; i < cacheList.size(); i++) {
                    stmt.setString(1, cacheList.get(i).getDataDate().toString());
                    stmt.setLong(2, cacheList.get(i).getPointerID());
                    stmt.setInt(3, cacheList.get(i).getCDataID());
                    stmt.setInt(4, cacheList.get(i).getDataPackID());
                    stmt.setLong(5, cacheList.get(i).getDataID());
                    stmt.setString(6, cacheList.get(i).getData());
                    stmt.setString(7, cacheList.get(i).getTimestamp().toString());
                    stmt.addBatch();
                }
                int[] res = stmt.executeBatch();
                log.info("stmt.executeBatch:{}", cacheList.size());
                cacheList.clear();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (stmt != null) {
                        stmt.close();
                    }
                } catch (SQLException se2) {
                    se2.printStackTrace();
                }
//            try {
//                if (conn != null) conn.close();
//            } catch (SQLException se) {
//                se.printStackTrace();
//            }
            }
        }
        log.info("end:{},{}", datas.size(), cacheList.size());
    }
}

Flink stream load方式写入到doris遇到的问题 1,Flinkstreamload写入数据到doris的时候,偶然发现be节点挂掉的时候,我的yarn任务也会跟着报错,然后询问了开发小姐姐: 继续跟小姐姐沟通: 通过查看跟确认,发现tablet没有问题,这有尴尬了,只有继续测试,结果如下 2,这我就没办法理解了。我目前使用的是doris 0.13.15,遇到这个问题,是因为在通过http写入doris的时候,需要通过FE去查找BE节点的状态,还有个写入是直接写入到BE,但是如果BE节点挂了也会遇到类似的问题。... 阅读详情

相关推荐

Doris建routineLoad极为缓慢,任务长时间处于NEED_SCHEDUAL

问题 开发反馈,doris测试集群里执行操作比较缓慢 1、建routineLoad很慢 2、routineLoad长时间处于NEED_SCHEDUAL,好一会才RUNNING 分析 估计是fe的问题,看了眼监控,发现doris并没有任何异常 去捞了把fe-master日志,发现有很多WARN 大致分为如上两类task_type STORAGE_MEDIUM_MIGRATE MAKE_SNAPSHOT STORAGE_MEDIUM_MIGRATE 此类问题看了源码发现是表的分区在进行SSD跟HDD的切换 但

gaofeng的博客 2526

【Doris】spark 写入doris太慢方案解决

【Doris】spark 写入doris太慢方案解决

u011250186的博客 2696

Apache Doris 01|集群部署及BE启动遇到问题记录

直接下载编译好的二进制文件,进行解压。(下载地址:百度开源社区选择对应的版本,或linux执行链接下载wget https://palo-cloud-repo-bd.bd.bcebos.com/baidu-doris-release/DORIS-0.14.7-release-binary.tar.gz) 本机的JAVA_HOME配置好 FE的配置 单个配置fe.conf 在fe下创建doris-meta目录,用来存放元数据。 配置conf里的fe.conf。很多都是默认设置。修改的地方: m...

longqiancao1的博客 1万+

记录apache doris使用过程中出现的问题

1,执行创建语句过程中出现: [Err] 1064 - errCode = 2, detailMessage = Failed to find enough host in all backends. need: 3 原因: 语句中指定了PROPERTIES("replication_num" = "3"); 结果BE只有2个: 查看对应节点的日志:. ==> ./be.WARNING.log.20200921-141304 <== W1026 18:13:39.1399..

qq_31866793的博客 3万+

Apache Doris 03|杂问题记录和案例测试

http://palo.baidu.com/docs/%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8/%E5%85%B3%E7%B3%BB%E6%A8%A1%E5%9E%8B%E4%B8%8E%E6%95%B0%E6%8D%AE%E5%88%92%E5%88%86/

longqiancao1的博客 1034

Apache Doris 2.x 版本【保姆级】安装+使用教程

Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库,以极速易用的特点被人们所熟知,仅需亚秒级响应时间即可返回海量数据下的查询结果,不仅可以支持高并发的点查询场景,也能支持高吞吐的复杂分析场景。基于此,Apache Doris 能够较好的满足报表分析、即席查询、统一数仓构建、数据湖联邦查询加速等使用场景,用户可以在此之上构建用户行为分析、AB 实验平台、日志检索分析、用户画像分析、订单分析等应用。

李指导的博客 8411

Apache doris 问题记录

Apache doris 窗口函数LEAD()及手动分区的问题记录

人生需要曲折和转折 941

Apache Doris (四十五): Doris数据更新与删除 - Sequence 列

🏡🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。为了能更好的了解Doris中批量删除,我们需要了解Sequence列。Unique模型主要针对需要唯一主键的场景,可以保证主键唯一性约束,但是由于使用REPLACE聚合方式,在同一批次中导入的数据,替换顺序不做保证。替换顺序无法保证则无法确定最终导入到表中的具体数据,存在了不确定性。

qq_32020645的博客 1045

【记录】apache doris 的 fe 启动报错

2021-04-27 17:27:14,292 INFO (UNKNOWN 192.168.122.1_9010_1619509366080(-1)|1) [Catalog.waitForReady():786] wait catalog to be ready. FE type: UNKNOWN. is ready: false 2021-04-27 17:27:16,292 INFO (UNKNOWN 192.168.122.1_9010_1619509366080(-1)|1) [Catalog.wa

遇事不决问春风 4397

解决Docker拉取镜像报错:Get https://registry-1.docker.io/v2/: 报错

解决Docker拉取镜像报错: Get “https://registry-1.docker.io/v2/”: net/http: request canceled while waiting for connection问题描述Get "https://registry-1.docker.io/v2/"是docker官方的镜像源,下载很慢的,一般会自己指定国内映射的加速镜像源。

qq_33650333的博客 4172

阿里云大模型ACP认证模拟考试(二)

摘要:在阿里云大模型高级工程师 ACP 认证暂无真题题库的现状下,模拟题具有重要意义。其依照真实考试设计,涵盖题型、题量与分值分布,助力考生熟悉考试框架,合理分配答题时间精力,提升效率。同时,模拟题紧扣官方课程,能帮助考生精准定位知识盲点,如大模型架构原理和通义千问应用实践等重点内容,以便针对性完善知识体系。此外,通过练习模拟题,考生可掌握不同题型的解题思维与技巧,快速洞察复杂题目本质,提高答题准确率。

davidkorhenn的博客 2077

Apache Doris 的各种特性和业务场景常见问题FAQ整理

这个要看具体的场景了,在大部分 TP 场景下,Doris 是满足不了的,因为 TP 主打事务和毫秒插入频次,而对于一个 AP 库而言,是非常吃亏的,这里主要是因为 AP 库在本身设计的阶段,就是采用了数据版本做数据可见性控制,一批数据导入以后,可以根据数据批次进行打版本号,在默认的 MOR 的策略下,根据高版本号进行展示。,如果有新的节点加入,可以参照问题 3。但是当前的资源隔离做的还是不够好,粒度有点粗,有时候无法彻底发挥出多副本的优势,故而社区再进一步的设计做新版本的资源隔离了,敬请期待。

学亮编程手记 1108

74LS161/48 交通灯控制系统:30-5-20-5 时序逻辑电路 Multisim 仿真验证

本文详细解析了基于74LS161/48芯片的交通灯控制系统设计,通过Multisim仿真验证30-5-20-5时序逻辑电路。从系统架构搭建、状态机实现到波形分析,提供全流程操作指南与典型问题排查方法,助力数字电路课程设计高效完成。

weixin_26742753的博客 380

Apache Doris 2.1.10 集群部署与 Paimon 数据湖集成实战文档

操作系统: CentOS 7 (CDH 6.3.2 环境混合部署)节点配置CPU: 10核内存: 14GB (资源紧缺,需精细调优)存储: 400GB SSD部署用户bigdataJava 环境问题现象报错信息关键词原因分析解决方案Java 环境缺失启动脚本未找到 CDH 自带的 JDK 路径。在fe.conf和be.conf第一行添加。FE 启动权限错误或首次使用了sudo启动,导致文件归属变为 root,后续bigdata用户无法写入。1. 停止 root 进程。2.修复目录权限。

QXXDYL的博客 1223

单细胞数据导入实战:Read10X函数常见报错与解决方案

本文针对单细胞转录组分析中Read10X函数数据导入的常见问题,提供了详细的实战解决方案。重点解析了因文件路径错误、压缩文件未解压、版本命名不符及内存不足导致的报错,并给出了检查路径、正确解压、重命名文件、调整参数及优化内存等具体操作步骤,帮助用户高效完成单细胞数据导入,为后续分析奠定坚实基础。

weixin_28235513的博客 238

YOLOv8 更换损失函数DIoU、EIoU、GIoU...Inner-IoU...

介绍了一些损失函数,并将其应用到yolov8训练中

分享一些自己改进代码的实例 888

记录第一次部署银河麒麟环境Apache Doris单机部署

本文详细介绍了在银河麒麟V10系统上部署Apache Doris 4.0.2单机版集群的完整流程。重点包括:环境准备(Java17安装、Swap关闭、内核参数调整)、Doris下载解压(推荐x64非AVX2版本)、以及创建数据库时需指定"replication_num=1"的关键配置。文章特别强调部署过程中的常见问题解决方案,为新手提供了从零开始的完整指导,最终成功实现了包含1个FE和1个BE的功能性Doris集群部署。

dayulxl的博客 664

【OS】AUTOSAR OS Alarm实现原理

AUTOSAR OS Alarm实现原理

qq_36056498的博客 1022

一次 Doris FE 节点无法启动的排查与解决

本文记录一次 Apache Doris 前端(FE)节点因系统意外挂掉导致无法重启的问题,分享排查过程与最终解决方案,供有类似问题的同学参考。

常备不懈 1335

超十万字解读Spring AI实战:开篇

大模型技术正以惊人的速度改变世界,2025年的人工智能已不再是科幻,而是现实。大模型如ChatGPT等,正在重塑各行各业,降低技术门槛,使专业能力普及化。SpringAI的出现为Java开发者提供了桥梁,使其能在企业级系统中稳定运行AI,同时保持工程化思维。尽管SpringAI在生态、学习成本和性能上存在不足,但其企业级基因和国产化适配能力使其成为Java开发者的重要工具。本系列文章旨在介绍SpringAI的功能与特性,鼓励更多Java开发者参与AI实践,共同探索AI时代的无限可能。

liaokailin的专栏 1577

Nerf 训练自有数据

colmap相机位姿转为LLFF格式数据

zfjBIT的专栏 2309

Apache Doris Pipeline Tracing:Pipeline 调度追踪记录与可视化工具实战指南

Pipeline Tracing 是 Apache Doris 自带的调度追踪与可视化工具链,用于观察 Pipeline 执行引擎中成千上万个 Pipeline Task 在 CPU 核心与线程之间的调度过程。它由 BE 端的追踪记录组件(`PipelineTracerContext`)与仓库 [tools/pipeline-tracing](https://link.gitcode.com/i/

gitblog_01096的博客 457

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Apache Doris部署实战:从单机到集群的踩坑与排错全记录

在实时报表、用户行为分析与日志分析等大数据场景中,OLAP数据库的作用越来越关键。Apache Doris作为一款基于MPP架构的分布式数据库,凭借亚秒级查询响应、灵活的多表Join以及高并发支撑能力,成为许多团队构建实时数仓的热门选择。其核心由FE与BE两类节点组成,FE负责SQL解析与元数据管理,BE负责分布式存储与并行计算,理解这套原理是顺利部署的前提。从单机验证到多节点集群搭建,涉及端口规划、FE角色配置、BE扩容、数据模型选择等关键环节。实践中常见的BE状态异常、Presto连接missing错误

weixin_28933797的博客 367

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

上一篇: 阿里云OSS获取STS临时访问凭证
下一篇: window11 中idea、webstorm termical【报错】yarn : 无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
grootblockchain
博客等级 码龄11年 55粉丝 101原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值