StarRocks 【新一代MPP数据库】(2)https://developer.aliyun.com/article/1534281
2.4.7、Bitmap 索引
StarRocks支持基于BitMap索引,对于Filter(比如where过滤)的查询有明显的加速效果。
原理:
Bitmap是元素为bit的, 取值为0、1两种情形的, 可对某一位bit进行置位(set)和清零(clear)操作的数组。Bitmap的使用场景有(判断是非):
- 用一个long型表示32位学生的性别,0表示女生,1表示男生。
- 用Bitmap表示一组数据中是否存在null值,0表示元素不为null,1表示为null。
- 一组数据的取值为(Q1, Q2, Q3, Q4),表示季度,用Bitmap表示这组数据中取值为Q4的元素,1表示取值为Q4的元素, 0表示其他取值的元素。
什么是 bitmap 索引?
Bitmap只能表示取值为两种情形的列数组, 当列的取值为多种取值情形枚举类型时, 例如季度(Q1, Q2, Q3, Q4), 系统平台(Linux, Windows, FreeBSD, MacOS), 则无法用一个Bitmap编码; 此时可以为每个取值各自建立一个Bitmap的来表示这组数据; 同时为实际枚举取值建立词典.
如上图所示,Platform列有4行数据,可能的取值有Android、Ios。StarRocks中会首先针对Platform列构建一个字典,将Android和Ios映射为int,然后就可以对Android和Ios分别构建Bitmap。具体来说,我们分别将Android、Ios 编码为0和1,因为Android出现在第1,2,3行,所以Bitmap是0111(从右往左),因为Ios出现在第4行,所以Bitmap是1000(从右往左)。
假如有一个针对包含该Platform列的表的SQL查询,select xxx from table where Platform = iOS,StarRocks会首先查找字典,找出iOS对于的编码值是1,然后再去查找 Bitmap Index,知道1对应的Bitmap是1000,我们就知道只有第4行数据符合查询条件,StarRocks就会只读取第4行数据,不会读取所有数据。
适用场景:
使用Bitmap可以大大减少判断过滤时间(存储体积小:只存储一个向量比如0001),提高查询效率
- 当需要对表数据进行非前置列(排序键)进行过滤时,可以创建bitmap索引加速效率。
- 对表数据进行多列过滤,也可以考虑对多列分别创建bitmap索引加速效率
测试:
CREATE TABLE IF NOT EXISTS user_dup ( user_id INT, sex INT , age INT )DUPLICATE KEY(user_id)DISTRIBUTED BY HASH(user_id) BUCKETS 8
插入数据:
INSERT INTO user_dup VALUES(1001,0,18); INSERT INTO user_dup VALUES(1002,1,18); INSERT INTO user_dup VALUES(1003,0,18); INSERT INTO user_dup VALUES(1004,1,18); INSERT INTO user_dup VALUES(1005,0,18); INSERT INTO user_dup VALUES(1006,1,18); INSERT INTO user_dup VALUES(1007,0,18); INSERT INTO user_dup VALUES(1008,1,18);
创建位图索引:
CREATE INDEX user_sex_index ON user_dup(sex) USING bitmap;
查看索引:
SHOW INDEX FROM user_dup;
注意事项:
(1)对于明细模型,所有列都可以建Bitmap 索引;对于聚合模型,只有Key列可以建Bitmap 索引。
(2)Bitmap索引, 应该在取值为枚举型, 取值大量重复, 较低基数, 并且用作等值条件查询或者可转化为等值条件查询的列上创建.
(3)不支持对Float、Double、Decimal 类型的列建Bitmap 索引。
(4)如果要查看某个查询是否命中了Bitmap索引,可以通过查询的Profile信息查看。
2.4.8、Bloom Filter 索引
什么是Bloom Filter:
Bloom Filter(布隆过滤器)是用于判断某个元素是否在一个集合中的数据结构,优点是空间效率和时间效率都比较高,缺点是有一定的误判率(因为不同值的hash值可能是相同的,默认循环三次hash算法,如果要求准确率高,需要进行更多层的for循环)。
布隆过滤器是由一个Bit数组和n个哈希函数构成。Bit数组初始全部为0,当插入一个元素时,n个Hash函数对元素进行计算, 得到n个slot,然后将Bit数组中n个slot的Bit置1。
当我们要判断一个元素是否在集合中时,还是通过相同的n个Hash函数计算Hash值,如果所有Hash值在布隆过滤器里对应的Bit不全为1,则该元素不存在。当对应Bit全1时, 则元素的存在与否, 无法确定. 这是因为布隆过滤器的位数有限, 由该元素计算出的slot, 恰好全部和其他元素的slot冲突. 所以全1情形, 需要回源查找才能判断元素的存在性。
什么是Bloom Filter 索引:
StarRocks的建表时, 可通过PROPERTIES{"bloom_filter_columns"="c1,c2,c3"}指定需要建BloomFilter索引的列,查询时, BloomFilter可快速判断某个列中是否存在某个值。如果Bloom Filter判定该列中不存在指定的值,就不需要读取数据文件;如果是全1情形,此时需要读取数据块确认目标值是否存在。另外,Bloom Filter索引无法确定具体是哪一行数据具有该指定的值。
- 建表时指定需要加Bloom Filter索引的列,创建一张测试表
CREATE TABLE test_bf( id INT, event_type INT, email INT, sex INT, age INT )DUPLICATE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 8 PROPERTIES("bloom_filter_columns"="event_type,sex");
- 查看Bloom Filter索引。使用show index查看不到Bloom Filter索引,得用show create table 命令
SHOW CREATE TABLE test_bf
- 删除索引
alter table test_bf set("bloom_filter_columns"="");
注意事项:
(1)不支持对Tinyint、Float、Double 类型的列建Bloom Filter索引。
(2)Bloom Filter索引只对in和=过滤查询有加速效果。
(3)如果要查看某个查询是否命中了Bloom Filter索引,可以通过查询的Profile信息查看(TODO:加上查看Profile的链接)。
3、数据导入与查询
3.1、Stream Load(同步导入)
StarRocks支持从本地直接导入数据,支持CSV格式。数据量在10G以下,可以使用Stream Load导入,这种导入方式是通过用户发送HTTP请求将本地文件或数据流导入到StarRocks中。Stream Load 同步执行导入并返回结果。用户可以直接通过返回结果判断是否导入成功。
基本原理:Steam Load中,用户通过HTTP协议提交导入命令,提交到FE节点,FE节点则会通过HTTP 重定向指令请求转发给某一个BE节点,用户也可以直接提交导入命令指定BE节点。
测试:
[root@hadoop102 ~]# vim test.csv 1001,'test1',123456@.qqcom,'测试地址1',18,1 1002,'test2',123456@.qqcom,'测试地址2',18,1 1003,'test3',123456@.qqcom,'测试地址3',20,0 1004,'test4',123456@.qqcom,'测试地址4',21,1 1005,'test5',123456@.qqcom,'测试地址5',23,0 1006,'test6',123456@.qqcom,'测试地址6',22,1 1007,'test7',123456@.qqcom,'测试地址7',18,0 1008,'test8',123456@.qqcom,'测试地址8',25,1 1009,'test9',123456@.qqcom,'测试地址9',19,0 1010,'test10',123456@.qqcom,'测试地址10',10,1 1011,'test11',123456@.qqcom,'测试地址11',18,1
根据官网语法将CSV数据导入对应user表中,官网语法:
curl --location-trusted -u user:passwd [-H ""...] -T data.file -XPUT http://fe_host:http_port/api/{db}/{table}/_stream_load
注意:命令-H 为头部信息 column_separator为测试文件中字段间隔符,虽然官网写着支持csv但默认是\t,默认支持tsv所以这把这个参数改成逗号
[root@hadoop102 ~]# curl --location-trusted -u root -T test.csv -H "column_separator:," http://hadoop102:8030/api/test/users/_stream_load
因为Stream load是同步导入,所以可以立马看到是否导入成功:
这里的 '_stream_load' 只是一个标识符
导入成功后,查看对应的users表
同时,我们也可以通过访问 hadoop102:8030 来访问 starrocks 的 Web UI:
3.2、Broker Load(异步导入)
StarRocks支持从Apache HDFS、Amazon S3等外部存储系导入数据,支持CSV、ORCFile、Parquet等文件格式。数据量在几十GB到上百GB 级别。
在Broker Load模式下,通过部署的Broker程序,StarRocks可读取对应数据源(如HDFS, S3)上的数据,利用自身的计算资源对数据进行预处理和导入。这是一种异步的导入方式,用户需要通过MySQL协议创建导入,并通过查看导入命令检查导入结果。
使用 broker load 的时候必须保证 broker 进程启动!
这里演示Apache HDFS导入StarRocks,将Hadoop集群的hdfs-site.xml文件复制到对应broker conf 目录下:
Broker Load 支持如下数据文件格式:
- CSV
- Parquet
- ORC
创建两个 csv 文件并上传到 HDFS :
file1.csv:
1,Lily,23 2,Rose,23 3,Alice,24 4,Julia,25
file2.csv:
200,'北京'
StarRocks 创建两张表,分别对应两个文件:
CREATE TABLE `table1` ( `id` int(11) NOT NULL COMMENT "用户 ID", `name` varchar(65533) NULL DEFAULT "" COMMENT "用户姓名", `score` int(11) NOT NULL DEFAULT "0" COMMENT "用户得分" ) ENGINE=OLAP PRIMARY KEY(`id`) DISTRIBUTED BY HASH(`id`) BUCKETS 10; CREATE TABLE `table2` ( `id` int(11) NOT NULL COMMENT "城市 ID", `city` varchar(65533) NULL DEFAULT "" COMMENT "城市名称" ) ENGINE=OLAP PRIMARY KEY(`id`) DISTRIBUTED BY HASH(`id`) BUCKETS 10;
从 HDFS 导入:
LOAD LABEL test_db.label1 ( DATA INFILE("hdfs://hadoop102:8020/starrocks/file1.csv") INTO TABLE table1 COLUMNS TERMINATED BY "," (id, name, score) , DATA INFILE("hdfs://hadoop102:8020/starrocks/file2.csv") INTO TABLE table2 COLUMNS TERMINATED BY "," (id, city) ) WITH BROKER "broker1" ( "hadoop.security.authentication" = "simple", "username" = "lyh", "password" = "123456" ) PROPERTIES ( "timeout" = "3600" );
注意:下面标记的地方是需要自定义的地方,参考官网文档:
查看 load 计划:
show load where label=load名称
查询导入结果:
StarRocks 【新一代MPP数据库】(4)https://developer.aliyun.com/article/1534284