Hologres V2.0版本推出了全新的彈性高可用執行個體形態,將計算資源分解為不同的計算群組(Virtual Warehouse),更好的服務於高可用部署。本文為您介紹如何使用計算群組。
背景資訊
在Hologres 1.1版本已經實現了共用儲存的多執行個體讀寫分離的高可用部署架構,一個主執行個體可以綁定多個唯讀從執行個體,執行個體與執行個體之間共用儲存,但是計算資源是互相隔離的,從而實現讀寫分離高可用部署,詳情請參見主從執行個體讀寫分離部署(共用儲存)。
但是現在的唯讀從執行個體模式,存在以下限制:
多個執行個體使用獨立的Endpoint,切換流量時,需要更改Endpoint。
唯讀從執行個體和主執行個體共用一套中繼資料,無法根據每個唯讀從執行個體的作用單獨設定參數,例如根據查詢高可用的要求,針對每個唯讀從執行個體設定不一樣的Replica(副本)數。
為瞭解決以上問題,Hologres V2.0版本推出了全新的彈性高可用執行個體形態,將計算資源分解為不同的計算群組(Virtual Warehouse),相較於唯讀從執行個體模式,具備如下優點:
計算群組之間共用資料、中繼資料。
使用一個Endpoint,無需切換Endpoint即可實現流量切換。
計算群組架構介紹請參見計算群組架構介紹。
注意事項
僅Hologres V2.0.4及以上版本支援使用計算群組執行個體,如果您的執行個體是V2.0.4以下版本,請您使用自助升級或加入HologresDingTalk交流群反饋,詳情請參見如何擷取更多的線上支援?。
使用說明
情境1:建立全新的計算群組執行個體
示意圖
情境示意圖如下:使用
init_warehouse
寫入計算群組用於寫入資料;使用read_warehouse_1
查詢計算群組用於服務查詢。操作步驟
建立資料庫。
Superuser帳號登入HoloWeb建立名稱為
erp_database
的資料庫,詳情請參見建立資料庫。登入資料庫後,使用如下SQL向其中匯入範例資料。
DROP FOREIGN TABLE IF EXISTS odps_customer_10g; DROP FOREIGN TABLE IF EXISTS odps_lineitem_10g; DROP FOREIGN TABLE IF EXISTS odps_nation_10g; DROP FOREIGN TABLE IF EXISTS odps_orders_10g; DROP FOREIGN TABLE IF EXISTS odps_part_10g; DROP FOREIGN TABLE IF EXISTS odps_partsupp_10g; DROP FOREIGN TABLE IF EXISTS odps_region_10g; DROP FOREIGN TABLE IF EXISTS odps_supplier_10g; IMPORT FOREIGN SCHEMA "MAXCOMPUTE_PUBLIC_DATA#default" LIMIT to ( odps_customer_10g, odps_lineitem_10g, odps_nation_10g, odps_orders_10g, odps_part_10g, odps_partsupp_10g, odps_region_10g, odps_supplier_10g ) FROM SERVER odps_server INTO public OPTIONS(if_table_exist'error',if_unsupported_type'error'); DROP TABLE IF EXISTS LINEITEM; BEGIN; CREATE TABLE LINEITEM ( L_ORDERKEY BIGINT NOT NULL, L_PARTKEY INT NOT NULL, L_SUPPKEY INT NOT NULL, L_LINENUMBER INT NOT NULL, L_QUANTITY DECIMAL(15,2) NOT NULL, L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL, L_DISCOUNT DECIMAL(15,2) NOT NULL, L_TAX DECIMAL(15,2) NOT NULL, L_RETURNFLAG TEXT NOT NULL, L_LINESTATUS TEXT NOT NULL, L_SHIPDATE TIMESTAMPTZ NOT NULL, L_COMMITDATE TIMESTAMPTZ NOT NULL, L_RECEIPTDATE TIMESTAMPTZ NOT NULL, L_SHIPINSTRUCT TEXT NOT NULL, L_SHIPMODE TEXT NOT NULL, L_COMMENT TEXT NOT NULL, PRIMARY KEY (L_ORDERKEY,L_LINENUMBER) ); CALL set_table_property('LINEITEM', 'clustering_key', 'L_SHIPDATE,L_ORDERKEY'); CALL set_table_property('LINEITEM', 'segment_key', 'L_SHIPDATE'); CALL set_table_property('LINEITEM', 'distribution_key', 'L_ORDERKEY'); CALL set_table_property('LINEITEM', 'bitmap_columns', 'L_ORDERKEY,L_PARTKEY,L_SUPPKEY,L_LINENUMBER,L_RETURNFLAG,L_LINESTATUS,L_SHIPINSTRUCT,L_SHIPMODE,L_COMMENT'); CALL set_table_property('LINEITEM', 'dictionary_encoding_columns', 'L_RETURNFLAG,L_LINESTATUS,L_SHIPINSTRUCT,L_SHIPMODE,L_COMMENT'); CALL set_table_property('LINEITEM', 'time_to_live_in_seconds', '31536000'); COMMIT; DROP TABLE IF EXISTS ORDERS; BEGIN; CREATE TABLE ORDERS ( O_ORDERKEY BIGINT NOT NULL PRIMARY KEY, O_CUSTKEY INT NOT NULL, O_ORDERSTATUS TEXT NOT NULL, O_TOTALPRICE DECIMAL(15,2) NOT NULL, O_ORDERDATE timestamptz NOT NULL, O_ORDERPRIORITY TEXT NOT NULL, O_CLERK TEXT NOT NULL, O_SHIPPRIORITY INT NOT NULL, O_COMMENT TEXT NOT NULL ); CALL set_table_property('ORDERS', 'segment_key', 'O_ORDERDATE'); CALL set_table_property('ORDERS', 'distribution_key', 'O_ORDERKEY'); CALL set_table_property('ORDERS', 'bitmap_columns', 'O_ORDERKEY,O_CUSTKEY,O_ORDERSTATUS,O_ORDERPRIORITY,O_CLERK,O_SHIPPRIORITY,O_COMMENT'); CALL set_table_property('ORDERS', 'dictionary_encoding_columns', 'O_ORDERSTATUS,O_ORDERPRIORITY,O_CLERK,O_COMMENT'); CALL set_table_property('ORDERS', 'time_to_live_in_seconds', '31536000'); COMMIT; DROP TABLE IF EXISTS PARTSUPP; BEGIN; CREATE TABLE PARTSUPP ( PS_PARTKEY INT NOT NULL, PS_SUPPKEY INT NOT NULL, PS_AVAILQTY INT NOT NULL, PS_SUPPLYCOST DECIMAL(15,2) NOT NULL, PS_COMMENT TEXT NOT NULL, PRIMARY KEY(PS_PARTKEY,PS_SUPPKEY) ); CALL set_table_property('PARTSUPP', 'distribution_key', 'PS_PARTKEY'); CALL set_table_property('PARTSUPP', 'colocate_with', 'LINEITEM'); CALL set_table_property('PARTSUPP', 'bitmap_columns', 'PS_PARTKEY,PS_SUPPKEY,PS_AVAILQTY,PS_COMMENT'); CALL set_table_property('PARTSUPP', 'dictionary_encoding_columns', 'PS_COMMENT'); CALL set_table_property('PARTSUPP', 'time_to_live_in_seconds', '31536000'); COMMIT; DROP TABLE IF EXISTS PART; BEGIN; CREATE TABLE PART ( P_PARTKEY INT NOT NULL PRIMARY KEY, P_NAME TEXT NOT NULL, P_MFGR TEXT NOT NULL, P_BRAND TEXT NOT NULL, P_TYPE TEXT NOT NULL, P_SIZE INT NOT NULL, P_CONTAINER TEXT NOT NULL, P_RETAILPRICE DECIMAL(15,2) NOT NULL, P_COMMENT TEXT NOT NULL ); CALL set_table_property('PART', 'distribution_key', 'P_PARTKEY'); CALL set_table_property('PART', 'bitmap_columns', 'P_PARTKEY,P_SIZE,P_NAME,P_MFGR,P_BRAND,P_TYPE,P_CONTAINER,P_COMMENT'); CALL set_table_property('PART', 'dictionary_encoding_columns', 'P_NAME,P_MFGR,P_BRAND,P_TYPE,P_CONTAINER,P_COMMENT'); CALL set_table_property('PART', 'time_to_live_in_seconds', '31536000'); COMMIT; DROP TABLE IF EXISTS CUSTOMER; BEGIN; CREATE TABLE CUSTOMER ( C_CUSTKEY INT NOT NULL PRIMARY KEY, C_NAME TEXT NOT NULL, C_ADDRESS TEXT NOT NULL, C_NATIONKEY INT NOT NULL, C_PHONE TEXT NOT NULL, C_ACCTBAL DECIMAL(15,2) NOT NULL, C_MKTSEGMENT TEXT NOT NULL, C_COMMENT TEXT NOT NULL ); CALL set_table_property('CUSTOMER', 'distribution_key', 'C_CUSTKEY'); CALL set_table_property('CUSTOMER', 'bitmap_columns', 'C_CUSTKEY,C_NATIONKEY,C_NAME,C_ADDRESS,C_PHONE,C_MKTSEGMENT,C_COMMENT'); CALL set_table_property('CUSTOMER', 'dictionary_encoding_columns', 'C_NAME,C_ADDRESS,C_PHONE,C_MKTSEGMENT,C_COMMENT'); CALL set_table_property('CUSTOMER', 'time_to_live_in_seconds', '31536000'); COMMIT; DROP TABLE IF EXISTS SUPPLIER; BEGIN; CREATE TABLE SUPPLIER ( S_SUPPKEY INT NOT NULL PRIMARY KEY, S_NAME TEXT NOT NULL, S_ADDRESS TEXT NOT NULL, S_NATIONKEY INT NOT NULL, S_PHONE TEXT NOT NULL, S_ACCTBAL DECIMAL(15,2) NOT NULL, S_COMMENT TEXT NOT NULL ); CALL set_table_property('SUPPLIER', 'distribution_key', 'S_SUPPKEY'); CALL set_table_property('SUPPLIER', 'bitmap_columns', 'S_SUPPKEY,S_NAME,S_ADDRESS,S_NATIONKEY,S_PHONE,S_COMMENT'); CALL set_table_property('SUPPLIER', 'dictionary_encoding_columns', 'S_NAME,S_ADDRESS,S_PHONE,S_COMMENT'); CALL set_table_property('SUPPLIER', 'time_to_live_in_seconds', '31536000'); COMMIT; DROP TABLE IF EXISTS NATION; BEGIN; CREATE TABLE NATION( N_NATIONKEY INT NOT NULL PRIMARY KEY, N_NAME text NOT NULL, N_REGIONKEY INT NOT NULL, N_COMMENT text NOT NULL ); CALL set_table_property('NATION', 'distribution_key', 'N_NATIONKEY'); CALL set_table_property('NATION', 'bitmap_columns', 'N_NATIONKEY,N_NAME,N_REGIONKEY,N_COMMENT'); CALL set_table_property('NATION', 'dictionary_encoding_columns', 'N_NAME,N_COMMENT'); CALL set_table_property('NATION', 'time_to_live_in_seconds', '31536000'); COMMIT; DROP TABLE IF EXISTS REGION; BEGIN; CREATE TABLE REGION ( R_REGIONKEY INT NOT NULL PRIMARY KEY, R_NAME TEXT NOT NULL, R_COMMENT TEXT ); CALL set_table_property('REGION', 'distribution_key', 'R_REGIONKEY'); CALL set_table_property('REGION', 'bitmap_columns', 'R_REGIONKEY,R_NAME,R_COMMENT'); CALL set_table_property('REGION', 'dictionary_encoding_columns', 'R_NAME,R_COMMENT'); CALL set_table_property('REGION', 'time_to_live_in_seconds', '31536000'); COMMIT; INSERT INTO public.customer SELECT * FROM public.odps_customer_10g ; INSERT INTO public.lineitem SELECT * FROM public.odps_lineitem_10g ; INSERT INTO public.nation SELECT * FROM public.odps_nation_10g ; INSERT INTO public.orders SELECT * FROM public.odps_orders_10g ; INSERT INTO public.part SELECT * FROM public.odps_part_10g ; INSERT INTO public.partsupp SELECT * FROM public.odps_partsupp_10g ; INSERT INTO public.region SELECT * FROM public.odps_region_10g ; INSERT INTO public.supplier SELECT * FROM public.odps_supplier_10g ; vacuum nation; vacuum region; vacuum supplier; vacuum customer; vacuum part; vacuum partsupp; vacuum orders; vacuum lineitem; analyze nation; analyze region; analyze lineitem; analyze orders; analyze customer; analyze part; analyze partsupp; analyze supplier; analyze lineitem (l_orderkey,l_partkey,l_suppkey); analyze orders (o_custkey); analyze partsupp(ps_partkey,ps_suppkey);
建立計算群組。
Superuser帳號登入HoloWeb,在頂部功能表列選擇資訊安全中心 > 計算群組管理。
您可以在計算群組管理頁面查看執行個體現有的計算群組。
在計算群組管理頁面的右上方,單擊新增計算群組。
在新增計算群組對話方塊,填寫計算群組名稱和選擇計算群組資源。
本情境新增名稱為
read_warehouse_1
的計算群組:在計算群組管理頁面可查看計算群組狀態,待計算群組對應的狀態列為正在運行時,即計算群組建立成功。
向計算群組載入資料。
Table Group是Hologres中資料的載體。預設情況下,新建立的計算群組無權訪問任何Table Group,所以如果要使用計算群組查詢資料,需要先為計算群組賦予Table Group的許可權。
查看當前資料庫的Table Group。
使用如下SQL查看當前資料庫有哪些Table Group:
SELECT tablegroup_name FROM hologres.hg_table_group_properties GROUP BY tablegroup_name;
返回結果樣本如下:
即當前資料庫僅有一個Table Group。
為計算群組載入Table Group。
由於需要使用read_warehouse_1查詢該資料庫中erp_database_tg_default Table Group的資料,所以需要使用如下SQL為計算群組read_warehouse_1載入erp_database_tg_default:
CALL hg_table_group_load_to_warehouse ('erp_database.erp_database_tg_default', 'read_warehouse_1', 1);
查看計算群組載入Table Group的情況。
select * from hologres.hg_warehouse_table_groups;
樣本返回結果如下:
即read_warehouse_1已經載入了erp_database_tg_default 這個Table Group的資料。
設定使用者權限。
預設情況下建立的計算群組,非授權使用者不能訪問,當您需要讓其他帳號訪問計算群組時需要進行授權。為
ram_test
RAM使用者授權訪問read_warehouse_1計算群組授權樣本如下:查看使用者擁有計算群組的許可權資訊。
select * from hologres.hg_warehouse_users;
查看使用者預設計算群組的資訊。
select * from hologres.hg_user_default_warehouse;
在執行個體中加入使用者。
在HoloWeb的使用者管理頁面添加RAM使用者至Hologres執行個體,詳情請參見使用者管理。
賦予
ram_test
使用者erp_databse
資料庫的查詢許可權。在HoloWeb的DB授權頁面,為
ram_test
使用者授予資料庫的查詢許可權,詳情請參見RAM使用者權限授權快速入門。為使用者
ram_test
添加read_warehouse_1計算群組的許可權。CALL hg_grant_warehouse_access_privilege ('read_warehouse_1', 'p4_2xxxxxxxxxxxxxxx');
參數說明請參見計算群組授權管理。
將read_warehouse_1計算群組設定為
ram_test
使用者的預設計算群組。由於需要
ram_test
使用者串連Hologres使用read_warehouse_1的資源,不使用init_warehouse,實現讀寫分離,那麼就需要使用如下命令將ram_test
的預設計算群組設定為read_warehouse_1:CALL hg_set_user_default_warehouse ('p4_2xxxxxxxxxxxxxxx', 'read_warehouse_1');
查看當前帳號使用的計算群組。
此時使用
ram_test
使用者串連執行個體時,使用如下命令驗證使用的計算群組是否為read_warehouse_1:select current_warehouse();
情境2:計算群組流量切換
在情境一的基礎上,如果發現計算群組read_warehouse_1有故障,此時需要將帳號ram_test
的流量切換到init_warehouse計算群組上。
示意圖。
注意事項
由於切換流量需要重新串連才生效,所以需要保證您串連到Hologres的應用具備重連機制。
串連到Hologres時請使用Hologres自動的路由邏輯,切勿在連接字串中指定使用的計算群組名。
操作步驟
為使用者
ram_test
添加init_warehouse計算群組的許可權。如果之前未給
ram_test
添加init_warehouse的許可權,需要使用如下命令為使用者ram_test
添加init_warehouse計算群組的許可權,讓ram_test
使用者可以使用init_warehouse的資源。CALL hg_grant_warehouse_access_privilege ('init_warehouse', 'p4_2xxxxxxxxxxxxxxx');
將init_warehouse計算群組設定為
ram_test
使用者的預設計算群組。使用如下命令將
ram_test
使用者的預設計算群組設定為init_warehouse,設定完畢後,使用者和執行個體建立新串連即會使用計算群組init_warehouse的資源。CALL hg_set_user_default_warehouse ('p4_2xxxxxxxxxxxxxxx', 'init_warehouse');
斷開所有使用者非預設計算群組的串連。
SELECT hg_kill_non_default_warehouse_connections();
重建立立串連後,即會使用新配置的預設計算群組串連到執行個體。