关于OceanBase与CDH适配的经验分享

CDH是Cloudera早期推出的一个开源平台版本,它实质上成为了Apache Hadoop生态系统内公认的安装与管理平台,专为企业级需求量身打造。CDH为用户提供了即装即用的企业级解决方案。通过整合Hadoop与另外十多项关键开源项目,Cloudera构建了一个功能强大的系统,能够支持从端到端的大数据工作流处理。CDH的免费版本在6.3.2版本后停止了更新,转而专注于商业版本的发布。尽管如此,许多企业仍选择利用该免费版本的CDH成功部署了Hadoop大数据平台。

简单来说:CDH 是一个拥有集群自动化安装、中心化管理、集群监控、报警功能的一个工具(软件),使得集群的安装可以从几天的时间缩短为几个小时,运维人数也会从数十人降低到几个人,极大的提高了集群管理的效率。

1、前言

CDH的配置库支持Mysql,Oracle及postgresql数据库,大部分公司使用的是Mysql作为CDH的配置库,在高可用场景中,Mysql容易成为单点故障的关键点,而OceanBase天然具备高可用特性,有必要研究切换CDH的配置库为OceanBase,如此就有了这篇文章。

2、遇到的问题

**问题一:**在安装启动CM启动过程中,第一步将初始化配置数据库SQL的时候,有检查数据库的引擎,必须是InnoDB,如图1,原因是OB执行show engines返回的是OceanBase,如图2。(OB数据库可定制show engines输出来支持就好了)

图1-CM启动报错图

图2-OB执行show engines

**问题2:**通过重新编译源码,绕过CM对数据库引擎检查后,报不支持连续修改的错误,报错见图3-1及图3-2,原因是OB作为分布式数据库,为分布式一致性不支持连续执行ddl修改操作,需分步骤执行才能成功,如图4。(OB数据库能社加个开关支持连续修改就好了)

图3-1,通过逗号连接,连续修改数据库表报错-1

图3-2连续修改数据库表,上条未执行完执行下一条报错

图4-需改造CM的ddl语句

应对以上两个问题,经和社区大佬分析、评估及指导后,做出以下两个解决方案:

  1. 修改OB源码,编译并安装修改后的Observer,绕过CM的show engines的检查;
  2. 修改CM的ddl,绕过OB不支持连续执行的ddl;

下面以此操作步骤为线,记录这个过程。

3、编译OceanBase、安装和租户创建

1. 下载源码

复制代码
git clone https://github.com/oceanbase/oceanbase.git

2. 修改源码

复制代码
vim src/observer/virtual_table/ob_all_virtual_engine_table.cpp

第58行OceanBase改为InnoDB,如图5

图5-OceanBase改为InnoDB

3. 编译源码

编译流程见 编译方法 ,编译后新的RPM包在oceanbase/build_rpm目录下,RPM包见图6

图6-编译后的RPM包

4. 安装及启动

安装oceanbase-ce-4.1.0.0-1.el7.x86_64.rpm

复制代码
rpm -ivh oceanbase-ce-4.1.0.0-1.el7.x86_64.rpm

拷贝安装目录bin下observer文件,使用OBD部署一个4.0环境,替换bin下observer文件为新文件,并启动,如图7;修改后的show engines如图8

图7-启动OB

图8-show engine

5. 准备用于安装CDH的租户及用户

登录系统root,并创建租户

复制代码
CREATE RESOURCE UNIT unit001 MAX_CPU 8,MEMORY_SIZE '10G';
CREATE RESOURCE POOL pool001 UNIT='unit001',UNIT_NUM=1,ZONE_LIST=('zone1');
CREATE TENANT IF NOT EXISTS cdh
     CHARSET='utf8mb4',
     PRIMARY_ZONE='zone1',
     RESOURCE_POOL_LIST=('pool001')
     SET ob_tcp_invited_nodes='%';

登录租户root,并准备用户 bigdata 密码 Bigdata@cdh_test,并创建cmdb数据库和hive数据库

复制代码
alter user root identified by 'Root@cdh_test' ;
CREATE USER 'bigdata' IDENTIFIED BY 'Bigdata@cdh_test';
CREATE DATABASE cmdb
 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
CREATE DATABASE hive DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON *.* TO bigdata WITH GRANT OPTION;

4、安装CDH并配置CM

(省略1千字的安装过程)

