Phoenix常见问题解答

我想开始 有没有凤凰Hello World

先决条件:这里下载最新的凤凰,将凤凰 - *。jar复制到HBase lib文件夹并重启HBase。

1.使用控制台

  1. 开始Sqlline:$ sqlline.py [zookeeper]
  2. 当Sqlline连接时执行以下语句:
 
    
create table test (mykey integer not null primary key, mycolumn varchar);
upsert into test values (1,'Hello');
upsert into test values (2,'World!');
select * from test;

  1. 您应该得到以下输出
 
    
+-------+------------+
| MYKEY |  MYCOLUMN  |
+-------+------------+
| 1     | Hello      |
| 2     | World!     |
+-------+------------+

2.使用java

创建具有以下内容的test.java文件:

 
    
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.Statement;

public class test {

	public static void main(String[] args) throws SQLException {
		Statement stmt = null;
		ResultSet rset = null;
		
		Connection con = DriverManager.getConnection("jdbc:phoenix:[zookeeper]");
		stmt = con.createStatement();
		
		stmt.executeUpdate("create table test (mykey integer not null primary key, mycolumn varchar)");
		stmt.executeUpdate("upsert into test values (1,'Hello')");
		stmt.executeUpdate("upsert into test values (2,'World!')");
		con.commit();
		
		PreparedStatement statement = con.prepareStatement("select * from test");
		rset = statement.executeQuery();
		while (rset.next()) {
			System.out.println(rset.getString("mycolumn"));
		}
		statement.close();
		con.close();
	}
}

在命令行编译和执行

$ javac test.java

$ java -cp“../phoenix-[version]-client.jar:” test

您应该得到以下输出

Hello World!

凤凰城有没有办法批量加载?

地图缩小

这里的例子

CSV

CSV数据可以批量加载内置的名为psql的实用程序。典型的上传速率是每秒20K到50K行(取决于行的宽度)。

使用示例:
使用psql $ psql.py [zookeeper] ../examples/web_stat.sql创建表

Upsert CSV批量数据$ psql.py [zookeeper] ../examples/web_stat.csv

如何将Phoenix表映射到现有的HBase表?

您可以通过预先存在的HBase表上的CREATE TABLE / CREATE VIEW DDL语句创建Phoenix表或视图。在这两种情况下,我们将按原样保留HBase元数据。对于CREATE TABLE,我们将创建不存在的任何元数据(表,列族)。我们还将为每行添加一个空键值,以便查询按预期行为(不需要在扫描期间投影所有列)。

另一个警告是字节串行化的方式必须与Phoenix串行化的方式相匹配。对于VARCHAR,CHAR和UNSIGNED_ *类型,我们使用HBase Bytes方法。CHAR类型只需要单字节字符,而UNSIGNED类型期望值大于或等于零。对于有符号类型(TINYINT,SMALLINT,INTEGER和BIGINT),Phoenix将翻转第一个位,使负值在正值之前排序。因为HBase按字典顺序排列行键,所以负值的第一位为1,而正值为0,如果我们不翻转第一位,则负值为“大于”正值。因此,如果您使用HBase native API存储整数,并希望通过Phoenix访问它们,请确保所有数据类型均为UNSIGNED类型。

我们的复合行键通过简单地将值连接在一起而形成,在变量长度类型之后使用零字节字符作为分隔符。

如果你创建一个这样的HBase表:

创建't1',{NAME =>'f1',VERSIONS => 5}

那么你有一个名为“t1”的HBase表,名称为“f1”的列族。请记住,在HBase中,不要对可能的KeyValues或行键的结构建模。这是您在凤凰城指定的信息,超出了表和列系列。

所以在凤凰城,你会创建一个这样的视图:

CREATE VIEW“t1”(pk VARCHAR PRIMARY KEY,“f1”.val VARCHAR)

“pk”列声明您的行键为VARCHAR(即字符串),而“f1”.val列声明您的HBase表将包含具有列族和列限定符“f1”的键值:VAL,并且它们值将是VARCHAR。

请注意,如果您创建具有所有大写字母名称的HBase表,那么您不需要双引号(因为这是Phoenix如何通过上面的框架来规范字符串)。例如:

创建'T1',{NAME =>'F1',VERSIONS => 5}

