Hologres使用小记

家电维修 2023-07-16 19:16www.caominkang.com家电维修技术

1、Hologres 0.8 创建数组类型外部表采坑

ODPS:CREATE TABLE `test_clue` ( `id_c` array, `name` array ) ;

Holo:

CREATE FOREIGN TABLE test_clue(

id int8[],

name text[])

SERVER odps_server

OPTIONS(project_name 'itsl_dev', table_name 'test_clue');

报错

 原因odps文件类型不是orc

odps的文件类型有哪些??aliorc

hive的文件存储类型

||SequenceFile
Hadoop用来存储二进制形式的[Key,Value]对而设计的一种平面文件(Flat File)。

||TextFile文本格式

||RCFile一种列存储格式

||ORC ★一种列存储格式 进阶版RCFile

||Parquet ★一种列存储格式AVRO

||JsonFile(json文件)

||InputFormat

解决方法

odps建表前加

set odps.sql.default.file.format=aliorc;

set odps.storage.force.aliorc=true;

CREATE TABLE `test_clue` ( `id_c` array, `name` array ) ;

2、Hologres 0.8 使用get_json_object函数

先用super账号设置开启hive函数支持CREATE extension hive_patible;

SELECt

get_json_object(message,'$.profileData.advertisingID') AS advertisingID

,get_json_object(message,'$.profileData.appKey') AS appkey

,get_json_object(message,'$.profileData.identityId') AS identityId

,get_json_object(message,'$.profileData.productid') AS productid

,get_json_object(message,'$.profileData.properties._td_mobile') AS td_mobile

,get_json_object(message,'$.profileData.properties._td_pixel') AS td_pixel

,get_json_object(message,'$.profileData.properties._td_platform') AS td_platform

,get_json_object(message,'$.profileData.properties._td_brand') AS td_brand

,get_json_object(message,'$.profileData.properties.tenantid') AS tenantid

,get_json_object(message,'$.profileData.properties._td_os') AS td_os

,get_json_object(message,'$.type') AS TYPE

,get_json_object(message,'$.version') AS version

,get_json_object(message,'$.profileData.properties._td_sdk_source') AS td_sdk_source

,get_json_object(message,'$.profileData.properties._td_broser') AS td_broser

,get_json_object(message,'$.profileData.properties._td_channel') AS td_channel

FROM ti_datahub_ae_collector_data_4h

;

3、hologres 优化查询设置

①analyze ;分析元数据,优化查询方式

②建表增加索引

分布式键distribution_key

call set_table_property('table1','distribution key','b');

指定分布列,数据将按照指定列,将数据shuffle到各个shard,同样的数值肯定会在同样的shrad中。
例select count(1) from tmp1 join tmp2 on tmp1.a = tmp2.b
注对于有pk的表,其分布键默认就是pk,如果不想pk字段作为分布键,可以指定pk字段的子集,不能随意指定。可以通过shard_count来指定表的shard数,如果不指定的话每个数据库都有一个默认的shard数,一旦指定了一个表的shard数,其他的表如果想要和这个表做local join,就必须指定colcate ith这个表。

聚簇索引 Clustering key对建立索引数据进行排序,建立聚簇索引能够加速用户在索引列上的range和filter查询;注desc和asc表名构建索引时的排序方式,默认为asc。clustering key创建的时候数据类型不能为float/double,每个表最多只有一个clustering key
如call set_table_property('table1','clustering_key','a'); or call set_table_property('tbl', 'clustering_key', 'a:desc,b:asc');

比特编码列bitmap指定比特编码列使Hologres会在这些列上构建比特编码,相当于把数据与对应的行号做一个映射;注bitmap可以对segment内部的数据进行快速过滤,建议把filter条件的数据建成比特编码。目前Hologres会默认所有text列都会被隐藏式地设置到bitmap_columns中。只有列存表支持比特编码列

分段键Segment Key分段键帮助Hologres进行一些文件的快速筛选和跳过。指定分段键,当查询条件包含分段列时,查询可以通过segment key快速找到相应数据对应的存储位置。注segment key要求按照数据输入自增,一般只有时间类型的字段(timestamptz)适合设置为segment key,其他场景基本不需要设置。只有列存表支持分段键设置。

字典编码列设置

call set_table_property('table1','dictionary_encoding_columns','b');

字典编码可以将字符串的比较转换成数字的比较,加速group by查询
例select sum(a) from table1 group by b;
注不建议将基数高的列建为字典编码列,会导致查询性能变差。目前Hologres会默认所有text列都会被隐藏式地设置到bitmap_columns中。只有列存表支持比特编码列

③存储类型call set_table_property('table1','orientation','[ro|colume]');

行存适用于高QPS的基于primary key的点查询,例如here pk=abc,其余场景都应该选用列存方式。

例如

