CDH是Cloudera的早前开源平台发行版,是事实上的Apache Hadoop生态系统的安装管理平台,专为满足企业需求而构建。CDH提供开箱即用的企业使用所需的一切。通过将Hadoop与十几个其他关键的开源项目集成,Cloudera创建了一个功能先进的系统,可帮助您执行端到端的大数据工作流程。免费版本停更至6.3.2版本,后续只发布了商业版本,即使如此,许多公司都使用了免费版本的CDH部署了Hadoop大数据平台,其存量是很大的。
简单来说:CDH 是一个拥有集群自动化安装、中心化管理、集群监控、报警功能的一个工具(软件),使得集群的安装可以从几天的时间缩短为几个小时,运维人数也会从数十人降低到几个人,极大的提高了集群管理的效率。
1、前言
CDH的配置库支持Mysql,Oracle及postgresql数据库,大部分公司使用的是Mysql作为CDH的配置库,在高可用场景中,Mysql容易成为单点故障的关键点,而OB天然具备高可用特性,有必要研究切换CDH的配置库为OB,如此就有了这篇文章。
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语句
应对以上两个问题,经和社区大佬分析、评估及指导后,做出以下两个解决方案:
- 修改OB源码,编译并安装修改后的Observer,绕过CM的show engines的检查;
- 修改CM的ddl,绕过OB不支持连续执行的ddl;
下面以此操作步骤为线,记录这个过程。
3、编译OB、安装和租户创建
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