您可以创建此凤凰视图:

CREATE VIEW t1(pk VARCHAR PRIMARY KEY,f1.val VARCHAR)

或者如果您正在创建新的HBase表,只需让Phoenix为您完成所有操作(不需要使用HBase shell)。

CREATE TABLE t1(pk VARCHAR PRIMARY KEY,val VARCHAR)

有没有任何提示来优化凤凰?

  • 盐腌提高读/写性能盐腌可以显著增加读取预裂/写性能的数据分成多个区域。尽管Salting在大多数情况下都能获得更好的表现。

例:

CREATE TABLE TEST(HOST VARCHAR NOT NULL PRIMARY KEY,DESCRIPTION VARCHAR)SALT_BUCKETS = 16

注意:理想情况下,对于具有四核CPU的16区域服务器群集,请选择32-64之间的盐桶,以获得最佳性能。

  • 每个分割表Salting会自动进行表分割,但是如果要精确控制表分割发生的位置,除了添加额外的字节或更改行键顺序,那么您可以预分割表。

例:

CREATE TABLE TEST(HOST VARCHAR NOT NULL PRIMARY KEY,DESCRIPTION VARCHAR)SPLIT ON('CS','EU','NA')

  • 使用多个列系列

列系列包含单独文件中的相关数据。如果您查询使用所选列,那么在列族中将这些列组合在一起是有意义的,以提高读取性能。

例:

以下创建表DDL将创建两列F和A和B。

创建表测试(MYKEY VARCHAR NOT NULL PRIMARY KEY,A.COL1 VARCHAR,A.COL2 VARCHAR,B.COL3 VARCHAR)

  • 使用压缩磁盘压缩可以提高大型表的性能

例:

CREATE TABLE TEST(HOST VARCHAR NOT NULL PRIMARY KEY,DESCRIPTION VARCHAR)COMPRESSION ='GZ'

如何在表上创建辅助索引?

Phoenix从凤凰2.1版开始,支持对可变和不可变数据的索引。请注意,Phoenix 2.0.x仅支持对不可变数据的索引。不可变表的索引写性能指标略高于可变表,但不可更改表中的数据不能更新。

  • 创建表

不变表:创建表测试(mykey varchar主键,col1 varchar,col2 varchar)IMMUTABLE_ROWS = true;

可变表:创建表测试(mykey varchar主键,col1 varchar,col2 varchar);

  • 在col2上创建索引

在测试(col2)上创建索引idx

  • 在col1上创建索引,在col2上创建一个包含的索引

在test(col1)上创建索引idx include(col2)

在这个测试表中上升行,而Phoenix查询优化器将选择正确的索引来使用。如果Phoenix正在使用索引表,您可以在explain plan中看到。您也可以在Phoenix查询中给出一个提示来使用特定的索引。

为什么我的辅助索引不被使用?

除非查询中使用的所有列都在其中(作为索引或覆盖的列),否则不会使用辅助索引。构成数据表主键的所有列将自动包含在索引中。

示例:DDL create table usertable(id varchar primary key,firstname varchar,lastname varchar); 在usertable(firstname)上创建索引idx_name;

查询:DDL select id,firstname,lastname from usertable where firstname ='foo';

在这种情况下,索引不会被使用,因为姓氏不是索引或覆盖列的一部分。这可以通过查看解释计划来验证。要修复这个创建索引,它具有索引或覆盖列的lastname部分。示例:在usertable(firstname)上创建idx_name include(lastname);

凤凰多快?为什么这么快?

凤凰快。100M行的全表扫描通常在20秒内完成(中等大小的集群上的窄表)。如果查询包含关键列上的过滤器,则此时间会下降到几毫秒。对于非键列或非领先键列上的过滤器,可以在这些列上添加索引,通过复制具有索引列的键的一部分表,可以获得与键列上的过滤相同的性能。

凤凰城甚至在全扫时也是如此:

  1. Phoenix使用区域边界块查询您的查询,并使用可配置数量的线程在客户端上并行运行它们
  2. 聚合将在服务器端的协处理器中进行,将返回给客户端的数据量折返,而不是全部返回。

如何连接Hadoop-2上运行的HBase?

Hadoop-2配置文件存在于Phoenix pom.xml中。

