1. 背景

以Docker和Rocket为代表的容器技术现在正变得越来越流行,它改变着公司和用户创建、发布、运行分布式应用的方式,在未来5年将给云计算行业带来它应有的价值。它的诱人之处在于:

1)资源独立、隔离

资源隔离是云计算平台的最基本需求。Docker通过Linux namespace, cgroup限制了硬件资源与软件运行环境,与宿主机上的其他应用实现了隔离,做到了互不影响。不同应用或服务以“集装箱”(container)为单位装“船”或卸“船”,“集装箱船”(运行container的宿主机或集群 )上,数千数万个“集装箱”排列整齐,不同公司、不同种类的“货物”(运行应用所需的程序、组件、运行环境、依赖)保持独立。

2)环境的一致性

开发工程师完成应用开发后build一个docker image,基于这个image创建的container像是一个集装箱,里面打包了各种“散件货物”(运行应用所需的程序、组件、运行环境、依赖)。无论这个集装箱在哪里:开发环境、测试环境、生产环境,都可以确保集装箱里面的“货物”种类与个数完全相同,软件包不会在测试环境缺失,环境变量不会在生产环境忘记配置,开发环境与生产环境不会因为安装了不同版本的依赖导致应用运行异常。这样的一致性得益于“发货”(build docker image)时已经密封到“集装箱”中,而每一个环节都是在运输这个完整的、不需要拆分合并的“集装箱”。

3)轻量化

相比传统的虚拟化技术(VM),使用docker在cpu, memory, disk IO, network IO上的性能损耗都有同样水平甚至更优的表现。Container的快速创建、启动、销毁受到很多赞誉。

4)Build Once, Run Everywhere

这个特性着实吸引了很多人,“货物”(应用)在“汽车”、“火车”、“轮船”(私有云、公有云等服务)之间迁移交换时,只需要迁移符合标准规格和装卸方式的“集装箱”(docker container),削减了耗时费力的人工“装卸”(上线、下线应用),带来的是巨大的时间人力成本节约。这使未来仅有少数几个运维人员运维超大规模装载线上应用的容器集群成为可能,如同60年代后少数几个机器操作员即可在几小时内连装带卸完一艘万级集装箱船。

容器技术现在也被广泛应用于数据库领域。它的“Build Once, Run Everywhere”的特性大大减少了花在安装配置数据库环境上的时间,因为即使对于从事数据库多年的DBA而言,安装配置数据库环境依旧是一项看似简单但却经常不顺利的工作。当然,容器技术的其他优势也被很好的应用在数据库的使用中。

SequoiaDB作为一款优秀的国产分布式NewSQL数据库,已经得到了越来越多用户的认可。本文以Docker为例,着重介绍如何用Dockerfile快速构建SequoiaDB镜像,以及如何利用容器快速搭建和启动SequoiaDB集群供应用系统使用。

2. 构建SequoiaDB镜像