复制代码
tar -zxvf cm6.3.1-redhat7.tar.gz
cd /home/shaqf/cm6.3.1/RPMS/x86_64
rpm -ivh cloudera-manager-daemons-6.3.1-1466458.el7.x86_64.rpm
yum install cloudera-manager-server-6.3.1-1466458.el7.x86_64.rpm

1. 修改数据库配置文件

复制代码
vim /etc/cloudera-scm-server/db.properties

内容

复制代码
com.cloudera.cmf.db.type=mysql
com.cloudera.cmf.db.host=192.168.21.17:2881
com.cloudera.cmf.db.name=cmdb
com.cloudera.cmf.db.user=bigdata@cdh
com.cloudera.cmf.db.setupType=EXTERNAL
com.cloudera.cmf.db.password=Bigdata@cdh_test

启动CM

复制代码
service cloudera-scm-server restart

查看日志:more /var/log/cloudera-scm-server/cloudera-scm-server.log,报错如图9

图9-执行ddl报错

2. 修改ddl

修改/opt/cloudera/cm/schema/mysql下的所有ddl文件,修改如图4;

这里使用java进行批量修改,代码如下:

复制代码
import java.io.*;
import java.util.HashSet;
import java.util.Set;

public class StartMain {
    public static void main(String[] args) throws Exception {
        File pathFile = new File("C:\\Users\\sha\\Desktop\\mysql\\");
        Set<File> fileSet = new HashSet<>();
        findFiles(pathFile, fileSet);
        for (File file:fileSet) {
            RandomAccessFile raf = new RandomAccessFile(file,"r");
            String line = null;
            String preLine = null;
            StringBuffer sbfDDL = new StringBuffer();
            while ((line = raf.readLine()) != null){
                if(line.trim().startsWith("alter table ")){
                    preLine = line;
                    sbfDDL.append(line);
                    sbfDDL.append("\n");
                } else if (line.trim().startsWith("add index ") && line.trim().endsWith(",")){
                    line = line.replaceAll(",",";");
                    sbfDDL.append(line);
                    sbfDDL.append("\n");
                    sbfDDL.append(preLine);
                    sbfDDL.append("\n");
                } else {
                    sbfDDL.append(line);
                    sbfDDL.append("\n");
                }
            }
            BufferedWriter bufWriter = null;
            try {
                bufWriter = new BufferedWriter(new FileWriter(file, false));// 覆盖
                bufWriter.write(sbfDDL.toString());
                bufWriter.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bufWriter != null) {
                    try {
                        bufWriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    private static void findFiles(File file, Set<File> files) {
        if (file.isDirectory()) {
            File[] fileArray = file.listFiles();
            if (fileArray != null) {
                for (int i = 0; i < fileArray.length; i++) {
                    findFiles(fileArray[i], files);
                }
            }
        } else {
            files.add(file);
        }
    }
}

上传修改后的ddl,清空cmdb数据库,再次执行重启任务,有关命令如下

复制代码
drop database cmdb;
CREATE DATABASE cmdb
DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
service cloudera-scm-server restart

查看日志:more /var/log/cloudera-scm-server/cloudera-scm-server.log,报错如图9

图9-ddl报错

3. 继续修改ddl

继续修改/opt/cloudera/cm/schema/mysql下的所有ddl文件,修改如图4;

这里使用java到Linux上进行批量修改,代码如下:

复制代码
import java.io.*;
import java.util.HashSet;
import java.util.Set;
 
public class StartMain {
    public static void main(String[] args) throws Exception {
        File pathFile = new File("/opt/cloudera/cm/schema/mysql");
        Set<File> fileSet = new HashSet<>();
        findFiles(pathFile, fileSet);
        for (File file:fileSet) {
            RandomAccessFile raf = new RandomAccessFile(file,"r");
            String line = null;
            String preLine = null;
            StringBuffer sbfDDL = new StringBuffer();
            boolean isAlterLine = false;
            while ((line = raf.readLine()) != null){
                if(line.trim().startsWith("alter table ")){
                    preLine = line;
                    sbfDDL.append(line);
                    sbfDDL.append("\n");
                    isAlterLine = true;
                } else if (line.trim().startsWith("add ") && line.trim().endsWith(",")){
                    line = line.replaceAll(",","; select sleep(1); ");
                    sbfDDL.append(line);
                    sbfDDL.append("\n");
                    sbfDDL.append(preLine);
                    sbfDDL.append("\n");
                } else if (line.trim().startsWith("modify ") && line.trim().endsWith(",")){
                    line = line.replaceAll(",","; select sleep(1); ");
                    sbfDDL.append(line);
                    sbfDDL.append("\n");
                    sbfDDL.append(preLine);
                    sbfDDL.append("\n");
                } else if (line.trim().startsWith("drop ") && line.trim().endsWith(",")){
                    line = line.replaceAll(",","; select sleep(1); ");
                    sbfDDL.append(line);
                    sbfDDL.append("\n");
                    sbfDDL.append(preLine);
                    sbfDDL.append("\n");
                } else {
                    if(isAlterLine && line.trim().endsWith(";")){
                        line = line.replaceAll(";","; select sleep(1); ");
                    }
                    sbfDDL.append(line);
                    sbfDDL.append("\n");
                }
            }
            BufferedWriter bufWriter = null;
            try {
                bufWriter = new BufferedWriter(new FileWriter(file, false));// 覆盖
                bufWriter.write(sbfDDL.toString());
                bufWriter.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bufWriter != null) {
                    try {
                        bufWriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    private static void findFiles(File file, Set<File> files) {
        if (file.isDirectory()) {
            File[] fileArray = file.listFiles();
            if (fileArray != null) {
                for (int i = 0; i < fileArray.length; i++) {
                    findFiles(fileArray[i], files);
                }
            }
        } else {
            files.add(file);
        }
    }}

修改ddl文件:

复制代码
vim 05021_cmf_schema.mysql.ddl
vim 05300_cmf_schema.mysql.ddl

分别注释掉下面两行(05021_cmf_schema.mysql.ddl新增IDX_CLIENT_CONFIG_HOST索引,05300_cmf_schema.mysql.ddl又删除IDX_CLIENT_CONFIG_HOST索引,而05300_cmf_schema.mysql.ddl删除索引会报错)

复制代码
--alter table CLIENT_CONFIGS
--  add index IDX_CLIENT_CONFIG_HOST (HOST_ID); select sleep(1);

-- alter table CLIENT_CONFIGS
--  drop index IDX_CLIENT_CONFIG_HOST; select sleep(1);

如图-10修复所有即建索引又指定主键的ddl

图-10 在建表时不能即建索引又指定主键(修复方法:索引单独创建)

确保ddl修改完成后,清空cmdb数据库,再次执行重启任务,有关命令如下

复制代码
drop database cmdb;
CREATE DATABASE cmdb DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
service cloudera-scm-server restart

查看日志:more /var/log/cloudera-scm-server/cloudera-scm-server.log,报错如图-11,报错不影响接入系统(后续得观察运行稳定性)

图-11 启动报错

5 、登录系统

登录地址:http://192.168.25.47:7180/ 如图-12

图-12 成功接入CM

相关推荐
冰 河9 天前
《Mycat核心技术》第21章:高可用负载均衡集群的实现(HAProxy + Keepalived + Mycat)
分布式·微服务·程序员·分布式数据库·mycat
韩曙亮12 天前
【系统架构设计师】数据库系统 ② ( 分布式数据库 | 分布式数据库 特点 | 分布式数据库 分层模式 | 两阶段提交协议 - 2PC 协议 )
数据库·分布式·系统架构·分布式数据库·软考·dbms·两阶段提交协议
ActionTech14 天前
ChatDBA VS DeepSeek:快速诊断 OceanBase 集群新租户数据同步异常
oceanbase·deepseek·chatdba·爱可生
码农老起14 天前
从Oracle到OceanBase数据库迁移:全方位技术解析
数据库·oracle·oceanbase
OceanBase数据库官方博客15 天前
数据文件误删除,OceanBase中如何重建受影响的节点
oceanbase·分布式数据库·运维管理·实践经验
码农老起18 天前
OceanBase数据库基于脚本的分布式存储层性能深度优化
数据库·分布式·oceanbase
码农老起18 天前
万亿级数据量的OceanBase应用从JVM到协议栈立体化改造实现性能调优
jvm·oceanbase
OceanBase数据库官方博客20 天前
OceanBase 读写分离最佳实践
oceanbase·分布式数据库·读写分离·最佳实践
OceanBase数据库官方博客22 天前
网易云信架构升级实践,故障恢复时间缩至8秒
oceanbase·分布式数据库·架构选型·布道师计划
OceanBase数据库官方博客24 天前
自然语言秒转SQL—— 免费体验 OB Cloud Text2SQL 数据查询
数据库·sql·ai·oceanbase·分布式数据库·向量·text2sql