Mdrill集群安装

mdrill是阿里妈妈-adhoc-海量数据多维自助即席查询平台下的一个子项目。旨在帮助用户在几秒到几十秒的时间内,分析百亿级别的任意维度组合的数据。mdrill是一个分布式的在线分析查询系统,基于hadoop,lucene,solr,jstorm等开源系统作为实现,基于SQL的查询语法。

准备阶段

软件准备:

  • 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

服务器准备:
如果是线上服务器,建议配置如下:

  • 机器数量:10~12台
  • CPU:E5-2630(6核)*2
  • 内存:>=48GB
  • 硬盘规格数量:>=480GB*12 (SSD最佳,普通磁盘也可)。
    本次安装采用的是线下私有云
    • 服务器三台(CentOS-6.6-x86_64)
    • 内存 8G

基础环境配置

升级系统

yum update

安装lrzsz

lrzsz是一个可以搭配Xshell和SecureCRT能方便的在本地PC机和远程服务器之间传输文件的小工具。
yum install lrzsz -y

关闭IPV6

vi /etc/sysctl.conf
在文件的末尾追加:

 
 
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 #临时禁用,不需要重启
iptables -F #清空iptables
vi /etc/sysconfig/selinux #修改SELINUX=disabled
chkconfig iptables off && chkconfig ip6tables off #重启后永久失效

修改及设置host

修改hosts文件:
vi /etc/hosts
追加如下内容:(注意 这里使用的是局域网IP,在私有云上部署时要特别留意)

 
 
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
将配置文件修改为:

 
 
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 &amp;&amp; hwclock -w

新增账号

服务器在使用时不建议使用root账户,在这里我们为每台主机添加mdrill账户
groupadd mdrill
useradd -g mdrill mdrill
passwd mdrill
创建/data目录,并赋予权限
mkdir /data
chown -R mdrill:mdrill /data

设置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

安装相应的应用

  1. 安装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台主机上执行,等最后完成后同步到其他两台机器即可
  2. 安装jdk
    直接解压压缩包
    tar zxvf jdk1.6.0_45.tar.gz
  3. 安装hadoop
    直接解压压缩包
    tar zxvf hadoop-0.20.2-cdh3u3.tar.gz
  4. 安装zookeeper
    直接解压压缩包
    tar zxvf zookeeper-3.4.5.tar.gz
  5. 安装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
  6. 清理安装包
    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">&lt;?xml version="1.0"?&gt;</span>
<span class="hljs-pi">&lt;?xml-stylesheet type="text/xsl"   href="configuration.xsl"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-title">configuration</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">property</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">name</span>&gt;</span>hadoop.tmp.dir<span class="hljs-tag">&lt;/<span class="hljs-title">name</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">value</span>&gt;</span>/data/tmp<span class="hljs-tag">&lt;/<span class="hljs-title">value</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">property</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">name</span>&gt;</span>fs.default.name<span class="hljs-tag">&lt;/<span class="hljs-title">name</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">value</span>&gt;</span>hdfs://mdrill01:9000<span class="hljs-tag">&lt;/<span class="hljs-title">value</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-title">configuration</span>&gt;</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">&lt;?xml version="1.0"?&gt;</span>
<span class="hljs-pi">&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-title">configuration</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">property</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">name</span>&gt;</span>dfs.replication<span class="hljs-tag">&lt;/<span class="hljs-title">name</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">value</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-title">value</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">property</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">name</span>&gt;</span>dfs.name.dir<span class="hljs-tag">&lt;/<span class="hljs-title">name</span>&gt;</span>  
        <span class="hljs-tag">&lt;<span class="hljs-title">value</span>&gt;</span>/data/dfs/name<span class="hljs-tag">&lt;/<span class="hljs-title">value</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">property</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">name</span>&gt;</span>dfs.data.dir<span class="hljs-tag">&lt;/<span class="hljs-title">name</span>&gt;</span>  
        <span class="hljs-tag">&lt;<span class="hljs-title">value</span>&gt;</span>/data/dfs/data<span class="hljs-tag">&lt;/<span class="hljs-title">value</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-title">configuration</span>&gt;</span>

vi mapred-site.xml

 
 
1
2
3
4
5
6
7
8
<span class="hljs-pi">&lt;?xml version="1.0"?&gt;</span>
<span class="hljs-pi">&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-title">configuration</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">property</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">name</span>&gt;</span>mapred.job.tracker<span class="hljs-tag">&lt;/<span class="hljs-title">name</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">value</span>&gt;</span>http://mdrill01:9001<span class="hljs-tag">&lt;/<span class="hljs-title">value</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-title">configuration</span>&gt;</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 &

