MyCat (Mycat schema配置)

MyCat 作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一

作者简介: 大家好。我是聪明哥,曾任中兴、美团的架构师,现任一家互联网公司的CTO。

联系QQ:184480602,请加我进群,我们一起学习,一起进步,一起抗击互联网的寒冬

想要学习,就必须深入挖掘。挖得越深,地基就越牢固。

第1 阶段:解决多线程的细节

第2 阶段:详细的多线程设计模式

第三阶段.juc源码详细分析

第四阶段.jdk源码其余部分详细分析

阶段5. JVM源码详细分析

代码源码部分

哥码浅谈源码- 源码原理【2024年最新场景:各大厂商使用线程池的问题】

码哥谈源码【炸了!雷!秃头粉丝终于逃脱了! ]

码哥聊源码~【JVM课程必备知识及c/c++调试环境搭建】

马哥谈源码-原理源码篇【阐明join方法的唤醒基本是由jvm底层析构函数决定的】

码哥源码-原理源码篇【Doug Lea为什么要在运算前将成员变量赋值给局部变量?】

码哥谈源码【傻并不坏,但因为你说的是傻话就错了! ]

码哥谈源码【谁说Spring不支持多线程事务?】

B站没有人能清楚解释红黑树的历史。如果您不能接受,请加入我们。

啪啪系列【3小时讲解020-MESI协议与波动性的关系,认为x86验证结果就是最终结果的水货请闭嘴】

4.配置模块

4.2 schema.xml

接上一篇文章,接下来加载每个schema的配置(即MyCat中每个虚拟化数据库的配置)。

XMLSchemaLoader.java

私有无效loadSchemas(元素根){

NodeList 列表=root.getElementsByTagName(\’schema\’);

for (int i=0, n=list.getLength(); i n; i++) {

元素schemaElement=(元素) list.item(i);

//读取各个属性

字符串名称=schemaElement.getAttribute(\’名称\’);

String dataNode=schemaElement.getAttribute(\’dataNode\’);

String checkSQLSchemaStr=schemaElement.getAttribute(\’checkSQLschema\’);

字符串sqlMaxLimitStr=schemaElement.getAttribute(\’sqlMaxLimit\’);

int sqlMaxLimit=-1;

//读取SQL返回结果集的限制

if (sqlMaxLimitStr !=null !sqlMaxLimitStr.isEmpty()) {

sqlMaxLimit=Integer.valueOf(sqlMaxLimitStr);

}

//检查dataNode是否已经存在并检查schema标签是否有datanode

字符串默认DbType=null;

//添加验证检查和dataNode

if (dataNode !=null !dataNode.isEmpty()) {

ListString dataNodeLst=new ArrayListString(1);

dataNodeLst.add(dataNode);

checkDataNodeExists(dataNodeLst);

String dataHost=dataNodes.get(dataNode).getDataHost();

defaultDbType=dataHosts.get(dataHost).getDbType();

} 除此之外{

数据节点=空;

}

//加载schema下的所有表

MapString, TableConfig 表=loadTables(schemaElement);

//判断schema是否重复

if (schemas.containsKey(name)) {

throw new ConfigException(\’架构\’ + 名称+ \’重复!\’);

}

//如果设置了table,则不需要设置dataNode属性。如果未设置表,则必须设置dataNode 属性。

if (dataNode==null table.size()==0) {

抛出一个新的ConfigException()

\’Schema\’+name+\’没有配置表,所以必须设置dataNode属性!\’);

}

SchemaConfig schemaConfig=new SchemaConfig(名称, dataNode,

表, sqlMaxLimit, \’true\’.equalsIgnoreCase(checkSQLSchemaStr));

//设置数据库类型。这对于后续SQL语句的路由分析很有用。

if (defaultDbType !=null) {

schemaConfig.setDefaultDataNodeDbType(defaultDbType);

if (!\’mysql\’.equalsIgnoreCase(defaultDbType)) {

schemaConfig.setNeedSupportMultiDBType(true);

}

}

//判断是否存在非mysql的数据库类型。这样方便解析,判断是否开启多库分页解析。

for (String tableName : table.keySet()) {

TableConfig tableConfig=tables.get(表名);

如果(isHasMultiDbType(tableConfig)){

schemaConfig.setNeedSupportMultiDBType(true);

休息;

}

}

//记录每个dataNode的DB类型

MapString, String dataNodeDbTypeMap=new HashMap();

for (String dataNodeName : dataNodes.keySet()) {

DataNodeConfig dataNodeConfig=dataNodes.get(dataNodeName);

String dataHost=dataNodeConfig.getDataHost();

DataHostConfig dataHostConfig=dataHosts.get(dataHost);

if (dataHostConfig !=null) {

字符串dbType=dataHostConfig.getDbType();

dataNodeDbTypeMap.put(dataNodeName, dbType);

}

}

schemaConfig.setDataNodeDbTypeMap(dataNodeDbTypeMap);

schemas.put(名称,schemaConfig);

}

}

