基于mysql数据库集群的360度水平切割

1.why sharding?

我们都知道,信息行业发展日益迅速,积累下来的数据信息越来越多,互联网公司门要维护的数据日益庞大。设想一下,假如腾讯公司只用一个数据库的一张表格来存储所有qq注册用户的登录相关信息,毫不夸张的说,那好比就是一场灾难,腾讯少说都有好几个亿的用户,所有的信息都存储在一个数据库的一张表中,那么我们的sleect语句那得多么的消耗硬件资源,用户体验度那是相当的差的,基本上不能去运行了,那谁还去用qq,那怎么办呢,数据分割这时候就派上用场了,它根据数据的特性,将一张表单上的内容根据实际需求分割成多张表单,存储在不同的真实的服务器器上,能够做到指定用户访问指定的服务器,缩小表单,减小单个服务器的压力。其实这样做带来的好处还远不止缩小了表单的大小,来提高用户体验,其实,将数据分割,还可以减小锁表的概率,不会去锁整张表的内容,提高了表的可用率,当单台数据库服务器宕机了,也是是损坏了数据的一小部分,不会导致所有的数据都丢失,数据切割能带来这么多好处,何乐而不为呢?

取模和用户量分布计算
取值说明: user_id % 360 这个取模值均匀的分布到这12台DB,
所有server的库名相同,表结构保持一致,
DB_Server1 0~30度 用户数量为:2583354
DB_Server2 31~60度 用户数量为:2500020
DB_Server3 61~90度 用户数量为:2500020
DB_Server4 91~120度 用户数量为:2500019
DB_Server5 121~150度 用户数量为:2499990
DB_Server6 151~180度 用户数量为:2499990
DB_Server7 181~210度 用户数量为:2499990
DB_Server8 211~240 度 用户数量为:2499990
DB_Server9 241~270 度 用户数量为:2499990
DB_Server10 271~300 度 用户数量为:2499990
DB_Server11 301~330 度 用户数量为:2499990
DB_Server12 331~360 度 用户数量为:2416657

DB架构图
当第一个360度环形库,用户量超过3000万怎么办???开始扩容第二个360度环形库

2.数据原型

数据原形:一个数据库,用来存储用户的编号,姓名,以及地址(当然,你可以有多个数据库作为数据原形,可以用到垂直分割进行处理,这里直接用一个数据库作为数据原型进行数据水平切割处理)因为仅仅是去实现水平分割,不做读写分离、也不配置双机热备,所以仅仅需要三台机器,两台独立的mysql服务器,一台amoeba代理服务器即可。

3.环境介绍

Mysql_server1--IP:192.168.1.135(服务器1)
Msyql_serrver2---IP:192.168.1.136(从服务器2)
Amoeba_server--IP:192.168.1.137(代理服务器)

4、设置Mysql_server1 Mysql_server2 设置Amoeba远程访问授权

(首先授权登录mysql服务器的用户,两台mysql服务器都要进行授权)
mysql-->grant all privileges on *.* to [email protected]‘%‘ identified by ‘amoeba‘;
mysql-->flush privileges;

5、创建测试表

