Phoenix
安装(续)
-
在HBase中添加配置,是的Phoenix支持二级索引
sh# 进入HBase的安装目录下 cd /opt/software/hbase-2.5.5/conf/ # 编辑文件 vim hbase-site.xml
在文件中添加
xml<property> <name>hbase.regionserver.wal.codec</name> <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value> </property> <property> <name>hbase.region.server.rpc.scheduler.factory.class</name> <value>org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory</value> </property> <property> <name>hbase.rpc.controller.factory.class</name> <value>org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory</value> </property>
-
远程分发
shscp hbase-site.xml root@hadoop02:$PWD scp hbase-site.xml root@hadoop03:$PWD
-
启动:Zookeeper -> HDFS -> HBase,启动Phoenix
shsqlline.py hadoop01:2181
操作
概述
- Phoenix将类SQL在底层转化为HBase API操作来执行,所以Phoenix中的每一个字段对应了HBase的命令
- 在Phoenix中,建表的时候需要指定一个或者多个字段作为主键,主键被映射成HBase的行键
- Phoenix在建表的时候,如果没有指定列族,那么这些列会默认被放入0列族
- 注意:Phoenix会自动的将表明、列名等转化为大写形式,如果要保持小写形式,那么需要使用双引号来标记
SQL
-
查看所有的表
sqlshow tables; -- 或者 !table -- 或者 !tables
-
创建表
sqlcreate table employers( id varchar primary key, name varchar, age integer, gender varchar ); -- 保持小写 create table "department"( "id" varchar primary key, "dept_name" varchar );
-
多个字段作为联合主键。注意:
- 如果需要将多个字段来作为联合主键,那么字段的声明顺序和主键的定义顺序必须相同
- 多字段作为联合主键的时候,要求字段类型必须一致
- 多字段的值不能为空
sqlcreate table students( grade integer not null, class integer not null, id integer not null, name varchar, age integer, gender varchar constraint s_pk primary key(grade, class, id) );
-
需要注意的是,Phoenix为了减少对磁盘空间的占用,默认会对每一列的数据进行编码处理。如果不需要进行编码处理,那么在建表的时候可以在尾部添加
sqlcolumn_encoded_bytes=0
-
建表的时候需要指定的列族
sqlcreate table users( id varchar primary key, basic.username varchar, basic.phone varchar, basic.password varchar, info.address varchar, info.age integer );
-
插入数据
sqlupsert into employers values('e0001', 'Danny', 25, 'male');
-
查询数据
sqlselect * from employers;
-
删除数据
sqldelete from employers where id = 'e0001';
-
删除表
sqldrop table employers;
-
退出命令行
sql!quit
JDBC操作
Thick Client
-
Thick Client(胖客户端)是将Phoenix的所有的功能都集成到了客户端,因此提供的功能比较齐全,缺点是客户端打成jar包体积较大
-
API操作
javapackage com.fe.phoenix; import java.sql.*; // 胖客户端 public class ThickClientDemo { public static void main(String[] args) throws SQLException { // 获取连接 Connection con = DriverManager.getConnection("jdbc:phoenix:hadoop01:2181"); // 获取表述 Statement stat = con.createStatement(); // 查询 ResultSet rs = stat.executeQuery("select * from students"); while(rs.next()){ String name = rs.getString("name"); System.out.println(name); } // 关闭连接 rs.close(); stat.close(); con.close(); } }
Thin Client
-
Thin Client(瘦客户端)将Phoenix的功能进行了拆解,大部分的功能基本上由Phoenix服务器来承担,客户端只负责发送请求获取数据
-
从Phoenix5.X开始,Phoenix安装包中默认不提供对瘦客户端的支持,所以需要额外安装PhoenixQueryServer来增加支持
-
安装PhoenixQueryServer
sh# 进入预安装目录 cd /opt/presoftware/ # 上传或者下载安装包 # 解压 tar -xvf phoenix-queryserver-6.0.0-bin.tar.gz -C ../software/ # 进入安装路径 cd /opt/software/phoenix-queryserver-6.0.0/ # 将Phoenix的连接jar包复制到当前路径下 cp /opt/software/phoenix-5.1.3/phoenix-client-hbase-2.5-5.1.3.jar ./ # 启动QueryServer bin/queryserver.py start
二级索引
概述
-
在HBase中,查询数据的时候,需要指定行键,通过行键来锁定数据
shget 'tableName', 'rowKey', 'cf:c'
但是Phoenix将命令包装成了SQL形式,那么也就意味着必然会出现不通过主键来查询的情况,例如:
sql-- 通过主键查询,对应到HBase上是有行键的 select age from person where id = 'p001'; -- 没有通过主键来查询指定数据 select age from person name = 'tom';
这个SQL在HBase上是先对全表来进行扫描(scan),然后扫描完成之后进行的过滤,因此效率会非常低
-
Phoenix针对这种情况提供了二级索引:针对非主键列建立索引。那么建立索引之后,能够在不使用主键的前提下,来提升查询效率
全局索引(Global Index)
-
在Phoenix中,当建立索引的时候,如果不指定,那么默认建立的就是全局索引
-
建立全局索引的时候,在HBase中会生成一张新的表专门用于存储这个索引列,也就意味着,如果更改原始表中的数据,索引表中的数据同步更改,因此全局索引更适合于读多写少的场景
-
基本语法
sqlcreate index 索引(表)名 on 表名(列名); -- 例如 create index s_name_index on students(name); -- 会在HBase中生成一个索引表s_name_index,其中以name列的值作为s_name_index的行键 create index s_name_index on students(name, gender); -- 会在HBase中生成一个索引表s_name_index,其中以name列和gender列拼接的值作为s_name_index的行键
包含索引(Covered Index)
-
基本语法
sqlcreate index 索引(表)名 on 表名(列名1) include(列名2); create index s_name_index on students(name) include(gender); -- 针对name和gender类建立索引,但是在索引表中,只把name作为行键,gender作为普通列来存储
本地索引(Local Index)
-
全局索引是建立一个新的索引表,本地索引不是建立索引表,而是在原表中添加一个列族作为索引列族
-
这种方式的优势:当需要对数据进行更新的时候,不需要跨表更新
-
基本语法
sqlcreate local index 索引(表)名 on 表名(列名); create local index s_name_index on students(name, gender);
Scala
简介
概述
- Scala是Martin Ordersky(马丁.奥德斯科/基)于2001年开始设计的一门支持面向对象(Object-oriented )和函数式编程(Functional Programming)的多范式语言
- Scala的官网:www.scala-lang.org
- Scala目前为止有3个大版本:Scala1.X~3.X。目前Scala1.X已经停止使用,Scala3.x兼容Scala2.x的所有特性,但是Scala3.x从2021年才推出的版本,也因此,目前大数据中的主流框架Spark、Flink等基本上是基于Scala2.x实现的,所以上课阶段使用Scala2.x
- Scala语言即支持脚本方式来运行,也支持编译之后执行。Scala也是通过JVM来编译的,所以Scala代码编译完成之后依然产生的是
.class
文件,也因此Scala定义的逻辑可以在Java中执行,同样,Java中所有的类都可以被Scala调用 - 安装Scala之前,需要先安装JDK1.8
特点
- Scala是一门多范式编程语言,支持面向对象和函数式编程两种方式。目前市面上的编程语言可以分为四类:面向对象、面向过程、函数式、泛型式
- Scala是一门静态类型(强类型)的编程语言,在编译的时候就需要确定数据类型,定义之后类型不能更改
- Scala是一门基于JVM的编程语言,所以和Java是互通的
- 相对于Java代码而言,Scala会更加的优雅和简洁
基本语法
注意问题
- 在Scala中,认为换行就是新的一行语句,所以省略分号不写
- 主函数必须定义到伴生对象object中
- Scala的注释方式和Java的注释方式是一模一样的,支持单行注释、多行注释和文档注释
- 在Scala中,一共有39个关键字,其中大部分关键字是Java是重合的,例如
package
,class
,for
等,但是Scala同时提供了自有的关键字,例如object
,def
,yield
,var
,val
,implicit
等
标识符命名规则
- 由字母、数字和下划线组成
- 数字不能开头
- 不能使用关键字
- 严格区分大小写
- 可以使用符号作为标识符,但是如果使用符号作为标识符,那么整个标识符必须全部使用符号
- 可以使用反引号来将任意字符串标记为标识符
变量和常量
-
变量的定义规则
scalavar 变量名:数据类型 = 数据
-
常量的定义规则
scalaval 常量名:数据类型 = 数据
-
在Scala中,推荐使用常量
-
因为Scala是一门强类型语言,所以变量/常量在赋值之后,数据类型就不能发生变化,因此Scala中,可以根据值自动推导数据类型,所以定义变量/常量的时候,数据类型可以省略
-
除非值的类型和声明类型不完全一致,此时才需要显式声明
-
不同于Java的地方在于,不支持变量先声明后赋值
控制台输入输出
-
在Scala中,推荐使用
scala.io.StdIn
来从控制台获取数据 -
在Scala中,可以使用
print
或者println
来进行输出。println
是输出并换行 -
如果需要输出多个数据,可以使用
+
来进行字符串的拼接scalaprintln("name:" + name + ", age:" + age + ", gender:" + gender)
-
Scala中还提供了占位符的方式来输出数据
scalaprintf("name:%s, age:%d, gender:%s\n", name, age, gender)
-
Scala中还提供了数据的引用形式
scalaprintln(s"name:$name, age:$age, gender:$gender")
-
如果需要保留小数位(精确),那么此时需要以f作为开头
scalaprintln(f"total:${price * weight}%3.2f")
-
字符串中支持转义字符
scala// 字符串中支持转义字符 println("hello\tworld") // 原样输出字符串 println(raw"hello\tworld")
-
输出多行组成的字符串
scalaval sql = """ |select name, | sum(score) |from students |group by name; """.stripMargin println(sql)