如何安装docker以及配置镜像仓库不是本文的重点,网上有很多相关的技术文章。需要指出的是本文采用阿里云镜像仓库,因为将镜像上传到Docker官方仓库的速度实在不敢恭维。如何注册和使用阿里云镜像仓库,可以参考文章(http://www.jb51.net/article/123101.htm)。

STEP 1:创建Dockerfile,内容如下,只需要几行简单的指令即可

# Sequoiadb DOCKERFILES PROJECT

# --------------------------

# This is the Dockerfile for Sequoiadb 2.8.4

#

# REQUIRED FILES TO BUILD THIS IMAGE

# ----------------------------------

# (1) sequoiadb-2.8.4-linux_x86_64-enterprise-installer.run

# (2) installSDB.sh

#

# HOW TO BUILD THIS IMAGE

# -----------------------

# Put all downloaded files in the same directory as this Dockerfile

# Run:

#      $ sudo docker build -t sequoiadb:2.8.4 .

#

# Pull base image

FROM ubuntu

# Environment variables required for this build

ENV INSTALL_BIN_FILE="sequoiadb-2.8.4-linux_x86_64-enterprise-installer.run" \

INSTALL_SDB_SCRIPT="installSDB.sh" \

INSTALL_DIR="/opt/sequoiadb"

# Copy binaries

ADD $INSTALL_BIN_FILE $INSTALL_SDB_SCRIPT $INSTALL_DIR/

# Install SDB software binaries

RUN chmod 755 $INSTALL_DIR/$INSTALL_SDB_SCRIPT \

&& $INSTALL_DIR/$INSTALL_SDB_SCRIPT \

&& rm $INSTALL_DIR/$INSTALL_SDB_SCRIPT

其中installSDB.sh脚本内容如下:

chmod 755 $INSTALL_DIR/$INSTALL_BIN_FILE

$INSTALL_DIR/$INSTALL_BIN_FILE --mode unattended

rm $INSTALL_DIR/$INSTALL_BIN_FILE

echo 'service sdbcm start' >> /root/.bashrc

需要注意的是本例采用Sequoiadb企业版2.8.4,您也可以从巨杉官网下载社区版(选择tar包,下载然后解压),替换本例中的介质名称。

巨杉官网下载地址:http://download.sequoiadb.com/cn/

STEP 2:创建镜像

root用户执行:

docker build -t sequoiadb:2.8.4 .

如果是普通用户,需要使用sudo:

sudo docker build -t sequoiadb:2.8.4 .

STEP3:登陆阿里云镜像仓库

docker login --username=xxx registry.cn-hangzhou.aliyuncs.com

其中xxx为您在阿里云注册的账号。

STEP4:查看本地sequoiadb镜像id

docker images

STEP5:标记本地镜像,将其归入阿里云仓库

docker tag 04dc528f2a6f registry.cn-hangzhou.aliyuncs.com/508mars/sequoiadb:latest

其中04dc528f2a6f是笔者本地sequoiadb镜像id,新的标记格式有一定要求,registry.cn-hangzhou.aliyuncs.com为阿里云仓库地址,508mars是笔者在阿里云的用户名,sequoiadb是镜像名,latest是tag。

STEP6:提交sequoiadb镜像到镜像库

docker push registry.cn-hangzhou.aliyuncs.com/508mars/sequoiadb:latest

3. 利用容器启动SequoiaDB集群

Docker的网络默认采用bridge模式,采用bridge模式的容器有如下特点:

1)同一宿主机的容器之间可以互相ping通

2)不同宿主机的容器之间互相ping不同

但是SequoiaDB集群要求所有节点之间是可以互通的,所以如果运行SequoiaDB的容器跑在不同宿主机上,docker的默认网络模式显然不合适。有很多种方法可以解决不同宿主机容器之间的连通性问题,本文只介绍weave虚拟网络这个解决方案,因为weave同时提供了一个DNS server的功能,有了该功能,在利用容器部署SequoiaDB集群时不再需要修改各个容器内部的/etc/hosts,大大简化了自动化部署的步骤。

STEP1:安装weave网络

curl -s -L git.io/weave -o /usr/local/bin/weave

chmod a+x /usr/local/bin/weave

需要在所有宿主机安装,笔者采用了三台虚拟机作为宿主机:sdb1, sdb2和sdb3。

STEP2:启动weave网络

weave launch

第一次启动时会下载weave镜像。

STEP3:从阿里云仓库下载sequoiadb镜像

docker pull registry.cn-hangzhou.aliyuncs.com/508mars/sequoiadb

STEP4:在所有宿主机创建docker的挂载卷

cd /home/sdbadmin

mkdir -p data/disk1 data/disk2 data/disk3

mkdir -p conf/local

chmod -R 777 data

chmod -R 777 conf

挂载卷的位置可以自定义,但总的来说需要创建两大类挂载卷,一类用来存放集合数据,如本例中的data/disk1, data/disk2, data/disk3,一类用来存放节点配置信息,如本例中的conf/local。这样即使容器被误删了,依旧可以启动一个新容器来扮演被误删的容器的角色。

STEP5:启动容器

sdb1:

weave stop

weave launch

eval $(weave env)

docker run -dit --name sdbserver1 -p 11810:11810 -v /home/sdbadmin/data:/data -v /home/sdbadmin/conf/local:/opt/sequoiadb/conf/local registry.cn-hangzhou.aliyuncs.com/508mars/sequoiadb

sdb2:

