VoltDB是内存关系型数据库和计算引擎,能在廉价服务器集群上实现每秒数百万次数据事务处理和毫秒级的平均延迟,提供了NoSQL数据库的可伸缩性和传统关系数据库系统的ACID一致性。通过将数据库表进行自动哈希分区来支持按CPU内核的高并发,同时也支持复制表。支持存储过程、物化视图、自定义函数来存储和检索数据。VoltDB也满足SQL92和大部分SQL99标准,能良好的运行在商用x86服务器、虚拟机和容器之上。它是Postgres和Vertica联合创始人、2014年图灵奖得主Michael Stonebraker领导开发的New SQL管理系统。
VoltDB支持数据持久化,但所有的运营数据都是在内存中,能够容纳的数据量取决于集群内所有节点的全部内存大小。所以VoltDB并不适合用来做数仓。VoltDB内部采用按CPU内核分区并行计算的MPP架构,适合对性能要求极高的OLTP和实时流计算场景。但是对于复杂的Ad-Hoc查询可能会碰到瓶颈,而有时我们的规划中还有使用MySQL等传统数据库的应用需要纳入统一的考虑。所以当遇见类似这样较复杂的混合应用场景时,典型的做法是使用VoltDB处理实时线上事务处理,并将原始数据和/或计算结果保存在HDFS、Hive以及MySQL中,做离线分析。同时我们使用Presto作为单一访问接口,进行跨数据源的即席查询。
当涉及这么多不同组件集群环境的搭建时,安装调试往往是个麻烦事,所幸通过Terraform自动化云平台发布脚本,只需一个命令就几乎可以完成以上集群运行环境的搭建。
本文的目的就是记录下本安装过程的脚本和踩坑过程,通过Terraform 实现自动在Alicloud创建集群,并自动完成VoltDB(企业试用版)、Hadoop/Hive(CDH 发行版)、MySQL、Presto(StarburstData发行版)的安装和配置、启动过程。本文部分内容参考自互联网,特别是Terraform安装CDH,如:https://github.com/danielfrg/terraform-cloudera
搭建好的集群如下图示意:
- Terraform脚本准备
Terraform 是一种安全有效地构建、更改和版本控制基础设施的工具(基础架构自动化的编排工具)。它的目标是 "Write, Plan, and create Infrastructure as Code", 基础架构即代码。Terraform 几乎可以支持所有市面上能见到的云服务。具体的说就是可以用代码来管理维护 IT 资源,把之前需要手动操作的一部分任务通过程序来自动化的完成。
Terraform 支持使用多个tf脚本文件,便于项目规划。
本文只使用单个tf文件:main.tf,如下所示的Terraform脚本以操作Alicloud为例。如需详细的元素解释请参阅Terraform官方文档:https://www.terraform.io/docs/providers/alicloud/index.html
provider "alicloud" {
access_key = "" #Alicloud 的访问key pair,可以在Alicloud生成后填入。
secret_key = ""
region = "ap-northeast-1"
}
#定义Coordinator 数量
variable "cdh_server" {
default = "1"
}
#定义Worker 数量
variable "cdh_node" {
default = "2"
}
#选择Linux 版本
variable "platform"{
default = "centos7"
}
#定义Coordinator主机名前缀
variable "cdh_server_prefix" {
description = "Prefix to use when naming cluster members"
default = "cdh-master"
}
#定义Worker主机名前缀
variable "cdh_node_prefix" {
description = "Prefix to use when naming cluster members"
default = "cdh-peer"
}
#定义Linux root登录密码
variable "password" {
type = "string"
default = "XXX"
}
#Alicloud 服务器区域
variable "availabe_zone" {
type = "string"
default = "ap-northeast-1a"
}
#Alicloud ECS 硬件配置
data "alicloud_instance_types" "hardware_cfg" {
cpu_core_count = 4
memory_size = 16
}
#定义VPC Internal IP
resource "alicloud_vpc" "vpc" {
name = "voltdb_cdh_test"
cidr_block = "172.16.0.0/12"
}
#定义Virtual Switch
resource "alicloud_vswitch" "vsw" {
vpc_id = "${alicloud_vpc.vpc.id}"
cidr_block = "172.16.0.0/21"
availability_zone = "${var.availabe_zone}"
}
#定义安全组
resource "alicloud_security_group" "default" {
name = "default"
vpc_id = "${alicloud_vpc.vpc.id}"
}
#定义默认安全访问规则
resource "alicloud_security_group_rule" "allow_all_tcp" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "1/65535"
priority = 1
security_group_id = "${alicloud_security_group.default.id}"
cidr_ip = "0.0.0.0/0"
}
#定义将要启动的Coordinator实例的配置
resource "alicloud_instance" "cdh_server" {
count = "${var.cdh_server}" #启动数量
# ECS 所在区域
availability_zone = "${var.availabe_zone}"
security_groups = ["${alicloud_security_group.default.*.id}"]
# ECS 实例的配置
instance_type = "${data.alicloud_instance_types.hardware_cfg.instance_types.0.id}"
system_disk_category = "cloud_efficiency"
#操作系统版本
image_id = "centos_7_04_64_20G_alibase_201701015.vhd"
#实例和主机名
instance_name = "${var.cdh_server_prefix}-${count.index}"
host_name = "${var.cdh_server_prefix}-${count.index}"
vswitch_id = "${alicloud_vswitch.vsw.id}"
#可用外部访问的最大带宽(5M)
internet_max_bandwidth_out = 5
#登录密码
password = "${var.password}"
}
#Coordinator实例启动后执行一系列动作,通过脚本完成安装和配置
resource "null_resource" "configure-ins-ips" {
count = "${var.cdh_server}"
connection {
type = "ssh"
user = "root"
host = "${element(alicloud_instance.cdh_server.*.public_ip, count.index)}"
password = "${var.password}"
}
provisioner "remote-exec" {
scripts = [
"${path.module}/scripts/${var.platform}/base.sh",
"${path.module}/scripts/${var.platform}/cloudera-repo.sh"
]
}
provisioner "remote-exec" {
script = "${path.module}/scripts/${var.platform}/cdh-server.sh"
}
provisioner "file" {
source = "${path.module}/scripts/${var.platform}/cdh-agent.sh"
destination = "/tmp/cdh-agent.sh"
}
provisioner "file" {
source = "${path.module}/scripts/${var.platform}/passwd-free-access.sh"
destination = "/tmp/passwd-free-access.sh"
}
provisioner "file" {
source = "${path.module}/scripts/${var.platform}/presto-install-master.sh"
destination = "/tmp/presto-install-master.sh"
}
provisioner "remote-exec" {
inline = [
"chmod +x /tmp/cdh-agent.sh",
"/tmp/cdh-agent.sh ${alicloud_instance.cdh_server.private_ip}",
]
}
provisioner "file" {
source = "${path.module}/scripts/${var.platform}/initialization_env.sh"
destination = "~/initialization_env.sh"
}
provisioner "remote-exec" {
inline = [
# Adds all cluster members' IP addresses to /etc/hosts (on each member)
"sudo echo '${join("\n", formatlist("%v", alicloud_instance.cdh_server.*.private_ip))}' | awk 'BEGIN{ print \"\\n\\n# Cluster members:\" }; { print $0 \