视情况看是否需要启动mdrillui
mkdir ./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,则可以这样做

  1. 先停止表
  2. 在每台机器上杀死所有的mdrill任务
    ps -x|grep bluewhale|grep server|awk '{printf("%s\n",$1)}'|xargs kill
  3. 清理mdrill的临时目录
    rm /data/alimama/bluewhale/stormwork/* -rf
  4. 重新按照原先的步骤 启动mdrill
  5. 启动表

配置实时数据源(如果使用离线模式,请跳过此步)

编辑storm.yaml配置文件,假设要配置为实时的表的名字为p4p_v2

  1. 配置editlog记录的位置,可以选择为local或hdfs
    hdfs模式没有经过严格的测试,如果hadoop集群不是经常的停机维护或者出问题,那么可以考虑使用hdfs模式,这样因为机器宕机或者硬盘损坏导致的数据丢失损失会减少到最小
    local模式表示editlog会记录到本地的硬盘上,如果这台机器硬件损坏或者宕机,那么那些还没有同步到hdfs中的索引数据会丢失(默认同步间隔为4小时,配置目前为硬编码,请参考com.alimama.mdrill.utils.UniqConfig里面的设置)
    higo.realtime.binlog: "local"
  2. 需要先将表配置为实时模式,配置方法如下
    higo.mode.p4p_pv2: "@realtime@"
  3. 配置表的分区:可以为day,month,default
    higo.partion.type.p4p_pv2: "day"
  4. 配置日志解析类
    解析类需要实现com.alimama.mdrillImport.DataParser接口,示例程序如下
    p4p_pv2-parse: "com.alimama.quanjingmonitor.mdrillImport.parse.p4p_pv2"
  5. 配置reader
    reader用于实时的读取数据,然后交给解析类解析后导入到mdrill里
    reader在阿里可以使用tt4(默认已经实现),阿里外部可以考虑使用metaq或者kafka
    需要实现的接口为
    com.alimama.mdrillImport.ImportReader.RawDataReader
    TT4实现的示例为
    com.alimama.quanjingmonitor.mdrillImport.reader.TT4Reader
  6. 配置导入模式为local与merger
    数据导入到mdrill前,如果数据可以进行简单的合并,那么会大量的减少导入到mdrill里的数据量,合并的方式很简单就是按照解析类的getGroup方法进行分组,getSum里的值进行累加而已,如果我们的数据很难进行合并,则建议使用local模式以减少没必要的传输,如果合并比率很高,那么建议使用merger
    p4p_pv2-mode: "local"
  7. 配置各种缓存参数
    p4p_pv2-commitbatch: 5000 //单次向mdrill递交的记录数
    p4p_pv2-commitbuffer: 10000//commit阶段的buffer长度
    p4p_pv2-spoutbuffer: 10000//spout阶段的buffer长度
    p4p_pv2-boltbuffer: 10000 //bolt阶段的buffer长度
  8. 配置缓存的刷新时间:与解析类的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

数据在内存中是如何存储的

  1. mdrill是先进行分shard的,每个shard分布在不同的机器的不同的进程中
  2. 每个shard是按照时间进行分区的,每个分区是一个索引
  3. 每个索引是按照列进行存储的,每次缓存的时候加载一个列的值到内存中,多个分区,多个表,多个列之间LRU方式淘汰
  4. 加载到内存中的列,并非是原始值,而是一个值的整形的代号,比方说用一个数字899代替一个很长的字符串

对内存结构的解释

  1. 将lucene默认的将整个列数据全部都load到内存中的方式修改为load 每个列的值的编码代号,操作的时候也仅仅操作这些代号,真正展现的时候再将这些编号转换成真实的值,编号的数据类型根据某个列的值的重复程度可以为byte,short,int
  2. 将数据进行分区(默认按照时间),用到的数据会加载到分区中,不用的分区会从内存中踢出,采用LRU的方式管理,如果同时需要检索大量的分区,则进行排队处理,一个分区一个分区的处理。
  3. 多个表之间也合并,共享内存,用到的表才会加载到内存中,没用到的则在硬盘中存储。
  4. 原先merger server与shard是在同一个进程中的,每次查询的时候随机使用其中一个shard作为merger server,如果每次查询merger server使用1G的内存,但shard的数量非常多,merger server每次只用一个,但是为每个shard都额外分配1G内存就是浪费,新版mdrill将这两者分开,避免浪费。
  5. 按照内存大小进行LRU,而不是按照field的个数,不同列因为重复读不同对内存的消耗也不一样,按照个数LRU不合理,按照总内存使用LRU
  6. 由于每次逆旋都需要消耗时间,当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的数据据

Mdrill集群安装的更多相关文章

  1. 【Oracle 集群】Oracle 11G RAC教程之集群安装(七)

    Oracle 11G RAC集群安装(七) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总. ...

  2. kafka集群安装部署

    kafka集群安装 使用的版本 系统:centos6.5 centos6.7 jdk:1.7.0_79 zookeeper:3.4.9 kafka:2.10-0.10.1.0 一.环境准备[只列,不具 ...

  3. CentOS下Hadoop-2.2.0集群安装配置

    对于一个刚开始学习Spark的人来说,当然首先需要把环境搭建好,再跑几个例子,目前比较流行的部署是Spark On Yarn,作为新手,我觉得有必要走一遍Hadoop的集群安装配置,而不仅仅停留在本地 ...

  4. Hadoop多节点集群安装配置

    目录: 1.集群部署介绍 1.1 Hadoop简介 1.2 环境说明 1.3 环境配置 1.4 所需软件 2.SSH无密码验证配置 2.1 SSH基本原理和用法 2.2 配置Master无密码登录所有 ...

  5. codis集群安装

    在网上找了很多codis的集群安装方法,看起来都是大同小异,本人结合了大多种方法完成了一套自己使用的codis的集群安装,可以供大家学习使用,如果有什么问题或者不懂的地方欢迎指正 1.集群规划: 三台 ...

  6. [bigdata] spark集群安装及测试

    在spark安装之前,应该已经安装了hadoop原生版或者cdh,因为spark基本要基于hdfs来进行计算. 1. 下载 spark:  http://mirrors.cnnic.cn/apache ...

  7. (原) 1.2 Zookeeper伪集群安装

    本文为原创文章,转载请注明出处,谢谢 Zookeeper伪集群安装 zookeeper单机安装配置可以查看 1.1 zookeeper单机安装 1.复制三份zookeeper,分别为zookeeper ...

  8. 一步步教你Hadoop多节点集群安装配置

    1.集群部署介绍 1.1 Hadoop简介 Hadoop是Apache软件基金会旗下的一个开源分布式计算平台.以Hadoop分布式文件系统HDFS(Hadoop Distributed Filesys ...

  9. kafka 集群安装与安装测试

    一.集群安装 1. Kafka下载:wget https://archive.apache.org/dist/kafka/0.8.1/kafka_2.9.2-0.8.1.tgz 解压 tar zxvf ...

随机推荐

  1. 一个基于 easyui, vue 和 maptalks 的简单地图应用

    一个基于 easyui, vue 和 maptalks 的简单地图应用 做了一个小应用,结合 easyui , vue 和 maptalks 的简单的地图应用.可以用来画图,什么的. 地址

  2. 【解决】Git failed with a fatal error. Authentication failed for ‘http://......’

    今天在visual studio中运行项目,打算pull最新的代码的时候,报错: Git failed with a fatal error. Authentication failed for ‘h ...

  3. 面向对象(OOP)三

    一.面向对象基础原则 1)单一职责原则(类要写得小而精,低耦合) 内部类 单列模式 对于单一职责原则,其核心思想为:一个类,最好只做一件事,只有一个引起它的变化.单一职责原则可以看做是低耦合.高内聚在 ...

  4. 使用JAVA读写Properties属性文件

     使用JAVA读写Properties属性文件 Properties属性文件在JAVA应用程序中是经常可以看得见的,也是特别重要的一类文件.它用来配置应用程序的一些信息,不过这些信息一般都是比较少的数 ...

  5. es6-async

    含义 ES2017 标准引入了 async 函数,使得异步操作变得更加方便. async 函数是什么?一句话,它就是 Generator 函数的语法糖. 前文有一个 Generator 函数,依次读取 ...

  6. v-if与v-show的区别

    一.区别 v-if 动态的向DOM树内添加或者删除DOM元素:“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建:在初始渲染条件为假时,什么也不做. v-sho ...

  7. jQuery_2_常规选择器-高级选择器2

    属性选择器 <a title="num1">num1</a> <a title="num-ad">num2</a> ...

  8. Visual Studio 2015简体中文版

    Visual Studio  2015简体中文版(企业版) http://download.microsoft.com/download/B/8/F/B8F1470D-2396-4E7A-83F5-A ...

  9. HTML5新特性 video '&#x25BA'

    var play = document.createElement('button') play.setAttribute('title','play') play.innerHTML = '►' 创 ...

  10. UVA 215 Spreadsheet Calculator (模拟)

    模拟题.每个单元格有表达式就dfs,如果有环那么就不能解析,可能会重复访问到不能解析的单元格,丢set里或者数组判下重复. 这种题首先框架要对,变量名不要取的太乱,细节比较多,知道的库函数越多越容易写 ...