mdrill是阿里媽媽-adhoc-海量數據多維自助即席查詢平臺下的一個子項目。旨在幫助用戶在幾秒到幾十秒的時間內,分析百億級別的任意維度組合的數據。mdrill是一個分佈式的在線分析查詢系統,基於hadoop,lucene,solr,jstorm等開源系統做爲實現,基於SQL的查詢語法。html
準備階段
軟件準備:java
- jdk1.6.0_45.tar.gz
- hadoop-0.20.2-cdh3u3.tar.gz
- alimama-adhoc.tar.gz
- jzmq-2.1.0-1.el6.x86_64.rpm
- zeromq-2.1.7-1.el6.x86_64.rpm
- zookeeper-3.4.5.tar.gz
服務器準備:
若是是線上服務器,建議配置以下:node
- 機器數量:10~12臺
- CPU:E5-2630(6核)*2
- 內存:>=48GB
- 硬盤規格數量:>=480GB*12 (SSD最佳,普通磁盤也可)。
本次安裝採用的是線下私有云- 服務器三臺(CentOS-6.6-x86_64)
- 內存 8G
基礎環境配置
升級系統
yum update
linux
安裝lrzsz
lrzsz是一個能夠搭配Xshell和SecureCRT能方便的在本地PC機和遠程服務器之間傳輸文件的小工具。yum install lrzsz -y
git
關閉IPV6
vi /etc/sysctl.conf
在文件的末尾追加:github
1
2
3
4
|
<span class="hljs-id">#disable</span> ipv6
net<span class="hljs-class">.ipv6</span><span class="hljs-class">.conf</span><span class="hljs-class">.all</span><span class="hljs-class">.disable_ipv6</span>=<span class="hljs-number">1</span>
net<span class="hljs-class">.ipv6</span><span class="hljs-class">.conf</span><span class="hljs-class">.default</span><span class="hljs-class">.disable_ipv6</span>=<span class="hljs-number">1</span>
net<span class="hljs-class">.ipv6</span><span class="hljs-class">.conf</span><span class="hljs-class">.lo</span><span class="hljs-class">.disable_ipv6</span>=<span class="hljs-number">1</span>
|
完成後刷新配置 :
sysctl -p
關閉防火牆
setenforce 0 #臨時禁用,不須要重啓
web
iptables -F #清空iptables
vi /etc/sysconfig/selinux #修改SELINUX=disabled
chkconfig iptables off && chkconfig ip6tables off #重啓後永久失效
修改及設置host
修改hosts文件:vi /etc/hosts
追加以下內容:(注意 這裏使用的是局域網IP,在私有云上部署時要特別留意)sql
1
2
3
|
192.168.113.90 mdrill01
192.168.113.88 mdrill02
192.168.113.101 mdrill03
|
修改每臺主機上的配置( 注意 hostname要與對應IP地址的主機對應)
vi /etc/sysconfig/network
設置以下內容:
1
|
<span class="hljs-attribute">HOSTNAME</span>=<span class="hljs-string">mdrill01</span>
|
爲了讓hostname快速生效,避免重啓,直接在命令行中設置
hostname mdrill01
設置時間同步
設置時區爲本地時間(每臺主機都須要執行)cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
選擇一臺主機爲始終同步服務器:這裏選擇的是mdrill01進行安裝yum install ntp -y
安裝完成後,修改配置文件:vi /etc/ntp.conf
將配置文件修改成:shell
1
2
3
4
|
<span class="hljs-title">restrict</span> default nomodify
restrict <span class="hljs-number">192.168.150.0</span> mask <span class="hljs-number">255.255.255.0</span> nomodify notrap
server <span class="hljs-number">127.127.1.0</span>
fudge <span class="hljs-number">127.127.1.0</span> stratum <span class="hljs-number">10</span>
|
啓動ntp:
service ntpd start
設置爲開機自啓
chkconfig ntpd on
同步服務器設置完畢,切換到mdrill02和mdrill03服務器,進行以下操做
yum install ntpdate -y
並設置爲每小時同步一次時間:
vim /etc/crontab
新增以下內容:
1
|
1 <span class="hljs-keyword">*</span> <span class="hljs-keyword">*</span> <span class="hljs-keyword">*</span> <span class="hljs-keyword">*</span> root ntpdate h1.hadoop && hwclock -w
|
新增帳號
服務器在使用時不建議使用root帳戶,在這裏咱們爲每臺主機添加mdrill帳戶groupadd mdrill
useradd -g mdrill mdrill
passwd mdrill
建立/data目錄,並賦予權限mkdir /data
chown -R mdrill:mdrill /data
apache
設置SSH免密碼登錄
每臺機器所有切換成mdrill用戶su mdrill
在天天機器上執行以下操做(一路回車便可)ssh-keygen -t rsa -P ''
mdrill01執行以下操做cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
scp ~/.ssh/authorized_keys mdrill@mdrill02:~/.ssh/authorized_keys
mdrill02執行以下操做cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
scp ~/.ssh/authorized_keys mdrill@mdrill03:~/.ssh/authorized_keys
mdrill02執行以下操做cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
scp ~/.ssh/authorized_keys mdrill@mdrill01:~/.ssh/authorized_keys
scp ~/.ssh/authorized_keys mdrill@mdrill02:~/.ssh/authorized_keys
完成後再登陸每條主機執行chmod 400 ~/.ssh/authorized_keys
至此,免帳號登錄就已經打通了
安裝階段
上傳準備好的文件
將準備好的文件所有上傳到/data目錄
- jdk1.6.0_45.tar.gz
- hadoop-0.20.2-cdh3u3.tar.gz
- alimama-adhoc.tar.gz
- jzmq-2.1.0-1.el6.x86_64.rpm
- zeromq-2.1.7-1.el6.x86_64.rpm
安裝相應的應用
- 安裝jzmq和zeromq
因爲是rpm包,因此須要轉換到root帳號安裝,cd \data
yum localinstall zeromq-2.1.7-1.el6.x86_64.rpm jzmq-2.1.0-1.el6.x86_64.rpm
rm /data/*.rpm
su mdrill
以上操做須要在3臺主機上分別執行
如下操做僅需在1臺主機上執行,等最後完成後同步到其餘兩臺機器便可 - 安裝jdk
直接解壓壓縮包tar zxvf jdk1.6.0_45.tar.gz
- 安裝hadoop
直接解壓壓縮包tar zxvf hadoop-0.20.2-cdh3u3.tar.gz
- 安裝zookeeper
直接解壓壓縮包tar zxvf zookeeper-3.4.5.tar.gz
- 安裝mdrill
直接解壓壓縮包tar zxvf alimama-adhoc.tar.gz
因爲mdrill默認的使用的是hadoop-0.20.2,因此須要作下調整cp /data/hadoop-0.20.2-cdh3u3/hadoop-core-0.20.2-cdh3u3.jar /data/alimama/adhoc-core/lib/
cp /data/hadoop-0.20.2-cdh3u3/lib/guava-r09-jarjar.jar /data/alimama/adhoc-core/lib/
rm /data/alimama/adhoc-core/lib/hadoop-core-0.20.2.jar
- 清理安裝包
rm /data/*.tar.gz
配置環境變量
編輯用戶配置文件vi ~/.bashrc
在文件中追加以下內容
1
2
3
4
5
6
7
8
9
10
11
12
|
JAVA_HOME=/data/jdk1.<span class="hljs-number">6.0</span>_45
<span class="hljs-built_in">export</span> JAVA_HOME
PATH=<span class="mathjax-replacement"><span class="hljs-variable">$PATH</span>:<span class="hljs-variable">$</span></span><span class="hljs-variable">JAVA_HOME</span>/bin
<span class="hljs-built_in">export</span> PATH
HADOOP_HOME=/data/hadoop-<span class="hljs-number">0.20</span>.<span class="hljs-number">2</span>-cdh3u3
PATH=<span class="mathjax-replacement"><span class="hljs-variable">$PATH</span>:<span class="hljs-variable">$</span></span><span class="hljs-variable">HADOOP_HOME</span>/bin
<span class="hljs-built_in">export</span> PATH
ZOOKEEPER_HOME=/data/zookeeper-<span class="hljs-number">3.4</span>.<span class="hljs-number">5</span>
PATH=<span class="mathjax-replacement"><span class="hljs-variable">$PATH</span>:<span class="hljs-variable">$</span></span><span class="hljs-variable">ZOOKEEPER_HOME</span>/bin
<span class="hljs-built_in">export</span> PATH
|
先將此文件拷貝到另外兩臺主機上
scp .bashrc mdrill@mdrill02:~/
scp .bashrc mdrill@mdrill03:~/
爲了讓環境變量生效,須要每臺主機上執行
source ~/.bashrc
修改配置文件
修改hadoop配置文件
cd /data/hadoop-0.20.2-cdh3u3/conf/
vi masters
1
|
mdrill01
|
vi slaves
1
2
|
<span class="hljs-title">mdrill02</span>
mdrill03
|
vi core-site.xml
1
2
3
4
5
6
7
8
9
10
11
12
|
<span class="hljs-pi"><?xml version="1.0"?></span>
<span class="hljs-pi"><?xml-stylesheet type="text/xsl" href="configuration.xsl"?></span>
<span class="hljs-tag"><<span class="hljs-title">configuration</span>></span>
<span class="hljs-tag"><<span class="hljs-title">property</span>></span>
<span class="hljs-tag"><<span class="hljs-title">name</span>></span>hadoop.tmp.dir<span class="hljs-tag"></<span class="hljs-title">name</span>></span>
<span class="hljs-tag"><<span class="hljs-title">value</span>></span>/data/tmp<span class="hljs-tag"></<span class="hljs-title">value</span>></span>
<span class="hljs-tag"></<span class="hljs-title">property</span>></span>
<span class="hljs-tag"><<span class="hljs-title">property</span>></span>
<span class="hljs-tag"><<span class="hljs-title">name</span>></span>fs.default.name<span class="hljs-tag"></<span class="hljs-title">name</span>></span>
<span class="hljs-tag"><<span class="hljs-title">value</span>></span>hdfs://mdrill01:9000<span class="hljs-tag"></<span class="hljs-title">value</span>></span>
<span class="hljs-tag"></<span class="hljs-title">property</span>></span>
<span class="hljs-tag"></<span class="hljs-title">configuration</span>></span>
|
vi hdfs-site.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<span class="hljs-pi"><?xml version="1.0"?></span>
<span class="hljs-pi"><?xml-stylesheet type="text/xsl" href="configuration.xsl"?></span>
<span class="hljs-tag"><<span class="hljs-title">configuration</span>></span>
<span class="hljs-tag"><<span class="hljs-title">property</span>></span>
<span class="hljs-tag"><<span class="hljs-title">name</span>></span>dfs.replication<span class="hljs-tag"></<span class="hljs-title">name</span>></span>
<span class="hljs-tag"><<span class="hljs-title">value</span>></span>1<span class="hljs-tag"></<span class="hljs-title">value</span>></span>
<span class="hljs-tag"></<span class="hljs-title">property</span>></span>
<span class="hljs-tag"><<span class="hljs-title">property</span>></span>
<span class="hljs-tag"><<span class="hljs-title">name</span>></span>dfs.name.dir<span class="hljs-tag"></<span class="hljs-title">name</span>></span>
<span class="hljs-tag"><<span class="hljs-title">value</span>></span>/data/dfs/name<span class="hljs-tag"></<span class="hljs-title">value</span>></span>
<span class="hljs-tag"></<span class="hljs-title">property</span>></span>
<span class="hljs-tag"><<span class="hljs-title">property</span>></span>
<span class="hljs-tag"><<span class="hljs-title">name</span>></span>dfs.data.dir<span class="hljs-tag"></<span class="hljs-title">name</span>></span>
<span class="hljs-tag"><<span class="hljs-title">value</span>></span>/data/dfs/data<span class="hljs-tag"></<span class="hljs-title">value</span>></span>
<span class="hljs-tag"></<span class="hljs-title">property</span>></span>
<span class="hljs-tag"></<span class="hljs-title">configuration</span>></span>
|
vi mapred-site.xml
1
2
3
4
5
6
7
8
|
<span class="hljs-pi"><?xml version="1.0"?></span>
<span class="hljs-pi"><?xml-stylesheet type="text/xsl" href="configuration.xsl"?></span>
<span class="hljs-tag"><<span class="hljs-title">configuration</span>></span>
<span class="hljs-tag"><<span class="hljs-title">property</span>></span>
<span class="hljs-tag"><<span class="hljs-title">name</span>></span>mapred.job.tracker<span class="hljs-tag"></<span class="hljs-title">name</span>></span>
<span class="hljs-tag"><<span class="hljs-title">value</span>></span>http://mdrill01:9001<span class="hljs-tag"></<span class="hljs-title">value</span>></span>
<span class="hljs-tag"></<span class="hljs-title">property</span>></span>
<span class="hljs-tag"></<span class="hljs-title">configuration</span>></span>
|
在完成上述配置後,須要建立相應的目錄
mkdir /data/tmp
mkdir -p /data/dfs/name
mkdir -p /data/dfs/data
修改zookeeper配置文件
vi /data/zookeeper-3.4.5/conf/zoo.cfg
更新以下內容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<span class="hljs-comment"># The number of milliseconds of each tick</span>
<span class="hljs-constant">tickTime</span>=2000
<span class="hljs-comment"># The number of ticks that the initial </span>
<span class="hljs-comment"># synchronization phase can take</span>
<span class="hljs-constant">initLimit</span>=10
<span class="hljs-comment"># The number of ticks that can pass between </span>
<span class="hljs-comment"># sending a request and getting an acknowledgement</span>
<span class="hljs-constant">syncLimit</span>=5
<span class="hljs-comment"># the directory where the snapshot is stored.</span>
<span class="hljs-comment"># do not use /tmp for storage, /tmp here is just </span>
<span class="hljs-comment"># example sakes.</span>
<span class="hljs-constant">dataDir</span>=/data/zookeeper-3.4.5/data
<span class="hljs-comment"># the port at which the clients will connect</span>
<span class="hljs-constant">clientPort</span>=2181
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Be sure to read the maintenance section of the </span>
<span class="hljs-comment"># administrator guide before turning on autopurge.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The number of snapshots to retain in dataDir</span>
<span class="hljs-comment">#autopurge.snapRetainCount=5</span>
<span class="hljs-comment"># Purge task interval in hours</span>
<span class="hljs-comment"># Set to "0" to disable auto purge feature</span>
<span class="hljs-comment">#autopurge.purgeInterval=1</span>
<span class="hljs-constant">maxClientCnxns</span>=300
<span class="hljs-constant">maxSessionTimeout</span>=20000
server.1=mdrill101:2888:3888
server.2=mdrill102:2888:3888
server.3=mdrill103:2888:3888
|
建立相應的目錄,並寫入zookeeperid
mkdir /data/zookeeper-3.4.5/data
vi /data/zookeeper-3.4.5/data/myid
寫入數字1便可
1
|
1
|
修改mdrill配置文件
vi /data/alimama/adhoc-core/conf/storm.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
####zookeeper配置####
storm.zookeeper.<span class="hljs-string">servers:</span>
- <span class="hljs-string">"mdrill01"</span>
- <span class="hljs-string">"mdrill02"</span>
- <span class="hljs-string">"mdrill03"</span>
storm.zookeeper.<span class="hljs-string">port:</span> <span class="hljs-number">2181</span>
storm.zookeeper.<span class="hljs-string">root:</span> <span class="hljs-string">"/higo2"</span>
####藍鯨配置####
storm.local.<span class="hljs-string">dir:</span> <span class="hljs-string">"/data/alimama/bluewhale/stormwork"</span>
nimbus.<span class="hljs-string">host:</span> <span class="hljs-string">"mdrill162"</span>
####hadoop配置####
hadoop.conf.<span class="hljs-string">dir:</span> <span class="hljs-string">"/data/hadoop-0.20.2-cdh3u3/conf"</span>
hadoop.java.<span class="hljs-string">opts:</span> <span class="hljs-string">"-Xmx1536m"</span>
####藍鯨各類心跳間隔配置####
nimbus.task.timeout.<span class="hljs-string">secs:</span> <span class="hljs-number">240</span>
task.heartbeat.frequency.<span class="hljs-string">secs:</span> <span class="hljs-number">12</span>
nimbus.supervisor.timeout.<span class="hljs-string">secs:</span> <span class="hljs-number">360</span>
supervisor.heartbeat.frequency.<span class="hljs-string">secs:</span> <span class="hljs-number">10</span>
nimbus.monitor.freq.<span class="hljs-string">secs:</span> <span class="hljs-number">20</span>
supervisor.worker.timeout.<span class="hljs-string">secs:</span> <span class="hljs-number">240</span>
supervisor.monitor.frequency.<span class="hljs-string">secs:</span> <span class="hljs-number">12</span>
worker.heartbeat.frequency.<span class="hljs-string">secs:</span> <span class="hljs-number">4</span>
storm.zookeeper.session.<span class="hljs-string">timeout:</span> <span class="hljs-number">60000</span>
storm.zookeeper.retry.<span class="hljs-string">interval:</span> <span class="hljs-number">6000</span>
storm.zookeeper.retry.<span class="hljs-string">times:</span> <span class="hljs-number">10</span>
####mdrill配置####
higo.workdir.<span class="hljs-string">list:</span> <span class="hljs-string">"/data/alimama/higoworkerdir"</span>
#----mdrill的表格列表在hdfs下的路徑-----
higo.table.<span class="hljs-string">path:</span> <span class="hljs-string">"/mdrill/tablelist"</span>
#----mdrill中啓動的solr使用的初始端口號-----
higo.solr.ports.<span class="hljs-string">begin:</span> <span class="hljs-number">51110</span>
#----mdrill分區方式,目前支持<span class="hljs-keyword">default</span>,day,month,single,<span class="hljs-keyword">default</span>是將一個月分紅<span class="hljs-number">3</span>個區,single意味着沒有分區-----
higo.partion.<span class="hljs-string">type:</span> <span class="hljs-string">"day"</span>
#----每臺機器啓動的worker進程端口列表----
supervisor.slots.<span class="hljs-string">ports:</span>
- <span class="hljs-number">6701</span>
- <span class="hljs-number">6702</span>
- <span class="hljs-number">6703</span>
- <span class="hljs-number">6704</span>
- <span class="hljs-number">6705</span>
- <span class="hljs-number">6706</span>
- <span class="hljs-number">6707</span>
- <span class="hljs-number">6708</span>
- <span class="hljs-number">6709</span>
- <span class="hljs-number">6710</span>
- <span class="hljs-number">6711</span>
- <span class="hljs-number">6712</span>
- <span class="hljs-number">6713</span>
- <span class="hljs-number">6714</span>
- <span class="hljs-number">6601</span>
#----建立索引生成的每一個shard的並行----
higo.index.<span class="hljs-string">parallel:</span> <span class="hljs-number">3</span>
#----啓動的shard的數,每一個shard爲一個solr實例,結合cpu個數和內存進行配置,<span class="hljs-number">10</span>臺<span class="hljs-number">48</span>G內存配置<span class="hljs-number">60</span>----
higo.shards.<span class="hljs-string">count:</span> <span class="hljs-number">30</span>
#----基於冗餘的ha,設置爲<span class="hljs-number">1</span>表示沒有冗餘,若是設置爲<span class="hljs-number">2</span>,則冗餘號位<span class="hljs-number">0</span>,<span class="hljs-number">1</span>----
higo.shards.<span class="hljs-string">replication:</span> <span class="hljs-number">1</span>
#----啓動的merger server的worker數量,建議根據機器數量設定----
higo.mergeServer.<span class="hljs-string">count:</span> <span class="hljs-number">5</span>
#----分配給merger server的端口,建議每臺機器分配一個merger server----
higo.merge.<span class="hljs-string">ports:</span> <span class="hljs-string">"6601,6602,6603,6604,6605"</span>
#----mdrill同時最多加載的分區個數,取決於內存與數據量----
higo.cache.<span class="hljs-string">partions:</span> <span class="hljs-number">10</span>
#----通用的worker的jvm參數配置----
worker.<span class="hljs-string">childopts:</span> <span class="hljs-string">"-Xms4g -Xmx4g -Xmn2g -XX:SurvivorRatio=3 -XX:PermSize=96m -XX:MaxPermSize=256m -XX:+UseParallelGC -XX:ParallelGCThreads=16 -XX:+UseAdaptiveSizePolicy -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:%storm.home%/logs/gc-%port%.log "</span>
|
線上服務器配置建議:每臺機器上配置6個shard,1個merger server,均分配5GB的內存
建立配置文件中涉及到的目錄mkdir -p /data/alimama/bluewhale/stormwork
mkdir -p /data/alimama/higoworkerdir
同步全部內容到各臺主機
scp -r /data mdrill@mdrill02:/
scp -r /data mdrill@mdrill02:/
因爲是同步過去,因此 zookeeper的myid須要在另外兩臺主機上設置
在mdrill02主機上vi /data/zookeeper-3.4.5/data/myid
1
|
2
|
再mdrill03主機上
vi /data/zookeeper-3.4.5/data/myid
1
|
3
|
啓動服務器
啓動Hadoop
在啓動hadoop前須要先對namenode進行格式化hadoop namenode -format
因爲設置了環境變量,啓動起來很是簡單start-all.sh
只要在主節點執行上訴內容,其餘兩臺機器相關的進程會一併啓動
如需中止,可運行以下命令stop-all.sh
相關端口:
- jobtracker:50030
- tasktracker:50060
啓動zookeeper
在天天主機上執行以下命令便可zkServer.sh start
如需中止zkServer.sh stop
如需查看狀態zkServer.sh status
啓動mdrill
cd /data/alimama/adhoc-core/bin/
chmod 777 ./bluewhale
nimbus是整個mdrill集羣任務的總調度,有點相似hadoop的jobtracker
只須要在其中一臺機器啓動便可,啓動命令以下nohup ./bluewhale nimbus > nimbus.log &
supervisor用來管理其所在機器的work進程,其角色有點相似hadoop的tasktracker
須要在每臺機器上啓動,nohup ./bluewhale supervisor > supervisor.log &
視狀況看是否須要啓動mdrilluimkdir ./ui
nohup ./bluewhale mdrillui 1107 ../lib/adhoc-web-0.18-beta.war ./ui >ui.log &
啓動後,能夠經過瀏覽器打開對應ip的1107端口,看是否能正常打開便可。
測試mdrill
建表
將建表SQL存儲爲create.sql到「/data/alimama/adhoc-core/bin/」目錄下,
1
2
3
4
5
6
|
<span class="hljs-operator"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> st(
thedate <span class="hljs-keyword">string</span>,
c1 <span class="hljs-keyword">string</span>,
c2 tdouble,
cnt tlong
)</span>
|
執行以下命令
cd /data/alimama/adhoc-core/bin/
./bluewhale mdrill create ./create.sql
列的數據類型目前只支持4種
- string :字符串類型
- tlong :long整形
- tdouble :浮點型
- tdate :日期類型
- text:字符串類型(進行了分詞,意味着只能進行全文檢索,而不能參與統計與分組)
另外若是數據類型用_mdrill_進行了分割,後面的值表示是否存儲,在全文檢索模式中特別有用,全文檢索模式要把要進行展現的列配置成存儲(速度能提高不少)
舉例以下
下面這幾個爲只索引而不存儲數據的值
1
2
3
4
5
|
string_mdrill_<span class="hljs-literal">false</span>
tlong_mdrill_<span class="hljs-literal">false</span>
tdouble_mdrill_<span class="hljs-literal">false</span>
tdate_mdrill_<span class="hljs-literal">false</span>
text_mdrill_<span class="hljs-literal">false</span>
|
下面這幾個爲只既索引也存儲數據的值
1
2
3
4
5
|
string_mdrill_<span class="hljs-literal">true</span>
tlong_mdrill_<span class="hljs-literal">true</span>
tdouble_mdrill_<span class="hljs-literal">true</span>
tdate_mdrill_<span class="hljs-literal">true</span>
text_mdrill_<span class="hljs-literal">true</span>
|
另外若是要跳過某些列,能夠將數據類型配置成ignored,表示這個列既不存儲也不索引。
注意
- 建表語句要與數據存儲順序一致
- thedate:是分區的字段,必須存在,格式爲yyyyMMdd格式的字符串,且要與對應的分區目錄要對應
其餘信息
若是須要常常的進行全文檢索,那麼能夠配置成存儲明細,使用額外的存儲,換取全文檢索的時間./bluewhale mdrill create ./create.sql true
導入離線數據
數據目錄
首先要肯定數據表在hdfs上的根目錄,好比說/mdrill/tablelist。目錄在/data/alimama/adhoc-core/conf/storm.yaml的mdrill配置文件配置。
在該目錄下能夠有一個至多個數據表,每一個數據表目錄下會有三個子目錄。
- solr:表的配置目錄
- index:mdrill的索引在hdfs中的存儲路徑
- tmp:臨時目錄
數據格式
- mdrill默認處理的是sequencefile格式的數據,對key沒有要求,value則爲對應數據表中一條記錄,記錄的列與列之間的分隔符爲默認\001,若是使用文本格式的,或者分隔符不是\001,建立索引邏輯時要注意傳遞的參數。
- mdrill要求數據按照天進行分目錄,目錄命名必須爲dt=yyyyMMdd這種格式
- 數據的列中必須含有一列叫thedate,其值與其所在的目錄dt=yyyyMMdd中的yyyyMMdd相等,thedate實際上爲mdrill的分區字段,任何的查詢都必須指定thedate分區。若是數據列中的thedate與目錄中的dt=yyyyMMdd不相等,那麼mdrill以目錄的時間爲準確時間。
- mdrill默認必須按照日期分區,使用分區後總存儲的數據量會顯著提高,天天建立的索引也是增量的,若是確實由於某種緣由沒法按照日期分區,能夠將分區類型設置爲single,可是總的數據存儲量會減小不少。
生存索引
指令規則:./bluewhale mdrill index {表名}{hdfs源數據地址} 3650 {起始日期} {數據格式seq|txt,不寫默認seq} {分隔符,不寫默認\001} {分區下的文件匹配規則默認匹配*0* }
指令示例:./bluewhale mdrill index st /mdrill/tablelist/st 3650 20140101 txt
./bluewhale mdrill index st /mdrill/tablelist/st 3650 20140101 txt tab "\\*\\*" 3 1
啓動表
啓動表指令./bluewhale mdrill table {表1,表2,表3}
示例:./bluewhale mdrill table st
中止表指令./bluewhale mdrill drop {表1,表2,表3}
示例:./bluewhale mdrill drop st
注意
啓動表的操做只能執行一次,若是想添加新的表必須先中止表後再啓動表。
重啓服務
若是是由於mdrill自己的bug,須要重啓mdrill,則能夠這樣作
- 先中止表
- 在每臺機器上殺死全部的mdrill任務
ps -x|grep bluewhale|grep server|awk '{printf("%s\n",$1)}'|xargs kill
- 清理mdrill的臨時目錄
rm /data/alimama/bluewhale/stormwork/* -rf
- 從新按照原先的步驟 啓動mdrill
- 啓動表
配置實時數據源(若是使用離線模式,請跳過此步)
編輯storm.yaml配置文件,假設要配置爲實時的表的名字爲p4p_v2
- 配置editlog記錄的位置,能夠選擇爲local或hdfs
hdfs模式沒有通過嚴格的測試,若是hadoop集羣不是常常的停機維護或者出問題,那麼能夠考慮使用hdfs模式,這樣由於機器宕機或者硬盤損壞致使的數據丟失損失會減小到最小
local模式表示editlog會記錄到本地的硬盤上,若是這臺機器硬件損壞或者宕機,那麼那些尚未同步到hdfs中的索引數據會丟失(默認同步間隔爲4小時,配置目前爲硬編碼,請參考com.alimama.mdrill.utils.UniqConfig裏面的設置)higo.realtime.binlog: "local"
- 須要先將表配置爲實時模式,配置方法以下
higo.mode.p4p_pv2: "@realtime@"
- 配置表的分區:能夠爲day,month,default
higo.partion.type.p4p_pv2: "day"
- 配置日誌解析類
解析類須要實現com.alimama.mdrillImport.DataParser接口,示例程序以下p4p_pv2-parse: "com.alimama.quanjingmonitor.mdrillImport.parse.p4p_pv2"
- 配置reader
reader用於實時的讀取數據,而後交給解析類解析後導入到mdrill裏
reader在阿里可使用tt4(默認已經實現),阿里外部能夠考慮使用metaq或者kafka
須要實現的接口爲com.alimama.mdrillImport.ImportReader.RawDataReader
TT4實現的示例爲com.alimama.quanjingmonitor.mdrillImport.reader.TT4Reader
- 配置導入模式爲local與merger
數據導入到mdrill前,若是數據能夠進行簡單的合併,那麼會大量的減小導入到mdrill裏的數據量,合併的方式很簡單就是按照解析類的getGroup方法進行分組,getSum裏的值進行累加而已,若是咱們的數據很難進行合併,則建議使用local模式以減小不必的傳輸,若是合併比率很高,那麼建議使用mergerp4p_pv2-mode: "local"
- 配置各類緩存參數
p4p_pv2-commitbatch: 5000 //單次向mdrill遞交的記錄數
p4p_pv2-commitbuffer: 10000//commit階段的buffer長度
p4p_pv2-spoutbuffer: 10000//spout階段的buffer長度
p4p_pv2-boltbuffer: 10000 //bolt階段的buffer長度
- 配置緩存的刷新時間:與解析類的getTs()方法組合使用
p4p_pv2-timeoutSpout: 240 //配置在spout的最大緩存時間
p4p_pv2-timeoutBolt: 60 //配置在bolt裏的最大緩存時間
p4p_pv2-timeoutCommit: 30 //配置在commit階段的最大緩存時間
導入實時數據
導入指令./bluewhale jar ./mdrill.jar com.alimama.mdrillImport.Topology {自定義任務名稱} {導入的表列表多個表之間用逗號分隔} {使用的進程總數} {每一個進程使用多少mb的內存} {從什麼時間開始導入}
示例以下./bluewhale jar ./mdrill.jar com.alimama.quanjingmonitor.mdrillImport.Topology p4p_pv2topology p4p_pv2 66 512 20131231074710
若是想中止導入數據的程序./bluewhale kill {自定義的任務名稱}
示例以下./bluewhale kill p4p_pv2topology
測試mdrill查詢
mdrill的分區
mdrill的設計默認是使用分區的,也是按照分區進行存儲的,除非強制使用single類型的分區外,查詢的時候必須指定分區。目前mdrill的分區字段爲thedate,格式爲yyyyMMdd
在頂層SQL的where條件中必須有以下三種分區設定的一種
- thedate=’yyyyMMdd’ 直接指定某一個分區
- thedate in (yyyyMMdd, yyyyMMdd, yyyyMMdd) 給出一系列日期
- thedate >= yyyyMMdd and thedate<= thedate 給出一個範圍
查詢明細
- mdrill能夠查詢top 10000 條數據的明細,使用limit關鍵詞
- 對於明細的數據,能夠進行排序,也就是order by
統計彙總
mdrill目前支持sum,max,min,count,dist五種彙總函數
- dist就是sql中的count(distinct(xxx)),可是採用的是近似計算,會有必定的偏差具體實現原理,請參考https://github.com/muyannian/higo/wiki/distinct
- count有兩種使用方法
- count(列名),針對具體某一列進行count統計,固然若是該列值若是存在NULL值,不會做爲count計數。
- count(*),即便存在NULL的列,也會列入計數。
分類彙總
mdrill目前支持多維分類彙總統計,也就是sql中的group by。另外分類彙總後,mdrill能夠按照某一列的值進行排序,若是分類彙總後的組數小於10000組爲準確排序,若是超過10000組則爲近似的排序和計算,有可能存在排序的順序和計算的結果不正確的狀況。
mdrill的過濾
目前mdrill的過濾支持以下幾種
- =:等於
- <>:不等於
- >=:大於等於
- <=:小於等於
- >:大於
- <:小於
- in:屬於列表
- not in:屬於列表
- like:模糊匹配
mdrill FAQ
數據在內存中是如何存儲的
- mdrill是先進行分shard的,每一個shard分佈在不一樣的機器的不一樣的進程中
- 每一個shard是按照時間進行分區的,每一個分區是一個索引
- 每一個索引是按照列進行存儲的,每次緩存的時候加載一個列的值到內存中,多個分區,多個表,多個列之間LRU方式淘汰
- 加載到內存中的列,並不是是原始值,而是一個值的整形的代號,比方說用一個數字899代替一個很長的字符串
對內存結構的解釋
- 將lucene默認的將整個列數據所有都load到內存中的方式修改成load 每一個列的值的編碼代號,操做的時候也僅僅操做這些代號,真正展示的時候再將這些編號轉換成真實的值,編號的數據類型根據某個列的值的重複程度能夠爲byte,short,int
- 將數據進行分區(默認按照時間),用到的數據會加載到分區中,不用的分區會從內存中踢出,採用LRU的方式管理,若是同時須要檢索大量的分區,則進行排隊處理,一個分區一個分區的處理。
- 多個表之間也合併,共享內存,用到的表纔會加載到內存中,沒用到的則在硬盤中存儲。
- 原先merger server與shard是在同一個進程中的,每次查詢的時候隨機使用其中一個shard做爲merger server,若是每次查詢merger server使用1G的內存,但shard的數量很是多,merger server每次只用一個,可是爲每一個shard都額外分配1G內存就是浪費,新版mdrill將這二者分開,避免浪費。
- 按照內存大小進行LRU,而不是按照field的個數,不一樣列由於重複讀不一樣對內存的消耗也不同,按照個數LRU不合理,按照總內存使用LRU
- 因爲每次逆旋都須要消耗時間,當LRU被淘汰的時候,將逆旋的結果保留到硬盤中,以備下次使用。
worker.childopts與 higo.merge.ports有什麼區別
merger server只管理合並數據,shard纔是資源使用大戶,通常一臺機器啓動一個merger server就夠了 ,不必啓動那麼多。
- worker.childopts用來標記 這臺機器能夠啓動那些端口
- higo.merge.ports用來標記 這些端口中哪些是merger server的端口
higo.shards.count+higo.mergeServer.count = 啓動的總的進程數
- higo.shards.count:表示啓動的shard數量,一個shard就是一個存儲索引的solr
- higo.mergeServer.count:表示啓動的merger server的數量,一個merger server也是一個solr,可是他沒有索引,僅僅用於合併shard的數據據