实战|Flink不支持分库分表的改造之路(二)

WilliamGates
发布于 2022-6-20 17:53
浏览
0收藏

 

2.3 方案落地


经过上面的分析,主要涉及如下5个改造点。

 

2.3.1 改造flink-jdbc-connection配置


主要涉及url、table-name的改造:

  • url:支持多个数据库配置,并在schema支持正则表达式动态匹配数据库中的schema
  • table-name:表名支持正则匹配,可同时匹配多个表


具体代码如下:

'url' = 'jdbc:mysql://localhost:3306/order_([0-9]{1,}),jdbc:mysql://localhost:3306/order_([0-9]{1,})',
   'table-name' = 'order_([0-9]{1,})',

 

2.3.2 解析URL、Table名称


主要是根据配置的url,table_name表达式,基本的编码步骤如下:

  1. 查询数据库中所有schema
  2. 通过正则匹配schema
  3. 查询匹配schema下面的table
  4. 通过正则匹配表
  5. 返回数据库url与table的对应关系:List<TableItem>


2.3.3 实现分库分表JdbcMultiTableProvider


主要基于原有数据分片结果,根据分库分表,对Serializable[][]进行二次拆分,示例代码如下:

public class JdbcMultiTableProvider implements JdbcParameterValuesProvider {
    //匹配的数据库连接与table的对应关系
 private List<TableItem> tables;
    //原jdbc数据分片配置后的拆分结果
 private Serializable[][] partition;

 public JdbcMultiTableProvider(List<TableItem> tables) {
  this.tables = tables;
 }

 /**
  * @return 返回拆分后的分片和数据块的对应关系,Serializable[partition][parameterValues]
  * 启动partition为分片索引,parameterValues为每个分片对应的数据参数。
  */
 @Override
 public Serializable[][] getParameterValues() {
  int tableNum = tables.stream().mapToInt(item -> item.getTable().size()).sum();
  int splitCount = partition == null ? tableNum : tableNum * partition.length;
  int paramLength = partition == null ? 2 : 4;
  Serializable[][] parameters = new Serializable[splitCount][paramLength];
  int splitIndex = 0;

  for (TableItem tableItem : tables) {
   for (String table : tableItem.getTable()) {
    if (partition != null) {
     for (Serializable[] serializables : partition) {
      parameters[splitIndex][0] = tableItem.getUrl();
      parameters[splitIndex][1] = table;
      //数据分片配置
      parameters[splitIndex][2] = serializables[0];
      parameters[splitIndex][3] = serializables[1];
      splitIndex++;
     }
    } else {
     parameters[splitIndex][0] = tableItem.getUrl();
     parameters[splitIndex][1] = table;
     splitIndex++;
    }
   }
  }
  return parameters;
 }
 
 public JdbcParameterValuesProvider withPartition(JdbcNumericBetweenParametersProvider jdbcNumericBetweenParametersProvider) {
  if (null == jdbcNumericBetweenParametersProvider) {
   return this;
  }
  this.partition = jdbcNumericBetweenParametersProvider.getParameterValues();
  return this;
 }

 public static class TableItem {
  private String url;
  private List<String> table;
        //get/set..
 }
}

 

2.3.4 改造JdbcDynamicTableSource


主要目的生成基于分库分表的JdbcRowDataInputFormat对象,示例代码如下:

 

文章转自公众号:中间件兴趣圈

标签
已于2022-6-20 17:53:44修改
收藏
回复
举报
回复
    相关推荐