weave stop

weave launch 192.168.17.132

eval $(weave env)

docker run -dit --name sdbserver2 -p 11810:11810 -v /home/sdbadmin/data:/data -v /home/sdbadmin/conf/local:/opt/sequoiadb/conf/local registry.cn-hangzhou.aliyuncs.com/508mars/sequoiadb

sdb3:

weave stop

weave launch 192.168.17.132

eval $(weave env)

docker run -dit --name sdbserver3 -p 11810:11810 -v /home/sdbadmin/data:/data -v /home/sdbadmin/conf/local:/opt/sequoiadb/conf/local registry.cn-hangzhou.aliyuncs.com/508mars/sequoiadb

其中192.168.17.132是sdb1的IP地址,11810是对外暴露的集群访问端口。宿主机存放节点配置信息的卷必须挂到容器的/opt/sequoiadb/conf/local目录,存放表数据的卷可以挂载到用户自定义的目录,但是集群一旦创建后,不可更改。启动容器的时候必须指定机器名,因为在构建完集群后,机器名会被保存在SequoiaDB的系统表中,节点的机器名与系统表中不一致会导致无法加入到集群。在使用weave的场景下,建议使用--name选项,不要使用--hostname设置机器名。后者会阻止weave将机器名添加到DNS服务器,weave会自动根据--name的值来设置机器名,同时在机器名后增加weave.local域名,并添加到的DNS服务器。

STEP6:将创建SequoiaDB集群的脚本拷贝到容器中

docker cp create_cluster.js sdbserver1:/data

create_cluster.js内容如下:

var array_hosts = ["sdbserver1.weave.local", "sdbserver2.weave.local", "sdbserver3.weave.local"];

var array_dbroot = ["/data/disk1/sequoiadb/database","/data/disk2/sequoiadb/database","/data/disk3/sequoiadb/database"];

var port_sdbcm = "11790";

var port_temp_coord = "18888";

var cataloggroup = {gname:"SYSCatalogGroup", gport:"11820", ghosts:["sdbserver1.weave.local", "sdbserver2.weave.local", "sdbserver3.weave.local"]};

var array_coordgroups = [

{gname:"SYSCoord", gport:"11810", ghosts:["sdbserver1.weave.local", "sdbserver2.weave.local", "sdbserver3.weave.local"]}

];

var array_datagroups = [

{gname:"dg1", gport:"11830", ghosts:["sdbserver1.weave.local", "sdbserver2.weave.local", "sdbserver3.weave.local"], goptions:{transactionon:true}}

,{gname:"dg2", gport:"11840", ghosts:["sdbserver1.weave.local", "sdbserver2.weave.local", "sdbserver3.weave.local"], goptions:{transactionon:true}}

,{gname:"dg3", gport:"11850", ghosts:["sdbserver1.weave.local", "sdbserver2.weave.local", "sdbserver3.weave.local"], goptions:{transactionon:true}}

];

var array_domains = [

{dname:"allgroups", dgroups:["dg1", "dg2", "dg3"], doptions:{AutoSplit:true}}

];

println("启动临时协调节点");

var oma = new Oma(array_coordgroups[0].ghosts[0], port_sdbcm);

oma.createCoord(port_temp_coord, array_dbroot[0]+"/coord/"+port_temp_coord);

oma.startNode(port_temp_coord);

println("创建编目节点组:"+cataloggroup.ghosts[0]+"   "+cataloggroup.gport+"    "+array_dbroot[0]+"/cata/"+cataloggroup.gport);

var db = new Sdb(array_coordgroups[0].ghosts[0], port_temp_coord);

db.createCataRG(cataloggroup.ghosts[0], cataloggroup.gport, array_dbroot[0]+"/cata/"+cataloggroup.gport);

var cataRG = db.getRG("SYSCatalogGroup");

for (var i in cataloggroup.ghosts) {

if (i==0) {continue;}

println("创建编目节点: "+cataloggroup.ghosts[i]+"  "+cataloggroup.gport+"    "+array_dbroot[0]+"/cata/"+cataloggroup.gport);

var catanode = cataRG.createNode(cataloggroup.ghosts[i], cataloggroup.gport, array_dbroot[0]+"/cata/"+cataloggroup.gport);

catanode.start();

}

