Phoenix最早是saleforce的一个开源项目,后来成为Apache基金的顶级项目。
Phoenix是构建在HBase上的一个SQL层,能让我们用标准的JDBC APIs而不是HBase客户端APIs来创建表,插入数据和对HBase数据进行查询。
Phoenix完全使用Java编写,作为HBase内嵌的JDBC驱动。Phoenix查询引擎会将SQL查询转换为一个或多个HBase扫描,并编排执行以生成标准的JDBC结果集。直接使用HBase API、协同处理器与自定义过滤器,对于简单查询来说,其性能量级是毫秒,对于百万级别的行数来说,其性能量级是秒。
上面是Phoenix的整体介绍。由于项目中运用了phoenix,一直在增量的导入数据。导致Phoenix的空间不足。但是项目中只用到一个月以内的数据。所以,要进行冗余数据的删除的。
DruidDataSource的数据源,导致报错MutationState size of 512000 isbigger than max allowed size of 500000 代码如下:
@Resource(name = "phoenixDataSource")
private DruidDataSource phoenixDataSource;
public Integer delete(String sql, Object... params) throws Exception {
Connection conn = null;
PreparedStatement statement = null;
try {
conn = phoenixDataSource.getConnection();
conn.setAutoCommit(false);
statement = conn.prepareStatement(sql);
fillParameter(statement, params);
Integer number = statement.executeUpdate();
conn.commit();
return number;
} catch (Exception e) {
throw new Exception("查询phoenix出错", e);
} finally {
if (statement != null) {
statement.close();
}
if (conn != null) {
conn.close();
}
}
}
报错查询资料得知是由于内存中的Phoenix限制只能查询50W条的数据,于是想到修改配置文件。有了第二次尝试:使用DriverManager类修改配置文件属性,将默认的50W条数据,增加到1000W。
public Integer delete(String sql, Object... params) throws Exception {
Connection conn = null;
PreparedStatement statement = null;
try {
Properties connectionProperties = new Properties();
//默认的500000
connectionProperties.setProperty(QueryServices.MAX_MUTATION_SIZE_ATTRIB,"10000000");
// 默认的500000 改成1000000
connectionProperties.setProperty(QueryServices.IMMUTABLE_ROWS_ATTRIB,"10000000");
connectionProperties.setProperty("user",instanceNumber);
connectionProperties.setProperty("password",accessKey);
StringBuilder url = new StringBuilder("jdbc:phoenix:thin:url=http://").append(address).append(";serialization=PROTOBUF");
conn = DriverManager.getConnection(url.toString(), connectionProperties);
conn.setAutoCommit(false);
statement = conn.prepareStatement(sql);
fillParameter(statement, params);
Integer number = statement.executeUpdate();
conn.commit();
return number;
} catch (Exception e) {
throw new Exception("查询phoenix出错", e);
} finally {
if (statement != null) {
statement.close();
}
if (conn != null) {
conn.close();
}
}
}
删除结果还是报错:mutationstate size is bigger than maximum allowed number of bytes.
明明已经修改配置文件了,看来是配置文件没有起作用。于是继续找资料,进行验证。在阅读phoenix官方文档的时候,查看delete命令的时候,看到了关键的一句话
DELETE
DELETE
/ * + hint * /
FROM tableName
WHERE expression
ORDER BY order
, ...
LIMIT
bindParameter
number
删除where子句选择的行。如果启用了自动提交,则完全在服务器端执行删除。
例:DELETE FROM TEST;
DELETE FROM TEST WHERE ID=123;
DELETE FROM TEST WHERE NAME LIKE 'foo%';
如果启用了自动提交,则完全在服务器端执行删除。这句话很重要,在我们程序中设置把自动提交设置为false,也就是说我们是在客户端的内存进行删除的,而内存是有限的,所以就导致了报错。于是有了最终版本的删除实现。
public Integer delete(String sql, Object... params) throws Exception {
Connection conn = null;
PreparedStatement statement = null;
try {
Properties connectionProperties = new Properties();
connectionProperties.setProperty(QueryServices.MAX_MUTATION_SIZE_ATTRIB,"10000000");
connectionProperties.setProperty(QueryServices.IMMUTABLE_ROWS_ATTRIB,"10000000");
connectionProperties.setProperty("user",instanceNumber);
connectionProperties.setProperty("password",accessKey);
StringBuilder url = new StringBuilder("jdbc:phoenix:thin:url=http://").append(address).append(";serialization=PROTOBUF");
conn = DriverManager.getConnection(url.toString(), connectionProperties);
conn.setAutoCommit(true);
statement = conn.prepareStatement(sql);
fillParameter(statement, params);
Integer number = statement.executeUpdate();
conn.commit();
return number;
} catch (Exception e) {
throw new Exception("查询phoenix出错", e);
} finally {
if (statement != null) {
statement.close();
}
if (conn != null) {
conn.close();
}
}
}
设置conn.setAutoCommit(true);让删除语句在服务端进行删除,就不会报:java.sql.SQLException: ERROR 730 (LIM02): MutationState size is bigger than maximum allowed number of bytes 和 MutationState size of 512000 is bigger than max allowed size of 500000。并且删除成功。在删除数据时,会返回前端超时,但是delete语句还在服务端执行。
9000W数据删除用时 43分钟。删除实现成功,但是没有删除干净,在6000W条删除时,留下600多条数据未删除,9000W时留下1400多条数据。这是由于删除中有数据报错导致,对于这个问题,就是在执行一下删除。可以看到能正确返回删除的数据条数。
phoenix官网链接:http://phoenix.apache.org/