MySQL数据切分、负载均衡和集群

1 系统环境

系统:CentOS 7。

版本:MySQL 5.6.35。

2 概述

3 数据切分(Sharding)

水平分库分表需用一个冗余字段(如id)作为切分依据和标记字段,常用有如下策略:

id取模,将不同段位id分配到对应库表。

hash取模,根据id的hash值,划分到不同库表。

路由表,由一个服务器保存id和对应库表的映射关系,通过查询该映射连接到对应库表。

3.1 分库

分库分表均有水平切分和垂直切分两种方式。水平切分即增加相同结构的数据库,库名不一样,分担单库存取压力;垂直切分即根据业务进行分析,把一个库里的表归类,分到不同的数据库里。

3.2 分表

水平切分即增加相同结构的数据表,表名不一样,分担单表的存取压力;垂直切分即根据业务进行分析,把一张表里的属性分类,分到不同的表里。

3.3 MySQL自带的分表分区功能

3.3.1 表分区

配置不同分区存储到指定路径

MySQL 5 之后才有数据表分区功能,仅支持水平分区,不支持垂直分区。分区后的表数据存储在不同的数据文件里,表还是一张表,只是数据存储在不同数据文件。如:

按RANGE分区:

CREATE TABLE emp (

id INT NOT NULLAUTO_INCREMENT,

nameVARCHAR(30),

age int,

addr text,

PRIMARY KEY(id)

)

PARTITION BY RANGE (id) (

PARTITION p0VALUES LESS THAN (3),

PARTITION p1VALUES LESS THAN (6),

PARTITION p2VALUES LESS THAN (10),

PARTITION p3VALUES LESS THAN MAXVALUE

);

查看分区文件:

[root@dn03 ~]# ll /var/lib/mysql/test/

total 512

-rw-rw—- 1 mysql mysql 61 Apr 17 09:41 db.opt

-rw-rw—- 1 mysql mysql 8644 Apr 17 10:05 emp.frm

-rw-rw—- 1 mysql mysql 32 Apr 17 10:05 emp.par

-rw-rw—- 1 mysql mysql 98304 Apr 17 10:07emp#P#p0.ibd

-rw-rw—- 1 mysql mysql 98304 Apr 17 10:07emp#P#p1.ibd

-rw-rw—- 1 mysql mysql 98304 Apr 17 10:07 emp#P#p2.ibd

-rw-rw—- 1 mysql mysql 98304 Apr 17 10:07emp#P#p3.ibd

MySQL数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.cnf中的datadir来查看),一张表主要对应着三个文件,一个是frm存放表结构的,一个是myd存放表数据的,一个是myi存表索引的。

3.3.1.1 分区类型

其实就是路由算法了。

RANGE分区:基于属于一个[给定连续区间]的列值,把多行分配给分区。

LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个[离散值集合]中的某个值来进行选择。

HASH分区:基于[用户定义的表达式的返回值]来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。

KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

复合分区:对分区的再次分区。

3.3.2 分表(merge引擎)

参考:https://www.cnblogs.com/miketwais/articles/mysql_partition.html

通过Merger存储引擎(mrg_myisam引擎)进行分表,是把一张大表分成多张子表,数据存储到各个子表里,大表不实际存储数据,只起到整合子表的作用,但可以对大表进行数据的CRUD操作,分表对上层应用来说是透明的。

注:

该方式仅适用myisam引擎的表。

ID如果自增的话,子表里可能含有相同ID,则根据ID查询主表,结果为最后一条子表插入的ID符合条件的数据。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
create table tb_member1(
    id bigint primary key auto_increment ,
    name varchar(20),
    sex tinyint not null default '0'
)ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
create table tb_member2(
    id bigint primary key auto_increment ,
    name varchar(20),
    sex tinyint not null default '0'
)ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
create table tb_member3 like tb_member1;
insert into tb_member1(id,name,sex) values (1,'jack','0');
insert into tb_member1(name,sex) select name,sex from tb_member1;
create table tb_member(
    id bigint primary key auto_increment ,
    name varchar(20),
    sex tinyint not null default '0'
)ENGINE=MERGE UNION=(tb_member1,tb_member2,tb_member3) INSERT_METHOD=LAST CHARSET=utf8 AUTO_INCREMENT=1 ;

3.3.3 表分区与分表的区别

分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表。分表和分区不矛盾,可以相互配合使用。

4 MySQL Cluster集群

MySQL集群包含3种节点:

管理(MGM)节点:负责管理MySQL Cluster内的其他节点,如提供配置数据、启动并停止节点、运行备份等。由于这类节点负责管理其他节点的配置,应在启动其他节点之前首先启动这类节点。MGM节点是用命令“ndb_mgmd”启动的。

数据节点:用于保存 Cluster的数据。数据节点的数目与副本的数目相关,是片段的倍数。数据节点是用命令“ndbd”启动的。

SQL节点:用来访问 Cluster数据的节点。也就是Mysql服务,可以使用service mysqld start启动。

管理服务器(MGM节点)负责管理 Cluster配置文件和 Cluster日志。 Cluster中的每个节点从管理服务器检索配置数据,并请求确定管理服务器所在位置的方式。当数据节点内出现新的事件时,节点将关于这类事件的信息传输到管理服务器,然后,将这类信息写入 Cluster日志。

“NDB” 是一种“内存中”的存储引擎,也是事务型存储引擎,具备ACID属性。

注:mysql-cluste与非集群时用的mysql-server与mysql-client没有任何关系,mysql-cluste安装包中已自带了集群用的server与client,启动mysql也是启动mysql-cluste中的mysql,与原先的mysql-server没有任何关系。

