2.1 軟件安裝及數據庫初始化
2.1.1 greenplum 架構
1
Master主機與Segment主機對比:
Master主機負責 | Segment主機負責 |
---|---|
1. 建立與客戶端的會話連接和管理 | 1. 業務數據的存儲和存取 |
2. sql的解析並形成分佈式的執行計劃 | 2. 執行由master分發的sql語句 |
3. 將生成好的執行計劃分發到每個Segment上執行 | 3. 對於master來說,每個Segment都是對等的,負責對應數據的存儲和計算 |
4. 收集Segment的執行結果 | 4. 每一臺機器上可以配置一到多個Segment |
5. master不存儲業務數據,只存儲數據字典 | 5. 由於每個Segment都是對等的,建議採用相同的機器配置 |
6. master主機可以一主一備,分佈在兩臺機器上 | 6. Segment分primary 和mirror兩種,一般交錯第存放在子節點上 |
7. 爲了提高性能,master最好單獨佔用一臺機器 |
Master和Segment的關係:
2
Master和Segment其實都是一個單獨的PostgreSQL數據庫,每一個都有自己單獨的一套元數據字典。
Client一般只能與Master界面進行交互,Client將SQL發給Master,然後Master對SQL進行分析後,再將其分配給所有的Segment進行操作,並且將彙總結果返回給客戶端。
2.1.2 環境搭建
- greenplum集羣介紹
3
-
安裝linux
-
數據庫存儲:linux下建議使用XFS,Solaris下建議使用ZFS;Raid根據需求選擇硬Raid或軟Raid,需要更大空間則Raid5,性能要求高則Raid1+0
-
網絡(hosts):所有機器的網絡都通,防火牆都是關閉的,使用ping確定所有hostname都通
-
創建用戶及用戶組
- 刪除原有用戶:
#groupdel gpadmin # userdel gpadmin
-
創建新的用戶和用戶組:
#groupadd -g 530 gpadmin #useradd -g 530 -m -d /home/gpadmin -s /bin/bash gpadmin
-
對文件夾進行賦權,爲新用戶創建密碼:
#chown -R gpadmin:gpadmin /home/bash gpadmin #passwd gpadmin Changing password for user gpadmin. New UNIX password: Retype new UNIX password:
2.1.3 greenplum安裝
1. 安裝數據庫軟件
下載地址:https://network.gopivotal.com/products/pivotal-gpdb
- 準備好安裝文件:
greenplum-db-4.1.1.1-build-1-RHEL5-x86_64.zip
- 執行unzip命令解壓安裝文件:
unzip greenplum-db-4.1.1.1-build-1-RHEL5-x86_64.zip
-
解壓後生成兩個文件:
README_INSTALL; greenplum-db-4.1.1.1-build-1-RHEL5-x86_64.bin.
-
爲gp軟件創建安裝目錄,並且賦給gp用戶權限:
mkdir /opt/greenplum chown -R gpadmin:gpadmin /opt/greenplum
-
執行以下命令開始安裝軟件:
./greenplum-db-4.1.1.1-build-1-RHEL5-x86_64.bin
-
屏幕上回出現License的一些信息,按“空格”鍵使信息完全,如下圖:
4
-
確認License之後,接着出現如下圖:
5
-
輸入“yes”之後會提示安裝目錄,選擇安裝在/opt/greenplum/greenplum-db-4.1.1.1下,如下圖
6
-
完成以上步驟後,軟件開始自動安裝,最好顯示安裝成功,安裝目錄如下圖:
7
-
gp的環境變量已經在greenplum_path.sh中設置了,這裏需要應用一下這個環境變量配置
source /opt/greenplum/greenplum-db/greenplum_path.sh
2. 配置 hostlist
配置hostlist文件,將所有的服務器名記錄在裏面
[gpadmin@dw-greenplum-l conf]$ cat hostlist
mdw
sdw1
sdw2
sdw3
seg_hosts 只保存Segment節點的hostname。
[gpadmin@dw-greenplum-l conf]$ cat seg_hosts
sdw1
sdw2
sdw3
3. 使用gpssh-exkeys打通所有服務器
使用gpssh-exkeys將所有機器的通道打開,這樣就不用輸入密碼使登錄在每臺機器之間跳轉了,代碼如下:
[gpadmin@dw-greenplum-l conf]$ grssh-exkeys -f hostlist
[STEP 1 of 5] create local ID and authorize on local host
[STEP 2 of 5] keyscan all hosts and update known_hosts file
[STEP 3 of authorize current user on remote hosts]
... send to sdwl
***
*** Enter password for sdwl;
... send to sdw2
... send to sdw3
[STEP 4 of 5] determine common authentication file content
[STEP 5 of 5] copy authentication files to all remote hosts
... finished key exchange with sdw1
... finished key exchange with sdw2
... finished key exchange with sdw3
[INFO] completed successfully
在打通所有機器通道後,我們就可以使用grssh命令對所有機器進行批量操作了
[gpadmin@dw-greenplum-l conf]$ grssh -f hostlist
=> pwd
[sdw3] /home/gradmin
[ mdw] /home/gradmin
[sdw1] /home/gpadmin
[sdw2] /home/gpadmin
4. 將軟件分發到每一臺機器上
接下來將安裝後的文件打包:
tar -cf gp4.1.tar greenplum-db-4.1.1.1/
然後利用gpscp命令將這個文件複製到每一臺機器上:
gpscp -f /home/gpadmin/conf/hostlist gp4.1.tar =:/opt.greenplum
使用gpssh命令批量解壓文件包:
=> cd /opt/greenplum
[sdw3]
[ mdw]
[sdw1]
[sdw2]
=> tar -xf gp4.1.tar
[sdw3]
[ mdw]
[sdw1]
[sdw2]
建立軟連接,如圖:
8
下面創建數據庫數據目錄
MASTER目錄:
=> mkdir -p /home/gpadmin/gpdata/gpmaster
Primary節點目錄:
=> mkdir -p /home/gpadmin/gpdata/gpdatap1
=> mkdir -p /home/gpadmin/gpdata/gpdatap2
Mirror節點目錄:
=> mkdir -p /home/gpadmin/gpdata/gpdatam1
=> mkdir -p /home/gpadmin/gpdata/gpdatam2
Gpmaster目錄保存Master的數據,每個機器上的gpdatap1、gpdatap2否下對應這個機器的兩個主數據節點目錄,同樣的,gpdatam1、gpdatam2對應備數據節點目錄
5. 配置 ~/.bash_profile
要對系統的環境變量進行配置,需要修改~./bash.profile,添加以下內容:
source /opt.greenplum/greenplum-db/greenplum_path.sh
export MASTER_DATA_DIRECTORY=/home/gpadmin/gpdata/gpmaster/gpseg-l
export PGPORT=2345
export PGDATABASE=testDB
其中greenplum_path.sh保存了運行gp的以下環境變量設置,包括GPHOME、PYTHONHOME等設置
6. 初始化greenplum的配置文件
配置文件的模板可以在$GPHOME/docs/cli_help/gpconfigs、目錄下找到。gpinitsystem_config文件是初始化greenplum的模板,在這個模板中,Mirror Segment的配置都被註釋掉了,下面是初始化的配置文件initgp_config:
# 數據庫的代號
ARRAY_NAME="Greenplum"
MACHINE_LIST_FILE=/home/gpadmin/conf/se_hosts
#Segment的名稱前綴
SEG_PREFIX=gpseg
#Primary Segment起始的端口號
PROT_BASE=33000
# 指定 Primary Segment的數據目錄
declare -a DATA_DIRECTORY=(/home/gpadmin/gpdatap1 /home/gpadmin/gpdata/gpdatap2)
#Master所在的機器的Hostname
MASTER_HOSTNAME=mdw
# 指定Master的數據目錄
MASTER_DIRECTORY=/home/gpadmin/gpdata/gpmaster
#Master的端口
MASTER_PORT=2345
# 指定 Bash 的版本
TRUSRED_SHELL=/usr/bin/ssh
# 字符集 ENCODING=UNICODE
#MIRROR_PORT_BASE=43000
#Primary Segment 主備同步的起始端口號
REPLICATION_PORT_BASE=34000
#Mirror Segment 主備同步的起始端口號
MIRROR_REPLICATION_PORT_BASE=44000
#Mirror Segment 的數據目錄
declare -a MIRROR_DATA_DIRECTORY=(/home/gpadmin/gpdata/gpdatam1 /home/gpadmin/gpdata/gpdatam2)
7.初始化數據庫
使用gpinitsystem腳本來初始化數據庫,命令如下:
gpinitsystem -c initgp_config -s sdw3
根據腳本出現的額提示操作即可,如下:
9
10
這樣數據庫就初始化成功了,嘗試登陸greenplum默認的數據庫postgres:
[gpadmin@dw-greenplum-l ~]$ psql -d postgres
psql (8.2.15)
Type "help" for help.
postgres=#
2.1.4 創建數據庫
創建測試數據庫
createdb testDB -E utf-8
沒有設置PGDATABASE這個環境變量時,使用psql進行登陸,默認的數據庫是與操作系統用戶名一致的,這時候會報錯:
[gpadmin@dw-greenplum-l ~]$ psql
psql: FATAL: databasse "gpadmin" does not exist
然後撤職(export)環境變量PGDATABASE=testDB,這樣就默認testDB數據庫:
[gpadmin@dw-greenplum-l ~]$ export PGDATABASE=testDB
[gpadmin@dw-greenplum-l ~]$ psql
psql (8,2,15)
Type "help" for help
testDB=#
查詢數據庫版本並創建一張表:
testDB=# select version();
testDB=# create table test01(id int primary key,name varchar(128));
2.1.5 數據庫啓動與關閉
1. 啓動數據庫
可以用gpstart-help來查看幫助:
[gpadmin@inc-dw-hadoop-151-7 ~]$ gpstart --help
11
12
啓動數據庫,不用輸入“yes”,輸入後如下圖:
gpstart -a
13
2.關閉數據庫
關閉數據庫的腳本是gpstop:
14
一般使用gpstop -a,不用輸入“yes”:
gpstop -s
15
2.2 安裝Greenplum的常見問題
安裝gp最常見的錯誤就是環境變量設置錯誤,網卡配置錯誤,或者是每個Segment的通道或網絡沒有打通
2.2.1 /etc/hosts 配置錯誤
查詢一張普通表時報如下錯誤,但是查詢數據字典又不報錯:
16
報這個錯誤時因爲Master連接不到Segment。如果原先是一個正常的系統,突然報錯了,就要想想是否修改了什麼導致的。
也可以利用這個方法來判斷一個操作是否需要與Master交互,比如生成執行計劃是否只在Master上執行,與Segment有沒有交互:
17
這樣就可以看出生成分佈式執行計劃也是需要與Segment進行交互的
2.2.2 MASTER_DATA_DIRECTORY設置錯誤
沒有設置MASTER_DATA_DIRECTORY,會報這樣的錯誤:
18
這樣會導致MASTER_DATA_DIRECTORY參數的目錄設置錯誤:
19
在初始化數據庫的時候要多注意環境變量的設置,如果環境變量設置不當,很容易造成數據庫初始化錯誤
2.3 暢遊Greenplum
2.3.1 如何訪問Greenplum
1.psql
psql是greenplum/PostgreSQL默認的客戶端。
20
可以在其他機器上使用psql連接到數據庫中:
21
之所以報錯,是因爲Greenplum有權限控制,並不是所有的機器都可以連接到數據庫上。
如果有其他計算機要登錄Greenplum,先爲數據庫用戶gpadmin創建一個密碼,然後再pg_hba.conf文件中增加客戶端機器的權限配置,這樣就可以成功登錄
testDB=# alter role gpadmin with password 'gpadmin';
ALTER ROLE
接着在$MASTER_DATA_DIRECTORY//pg_hba.conf文件中增加:
host testDB gpadmin 10.20.151.1/32 md5
之後通過gpstop -u命令使配置生效,如下圖:
22
這樣我們就可以在其他機器上登錄數據庫:
23
2.pgAdmin
下載地址:http://www.pgadmin.org/download/
2.3.2 數據庫整體概況
1. greenplum基於PostgreSQL開發
gp是基於開源數據庫軟件PostgreSQL 8.3 開發的,其大部分語法和數據字典都與PostgreSQL一樣,很多工具使用的規範也基本一樣
2.gp的數據分佈
可以說gp將PostgreSQL改造成一個分佈式數據庫。其中Segment節點都是一個單獨的PostgreSQL數據庫,Master本身也是一個PostgreSQL數據庫
Master本身不儲存數據,所有數據拆分保存到每一個節點上,在指定分佈鍵的時候,數據按照分佈鍵的Hash值來分佈數據,稱爲哈希分佈。
還以一種分佈不用指定分部件,數據隨機分佈到每一個節點,稱作隨機分佈(也叫平均分佈)
2.3.3 基本語法介紹
1. 獲取語法介紹
可以使用\h查看gp支持的所有語法
在psql中使用 \h command 可以獲取具體命令的語法:
testDB=# \h create view
Command: CREATE VIEW
Description: define a new view
Syntax:
CREATE [ OR REPLACE ] [TEMP | TEMPORARY ] VIEW name [ ( column_name [, ...] ) ] AS query
24
2.CREATE TABLE
gp建表語句與其他數據庫不同的地方:
- 在gp中建表時需要制定表的分佈鍵
- 如果表需要用某個字段分區,可以通過partition by將表建成分區表
- 可以使用like操作創建與like的表一樣結構的表,功能類似create table t1 as select * from t2 limit 0
- 可以使用inherits實現表的繼承,棘突參考postgreSQL文檔
25
26
由於gp是一個分佈式數據庫,數據是分佈在每一個節點上的。在gp中有兩種數據分佈策略:
- hash分佈。指定一個或多個分佈鍵,計算hash值,並且通過hash值路由到特定的Segment節點上,語法爲Distributed by(..)。如果不指定分佈鍵,默認將第一個字段作爲分佈鍵。
- 隨機分佈,也叫平均分佈。數據隨機分散在每一個 節點中,這樣無論數據是什麼內容,都可以平均分佈在每個節點上,但是在執行SQL的過程中,關聯等操作都需要將數據重分佈,性能較差。語法爲在表字段定義的後面加上Distributed randomly。
下面兩個建表語句的執行結果一樣,都是以id作爲分佈鍵:
27
在下面的建表語句中指定了多個分佈鍵:
28
在下面的建表語法中採用了隨機分佈:
29
採用隨機分佈策略的表默認將主鍵或唯一鍵作爲分佈鍵,因爲每一個Segment都是一個單一的數據庫,單個的數據庫可以保證唯一性,多個數據庫節點就無法保證全局的跨庫唯一性。故只能按照唯一鍵分佈,同一個值得數據都在一個節點上,以此來保證唯一性
30
如果指定的分佈鍵與主鍵不一樣,那麼分佈鍵會被更改爲主鍵:
31
在創建表的時候,如果要建一張表結構一模一樣的表,可以利用create table like 命令:
32
使用like創建的表,只是表結構會與原表一模一樣,表的一些特殊屬性並不會一樣,例如壓縮、只增(appendonly)等屬性。如果不指定分佈鍵,則默認分佈鍵與原表一樣
3.select
33
需要注意的是,gp的數據切分放在所有的Segment上。當從一個表查詢數據的時候,Master的數據展現順序是以Master先接收到的數據的順序,每個Segment的數據到達Master的順序是隨機的,不是固定的,所以執行SELECT的結果的順序是隨機的,即使表中數據一點變化都沒有。這一點跟其他數據庫是不一樣的
4. create table as 與select into
create table as 可以加入distributed指定分佈鍵,select into 只能使用默認的分佈鍵
34
35
5. explain
explain用於查詢一個表的執行計劃,它在SQL優化的時候經常要用到(詳細的執行計劃解釋參考第五章執行計劃詳解)
下面代碼演示了簡單的執行計劃的查看方法:
36
上面的執行計劃是一個層次關係,先從最右邊開始查看:
- 數據庫先順序掃描test2表,掃描大概有118單位的消耗,有1667行數據,平均長度爲15字節。其中,1667行數據是一個估計值,是一個Segment的數據量,如果數據分佈均勻,大概是總數據量除以Segment的個數。由於這個gp集羣有6個Segment節點,因此可以推斷test2表大概有1萬行數據
- 掃描出test2表,並且計算hash值,將其保存在內存中
- 順序掃描test1表
- 在掃描test1表的過程中,與test2表進行hash後的結果關聯(hash join),關聯的條件是兩表的id字段相同
- 將數據彙總到Master上。Master將數據結果進行彙總並展現
6.insert、update和delete
幾點數據切片帶來的問題
-
insert:在執行insert語句的時候,要留意分佈鍵不要爲空,否則分佈鍵默認會編程null,數據都被保存在一個節點上,造成數據分佈不均
insert可以批量操作,語法如下:
insert into test001 values(100,'tom'),(101,'lily'),(102,'jack); INSERT 0 3
-
update:不能批量對分佈鍵執行update,因爲對分佈鍵執行update需要將數據重分佈,而gp暫時不支持這個功能
37
-
delete:在gp 3.x的版本中,如果delete操作涉及子查詢,並且子查詢的結果還會涉及數據重分佈,這樣的刪除語句會報錯,如下(gp 4.x中支持該操作):
38
如果對整張表執行Delete會比較慢,建議使用TRUNCATE
7.TRUNCATE
執行TRUNCATE直接刪除表的物理文件,然後創建新的數據文件,TRUNCATE操作比delete在;x;ng上有非常大的提升,當前如果有sql正在操作這張表,那麼TRUNCATE操作會被鎖住,知道表上面的所有鎖被釋放
testDB=# truncate test001;
TRUNCATE TABLE
2.3.4 常用數據類型
1. 數值類型
39
2.字符類型
40
3.時間類型
41
2.3.5 常用函數
1.字符串函數
42
43
2.時間函數
44
45
3.數值計算函數
46
47
4.其他常用函數
(1)序列號生成函數:generate_series(start,end,step)
(2)字符串列轉行函數:string_agg
(3)字符串行轉列-regexp_split_to_table
(4)hash函數:md5,hashbpchar
2.3.6 分析函數
1.開窗函數
聚合函數返回各個分組的結果,開窗函數則爲每一行返回結果:
{ rank() | row_number() | sum(...) | count(...) | ...} over ( [ partition by ...] [ order by ... ] )
2.grouping sets
如果需要對幾個字段的組合進行group by,就需要用到Grouping Sets的功能:
48
49
2.3.7 分區表
在創建表時,關於partition的語法如下:
50
alter table 對分區表特有的一些操作的語法:
51
52
對分區表的一些常用操作:
(1)新增分區:
testDB=# alter table public. test_partirion_every add partition p20120105_6 START ('2012-01-05'::date) END ('2012-01-07'::date);
NOTICE: CREATE TABLE will create partition "test_partition_l_l_prt_p20120105_6" for table "test_partition_l"
ALTER TABLE
(2)drop/truncate 分區
alter table public. test_partition_every drop partition p20120105_6;
(3)拆分分區:
alter table public. test_partition_every split partition p20120105_6 at(('2012-01-06'::date)) into (PARTITION p20120105,PARTITION p20120106;)
(4)交換分區
alter table public. test_partition_every exchange partition p20120102 with table public.test_one_partition;
2.3.8 外部表
gp在數據加載上有一個明顯的優勢,就是支持數據併發加載,gpfdist就是併發加載的工具,在數據庫中對應的就是外部表
53
外部表,就是一張表的數據是指向數據庫之外的數據文件的。在gp中,我們可以對一個外部表執行正常的DML操作,當讀取數據時,數據庫就從數據文件中加載數據。外部表支持在Segment上併發地告訴從gpfdist導入數據,由於是直接從Segment上導入數據,所以效率非常高
創建外部表的語法:
54
55
外部表需要制定 gpfdist 的 IP 和端口,還要有詳細的目錄地址,其中文件名支持通配符匹配。可以編寫多個 gpfdist 的地址,但是不能超過總的 Segment 數,否則會報錯。在創建外部表的時候可以制定分隔符、 err 表、制定允許出錯的數據條數,以及原文件的字符編碼等信息。
外部表還支持本地文本文件的導入,不過效率較低,不建議使用。外部表還支持 HDFS 的文件操作
啓動 gpfdist 及創建外部表的實際步驟如下:
1)首先在文件服務器(假設是 10.20.151.11 )上啓動 gpfdist 的服務,指定文件目錄及端口。
nohup $GPHOME/bin/gpdfist -d /home/admin -p 8888 > /tmp/gpfdist.log 2>&1 &
啓動 gpfdist 後,在 log 中可以看到:
Serving HTTP on plrt 8888, directory /home/admin
說明程序已經成功啓動了,端口是8888,這個服務只需要啓動一次以後就不用啓動了 nohup 保證程序在 Server 端執行,當前會話關閉後,程序仍然正常運行
2)準備好需要加載的數據文件,將其放在 10.20.151.11 機器上 /home/admin/ 目錄或該目錄的子目錄下,在 gp 中創建對應的外部表:
56
3)外部表查詢及數據加載:
57
4)如果加載報錯,報錯的數據會被插入到err表中,並顯示報錯詳細信息:
58
2.3.9 COPY命令
使用COPY命令可以實現將文件導出和導入,只不過要通過Master,效率沒有外部表高,但是在數據量比較小的情況下,COPY命令比外部表要方便很多
使用COPY命令的語法如下:
59
60
gp 4.x 中引入了可寫外部表,在導出數據的時候可以用可寫外部表併發導出,性能很好,但是在 gp 3.x 版本中,導出數據只能通過 COPY 命令實現,數據在 Master 上彙總導出。
如果需要將數據遠程導出到其他機器上,可以使用 copy to stdout ,遠程執行 psql 連接到數據庫上,然後通過管道將數據重定向成文件。