println("创建协调节点组");

var db = new Sdb(array_coordgroups[0].ghosts[0], port_temp_coord);

var coordRG = db.createCoordRG();

for (var i in array_coordgroups) {

for (var j in array_coordgroups[i].ghosts) {

println("创建协调节点组:"+array_coordgroups[i].ghosts[j]+"    "+array_coordgroups[i].gport+"    "+array_dbroot[0]+"/coord/"+array_coordgroups[i].gport);

coordRG.createNode(array_coordgroups[i].ghosts[j], array_coordgroups[i].gport, array_dbroot[0]+"/coord/"+array_coordgroups[i].gport);

}

}

coordRG.start();

println("删除临时协调节点")

var oma = new Oma(array_coordgroups[0].ghosts[0], port_sdbcm);

oma.removeCoord(port_temp_coord);

println("创建数据节点组")

var db = new Sdb(array_coordgroups[0].ghosts[0], array_coordgroups[0].gport);

var k=0;

for (var i in array_datagroups) {

var dataRG = db.createRG(array_datagroups[i].gname);

for (var j in array_datagroups[i].ghosts) {

println("创建数据节点:"+array_datagroups[i].gname+"    "+array_datagroups[i].ghosts[j]+"   "+array_datagroups[i].gport+"    "+array_dbroot[k]+"/data/"+array_datagroups[i].gport+"    "+array_datagroups[i].goptions)

dataRG.createNode(array_datagroups[i].ghosts[j], array_datagroups[i].gport, array_dbroot[k]+"/data/"+array_datagroups[i].gport, array_datagroups[i].goptions);

}

dataRG.start();

k++;

}

println("创建域");

var db = new Sdb(array_coordgroups[0].ghosts[0], array_coordgroups[0].gport);

for (var i in array_domains) {

println("创建域:"+array_domains[i].dname+"   "+array_domains[i].dgroups+"    "+array_domains[i].doptions)

db.createDomain(array_domains[i].dname, array_domains[i].dgroups, array_domains[i].doptions );

}

STEP7:创建SequoiaDB集群

docker exec sdbserver1 su - sdbadmin -c "sdb -f /data/create_cluster.js"

至此SequoiaDB集群创建并启动完成,后面再启动容器的时候集群会自动启动。

4. 结论

SequoiaDB利用容器技术很好的实现了集群快速部署,大大简化了初学者安装部署的难度。后期笔者还会在SequoiaDB镜像制作上做一些优化,因为目前做出来的镜像有点大,主要根源是采用ADD或COPY命令将安装介质拷贝到Docker容器中会生成一个新的镜像image1,最终生成的镜像image2中虽然删除了安装介质,但是它在image1之上,所以image2的大小依旧包含安装介质。最好采用ADD拷贝tar包(ADD会自动解压)或者采用类似如下的方式:

RUN mkdir -p /usr/src/things \

&& curl -SL http://example.com/big.tar.xz \

| tar -xJC /usr/src/things \

&& make -C /usr/src/things all

<END>

