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 amoeba@'%' 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 导致分片无效。

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

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

    MySQL数据库集群进行正确配置步骤 2010-06-09 10:47 arrowcat 博客园 字号:T | T 我们今天是要和大家一起分享的是对MySQL数据库集群进行正确配置,我前两天在相关网站 ...

  2. Facebook揭密:如何让MySQL数据库集群自主运行

    Facebook运行着全球最大的MySQL数据库集群,该集群分布在两个大洲上的多个数据中心中数以千计的服务器上.让人不解的是,Facebook只动用了一个很小的团队来管理这个庞大的MySQL数据库集群 ...

  3. 生产环境MySQL数据库集群MHA上线实施方案

    生产环境MySQL数据库集群MHA上线实施方案 一.不停库操作 1.在所有节点安装MHAnode所需的perl模块(需要有安装epel源) yum install perl-DBD-MySQL -y ...

  4. mysql数据库集群

    mysql数据库集群主要有2种常用方案: replication:速度快.弱一致性.适合保存低价值的数据,主要应用于日志.新闻.帖子等系统. PXC:速度慢.强一致性.适合保存高价值的数据,主要应用于 ...

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

    真机环境下MySQL-Cluster搭建文档  摘要:本年伊始阶段,由于实验室对不同数据库性能测试需求,才出现MySQL集群搭建.购置主机,交换机,双绞线等一系列准备工作就绪,也就开始集群搭建.起初笔 ...

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

    内容正式开始前,我已经在集群中添加了新的节点controller1(IP地址为10.0.0.14). 在所有节点上安装软件:# yum install -y mariadb-galera-server ...

  7. 数据库集群 MySQL主从复制

    MySQL主从复制 本节内容我们联系使用MySQL的主从复制功能配置Master和Slave节点,验证数据MySQL的数据同步功能. 因为要使用多个MySQL数据库,所以不建议在电脑上安装多个MySQ ...

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

    上一节,通过使用overlay网络,搭建了跨主机的docker容器集群.下面,在这个跨主机的docker容器集群环境下,搭建mysql 数据库集群. mysql主从自动备份和自动切换 从数据安全性考虑 ...

  9. mycat数据库集群系列之mysql主从同步设置

    最近在梳理数据库集群的相关操作,现在花点时间整理一下关于mysql数据库集群的操作总结,恰好你又在看这一块,供一份参考.本次系列终结大概包括以下内容:多数据库安装.mycat部署安装.数据库之读写分离 ...

随机推荐

  1. 【BZOJ2653】middle 二分+可持久化线段树

    [BZOJ2653]middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个 ...

  2. The Thinking of AutomaticTest(有关自动化测试的思考)

    考虑因素: 容易维护 简洁易懂 代码重用性好 系统的稳定性强 UI自动化:   数据的获取:装载的数据文件类型.数据的形式.数据的解析方法定义. 1.利用Junit单元测试组织用例,明确输入数据.预期 ...

  3. 巨蟒python全栈开发数据库前端4:CSS基础3

    1.float浮动 清除浮动 2.position定位&overflow溢出&z-index属性 3.定位补充 4.导航栏

  4. Spoken English Practice(not always estimating your status in other's hearts. you will lose yourself when you live in other's look. do your best and walk on you own way.)

    绿色:连读:                  红色:略读:               蓝色:浊化:               橙色:弱读     下划线_为浊化 口语蜕变(2017/7/8) 英 ...

  5. Share and NTFS Permission

    NTFS Permissions Share Permissions Share and NTFS Permission Similarities 共享权限和NTFS权限的相似性 Modifying ...

  6. 【Python之路】第十九篇--Python操作MySQL

    本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...

  7. 第08章—整合Spring Data JPA

    spring boot 系列学习记录:http://www.cnblogs.com/jinxiaohang/p/8111057.html 码云源码地址:https://gitee.com/jinxia ...

  8. pop 在列表中和字典中的区别

    pop 在列表中和字典中的区别 字典中 pop() 语法:dict.pop(key,[value]) 说明:删除指定键及对应的值,如果在字典中不存在键及value,则返回pop()中指定的key对应的 ...

  9. mybatis分享

    Mybatis入门 一.Mybatis环境搭建及简单实例 pom.xml mybatis-config.xml <?xml version="1.0" encoding=&q ...

  10. 【TensorFlow】tf.nn.conv2d是怎样实现卷积的?

    tf.nn.conv2d是TensorFlow里面实现卷积的函数,参考文档对它的介绍并不是很详细,实际上这是搭建卷积神经网络比较核心的一个方法,非常重要 tf.nn.conv2d(input, fil ...