为什么80%的码农都做不了架构师?>>>
用mysql-cluster-gpl-7.6.7搭建数据库集群
前言
当你的业务到达一定的当量,肯定需要一定数量的数据库来负载均衡你的数据库请求,但是有一个问题就是数据同步,因为负载均衡的前提就是,各个服务器的数据库是数据同步的。在业务量不大的时候,我们会使用主从复制的方法实现服务器数据同步,一主多从或者是双主等,但是虽然进行了读写分离,但是对于读的方法限制还是比较大,所以解决数据同步的问题就是数据库集群的意义。我这里使用mysql官网提供的mysql-cluster实现集群。
mysql cluster中的几个概念解释
为了简单,我后面简称mysql-cluster为mc。
1. mc已经包含了mysql,我下载的最新的mc7.6.7,官方说明包含的是mysql版本是7.6.7。所以不需要使用别的msyql的安装包安装数据库。同时注意mysql7.6.7的版本在安装的命令和配置上面和之前的版本有很大的不同,所以网上有很多mc7.6.7之前的版本,所包含的mysql版本不同,所以安装方法不同。
2. 管理节点,mc管理节点负责管理、配置、监控整个集群。
3. 数据节点,使用内存存放数据,保存进数据节点的数据都会自动复制并存储到其他数据节点。
4. mysql节点,也叫数据库节点,和我们平时使用的mysql相同,作为数据库使用。被数据节点访问。
架构图及说明
我实验中的配置就是如图所示,因为虚拟机占用内存较大,只使用了3台服务器,在实际情况中最好将数据节点和mysql节点分开。在实际中负载均衡服务还需要做备份,因为万一负载均衡服务器宕机将会导致所有数据节点都无法访问,所以需要对负载均衡服务器备份,有条件的话,分开管理节点和负载均衡器。实验只实现整个数据库集群,负载均衡请参考之前的博客配置即可。
在实际搭建过程中,IP地址有所变化:
hostname | ip | 说明 |
---|---|---|
mc.controller | 192.168.2.131 | 管理节点 |
mc.data1 | 192.168.2.132 | 数据节点1,mysql节点1 |
mc.data2 | 192.168.2.133 | 数据节点2,mysql节点2 |
下载mysql cluster
https://dev.mysql.com/downloads/cluster/
修改hosts
192.168.2.131 mc.controller
192.168.2.132 mc.data1
192.168.2.133 mc.data2
#执行以下命令关闭防火墙
[user@mc opt]systemctl stop firewalld && systemctl disable firewalld
[user@mc opt]setenforce 0
#将SELINUX的值改成disabled
[user@mc opt]vim /etc/selinux/config
SELINUX=disabled
安装数据和mysql节点
以下的所有操作需要在所有的集群节点都要进行相同的操作,即mc.data1、mc.data2
[user@mc opt] sudo mkdir -p /opt/mysql-cluster
[user@mc opt] sudo chown -R user:user mysql-cluster/
[user@mc opt] mv ~/mysql-cluster-gpl-7.6.7-linux-glibc2.12-x86_64.tar.gz /opt/mysql-cluster/
[user@mc opt] cd /opt/mysql-cluster
[user@mc opt]tar -zxvf mysql-cluster-gpl-7.6.7-linux-glibc2.12-x86_64.tar.gz
[user@mc opt] sudo mv /opt/mysql-cluster/mysql-cluster-gpl-7.6.7-linux-glibc2.12-x86_64/ /usr/local/mysql
[user@mc opt]cd /usr/local/mysql/bin
[user@mc opt]sudo ./mysqld --initialize --user=user --basedir=/usr/local/mysql
#启动mysql,修改密码
[user@mc bin]$ nohup ./mysqld &
[user@mc bin]$ ./mysql -uroot -h 127.0.0.1 -p
#输入上一步初始化时出现的密码
alter user user() identified by "你的密码";
grant all privileges on *.* to root@'%' identified by "你的密码";
flush privileges;
#将mysqld服务加入开机自启动项。
#首先需要将scripts/mysql.server服务脚本复制到/etc/init.d/,并重命名为mysqld。
[user@mc support-files]$ sudo cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
#添加环境变量
MYSQL_HOME=/usr/local/mysql
export PATH=$PATH:$MYSQL_HOME/bin
安装配置管理节点
#新建配置文件并且初始化管理节点
[user@mc opt]# vim /usr/local/mysql/config.ini
下面是配置文件,根据自己的需求修改,首先给出官网的默认配置文件,然后给出我的配置文件,根据我修改的修改即可,别的均可不动。
[ndbd default]
# Options affecting ndbd processes on all data nodes:
NoOfReplicas=2 # Number of replicas
DataMemory=80M # How much memory to allocate for data storage
IndexMemory=18M # How much memory to allocate for index storage
# For DataMemory and IndexMemory, we have used the
# default values. Since the "world" database takes up
# only about 500KB, this should be more than enough for
# this example NDB Cluster setup.
ServerPort=2202 # This the default value; however, you can use any
# port that is free for all the hosts in the cluster
# Note1: It is recommended that you do not specify the port
# number at all and simply allow the default value to be used
# instead
# Note2: The port was formerly specified using the PortNumber
# TCP parameter; this parameter is no longer available in NDB
# Cluster 7.5.
[ndb_mgmd]
# Management process options:
HostName=192.168.0.10 # Hostname or IP address of MGM node
DataDir=/var/lib/mysql-cluster # Directory for MGM node log files
[ndbd]
# Options for data node "A":
# (one [ndbd] section per data node)
HostName=192.168.0.30 # Hostname or IP address
NodeId=2 # Node ID for this data node
DataDir=/usr/local/mysql/data # Directory for this data node's data files
[ndbd]
# Options for data node "B":
HostName=192.168.0.40 # Hostname or IP address
NodeId=3 # Node ID for this data node
DataDir=/usr/local/mysql/data # Directory for this data node's data files
[mysqld]
# SQL node options:
HostName=192.168.0.20 # Hostname or IP address
# (additional mysqld connections can be
# specified for this node for various
# purposes such as running ndb_restore)
我自己的配置:
[NDBD DEFAULT]
NoOfReplicas=2 #定义在Cluster环境中相同数据的份数,最大为4
DataMemory=200M #每个数据节点中给数据分配的内存
IndexMemory=20M #每个数据节点中给索引分配的内存
MaxNoOfAttributes=20480 #该参数用于设置簇中触发程序对象的最大数目。该参数的默认值为768,不修改建表时可能会报708错误
[NDB_MGMD]
NodeId=1
#设置管理节点服务器
HostName=mc.controller
DataDir=/usr/local/mysql/data
[NDBD]
NodeId=2
#设置存储节点服务器(NDB节点)
HostName=mc.data1
DataDir=/usr/local/mysql/data
[NDBD]
NodeId=3
#第二个NDB节点
HostName=mc.data2
DataDir=/usr/local/mysql/data
[MYSQLD]
NodeId=4
HostName=mc.data1
[MYSQLD]
NodeId=5
HostName=mc.data2
使用配置文件初始化管理节点
/usr/local/mysql/bin/ndb_mgmd -f /usr/local/mysql/config.ini --initial
(#--initial:第一次启动时加上,其它时候不要加,不然会数据清空,除非是在备份、恢复或配置变化后重启时)
出现MySQL Cluster Management Server mysql-5.7.23 ndb-7.6.7就表示成功了
[user@mc mysql]$ ps -aux |grep ndb_mgmd
user 3500 1.0 0.6 502848 6672 ? Ssl 16:20 0:00 ./bin/ndb_mgmd -f config.ini --initial
user 3512 0.0 0.0 112720 980 pts/0 R+ 16:20 0:00 grep --color=auto ndb_mgmd
[root@mc bin]# ./ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=2 (not connected, accepting connect from mc.data1)
id=3 (not connected, accepting connect from mc.data2)
[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.2.131 (mysql-5.7.23 ndb-7.6.7)
[mysqld(API)] 2 node(s)
id=4 (not connected, accepting connect from mc.data1)
id=5 (not connected, accepting connect from mc.data2)
ndb_mgm> exit
[root@mc bin]#
配置数据和mysql节点
以下的所有操作需要在所有的集群节点都要进行相同的操作,即mc.data1、mc.data2
修改my.cnf配置文件
[mysqld]
ndbcluster #使用ndb集群引擎
ndb-connectstring=192.168.2.131 #指定管理集群的ip地址,多个以,分隔
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
#指定管理集群的ip地址,多个以,分隔
[mysql_cluster]
ndb-connectstring=192.168.2.131
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
在每台存储节点(ndbd)服务器上,如果是第一次启动ndbd进程的话,必须先执行以下命令:
[user@mc mysql]$ cd /usr/local/mysql/bin
[user@mc mysql]$ ./ndbd --initial
#注意,仅应在首次启动ndbd时,或在备份/恢复数据或配置文件发生变化后重启ndbd时使用“--initial”参数。因为该参数会使节点删除由早期ndbd实例创建的、用于恢复的任何文件,包括用于恢复的日志文件。如果不是第一次启动,直接运行如下命令即可
[user@mc mysql]$ cd /usr/local/mysql/bin
[user@mc mysql]$ ./ndbd
启动sql节点:
service mysqld start
查看集群状态
[user@mc bin]$ ./ndb_mgm
ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=2 @192.168.2.132 (mysql-5.7.23 ndb-7.6.7, Nodegroup: 0, *)
id=3 @192.168.2.133 (mysql-5.7.23 ndb-7.6.7, Nodegroup: 0)
[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.2.131 (mysql-5.7.23 ndb-7.6.7)
[mysqld(API)] 2 node(s)
id=4 @192.168.2.132 (mysql-5.7.23 ndb-7.6.7)
id=5 @192.168.2.133 (mysql-5.7.23 ndb-7.6.7)
启动和关闭
启动mysql集群。启动顺序为:管理节点→数据节点→SQL节点。
启动的命令上面都有,删去--initial即可
关闭时只需要关闭管理节点,后面的数据节点会同时被关闭,mysql就和原来一样即可
管理节点关闭命令:ndb_mgm -e shutdown
(执行完成之后管理节点会关闭,数据节点也会关闭,但SQL节点不会,也就是数据库服务需要手动到每一台服务器上停止以保证数据同步)
用nginx做负载均衡
nginx配置如下:
#user nobody;
worker_processes 2;
error_log /logs/error.log warn;
pid /logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
autoindex on;
#gzip on;
server {
listen 80;
server_name 192.168.2.169;
#charset koi8-r;
#access_log /wwwlogs/access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
stream {
upstream mysql {
server 192.168.2.132:3306 max_fails=2 fail_timeout=10s;
server 192.168.2.133:3306 max_fails=2 fail_timeout=10s;
}
server {
listen 3306;
proxy_pass mysql;
proxy_connect_timeout 10s;
#proxy_timeout 20s;
}
}
测试
数据表要加上ENGINE=ndbcluster才可以同步过去
连接 192.168.2.169:3306
create database mc_test;
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '用户名',
`password` varchar(200) NOT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=ndbcluster DEFAULT CHARSET=utf8;
INSERT INTO `mc_test`.`account` (`name`, `password`) VALUES ('2', '2');
连接 192.168.2.132:3306,192.168.2.133:3306
select * from account;