drop TABLE tags_humanbeings;
BEGIN;
CREATE TABLE public.tags_humanbeings (
 "oneid" text,
 "ssoid" text,
 "uid" text,
 "phone" text,
 "name" text,
 "idcard" text,
 "action" int8,
 "date_created" timestamptz,
 "gender" int8,
 "age_group" int8,
 "constellation" int8,
 "generation" int8,
 "education" int8,
 "birthday" text,
 "marital_status" int8,
 "oupation" int8,
 "industry" int8,
 "native_province" int8,
 "native_city" int8,
 "native_city_level" int8,
 "material_cost" text,
 
 PRIMARY KEY (oneid)
);
--分布式键
call set_table_property('public.tags_humanbeings',	'distribution_key',	'oneid');	
--存储方式 列存 行存		
CALL SET_TABLE_PROPERTY('public.tags_humanbeings',	'orientation',	'column');			
CALL SET_TABLE_PROPERTY('public.tags_humanbeings',	'time_to_live_in_seconds',	'3153600000');	
--dictionary_encoding_columns
CALL SET_TABLE_PROPERTY('public.tags_humanbeings', 'dictionary_encoding_columns', 'oneid');
--CALL SET_TABLE_PROPERTY('public.tags_humanbeings', 'clustering_key','oneid'); 默认和主键一致
--bitmap_columns
CALL SET_TABLE_PROPERTY('', 'bitmap_columns', 'phone:on,name:on,birthday:off,material_cost:off');
call set_table_property('public.tags_humanbeings','segment key','date_created');
ment on table public.tags_humanbeings is '人标签表';
COMMIT ;

4、调优

当表数据量较大时,可设置以下参数进行调优;

set hg_experimental_query_batch_size = 4096; --默认8192

set hg_experimental_foreign_table_executor_max_dop = 32; --默认64

5、BitmapRoaringRoaring 

1、CREATE EXTENSION roaringbitmap; 

      Roaring Bitmap函数在使用之前,需要执行以下语句开启extension才可以调用。extension是DB级别的函数,一个DB只需执行一次即可,新建DB需要重新执行。

不支持将Roaring Bitmap设置为Bitmap或者Dictionary。

2、 建表

BEGIN;

CREATE TABLE public.user_tags (

"tag_key" text,

"tag_value" text,

"userlist" roaringbitmap

) ;

CALL SET_TABLE_PROPERTY('public.user_tags', 'orientation', 'column');

CALL SET_TABLE_PROPERTY('public.user_tags', 'bitmap_columns', 'tag_key,tag_value');

CALL SET_TABLE_PROPERTY('public.user_tags', 'dictionary_encoding_columns', 'tag_key:auto,tag_value:auto');

COMMIT;

3、写入数据

①MC中

INSERT OVERWRITE TABLE tm_tag_userprofile_attribute_all_d_roaringbitmap

SELECT

,(

SELECT ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY phone ASC)

FROM (SELECt DISTINCT phone FROM tm_tag_userprofile_attribute_all_d WHERe data_date=20220316 ) t

WHERe t.phone=t1.phone

) as rk

FROM tm_tag_userprofile_attribute_all_d t1

WHERe data_date = 20220316

;

由于是测试,所以用户ID通过RK来代替,如果实际使用,应该通过oneid表生成唯一的ID,生成ID的目的是为了配合roaringbitmap字段的使用,因为该字段只支持INT类型的数据。

4、写入数据

①一些基础操作

创建表组CALL HG_CREATE_TABLE_GROUP ('mdp', 40);

修改表所属表组CALL HG_UPDATe_TABLE_SHARD_COUNT('user_tags','mdp');

创建schema:create schema mdp;

切换schema :set search_path to mdp; --切换至目标Schema

②外表向内表写入数据

SET hg_experimental_query_batch_size = 4096;
SET hg_experimental_foreign_table_executor_max_dop = 32;
INSERT INTO mdp.user_tags

SELECT tag_id

,tag_value_code

,rb_build(array_agg(rk::INT))

FROM (SELECt FROM public.tm_tag_userprofile_attribute_all_d_roaringbitmap

WHERe RK > 40000000

) t

GROUP BY tag_id

,tag_value_code

;

5、瓶颈

①MC窄表数据量1827194847/ bitmap表数据量 106010293

测试环境:CPU: 50core, mem: 200GB;shard=40 ,新建的table_group=mdp

正式环境:CPU: 140core, mem: 560GB;shard=40,新建的table_group=mdp

正式环境:CPU: 140core, mem: 560GB;shard=80,新建的table_group=mdp

当前配置无法一次性写入数据,报错链接超时或内存溢出

测试环境shard=40每500W 写一次 会偶尔链接超时,多次尝试可以写入

正式环境shard=40每 2000W写一次 写入正常

正式环境shard=80每 可以全量写入 写入时长573898 ms

