详细设计说明书_mysql同sqoop同步数据

1引言

1.1目的与范围

改造Sqoop,实现mysql与Phoenix的数据同步

1.2术语与缩写

1.3参考资料

Sqoop官方文档, http://sqoop.apache.org/docs/1.4.6/
Phoenix官方文档: http://phoenix.apache.org/

2项目概况

2.1需求概述

需要利用sqoop将mysql中的数据, 同步到phoenix.
但是, 由于sqoop并不支持将数据直接同步到phoenix中,
因此, 需要自定义开发.

3系统结构

3.1设计方法

Sqoop提供了直接将mysql中数据导入到hbase中的工具,
而phoenix是基于hbase的, 可以通过重写hbase的put转换类来实现.

3.2子系统规划

4 系统详细设计

4.1 Mysql, 同phoenix数据同步设计

4.1.1 数据同步设计

4.1.1.1 表示层设计
4.1.1.2 类设计
4.1.1.2.1 总体类图

自定义ToPhoenixPutTransformer类, 继承自PutTransformer类(sqoop中的类).

4.1.1.2.2 类说明ToPhoenixPutTransformer
  • 概述
    将mysql中的数据转换为phoenix类型的Put对象

  • 属性

属性属性名类型说明
LOG日志记录器Log记录日志
serializedFieldNames已经序列化属性Map保存已经处理的字段
  • 方法
    方法getFieldNameBytes
  • 说明:
    获得属性名称的字节数组。
  • 方法原型:

    private byte[] getFieldNameBytes(String fieldName) ;

  • 输入参数:

变量变量名类型说明
fieldName属性名String
  • 返回值:
类型说明
Byte[]返回字符串对应的字节数组
  • 方法
    getPutCommand

  • 说明:
    将mysql中的数据转换为Put对象列表。

  • 方法原型:
    public List getPutCommand(Map
4.1.1.3时序图

sqoop01

4.1.1.4详细代码
class ToPhoenixPutTransformer extends PutTransformer {

public static final Log LOG = LogFactory.getLog(ToBytesPutTransformer.class
        .getName());

// A mapping from field name -> bytes for that field name.
// Used to cache serialization work done for fields names.
private Map<String, byte[]> serializedFieldNames;

public ToBytesPutTransformer() {
    serializedFieldNames = new TreeMap<String, byte[]>();
}

/**
 * Return the serialized bytes for a field name, using the cache if it's
 * already in there.
 */
private byte[] getFieldNameBytes(String fieldName) {
    byte[] cachedName = serializedFieldNames.get(fieldName);
    if (null != cachedName) {
        // Cache hit. We're done.
        return cachedName;
    }

    // Do the serialization and memoize the result.
    byte[] nameBytes = Bytes.toBytes(fieldName);
    serializedFieldNames.put(fieldName, nameBytes);
    return nameBytes;
}

@Override
/** {@inheritDoc} */
public List<Put> getPutCommand(Map<String, Object> fields)
        throws IOException {

    String rowKeyCol = getRowKeyColumn();
    String colFamily = getColumnFamily().toUpperCase();
    byte[] colFamilyBytes = Bytes.toBytes(colFamily);

    // Multiple rowKey
    String[] rowKeys = rowKeyCol.split(",");
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    for (String item : rowKeys) {
        Object rowKey = fields.get(item);

        if (null == rowKey) {
            // If the row-key column is null, we don't insert this row.
            LOG
                    .warn("Could not insert row with null value for row-key column: "
                            + rowKeyCol);
            return null;
        }

        outputStream.write(getBytes(rowKey));
    }

    // New put object
    Put put = new Put(outputStream.toByteArray());
    outputStream.close();

    for (Map.Entry<String, Object> fieldEntry : fields.entrySet()) {

        String colName = fieldEntry.getKey().toUpperCase();

        if (!colName.equals(rowKeyCol.toUpperCase())) {
            // This is a regular field, not the row key.
            // Add it if it's not null.
            Object val = fieldEntry.getValue();
            if (null != val) {

                put.add(colFamilyBytes, getFieldNameBytes(colName),
                        getBytes(val));
            }
        }
    }

    return Collections.singletonList(put);
}

public byte[] getBytes(Object obj) {

    byte[] valBytes = null;

    if (obj instanceof String) {
        String s = (String) obj;
        valBytes = PVarchar.INSTANCE.toBytes(s);
    } else if (obj instanceof Boolean) {
        Boolean b = ((Boolean) obj).booleanValue();
        valBytes = PBoolean.INSTANCE.toBytes(b);
    } else if (obj instanceof Byte) {
        Byte b = ((Byte) obj).byteValue();
        valBytes = PTinyint.INSTANCE.toBytes(b);
    } else if (obj instanceof Short) {
        Short s = ((Short) obj).shortValue();
        valBytes = PSmallint.INSTANCE.toBytes(s);
    } else if (obj instanceof Integer) {
        Integer i = ((Integer) obj).intValue();
        valBytes = PInteger.INSTANCE.toBytes(i);
    } else if (obj instanceof Long) {
        Long l = ((Long) obj).longValue();
        valBytes = PLong.INSTANCE.toBytes(l);
    } else if (obj instanceof Float) {
        Float f = ((Float) obj).floatValue();
        valBytes = PFloat.INSTANCE.toBytes(f);
    } else if (obj instanceof Double) {
        Double d = ((Double) obj).doubleValue();
        valBytes = PDouble.INSTANCE.toBytes(d);
    } else if (obj instanceof java.math.BigInteger) {
        java.math.BigInteger b = (java.math.BigInteger) obj;
        valBytes = PLong.INSTANCE.toBytes(b);
    } else if (obj instanceof java.math.BigDecimal) {
        java.math.BigDecimal b = (java.math.BigDecimal) obj;
        valBytes = PDecimal.INSTANCE.toBytes(b);
    } else if (obj instanceof java.sql.Date) {
        java.sql.Date d = (java.sql.Date) obj;
        valBytes = PDate.INSTANCE.toBytes(d);
    } else if (obj instanceof java.sql.Time) {
        java.sql.Time t = (java.sql.Time) obj;
        valBytes = PTime.INSTANCE.toBytes(t);
    } else if (obj instanceof java.sql.Timestamp) {
        java.sql.Timestamp t = (java.sql.Timestamp) obj;
        valBytes = PTimestamp.INSTANCE.toBytes(t);
    }

    return valBytes;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值