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

WilliamGates
发布于 2022-6-20 17:53
890浏览
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,})',
  • 1.
  • 2.

 

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..
 }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.

 

2.3.4 改造JdbcDynamicTableSource


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

 

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

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


回复
    相关推荐