(1)在Mysql_server1 和mysql_server2 上。注意:两边的表结构以及表名是一样的.
创建test表
create table test (
user_id integer unsigned not null,
user_name varchar(45),
user_address varchar(100),
primary key (user_id)
)engine=innodb;  ·  
Query OK, 0 rows affected (0.01 sec

6.amoeba.xml相关配置(安装amoeba略,见前一篇mysql的读写分离)

<?xml version="1.0" encoding="gbk"?>

<!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">
<amoeba:configuration xmlns:amoeba="">http://amoeba.meidusa.com/">

<!--
amoeba开放接口相关配置
-->
<server>
<!-- proxy server绑定的端口 -->
<property name="port">9006</property>

<!-- proxy server绑定的IP -->
<property name="ipAddress">192.168.1.137</property>

<!-- proxy server net IO Read thread size -->
<property name="readThreadPoolSize">20</property>

<!-- proxy server client process thread size -->
<property name="clientSideThreadPoolSize">30</property>

<!-- mysql server data packet process thread size -->
<property name="serverSideThreadPoolSize">30</property>

<!-- socket Send and receive BufferSize(unit:K) -->
<property name="netBufferSize">128</property>

<!-- Enable/disable TCP_NODELAY (disable/enable Nagle‘s algorithm). -->
<property name="tcpNoDelay">true</property>

<!-- 对外验证的用户名 -->
<property name="user">amoeba</property>

<!-- 对外验证的密码 -->
<property name="password">aixocm</property>

<!-- query timeout( default: 60 second , TimeUnit:second) -->
<property name="queryTimeout">60</property>
</server>

<!--
每个ConnectionManager都将作为一个线程启动。
manager负责Connection IO读写/死亡检测
-->
<connectionManagerList>
<connectionManager name="defaultManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">
<property name="subManagerClassName">com.meidusa.amoeba.net.AuthingableConnectionManager</property>

<!--
default value is avaliable Processors
<property name="processors">5</property>
-->
</connectionManager>
</connectionManagerList>

<dbServerList>
<!--
一台mysqlServer 需要配置一个pool,
如果多台 平等的mysql需要进行loadBalance,
平台已经提供一个具有负载均衡能力的objectPool:com.meidusa.amoeba.mysql.server.MultipleServerPool
简单的配置是属性加上 virtual="true",该Pool 不允许配置factoryConfig
或者自己写一个ObjectPool。
-->

<!--
mysql服务器授权相关设置
-->
<dbServer name="server1">

<!-- PoolableObjectFactory实现类 -->
<factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="manager">defaultManager</property>

<!-- 真实mysql数据库端口 -->
<property name="port">3306</property>

<!-- 真实mysql数据库IP -->
<property name="ipAddress">192.168.1.135</property>

<property name="schema">test</property>

<!-- 用于登陆mysql的用户名 -->
<property name="user">amoeba</property>

<!-- 用于登陆mysql的密码 -->
<property name="password">amoeba</property>

</factoryConfig>

<!-- ObjectPool实现类 -->
<poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
<property name="maxActive">200</property>
<property name="maxIdle">200</property>
<property name="minIdle">10</property>
<property name="minEvictableIdleTimeMillis">600000</property>
<property name="timeBetweenEvictionRunsMillis">600000</property>
<property name="testOnBorrow">true</property>
<property name="testWhileIdle">true</property>
</poolConfig>
</dbServer>

<!--
mysql服务器授权相关设置
-->
<dbServer name="server2">

<!-- PoolableObjectFactory实现类 -->
<factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="manager">defaultManager</property>

<!-- 真实mysql数据库端口 -->
<property name="port">3306</property>

<!-- 真实mysql数据库IP -->
<property name="ipAddress">192.168.1.136</property>

<property name="schema">test</property>

<!-- 用于登陆mysql的用户名 -->
<property name="user">amoeba</property>

<!-- 用于登陆mysql的密码 -->
<property name="password">amoeba</property>

</factoryConfig>

<!-- ObjectPool实现类 -->
<poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
<property name="maxActive">200</property>
<property name="maxIdle">200</property>
<property name="minIdle">10</property>
<property name="minEvictableIdleTimeMillis">600000</property>
<property name="timeBetweenEvictionRunsMillis">600000</property>
<property name="testOnBorrow">true</property>
<property name="testWhileIdle">true</property>
</poolConfig>
</dbServer>

</dbServerList>
<queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
<property name="ruleConfig">${amoeba.home}/conf/rule.xml</property>
<property name="functionConfig">${amoeba.home}/conf/functionMap.xml</property>
<property name="ruleFunctionConfig">${amoeba.home}/conf/ruleFunctionMap.xml</property>
<property name="LRUMapSize">1500</property>

<property name="defaultPool">server1</property>
<!--
;默认地址池一定要开启
<property name="writePool">master</property>
<property name="readPool">slave</property>
<property name="needParse">true</property>
-->
</queryRouter>
</amoeba:configuration>

7.rule.xml相关配置

基于user_id的水平分割,360水平分割法,前提user_id是连续的。

<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:rule SYSTEM "rule.dtd">

<amoeba:rule xmlns:amoeba="">http://amoeba.meidusa.com/">
<tableRule name="test" schema="test" defaultPools="server1,server2">

<rule name="rule1">
<parameters>user_id</parameters>
<expression><![CDATA[
user_id % 360 >=0 and user_id % 360 <=180         ;分成两份,(1-180)+360并且小于5000000存在一个数据库
]]></expression>
<defaultPools>server1</defaultPools>
<readPools>server1</readPools>
<writePools>server1</writePools>
</rule>

<rule name="rule2">
<parameters>user_id</parameters>
<expression><![CDATA[
user_id % 360 >=181 and user_id % 360 <=360     (181-360)+360并且小于5000000存在于一个数据库
]]></expression>
<defaultPools>server2</defaultPools>
<writePools>server2</writePools>
<readPools>server2</readPools>
</rule>
<!--
<rule name="rule4">
<parameters>ID</parameters>
<expression><![CDATA[ ID > 20000000 ]]></expression>
<defaultPools>server3</defaultPools>
</rule>

<rule name="rule3">
<parameters>ID,CREATE_TIME</parameters>
<expression><![CDATA[ID>4 or CREATE_TIME between to_date(‘2008-11-12 00:00:00.0000‘) and to_date(‘2008-12-10 00:00:00.0000‘) ]]></expression>
<defaultPools>server3</defaultPools>
</rule>
-->
</tableRule>

</amoeba:rule>

8.启动服务

#:nohup bash -x amoeba & 
这样的启动方法是为了方便查看启动的过程,会生成nohup.out的文件记录启动过程

重新启动服务需要先杀死已经启动的服务再重新启动服务

ps -ef|grep amoeba|awk ‘{print $2}‘|xargs kill -9

9、插入测试数据

在Amoeba Server登录:
# mysql -uamoeba -paixocm -h 192.168.1.137 -P 9006
mysql->use test;
mysql->insert into test(user_id,user_name,user_address) values(‘1‘,‘user1‘,‘China‘);
特别提示,一定要将表的数组名带上,特别是用来作为水平分割的数组名,如果不接上,分割失败,会在两个服务器上全部插入数据。
mysql->insert into test(user_id,user_name,user_address) values(‘2‘,‘user1‘,‘China‘);
mysql->insert into test(user_id,user_name,user_address) values(‘3‘,‘user1‘,‘China‘);
mysql->insert into test(user_id,user_name,user_address) values(‘181‘,‘user1‘,‘China‘);
mysql->insert into test(user_id,user_name,user_address) values(‘182‘,‘user1‘,‘China‘);
mysql->insert into test(user_id,user_name,user_address) values(‘183‘,‘user1‘,‘China‘);

mysql_server1查看,user_id在1-180数据全部写入了server1

mysql_server2查看,user_id在181-360数据全部写入了server2

10.总结:

(1)、amoeba 是根据 sql 解析来进行水平切分的, 需要把切分的关键字段(这里是user_id),加入到insert  sql 语句 中。否则 切分规则无效。无效后,会在 server1, server2 均都插入数据。

(2)、amoeba插入数据的时候必须先use  dbname(比如要先use test库名,或者查询带上库名和表名,test.t_user) 否则插入数据会默认插到server1上面

(3)、在rule.xml 指定的ID范围,在插入数据user_id的时候。不能超过这个范围,否则分片无效,
比如定义的ID范围为:
1-500000号
insert into zyalvin(user_id,user_name,user_address)values(‘5000001‘,‘user1‘,‘China‘); 如果插入ID超过5000000,变成了5000001的话那么这个数据将同时写到server1和server2 导致分片无效。

时间: 2024-12-14 06:37:48

基于mysql数据库集群的360度水平切割的相关文章

MySQL数据库集群进行正确配置步骤

MySQL数据库集群进行正确配置步骤 2010-06-09 10:47 arrowcat 博客园 字号:T | T 我们今天是要和大家一起分享的是对MySQL数据库集群进行正确配置,我前两天在相关网站看见的资料,今天拿出来供大家分享. AD:51CTO 网+首届APP创新评选大赛火热启动——超百万资源等你拿! 此文章主要向大家讲述的是对MySQL数据库集群进行正确配置的实际操作步骤,以及对其概念的讲述,如果你对其相关的实际操作有兴趣了解的话,以下的文章将会给你提供相关的知识. 一.介绍 这篇文档

配置mysql数据库集群

1.先在所有数据库服务器上安装mysql-cluster包 管理机:192.168.1.6 数据节点:192.168.1.31   192.168.1.32 sql节点:192.168.1.33    192.168.1.111 2.在管理节点上配置  [[email protected] ~]# vim /etc/config.ini [ndbd default]    //数据节点公共配置 noofreplicas=2   //数据备份数 datamemory=300M  //查询缓存 in

【Data Cluster】真机环境下MySQL数据库集群搭建

阅读目录 MySQL Cluster简介 mysql-cluster构造 虚拟机安装centos6.6 mysql-cluster下载 centos6.6搭建环境配置 mysql-cluster安装包导入cent中 集群配置 运行mysql-cluster 常见问题 测试 真机环境下MySQL-Cluster搭建文档  摘要:本年伊始阶段,由于实验室对不同数据库性能测试需求,才出现MySQL集群搭建.购置主机,交换机,双绞线等一系列准备工作就绪,也就开始集群搭建.起初笔者对此不甚了解,查阅很多资

MySQL数据库集群-PXC方案

第1章 课程摘要课程内容的概要介绍,包括课程目标,面向用户,预备知识,课程大纲,软件与硬件环境等. 1-1 课程导学1-2 开发环境要求 第2章 创建PXC集群学习安装与创建PXC集群,为了搭建三高特点的数据库集群,我们将把两组PXC集群组建成分片,由MyCat做数据切分与读写分离,然后对MyCat做集群,用Keepalived+Haproxy实现双机热备.了解数据库的基准测试与压力测试,掌握PXC的实际性能.... 2-1 CentOS安装PerconaServer数据库2-2 安装PXC组建

使用MySQL-Cluster搭建MySQL数据库集群

1.MySQL集群的作用: - 解决访问节点的单点故障 - 数据存储节点的单点故障 - 解决数据存储节点数据备份问题 2.集群: 使用一组服务器提供相同的服务 3.关于MySQL-Cluster: MySQL官方提供的集群版本 已集成标准版MySQL程序,可独立安装使用 采用NDB(Network DataBase)引擎 假定每个节点都有独立内存.硬盘 利用廉价硬件减少整个数据库的单点故障 4.集群中服务器的角色 - 数据节点:ndbd(单线程) ndb_mtd(多线程)   存储数据的(表里的

Linux系统运维之MYSQL数据库集群部署(主从复制)

一.介绍 Mysql主从复制,前段时间生产环境部署了一套主从复制的架构,当时现找了很多资料,现在记录下 二.拓扑图 三.环境以及软件版本 主机名 IP 操作系统 角色 软件版本 MysqlDB_Master 192.168.0.1 CentOS release 7.1 Master Mysql 5.6.36 MysqlDB_Slave 192.168.0.2 CentOS release 7.1 Slave Mysql 5.6.36 四.源码安装 之前都是yum直接安装的,这次尝试使用源码安装,

openstack controller ha测试环境搭建记录(四)——配置mysql数据库集群

内容正式开始前,我已经在集群中添加了新的节点controller1(IP地址为10.0.0.14). 安装软件:# yum install -y mariadb-galera-server xinetd rsync 创建用于健康检查的用户:# systemctl start mysqld.service# mysql -e "CREATE USER 'clustercheck'@'localhost' IDENTIFIED BY '123456';"# systemctl stop m

docker应用-6(mysql+mycat 搭建数据库集群)

上一节,通过使用overlay网络,搭建了跨主机的docker容器集群.下面,在这个跨主机的docker容器集群环境下,搭建mysql 数据库集群. mysql主从自动备份和自动切换 从数据安全性考虑,对数据库的数据进行及时备份非常重要.mysql就提供了主从备份的机制,从数据库会非常及时的将主数据库的操作更新到从库上,从而当主数据库down掉之后,数据不会丢失:同时,也可以通过keepalived等程序来实现主库down掉之后,迅速将数据访问服务切换到从库,从而尽可能维护数据库服务的不间断运行

?Postgres-XL:基于PostgreSQL的开源可扩展数据库集群

?Postgres-XL:基于PostgreSQL的开源可扩展数据库集群 最近这一年业界去"IOE"越叫越响,很多传统企业也把去"IOE"计划摆上了桌面.我老是想不明白这些非互联网企业(比如:银行)做这种事的动力何在? 高大上的"自主可控"."振兴民族科技"等空洞口号先不去管,真正的动力在哪里? "安全"."成本"."互联网架构".......等等.等等, 唯一看起来