参考: https://www.jianshu.com/p/5e0062f6cf62
图中是两组分片,红色我们称为shard1,蓝色我们称为shard2
51 52是服务器
两个3307互为主从(双主),3309是本地3307的从库
说明:没有明确说明是只在某一个节点上做的,就是两个节点都做
两台虚拟机 db01 db02
每台创建四个mysql实例:3307 3308 3309 3310
mysql软件我们之前已完成二进制安装,直接初始化即可
我们server-id规划为:db01上是7/8/9/10,db02上是17/18/19/20
"箭头指向谁是主库"
10.0.0.51:3307<-----> 10.0.0.52:3307
10.0.0.51:3309------> 10.0.0.51:3307
10.0.0.52:3309------> 10.0.0.52:3307
两个分片,每个分片四个mysql节点
shard1:
Master:10.0.0.51:3307
slave1:10.0.0.51:3309
Standby Master:10.0.0.52:3307
slave2:10.0.0.52:3309
shard2:
Master:10.0.0.52:3308
slave1:10.0.0.52:3310
Standby Master:10.0.0.51:3308
slave2:10.0.0.51:3310
shard1
10.0.0.51:3307 <----->10.0.0.52:3307
db02
db01
db02
10.0.0.51:3309 ------>10.0.0.51:3307
db01
10.0.0.52:3309 ------>10.0.0.52:3307
db02
shard2
10.0.0.52:3308 <----->10.0.0.51:3308
db01
db02
db01
10.0.0.52:3310 ----->10.0.0.52:3308
db02
10.0.0.51:3310 ----->10.0.0.51:3308
db01
这个复制用户在谁上建都行
注:如果中间出现错误,在每个节点进行执行以下命令
常见方案:
360 Atlas-Sharding 360
Alibaba cobar 阿里
Mycat 开源
TDDL 淘宝
Heisenberg 百度
Oceanus 58同城
Vitess 谷歌
OneProxy
DRDS 阿里云
我们装的是openjdk,不是官方的那个
Mycat-server-xxxxx.linux.tar.gz
http://dl.mycat.io/
配置环境变量
我们mycat的命令也是在bin目录下
启动
8066就是对外提供服务的端口,9066是管理端口
连接mycat:
默认123456
db01:
我们一般先把原schema.xml备份,然后自己新写一个:
xml和html看起来差不多,xml是从下往上调用的
前三行我们不用看,直接从第四行schema开始看起:
定义了schema,然后以/schema结尾
为什么要用逻辑库?
业务透明化
此配置文件就是实现读写分离的配置
重启mycat
读写分离测试
总结:
以上案例实现了1主1从的读写分离功能,写 *** 作落到主库,读 *** 作落到从库.如果主库宕机,从库不能在继续提供服务了。
我们推荐这种架构
一写三读,
不设置双写的原因是:性能没提升多少,反而引起主键冲突的情况
配置文件:
之后重启:mycat restart
真正的 writehost:负责写 *** 作的writehost
standby writeHost :和readhost一样,只提供读服务
我们此处写了两个writehost,默认使用第一个
当写节点宕机后,后面跟的readhost也不提供服务,这时候standby的writehost就提供写服务,
后面跟的readhost提供读服务
测试:
读写分离测试
对db01 3307节点进行关闭和启动,测试读写 *** 作
结果应为另一台(52)的3307(17)是写,3309(19)是读
一旦7号节点恢复,此时因为7落后了,写节点仍是17
balance属性
负载均衡类型,目前的取值有3种:
writeType属性
负载均衡类型,目前的取值有2种:
switchType属性
-1 表示不自动切换
1 默认值,自动切换
2 基于MySQL主从同步的状态决定是否切换 ,心跳语句为 show slave status
datahost其他配置
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
maxCon="1000":最大的并发连接数
minCon="10" :mycat在启动之后,会在后端节点上自动开启的连接线程,长连接,好处是连接速度快,弊端是占内存
tempReadHostAvailable="1"
这个一主一从时(1个writehost,1个readhost时),可以开启这个参数,如果2个writehost,2个readhost时
<heartbeat>select user()</heartbeat> 监测心跳
其他参数sqlMaxLimit自动分页,必须在启用分表的情况下才生效
创建测试库和表:
我们重启mycat后连接到8066
发现跟一个库一样,实际上已经分到不同的物理硬件上了
分片:对一个"bigtable",比如说t3表
热点数据表 核心表
(1)行数非常多,800w下坡
(2)访问非常频繁
分片的目的:
(1)将大数据量进行分布存储
(2)提供均衡的访问路由
分片策略:
范围 range 800w 1-400w 400w01-800w 不适用于业务访问不均匀的情况
取模 mod(取余数) 和节点的数量进行取模
枚举 按枚举的种类分,如移动项目按省份分
哈希 hash
时间 流水
优化关联查询(否则join的表在不同分片上,效率会比单库还要低)
全局表
ER分片
案例:移动统一:先拆出边缘业务,再按地域分片,但对应用来说是统一的
vim rule.xml
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
<function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
===================================
vim autopartition-long.txt
0-10=0
11-20=1
创建测试表:
mysql -S /data/3307/mysql.sock -e "use taobaocreate table t3 (id int not null primary key auto_increment,name varchar(20) not null)"
mysql -S /data/3308/mysql.sock -e "use taobaocreate table t3 (id int not null primary key auto_increment,name varchar(20) not null)"
测试:
重启mycat
mycat restart
mysql -uroot -p123456 -h 127.0.0.1 -P 8066
insert into t3(id,name) values(1,'a')
insert into t3(id,name) values(2,'b')
insert into t3(id,name) values(3,'c')
insert into t3(id,name) values(4,'d')
insert into t3(id,name) values(11,'aa')
insert into t3(id,name) values(12,'bb')
insert into t3(id,name) values(13,'cc')
insert into t3(id,name) values(14,'dd')
取余分片方式:分片键(一个列)与节点数量进行取余,得到余数,将数据写入对应节点
vim schema.xml
<table name="t4" dataNode="sh1,sh2" rule="mod-long" />
vim rule.xml
<property name="count">2</property>
准备测试环境
创建测试表:
mysql -S /data/3307/mysql.sock -e "use taobaocreate table t4 (id int not null primary key auto_increment,name varchar(20) not null)"
mysql -S /data/3308/mysql.sock -e "use taobaocreate table t4 (id int not null primary key auto_increment,name varchar(20) not null)"
重启mycat
mycat restart
测试:
mysql -uroot -p123456 -h10.0.0.52 -P8066
use TESTDB
insert into t4(id,name) values(1,'a')
insert into t4(id,name) values(2,'b')
insert into t4(id,name) values(3,'c')
insert into t4(id,name) values(4,'d')
分别登录后端节点查询数据
mysql -S /data/3307/mysql.sock
use taobao
select * from t4
mysql -S /data/3308/mysql.sock
use taobao
select * from t4
t5 表
id name telnum
1 bj 1212
2 sh 22222
3 bj 3333
4 sh 44444
5 bj 5555
sharding-by-intfile
vim schema.xml
<table name="t5" dataNode="sh1,sh2" rule="sharding-by-intfile" />
vim rule.xml
<tableRule name="sharding-by-intfile">
<rule><columns>name</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
<property name="type">1</property>
<property name="defaultNode">0</property>
</function>
partition-hash-int.txt 配置:
bj=0
sh=1
DEFAULT_NODE=1
columns 标识将要分片的表字段,algorithm 分片函数, 其中分片函数配置中,mapFile标识配置文件名称
准备测试环境
mysql -S /data/3307/mysql.sock -e "use taobaocreate table t5 (id int not null primary key auto_increment,name varchar(20) not null)"
mysql -S /data/3308/mysql.sock -e "use taobaocreate table t5 (id int not null primary key auto_increment,name varchar(20) not null)"
重启mycat
mycat restart
mysql -uroot -p123456 -h10.0.0.51 -P8066
use TESTDB
insert into t5(id,name) values(1,'bj')
insert into t5(id,name) values(2,'sh')
insert into t5(id,name) values(3,'bj')
insert into t5(id,name) values(4,'sh')
insert into t5(id,name) values(5,'tj')
a b c d
join
t
select t1.name ,t.x from t1
join t
select t2.name ,t.x from t2
join t
select t3.name ,t.x from t3
join t
使用场景:
如果你的业务中有些数据类似于数据字典,比如配置文件的配置,
常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大,
而且大部分的业务场景都会用到,那么这种表适合于Mycat全局表,无须对数据进行切分,
要在所有的分片上保存一份数据即可,Mycat 在Join *** 作中,业务表与全局表进行Join聚合会优先选择相同分片内的全局表join,
避免跨库Join,在进行数据插入 *** 作时,mycat将把数据分发到全局表对应的所有分片执行,在进行数据读取时候将会随机获取一个节点读取数据。
vim schema.xml
<table name="t_area" primaryKey="id" type="global" dataNode="sh1,sh2" />
后端数据准备
mysql -S /data/3307/mysql.sock
use taobao
create table t_area (id int not null primary key auto_increment,name varchar(20) not null)
mysql -S /data/3308/mysql.sock
use taobao
create table t_area (id int not null primary key auto_increment,name varchar(20) not null)
重启mycat
mycat restart
测试:
mysql -uroot -p123456 -h10.0.0.52 -P8066
use TESTDB
insert into t_area(id,name) values(1,'a')
insert into t_area(id,name) values(2,'b')
insert into t_area(id,name) values(3,'c')
insert into t_area(id,name) values(4,'d')
A
join
B
为了防止跨分片join,可以使用E-R模式
A join B
on a.xx=b.yy
join C
on A.id=C.id
<table name="A" dataNode="sh1,sh2" rule="mod-long">
<childTable name="B" joinKey="yy" parentKey="xx" />
</table>
了解MySql必须牢牢记住其体系结构图,Mysql是由SQL接口,解析器,优化器,缓存,存储引擎组成的
1 Connectors指的是不同语言中与SQL的交互
2 Management Serveices &Utilities: 系统管理和控制工具
3 Connection Pool: 连接池。
管理缓冲用户连接,线程处理等需要缓存的需求
4 SQL Interface: SQL接口。
接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface
5 Parser: 解析器。
SQL命令传递到解析器的时候会被解析器验证和解析。解析器是由Lex和YACC实现的,是一个很长的脚本。
主要功能:
a . 将SQL语句分解成数据结构,并将这个结构传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的
b. 如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的
6 Optimizer: 查询优化器。
SQL语句在查询之前会使用查询优化器对查询进行优化。他使用的是“选取-投影-联接”策略进行查询。
用一个例子就可以理解: select uid,name from user where gender = 1
这个select 查询先根据where 语句进行选取,而不是先将表全部查询出来以后再进行gender过滤
这个select查询先根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤
将这两个查询条件联接起来生成最终查询结果
7 Cache和Buffer: 查询缓存。
如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。
这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等
8 Engine :存储引擎。
存储引擎是MySql中具体的与文件打交道的子系统。也是Mysql最具有特色的一个地方。
Mysql的存储引擎是插件式的。它根据MySql AB公司提供的文件访问层的一个抽象接口来定制一种文件访问机制(这种访问机制就叫存储引擎)
现在有很多种存储引擎,各个存储引擎的优势各不一样,最常用的MyISAM,InnoDB,BDB
默认下MySql是使用MyISAM引擎,它查询速度快,有较好的索引优化和数据压缩技术。但是它不支持事务。
InnoDB支持事务,并且提供行级的锁定,应用也相当广泛。 Mysql也支持自己定制存储引擎,甚至一个库中不同的表使用不同的存储引擎,这些都是允许的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)