②多次写入数据无法正常使用,因为位运算的原因

a)单次写入RK<20000000计算

SELECt Rb_cardinality(Rb_and(t1.r, t2.r))

FROM (

  SELECt Rb_and_agg(userlist) AS r

  FROM user_tags

  WHERe tag_key = '100001'

  AND tag_value = '男' ) AS t1,

  (

  SELECt rb_and_agg(userlist) AS r

  FROM user_tags

  WHERe tag_key = '100002'

  AND tag_value = '30-35岁' ) AS t2

;

6、圈选测试

正式环境圈选测试shard=80 时间20220323

①宽表圈选 性别男&年龄30-35岁

SELECt count(DISTINCT oneid) FROM tt_sl_tag_userprofile_attribute_all_mdp_holo_d WHERe gender=3 and age_group=7;

耗时 867ms  统计值 1574459

②Roaring Bitmap圈选

SELECt Rb_cardinality(Rb_and(t1.r, t2.r)) FROM (

  SELECt Rb_and_agg(userlist) AS r

  FROM user_tags1 WHERe tag_key = ‘100001’ AND tag_value = '男' ) AS t1,

        (SELECt rb_and_agg(userlist) AS r FROM user_tags1 WHERe tag_key = '100002'

          AND tag_value = '30-35岁' ) AS t2;

耗时 506ms 统计值 1574459

7、圈选测试

正式环境圈选测试shard=80 时间20220323

①宽表圈选 是否车主是&品牌WWW

SELECt count(DISTINCT a.oneid)

FROM tt_sl_tag_userprofile_attribute_all_mdp_holo_d a join

tt_sl_tag_userprofile_vehicle_rel_all_mdp_holo_d b

ON a.oneid = b.oneid

WHERe (oner=3795 and car_brand=111);

耗时 432ms  统计值 412298

②Roaring Bitmap圈选

SELECt Rb_cardinality(Rb_and(t1.r, t2.r)) FROM

(SELECt Rb_and_agg(userlist) AS r FROM user_tags1 WHERe tag_key = '100270'

AND tag_value = '是' ) AS t1,

(SELECt rb_and_agg(userlist) AS r FROM vehicle_tagsWHERe tag_key = '100020'

AND tag_value = 'WWW' ) AS t2

;

耗时 309ms 统计值 412234

8、更新写入,必须有主键

如表tb1 数据

BEGIN;CREATE TABLE tbl_1 (a int NOT NULL PRIMARY KEY,b int,c int);

INSERT INTO tbl_1 VALUES (1, 1, 1), (2, 3, 4);

1、支持更新某个字段,如通过主键a更新字段b

INSERT INTO tbl_1 (a, b)SELECt d,e FROM tbl_2

ON CONFLICT (a) DO UPDATe SET b = excluded.b;

SELECT FROM tbl_1;

2、支持更新整行,如通过主键a更新所有列

INSERT INTO tbl_1 (a, b, c) SELECt d,e,f FROM tbl_2

ON CONFLICT (a) DO UPDATe SET (a,b,c) = ROW (excluded.)

3、支持主键不存在追加

INSERT INTO tbl_1 VALUES (3, 2, 3)

ON CONFLICT (a) DO UPDATE SET

(a, b, c) = ROW (excluded.);

9、覆盖写入

1、刷新外表的Schema

IMPORT FOREIGN SCHEMA holo_demo LIMIT to ( odps_region_10g ) FROM SERVER odps_server INTO public OPTIONS(if_table_exist 'update',if_unsupported_type 'error');

2、清理潜在的临时表  

BEGIN ; DROP TABLE IF EXISTS public.region_ne;

3、创建临时表 SET hg_experimental_enable_create_table_like_properties=on; CALL HG_CREATE_TABLE_LIKE ('public.region_ne', 'select from public.region'); COMMIT ;

4、 向临时表插入数据 INSERT INTO public.region_ne SELECt FROM public.odps_region_10g; ANALYZE public.region_ne;

5、 删除旧表 BEGIN ;DROP TABLE IF EXISTS public.region;

6、临时表改名 ALTER TABLE IF EXISTS public.region_ne RENAME TO region; COMMIT ;

7、授权(MDP有权限问题,需要重新授权)

  ①用户授权

   GRANT USAGE ON SCHEMA schema_name TO "云账号/云邮箱";

  GRANT SELECT ON TABLE  TO "云账号/云邮箱";

  GRANT SELECT ON ALL TABLES IN SCHEMA public TO "云账号/云邮箱";

  ②角色授权

  CREATE USER "云账号ID/云邮箱";

  CREATE ROLE ;

  GRANT TO "云账号/云邮箱";

  ALTER TABLE OWNER TO ;

Copyright © 2016-2025 www.jianfeikang.com 建飞家电维修 版权所有 Power by