【技术解析】如何用Docker实现SequoiaDB集群的快速部署的更多相关文章

  1. 使用docker配置etcd集群

    docker配置etcd集群与直接部署etcd集群在配置上并没有什么太大差别. 我这里直接使用docker-compose来实现容器化的etcd部署 环境如下: HostName IP etcd1 1 ...

  2. Docker搭建PXC集群

    如何创建MySQL的PXC集群 下载PXC集群镜像文件 下载 docker pull percona/percona-xtradb-cluster 重命名 [root@hongshaorou ~]# ...

  3. 基于docker安装pxc集群

    基于docker安装pxc集群 一.PXC 集群的安装 PXC集群比较特殊,需要安装在 linux 或 Docker 之上.这里使用 Docker进行安装! Docker的镜像仓库中包含了 PXC数据 ...

  4. 庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

    庐山真面目之十二微服务架构基于Docker搭建Consul集群.Ocelot网关集群和IdentityServer版本实现 一.简介      在第七篇文章<庐山真面目之七微服务架构Consul ...

  5. #数据技术选型#即席查询Shib+Presto,集群任务调度HUE+Oozie

    郑昀 创建于2014/10/30 最后更新于2014/10/31   一)选型:Shib+Presto 应用场景:即席查询(Ad-hoc Query) 1.1.即席查询的目标 使用者是产品/运营/销售 ...

  6. docker安装hadoop集群

    docker安装hadoop集群?图啥呢?不图啥,就是图好玩.本篇博客主要是来教大家如何搭建一个docker的hadoop集群.不要问 为什么我要做这么无聊的事情,答案你也许知道,因为没有女票.... ...

  7. Docker 搭建 etcd 集群

    阅读目录: 主机安装 集群搭建 API 操作 API 说明和 etcdctl 命令说明 etcd 是 CoreOS 团队发起的一个开源项目(Go 语言,其实很多这类项目都是 Go 语言实现的,只能说很 ...

  8. docker~swarm搭建docker高可用集群

    回到目录 Swarm概念 Swarm是Docker公司推出的用来管理docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机.Swarm使用标准的Docker API接口作为其前端访问入 ...

  9. Docker 构建 RabbitMQ 集群

    刚开始,关于RabbitMQ集群的搭建,我找到了这篇文章:Docker 安装 RabbitMQ 集群 从而找到了第三方的RabbitMQ集群容器 rabbitmq-server 但是这个容器只有3.6 ...

随机推荐

  1. visual studio2015中开发python

    之前下载了visual studio2017但是发现很不好用,不如使用matlab与visual studio混合编程就根本找不到visual studio,只有下了visual studio2015 ...

  2. python接口自动化(二十六)--批量执行用例 discover(详解)

    简介 我们在写用例的时候,单个脚本的用例好执行,那么多个脚本的时候,如何批量执行呢?这时候就需要用到 unittest 里面的 discover 方法来加载用例了.加载用例后,用 unittest 里 ...

  3. Win10+RTX2080深度学习环境搭建:tensorflow、mxnet、pytorch、caffe

    目录 准备工作 设置conda国内镜像源 conda 深度学习环境 tensorflow.mxnet.pytorch安装 tensorflow mxnet pytorch Caffe安装 配置文件修改 ...

  4. Android Studio Run项目出现Failure [INSTALL_FAILED_TEST_ONLY]

    同名掘金博文:https://juejin.im/post/5c2e0c496fb9a049a711f09a 运行环境: AS 版 本:Android Studio 3.2.1 手机型号:vivo Y ...

  5. 8天入门docker系列 —— 第五天 使用aspnetcore小案例熟悉容器互联和docker-compose一键部署

    这一篇继续完善webnotebook,如果你读过上一篇的内容,你应该知道怎么去挂载webnotebook日志和容器的远程访问,但是这些还远不够,webnotebook 总要和一些数据库打交道吧,比如说 ...

  6. 详解mybatis映射配置文件

    一  mybatis 映射文件结构 mybatis映射配置文件存在如下顶级元素,且这些元素按照如下顺序被定义. cache – 给定命名空间的缓存配置. cache-ref – 其他命名空间缓存配置的 ...

  7. 如何高效的学习WEB前端

    IT 行业的变化快是众人皆知的,需要持续去学习新的知识内容.但是,往往我们工作之后,经常发现学习的东西很少了,学习效率非常低,感觉自己到了一个瓶颈期,久而久之,就演变成『一年工作经验,重复去用十年』的 ...

  8. Sharepoint 2013内容查询Web部件自定义显示样式(实战)

    分享人:广州华软 星尘 一. 前言 在进行Sharepoint开发时,经常会遇到内容展示个性化需求的问题,当然如果通过自定义开发控件对于内容展示的需求基本都可以很好的解决,但自定义开发也有不好的地方, ...

  9. 1、自动化运维之SaltStack实践

    自动化运维之SaltStack实践 1.1.环境 linux-node1(master服务端) 192.168.0.15 linux-node2(minion客户端) 192.168.0.16 1.2 ...

  10. 【原】无脑操作:Windows下搭建Kafka运行环境

    Kafka是一种高吞吐量的分布式发布订阅消息系统 1.优点:① 通过磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能.② 高吞吐量:即使是非常普通的硬件Kaf ...