凤凰可以在任意时间戳的表上工作,像HBase API一样灵活吗?

默认情况下,凤凰卫视让HBase管理时间戳,只显示所有内容的最新值。但是,Phoenix还允许用户提供任意时间戳。为此,您可以在连接时指定“CurrentSCN”,如下所示:

 
    
Properties props = new Properties();
props.setProperty("CurrentSCN", Long.toString(ts));
Connection conn = DriverManager.connect(myUrl, props);

conn.createStatement().execute("UPSERT INTO myTable VALUES ('a')");
conn.commit();

以上相当于使用HBase API:

 
    
myTable.put(Bytes.toBytes('a'),ts);

通过指定CurrentSCN,您可以告诉Phoenix,您希望在该时间戳内完成该连接的所有内容。请注意,这适用于在连接上完成的查询,例如,上面的myTable上的查询将不会看到刚刚插入的数据,因为它只会看到在其CurrentSCN属性之前创建的数据。这提供了一种快照,闪回或时间点查询的方法。

请记住,创建新连接不是一项昂贵的操作。相同的底层HConnection用于与同一个集群的所有连接,因此它或多或少与实例化一些对象。

为什么我的查询不做范围扫描?

DDL:CREATE TABLE TEST(pk1 char(1)not null,pk2 char(1)not null,pk3 char(1)not null,non-pk varchar CONSTRAINT PK PRIMARY KEY(pk1,pk2,pk3));

RANGE SCAN意味着只会扫描表中的一行子集。如果您使用主键约束中的一个或多个引导列,则会发生这种情况。在前导PK列上不进行过滤的查询。从测试中选择*,其中pk2 ='x'和pk3 ='y'; 将导致完全扫描,而以下查询将导致测试中的范围扫描select *,其中pk1 ='x'和pk2 ='y'; 。请注意,您可以在“pk2”和“pk3”列上添加辅助索引,这将导致对第一个查询进行范围扫描(通过索引表)。

DEGENERATE SCAN意味着查询不能返回任何行。如果我们可以确定在编译时,我们不用担心甚至不能运行扫描。

FULL SCAN意味着将扫描表的所有行(如果您有WHERE子句,则可能会应用过滤器)

SKIP SCAN意味着表中的子集或所有行将被扫描,但是会根据过滤器的条件跳过大量行。有关详细信息,请参阅博客。如果您在主要主键列上没有过滤器,则我们不会执行SKIP SCAN,但可以使用/ + SKIP_SCAN / hint 强制跳过扫描。在某些条件下,即当您的主键列的基数较低时,它将比全扫描更有效。

我应该汇集Phoenix JDBC连接吗?

不,没有必要汇集Phoenix JDBC连接。

由于基础的HBase连接,Phoenix的Connection对象与大多数其他JDBC Connections不同。Phoenix Connection对象被设计为一个成本低廉的薄对象。如果Phoenix Connections被重新使用,那么基本的HBase连接可能并不总是被前一个用户保持在健康状态。最好创建新的Phoenix Connections,以确保避免任何潜在的问题。

通过创建一个委托连接,可以通过创建一个代理连接,从池中检索到新的Phoenix连接,然后在将其返回到池时关闭连接(参见PHOENIX-2388)。

为什么Phoenix在做一个upsert时添加一个空的/虚拟的KeyValue?

需要空或虚拟的KeyValue(具有_0的列限定符),以确保给定的列可用于所有行。

您可能知道,数据作为KeyValues存储在HBase中,这意味着为每个列值存储完整的行键。这也意味着行密钥根本不存储,除非存储了至少一个列。

现在考虑具有整数主键的JDBC行,以及几个都为空的列。为了能够存储主键,需要存储一个KeyValue,以显示该行是否存在。此列由您注意到的空列表示。这允许执行“SELECT * FROM TABLE”并接收所有行的记录,即使是非pk列为空的记录。

即使对于某些(或全部)记录只有一列为空,同样的问题也会出现。在Phoenix上进行扫描将包括空列,以确保只包含主键(并且对于所有非键列都为空)的行将包含在扫描结果中。


原文:https://phoenix.apache.org/faq.html



猜你喜欢

转载自blog.csdn.net/high2011/article/details/72911687