首先,它读取模式中的每个配置属性项并确定其有效性。例如默认的dataNode是否存在。只需检查之前读取的数据节点是否存在即可。

私有无效checkDataNodeExists(CollectionString 节点) {

if (nodes==null ||nodes.size() 1) {

返回;

}

for (字符串节点: 节点) {

if (!dataNodes.containsKey(node)) {

throw new ConfigException(\’dataNode \’\’ + node + \’\’ 未找到!\’);

}

}

}

然后加载所有表和childTable。

私有MapString,TableConfigloadTables(元素节点){

//MapString, TableConfig table=new HashMapString, TableConfig();

//支持表名带引号[`] BEN GONG

MapString, TableConfig 表=new TableConfigMap();

NodeList 节点列表=node.getElementsByTagName(\’table\’);

for (int i=0; i nodeList.getLength(); i++) {

元素tableElement=(element) nodeList.item(i);

String tableNameElement=tableElement.getAttribute(\’name\’).toUpperCase();

//TODO: 添加对路由、动态日期表的支持

String tableNameSuffixElement=tableElement.getAttribute(\’nameSuffix\’).toUpperCase();

if ( !\’\’.equals( tableNameSuffixElement ) ) {

if( tableNameElement.split(\’,\’).length 1 ) {

throw new ConfigException(\’nameSuffix \’ + tableNameSuffixElement + \’, name 参数必需,不允许多次中断!\’);

}

//前缀用于表示日期格式

tableNameElement=doTableNameSuffix(tableNameElement, tableNameSuffixElement);

}

//记录主键,方便后续路由分析,并开启主键自增

String[] tableNames=tableNameElement.split(\’,\’);

字符串PrimaryKey=tableElement.hasAttribute(\’primaryKey\’)? tableElement.getAttribute(\’primaryKey\’).toUpperCase() : null;

//记录主键是否自增。默认不自动递增(启用全局序列处理程序)

布尔自动增量=false;

if (tableElement.hasAttribute(\’autoIncrement\’)) {

autoIncrement=Boolean.parseBoolean(tableElement.getAttribute(\’autoIncrement\’));

}

//记录是否需要对返回的结果集添加限制。应该默认添加。

布尔值needAddLimit=true;

if (tableElement.hasAttribute(\’needAddLimit\’)) {

needAddLimit=Boolean.parseBoolean(tableElement.getAttribute(\’needAddLimit\’));

}

//记录类型,全局或非全局

字符串tableTypeStr=tableElement.hasAttribute(\’type\’) ? tableElement.getAttribute(\’type\’) : null;

int tableType=TableConfig.TYPE_GLOBAL_DEFAULT;

if (\’global\’.equalsIgnoreCase(tableTypeStr)) {

表类型=TableConfig.TYPE_GLOBAL_TABLE;

}

//记录dataNode以及它被分发到哪个dataNode

String dataNode=tableElement.getAttribute(\’dataNode\’);

TableRuleConfig 表规则=null;

if (tableElement.hasAttribute(\’rule\’)) {

String 规则名称=tableElement.getAttribute(\’rule\’);

tableRule=tableRules.get(规则名称);

if (tableRule==null) {

throw new ConfigException(\’规则\’ + 规则名称+ \’ 未找到!\’);

}

}

需要布尔规则=false;

//记录是否有绑定的分片规则

if (tableElement.hasAttribute(\’ruleRequired\’)) {

rulesRequired=Boolean.parseBoolean(tableElement.getAttribute(\’ruleRequired\’));

}

if (表名==null) {

throw new ConfigException(\’未找到表名!\’);

}

//分配函数并重新定位dataNodes

字符串distPrex=\’分布(\’;

布尔distTableDns=dataNode.startsWith(distPlex);

如果(distTableDns){

dataNode=dataNode.substring(distPlex.length(), dataNode.length() – 1);

}

//子表函数

String subTables=tableElement.getAttribute(\’subTables\’);

for (int j=0; j tableNames.length; j++) {

字符串表名=表名[j];

TableConfig 表=new TableConfig(表名, 主键,

自动增量、需要添加限制、表类型、数据节点、

getDbType(数据节点),

(tableRule!=null) tableRule.getRule() : null,

规则必填,null,false,null,null,子表);

checkDataNodeExists(table.getDataNodes());

如果(distTableDns){

distributionDataNodes(table.getDataNodes());

}

//检查是否删除重复项

if (tables.containsKey(table.getName())) {

throw new ConfigException(\’table\’ + tableName + \’重复!\’);

}

//放入地图

table.put(table.getName(), 表);

}

//子表只有在tableName由单个表组成时才能存在(没有逗号)

if (tableNames.length==1) {

TableConfig 表=tables.get(tableNames[0]);

//处理子表

processChildTables(表,表,数据节点,表元素);

}

}

返回表。

}

对于子表,有一个递归读取配置。

私有无效processChildTables(MapString,TableConfig 表,

TableConfigparentTable, 字符串dataNodes, 元素tableNode) {

//解析子表

NodeList childNodeList=tableNode.getChildNodes();

for (int j=0; j childNodeList.getLength(); j++) {

节点theNode=childNodeList.item(j);

if (!theNode.getNodeName().equals(\’childTable\’)) {

继续;

}

元素childTbElement=(元素) theNode;

//读取子表信息

String cdTbName=childTbElement.getAttribute(\’name\’).toUpperCase();

字符串PrimaryKey=childTbElement.hasAttribute(\’primaryKey\’)

布尔自动增量=false;

if (childTbElement.hasAttribute(\’autoIncrement\’)) {

autoIncrement=Boolean.parseBoolean(childTbElement.getAttribute(\’autoIncrement\’));

}

布尔值needAddLimit=true;

if (childTbElement.hasAttribute(\’needAddLimit\’)) {

needAddLimit=Boolean.parseBoolean(childTbElement.getAttribute(\’needAddLimit\’));

}

String subTables=childTbElement.getAttribute(\’subTables\’);

//子表的Join键和对应的父键,父表和子表通过这个关联起来

String joinKey=childTbElement.getAttribute(\’joinKey\’).toUpperCase();

StringparentKey=childTbElement.getAttribute(\’parentKey\’).toUpperCase();

TableConfig 表=new TableConfig(cdTbName, PrimaryKey,

自动增量,需要添加限制,

TableConfig.TYPE_GLOBAL_DEFAULT,数据节点,

getDbType(dataNodes)、null、false、parentTable、true、

joinKey、parentKey、子表);

if (tables.containsKey(table.getName())) {

throw new ConfigException(\’table \’ + table.getName() + \’重复!\’);

}

table.put(table.getName(), 表);

//对于子表的子表,递归处理

processChildTables(表、表、数据节点、childTbElement);

}

}

对于表dataNode 支持,有一个类似于dataNode=\”distributed(dn$1-10)\” 的特殊设置。这意味着:

/**

* 将数据节点分布在多个主机上,即dn1(host1)、dn100

*(主机2)、dn300(主机3)、dn2(主机1)、dn101(主机2)、dn301(主机3).等。

* 根据主机的不同,重新定位每个主机上的数据节点。例如,在上面的例子中,host1拥有dn1、dn2,host2拥有dn100、dn101,host3拥有dn300、dn301,

* 按主机排序:0-dn1(主机1)、1-dn100(主机2)、2-dn300(主机3)、3-dn2(主机1)、4-dn101(主机2)、5-dn301(主机3)

*

* @param 数据节点

*/

私有无效distributionDataNodes(ArrayListString theDataNodes){

MapString, ArrayListString newDataNodeMap=new HashMapString, ArrayListString(dataHosts.size());

for (String dn : theDataNodes) {

DataNodeConfig dnConf=dataNodes.get(dn);

字符串主机=dnConf.getDataHost();

ArrayListString hostDns=newDataNodeMap.get(host);

hostDns=(hostDns==null) ? new ArrayListString() : hostDns;

hostDns.add(dn);

newDataNodeMap.put(主机,hostDns);

}

ArrayListString 结果=new ArrayListString(theDataNodes.size());

布尔值hasData=true;

while(有数据){

有数据=false;

for (ArrayListString dns : newDataNodeMap.values()) {

if (!dns.isEmpty()) {

结果.add(dns.remove(0));

有数据=true;

}

}

}

theDataNodes.clear();

theDataNodes.addAll(结果);

}

读取所有表后,记录DB类型。这对于后续SQL语句的路由分析很有用。将所有模式配置保存到:

私有最终MapString,SchemaConfig架构。

4.3 server.xml

然后读取并加载服务器配置。

XMLConfigLoader.java:

公共XMLConfigLoader(SchemaLoader schemaLoader) {

XMLServerLoaderserverLoader=new XMLServerLoader();

this.system=serverLoader.getSystem();

this.users=serverLoader.getUsers();

this.quarantine=serverLoader.getQuarantine();

this.cluster=serverLoader.getCluster();

this.dataHosts=schemaLoader.getDataHosts();

this.dataNodes=schemaLoader.getDataNodes();

this.schemas=schemaLoader.getSchemas();

模式加载器=null;

}

XMLServerLoader.java

公共XMLServerLoader() {

this.system=new SystemConfig();

this.users=new HashMapString, UserConfig();

this.quarantine=new QuarantineConfig();

this.load();

}

私有无效负载(){

//读取server.xml配置

输入流dtd=null;

输入流XML=null;

尝试{

dtd=XMLServerLoader.class.getResourceAsStream(\’/server.dtd\’);

xml=XMLServerLoader.class.getResourceAsStream(\’/server.xml\’);

元素根=ConfigUtil.getDocument(dtd, xml).getDocumentElement();

//加载系统标签

加载系统(根);

//加载用户标签

加载用户(root);

//加载集群配置

this.cluster=new ClusterConfig(root, system.getServerPort());

//加载权限和黑白名单

负载隔离(根);

} catch (ConfigException e) {

扔e。

} catch (异常e) {

抛出新的ConfigException(e)。

} 最后{

如果(dtd!=null){

尝试{

dtd.close();

} catch(IOException e) {

}

}

如果(xml!=null){

尝试{

xml.close();

} catch(IOException e) {

}

}

}

}

以上关于#MyCat的相关内容摘自网络,仅供参考。相关信息请参见官方公告。

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91416.html

(0)
CSDN's avatarCSDN
上一篇 2024年6月22日 上午6:42
下一篇 2024年6月22日 上午7:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注