官方文档:https://dev.mysql.com/doc/refman/5.7/en/mysql-cluster.html

4.1 下载

下载地址:https://dev.mysql.com/downloads/cluster

选择合适版本下载,本文选择版本为:mysql-cluster-gpl-7.5.6-linux-glibc2.5-x86_64。

4.2 安装

官网文档:https://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-install-linux-binary.html

解压下载的tar.gz文件,将解压后的文件夹移动到合适位置。安装需在不同类型(管理节点、数据节点、SQL节点)的节点上进行。

本例集群规划如下:

节点类型

IP规划

SQL节点

192.168.1.210、192.168.1.212

数据节点

192.168.1.210、192.168.1.212

管理节点

192.168.1.213

在各个类型的节点上进行对应节点的操作。

4.2.1 SQL节点

4.2.1.1 创建mysql用户组和mysql用户

若系统不存在mysql用户和mysql用户组,则需创建:

# groupadd mysql

# useradd -g mysql -s /bin/false mysql

4.2.1.2 建立数据库

创建目录:

# mkdir /usr/local/mysql

进入解压包里的bin文件夹,执行以下命令建立数据库:

# ./mysqld –initialize

执行成功后将为MySQL root用户生成一个随机密码,记得记下该密码。

4.2.2 数据节点

添加ndbd和ndbmtd到系统bin目录:

# cp bin/ndbd /usr/local/bin/ndbd

# cp bin/ndbmtd /usr/local/bin/ndbmtd

设置权限:

# cd /usr/local/bin

# chmod +x ndb*

4.2.3 管理节点

# cp bin/ndb_mgm* /usr/local/bin

# cd /usr/local/bin

# chmod +x ndb_mgm*

4.3 配置

官网文档:https://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-install-configuration.html

4.3.1 配置数据节点和SQL节点

数据节点和SQL节点需要一个my.cnf文件,位于/etc目录:

# vi /etc/my.cnf

内容如下:

[mysqld]

# Options for mysqld process:

ndbcluster # run NDB storage engine

[mysql_cluster]

# Options for NDB Cluster processes:

ndb-connectstring=192.168.1.213 # location of management server

4.3.2 配置管理节点

管理节点需一个config.ini文件:

# mkdir /var/lib/mysql-cluster

# cd /var/lib/mysql-cluster

# vi config.ini

内容如下:

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
[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.1.213          # 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.1.210          # 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.1.212          # 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.1.210          # Hostname or IP address
                                # (additional mysqld connections can be
                                # specified for this node for various
                                # purposes such as running ndb_restore)
[mysqld]
# SQL node options:
HostName=192.168.1.212          # Hostname or IP address
                                # (additional mysqld connections can be
                                # specified for this node for various
                                # purposes such as running ndb_restore)

4.4 启动

官网文档:https://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-install-first-start.html

启动MySQL Cluster集群需要在各个节点上启动。

确保目录存在:/usr/local/mysql,不存在则创建。

4.4.1 启动管理节点

在管理节点上执行如下命令:

# ndb_mgmd -f /var/lib/mysql-cluster/config.ini

4.4.2 启动数据节点

在各个数据节点上执行如下命令:

# ndbd

2017-04-20 12:56:56 [ndbd] INFO — Angel connected to ‘192.168.1.213:1186’

2017-04-20 12:56:56 [ndbd] INFO — Angel allocated nodeid: 3

4.5 连接管理节点

如果一切操作成功,则可在管理节点上使用ndb_mgm命令连接集群管理节点:

# ndb_mgm

— NDB Cluster — Management Client —

ndb_mgm> show

Connected to Management Server at: localhost:1186

Cluster Configuration

———————

[ndbd(NDB)] 2node(s)

id=2 @192.168.1.210 (mysql-5.7.18ndb-7.5.6, Nodegroup: 0, *)

id=3 @192.168.1.212 (mysql-5.7.18ndb-7.5.6, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)

id=1 @192.168.1.213 (mysql-5.7.18ndb-7.5.6)

[mysqld(API)] 2node(s)

id=4 (not connected, accepting connect from192.168.1.210)

id=5 (not connected, accepting connect from192.168.1.212)

ndb_mgm>

4.6 关闭

在管理节点上执行:

# ndb_mgm -e shutdown

4.7 启动集群MySQL Server

在各个SQL节点上,进入集群解压包里的bin目录,执行:

# ./mysqld_safe –user=mysql&

若出现如下错误:

[root@dn01 bin]# Logging to’/usr/local/mysql/data/dn01.hadoop.fjmb.com.err’.

2017-04-20T09:01:11.350004Z mysqld_safe Starting mysqld daemonwith databases from /usr/local/mysql/data

2017-04-20T09:01:11.746171Z mysqld_safe mysqld from pid file/usr/local/mysql/data/dn01.hadoop.fjmb.com.pid ended

则执行如下命令,赋予mysql用户该路径的权限:

# chown -R mysql/usr/local/mysql/data

再次执行:

# ./mysqld_safe –user=mysql &

则成功启动mysql服务。

4.8 连接MySQL Server

进入mysql cluster bin目录,执行:

# ./mysql -u root -p

回车后根据提示输入密码则成功连接server,并进入mysql操作提示符。

4.8.1 创建NDBCLUSTER表

在一个节点上,创建数据库和表

mysql> CREATE DATABASE test;

mysql> USE test;

mysql> CREATE TABLE ctest (i INT) ENGINE=NDBCLUSTER;

mysql> SHOW CREATE TABLE ctest \G

则可在所有启动的数据节点上看到创建的库表。建表时注意引擎为:ENGINE=NDBCLUSTER 或者 ENGINE=NDB。

至此,NDB集群搭建成功。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享